hedgewars/GSHandlers.inc
changeset 5841 ef0a76e154cb
parent 5839 7ea0745912f7
child 5866 9017a0ff4201
equal deleted inserted replaced
5840:00a3e2452e79 5841:ef0a76e154cb
   957         then
   957         then
   958         Gear^.doStep := @doStepShotIdle
   958         Gear^.doStep := @doStepShotIdle
   959 end;
   959 end;
   960 
   960 
   961 ////////////////////////////////////////////////////////////////////////////////
   961 ////////////////////////////////////////////////////////////////////////////////
       
   962 procedure spawnBulletTrail(Bullet: PGear);
       
   963 var oX, oY: hwFloat;
       
   964     VGear: PVisualGear;
       
   965 begin
       
   966     if Bullet^.PortalCounter = 0 then
       
   967         begin
       
   968         ox:= CurrentHedgehog^.Gear^.X + Int2hwFloat(GetLaunchX(CurrentHedgehog^.CurAmmoType, hwSign(CurrentHedgehog^.Gear^.dX), CurrentHedgehog^.Gear^.Angle));
       
   969         oy:= CurrentHedgehog^.Gear^.Y + Int2hwFloat(GetLaunchY(CurrentHedgehog^.CurAmmoType, CurrentHedgehog^.Gear^.Angle));
       
   970         end
       
   971     else
       
   972         begin
       
   973         ox:= Bullet^.Elasticity;
       
   974         oy:= Bullet^.Friction;
       
   975         end;
       
   976 
       
   977         // Bullet trail
       
   978         VGear := AddVisualGear(hwRound(ox), hwRound(oy), vgtLineTrail);
       
   979         if VGear <> nil then
       
   980             begin
       
   981             VGear^.X:= hwFloat2Float(ox);
       
   982             VGear^.Y:= hwFloat2Float(oy);
       
   983             VGear^.dX:= hwFloat2Float(Bullet^.X);
       
   984             VGear^.dY:= hwFloat2Float(Bullet^.Y);
       
   985 
       
   986             // reached edge of land. assume infinite beam. Extend it way out past camera
       
   987             if (hwRound(Bullet^.X) and LAND_WIDTH_MASK <> 0)
       
   988                 or (hwRound(Bullet^.Y) and LAND_HEIGHT_MASK <> 0) then
       
   989                     // only extend if not under water
       
   990                     if hwRound(Bullet^.Y) < cWaterLine then
       
   991                         begin
       
   992                         VGear^.dX := VGear^.dX + LAND_WIDTH * (VGear^.dX - VGear^.X);
       
   993                         VGear^.dY := VGear^.dY + LAND_WIDTH * (VGear^.dY - VGear^.Y);
       
   994                         end;
       
   995 
       
   996             VGear^.Timer := 200;
       
   997             end;
       
   998 end;
       
   999 
   962 procedure doStepBulletWork(Gear: PGear);
  1000 procedure doStepBulletWork(Gear: PGear);
   963 var 
  1001 var 
   964     i, x, y: LongWord;
  1002     i, x, y: LongWord;
   965     oX, oY: hwFloat;
  1003     oX, oY: hwFloat;
   966     VGear: PVisualGear;
  1004     VGear: PVisualGear;
   975         Gear^.Y := Gear^.Y + Gear^.dY;
  1013         Gear^.Y := Gear^.Y + Gear^.dY;
   976         x := hwRound(Gear^.X);
  1014         x := hwRound(Gear^.X);
   977         y := hwRound(Gear^.Y);
  1015         y := hwRound(Gear^.Y);
   978         if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0)
  1016         if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0)
   979            and (Land[y, x] <> 0) then inc(Gear^.Damage);
  1017            and (Land[y, x] <> 0) then inc(Gear^.Damage);
       
  1018         // let's interrupt before a collision to give portals a chance to catch the bullet
       
  1019         if (Gear^.Damage = 1) and (Gear^.Tag = 0) and (Land[y, x] > 255) then
       
  1020         begin
       
  1021             Gear^.Tag := 1;
       
  1022             Gear^.Damage := 0;
       
  1023             Gear^.X := Gear^.X - Gear^.dX;
       
  1024             Gear^.Y := Gear^.Y - Gear^.dY;
       
  1025             CheckGearDrowning(Gear);
       
  1026             break;
       
  1027         end
       
  1028         else
       
  1029             Gear^.Tag := 0;
       
  1030 
   980         if Gear^.Damage > 5 then
  1031         if Gear^.Damage > 5 then
   981             if Gear^.AmmoType = amDEagle then
  1032             if Gear^.AmmoType = amDEagle then
   982                 AmmoShove(Gear, 7, 20)
  1033                 AmmoShove(Gear, 7, 20)
   983         else
  1034         else
   984             AmmoShove(Gear, Gear^.Timer, 20);
  1035             AmmoShove(Gear, Gear^.Timer, 20);
  1020             begin
  1071             begin
  1021                 VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY);
  1072                 VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY);
  1022             end;
  1073             end;
  1023         end;
  1074         end;
  1024        
  1075        
  1025         if Gear^.PortalCounter = 0 then
  1076         spawnBulletTrail(Gear);
  1026             begin 
       
  1027             // Bullet trail
       
  1028             VGear := AddVisualGear(
       
  1029                 hwround(CurrentHedgehog^.Gear^.X) + GetLaunchX(CurrentHedgehog^.CurAmmoType, hwSign(CurrentHedgehog^.Gear^.dX), CurrentHedgehog^.Gear^.Angle), 
       
  1030                 hwround(CurrentHedgehog^.Gear^.Y) + GetLaunchY(CurrentHedgehog^.CurAmmoType, CurrentHedgehog^.Gear^.Angle),
       
  1031                 vgtLineTrail
       
  1032             );
       
  1033             if VGear <> nil then
       
  1034                 begin
       
  1035                 // http://mantis.freepascal.org/view.php?id=17714 hits again
       
  1036                 VGear^.dX := Gear^.X.QWordValue / SignAs(_1,_1).QWordValue;
       
  1037                 VGear^.dY := Gear^.Y.QWordValue / SignAs(_1,_1).QWordValue;
       
  1038 
       
  1039                 if (Gear^.X.isNegative) then VGear^.dX:= -VGear^.dX;
       
  1040                 if (Gear^.Y.isNegative) then VGear^.dY:= -VGear^.dY;
       
  1041                 
       
  1042                 // reached edge of land. assume infinite beam. Extend it way out past camera
       
  1043                 if (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) 
       
  1044                     or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then
       
  1045                         // only extend if not under water
       
  1046                         if hwRound(Gear^.Y) < cWaterLine then
       
  1047                             begin
       
  1048                             VGear^.dX := VGear^.dX + LAND_WIDTH * (VGear^.dX - VGear^.X);
       
  1049                             VGear^.dY := VGear^.dY + LAND_WIDTH * (VGear^.dY - VGear^.Y);
       
  1050                             end;
       
  1051                 
       
  1052                 VGear^.Timer := 200;
       
  1053                 end
       
  1054             end;
       
  1055         Gear^.doStep := @doStepShotIdle
  1077         Gear^.doStep := @doStepShotIdle
  1056     end;
  1078     end;
  1057 end;
  1079 end;
  1058 
  1080 
  1059 procedure doStepDEagleShot(Gear: PGear);
  1081 procedure doStepDEagleShot(Gear: PGear);
  3929 
  3951 
  3930             if (hwRound(Distance(Gear^.X-ox,Gear^.Y-oy)) > Gear^.Radius + 1 ) then
  3952             if (hwRound(Distance(Gear^.X-ox,Gear^.Y-oy)) > Gear^.Radius + 1 ) then
  3931                 continue;
  3953                 continue;
  3932         end;
  3954         end;
  3933 
  3955 
       
  3956         // draw bullet trail
       
  3957         if isbullet then
       
  3958             spawnBulletTrail(iterator);
       
  3959 
  3934         // calc gear offset in portal vector direction
  3960         // calc gear offset in portal vector direction
  3935         ox := (iterator^.X - Gear^.X);
  3961         ox := (iterator^.X - Gear^.X);
  3936         oy := (iterator^.Y - Gear^.Y);
  3962         oy := (iterator^.Y - Gear^.Y);
  3937         poffs:= (Gear^.dX * ox + Gear^.dY * oy);
  3963         poffs:= (Gear^.dX * ox + Gear^.dY * oy);
  3938 
  3964 
  3939         if poffs < _0 then
  3965         if not isBullet and poffs.isNegative then
       
  3966             continue;
       
  3967 
       
  3968         // only port bullets close to the portal
       
  3969         if isBullet and not (hwAbs(poffs) < _3) then
  3940             continue;
  3970             continue;
  3941 
  3971 
  3942         //
  3972         //
  3943         // gears that make it till here will definately be ported
  3973         // gears that make it till here will definately be ported
  3944         //
  3974         //
  3962             ny.isNegative := not ny.isNegative;
  3992             ny.isNegative := not ny.isNegative;
  3963 
  3993 
  3964         // calc gear offset in portal normal vector direction
  3994         // calc gear offset in portal normal vector direction
  3965         noffs:= (nx * ox + ny * oy);
  3995         noffs:= (nx * ox + ny * oy);
  3966 
  3996 
       
  3997         if isBullet and (hwRound(hwAbs(noffs)) >= Gear^.Radius) then
       
  3998             continue;
       
  3999 
  3967         // avoid gravity related loops of not really moving gear
  4000         // avoid gravity related loops of not really moving gear
  3968         if not iscake and (Gear^.dY.isNegative) and (conPortal^.dY.isNegative)
  4001         if not (iscake or isbullet) and (Gear^.dY.isNegative) and (conPortal^.dY.isNegative)
  3969             and ((iterator^.dX.QWordValue + iterator^.dY.QWordValue) < _0_08.QWordValue)
  4002             and ((iterator^.dX.QWordValue + iterator^.dY.QWordValue) < _0_08.QWordValue)
  3970             and (iterator^.PortalCounter > 0) then
  4003             and (iterator^.PortalCounter > 0) then
  3971              continue;
  4004              continue;
  3972 
  4005 
  3973         // calc gear speed along to the vector and the normal vector of the portal
  4006         // calc gear speed along to the vector and the normal vector of the portal
  4077         if iscake then iterator^.PortalCounter:= 33
  4110         if iscake then iterator^.PortalCounter:= 33
  4078         else inc(iterator^.PortalCounter);
  4111         else inc(iterator^.PortalCounter);
  4079 
  4112 
  4080         if not isbullet and (iterator^.Kind <> gtFlake) then
  4113         if not isbullet and (iterator^.Kind <> gtFlake) then
  4081             FollowGear := iterator;
  4114             FollowGear := iterator;
       
  4115 
       
  4116         // store X/Y values of exit for net bullet trail
       
  4117         if isbullet then
       
  4118         begin
       
  4119             iterator^.Elasticity:= iterator^.X;
       
  4120             iterator^.Friction  := iterator^.Y;
       
  4121         end;
  4082 
  4122 
  4083         // This jiggles gears, to ensure a portal connection just placed under a gear takes effect.
  4123         // This jiggles gears, to ensure a portal connection just placed under a gear takes effect.
  4084         iterator:= GearsList;
  4124         iterator:= GearsList;
  4085         while iterator <> nil do
  4125         while iterator <> nil do
  4086             begin
  4126             begin