hedgewars/uGearsHedgehog.pas
branchwebgl
changeset 9950 2759212a27de
parent 9521 8054d9d775fd
parent 9917 1ca194a8b509
child 9954 bf51bc7e2808
equal deleted inserted replaced
9521:8054d9d775fd 9950:2759212a27de
    18 
    18 
    19 {$INCLUDE "options.inc"}
    19 {$INCLUDE "options.inc"}
    20 
    20 
    21 unit uGearsHedgehog;
    21 unit uGearsHedgehog;
    22 interface
    22 interface
    23 uses uTypes;
    23 uses uTypes, uGearsHandlersMess; 
    24 
    24 
    25 procedure doStepHedgehog(Gear: PGear);
    25 procedure doStepHedgehog(Gear: PGear);
    26 procedure AfterAttack;
    26 procedure AfterAttack;
    27 procedure HedgehogStep(Gear: PGear);
    27 procedure HedgehogStep(Gear: PGear);
    28 procedure doStepHedgehogMoving(Gear: PGear);
    28 procedure doStepHedgehogMoving(Gear: PGear);
    33 
    33 
    34 implementation
    34 implementation
    35 uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions,
    35 uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions,
    36     uCommands, uLocale, uUtils, uStats, uIO, uScript,
    36     uCommands, uLocale, uUtils, uStats, uIO, uScript,
    37     uGearsList, uCollisions, uRandom, uStore, uTeams,
    37     uGearsList, uCollisions, uRandom, uStore, uTeams,
    38     uGearsUtils, uVisualGearsList;
    38     uGearsUtils, uVisualGearsList, uChat;
    39 
    39 
    40 var GHStepTicks: LongWord = 0;
    40 var GHStepTicks: LongWord = 0;
       
    41 
       
    42 procedure AFKSkip;
       
    43 var
       
    44     t: byte;
       
    45 begin
       
    46     t:= 0;
       
    47     while (TeamsArray[t] <> CurrentTeam) do inc(t);
       
    48 
       
    49     SendHogSpeech(#1 + char(t) + 'AFK');
       
    50 
       
    51     ParseCommand('/skip', true)
       
    52 end;
    41 
    53 
    42 // Shouldn't more of this ammo switching stuff be moved to uAmmos ?
    54 // Shouldn't more of this ammo switching stuff be moved to uAmmos ?
    43 function ChangeAmmo(HHGear: PGear): boolean;
    55 function ChangeAmmo(HHGear: PGear): boolean;
    44 var slot, i: Longword;
    56 var slot, i: Longword;
    45     ammoidx: LongInt;
    57     ammoidx: LongInt;
    51 with HHGear^.Hedgehog^ do
    63 with HHGear^.Hedgehog^ do
    52     begin
    64     begin
    53     HHGear^.Message:= HHGear^.Message and (not gmSlot);
    65     HHGear^.Message:= HHGear^.Message and (not gmSlot);
    54     prevAmmo:= CurAmmoType;
    66     prevAmmo:= CurAmmoType;
    55     ammoidx:= 0;
    67     ammoidx:= 0;
    56     if ((HHGear^.State and (gstAttacking or gstAttacked)) <> 0)
    68     if (((HHGear^.State and (gstAttacking or gstAttacked)) <> 0) and (GameFlags and gfInfAttack = 0))
    57     or ((HHGear^.State and gstHHDriven) = 0) then
    69     or ((HHGear^.State and gstHHDriven) = 0) then
    58         exit;
    70         exit;
    59     ChangeAmmo:= true;
    71     ChangeAmmo:= true;
    60 
    72 
    61     while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> CurAmmoType) do
    73     while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> CurAmmoType) do
   112             LoadHedgehogHat(HHGear^.Hedgehog^, 'Reserved/chef')
   124             LoadHedgehogHat(HHGear^.Hedgehog^, 'Reserved/chef')
   113         else if prevAmmo = amKnife then
   125         else if prevAmmo = amKnife then
   114             LoadHedgehogHat(HHGear^.Hedgehog^, Hat);
   126             LoadHedgehogHat(HHGear^.Hedgehog^, Hat);
   115         end;
   127         end;
   116     // Try again in the next slot
   128     // Try again in the next slot
   117     if CurAmmoType = prevAmmo then
   129     if (CurAmmoType = prevAmmo) and (slot < cMaxSlotIndex) then 
   118         begin
   130         begin
   119         if slot >= cMaxSlotIndex then slot:= 0 else inc(slot);
   131         inc(slot);
   120         HHGear^.MsgParam:= slot;
   132         HHGear^.MsgParam:= slot;
   121         ChangeAmmo(HHGear)
   133         ChangeAmmo(HHGear)
   122         end
   134         end
   123     end
   135     end
   124 end;
   136 end;
   126 procedure HHSetWeapon(HHGear: PGear);
   138 procedure HHSetWeapon(HHGear: PGear);
   127 var t: LongInt;
   139 var t: LongInt;
   128     weap: TAmmoType;
   140     weap: TAmmoType;
   129     Hedgehog: PHedgehog;
   141     Hedgehog: PHedgehog;
   130     s: boolean;
   142     s: boolean;
       
   143     prevState, newState: LongWord;
   131 begin
   144 begin
   132 s:= false;
   145 s:= false;
   133 
   146 
   134 weap:= TAmmoType(HHGear^.MsgParam);
   147 weap:= TAmmoType(HHGear^.MsgParam);
   135 Hedgehog:= HHGear^.Hedgehog;
   148 Hedgehog:= HHGear^.Hedgehog;
   141 
   154 
   142 t:= cMaxSlotAmmoIndex;
   155 t:= cMaxSlotAmmoIndex;
   143 
   156 
   144 HHGear^.Message:= HHGear^.Message and (not gmWeapon);
   157 HHGear^.Message:= HHGear^.Message and (not gmWeapon);
   145 
   158 
       
   159 prevState:= HHGear^.State;
       
   160 newState:= prevState;
   146 with Hedgehog^ do
   161 with Hedgehog^ do
   147     while (CurAmmoType <> weap) and (t >= 0) do
   162     while (CurAmmoType <> weap) and (t >= 0) do
   148         begin
   163         begin
   149         s:= ChangeAmmo(HHGear);
   164         s:= ChangeAmmo(HHGear);
       
   165         if HHGear^.State <> prevState then // so we can keep gstAttacked out of consideration when looping
       
   166             newState:= HHGear^.State;
       
   167         HHGear^.State:= prevState;
   150         dec(t)
   168         dec(t)
   151         end;
   169         end;
       
   170 HHGear^.State:= newState;
   152 
   171 
   153 if s then
   172 if s then
   154     ApplyAmmoChanges(HHGear^.Hedgehog^)
   173     ApplyAmmoChanges(HHGear^.Hedgehog^)
   155 end;
   174 end;
   156 
   175 
   332                    amMineStrike: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 1, _0, _0, 0);
   351                    amMineStrike: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 1, _0, _0, 0);
   333                   amDrillStrike: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 3, _0, _0, CurWeapon^.Timer);
   352                   amDrillStrike: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 3, _0, _0, CurWeapon^.Timer);
   334                        amNapalm: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 2, _0, _0, 0);
   353                        amNapalm: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 2, _0, _0, 0);
   335                     amBlowTorch: newGear:= AddGear(hwRound(lx), hwRound(ly), gtBlowTorch, 0, SignAs(_0_5, dX), _0, 0);
   354                     amBlowTorch: newGear:= AddGear(hwRound(lx), hwRound(ly), gtBlowTorch, 0, SignAs(_0_5, dX), _0, 0);
   336                        amGirder: newGear:= AddGear(0, 0, gtGirder, CurWeapon^.Pos, _0, _0, 0);
   355                        amGirder: newGear:= AddGear(0, 0, gtGirder, CurWeapon^.Pos, _0, _0, 0);
       
   356                        amRubber: begin
       
   357                                  newGear:= AddGear(0, 0, gtGirder, CurWeapon^.Pos, _0, _0, 0);
       
   358                                  newGear^.AmmoType:= amRubber
       
   359                                  end;
   337                      amTeleport: newGear:= AddGear(CurWeapon^.Pos, 0, gtTeleport, 0, _0, _0, 0);
   360                      amTeleport: newGear:= AddGear(CurWeapon^.Pos, 0, gtTeleport, 0, _0, _0, 0);
   338                        amSwitch: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSwitcher, 0, _0, _0, 0);
   361                        amSwitch: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSwitcher, 0, _0, _0, 0);
   339                        amMortar: begin
   362                        amMortar: begin
   340                                  playSound(sndMortar);
   363                                  playSound(sndMortar);
   341                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtMortar,  0, xx*cMaxPower/cPowerDivisor, yy*cMaxPower/cPowerDivisor, 0);
   364                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtMortar,  0, xx*cMaxPower/cPowerDivisor, yy*cMaxPower/cPowerDivisor, 0);
   363                                  end;
   386                                  end;
   364                   amExtraDamage: begin
   387                   amExtraDamage: begin
   365                                  PlaySound(sndHellishImpact4);
   388                                  PlaySound(sndHellishImpact4);
   366                                  cDamageModifier:= _1_5
   389                                  cDamageModifier:= _1_5
   367                                  end;
   390                                  end;
   368                  amInvulnerable: Invulnerable:= true;
   391                  amInvulnerable: Effects[heInvulnerable]:= 1;
   369                     amExtraTime: begin
   392                     amExtraTime: begin
   370                                  PlaySound(sndSwitchHog);
   393                                  PlaySound(sndSwitchHog);
   371                                  TurnTimeLeft:= TurnTimeLeft + 30000
   394                                  TurnTimeLeft:= TurnTimeLeft + 30000
   372                                  end;
   395                                  end;
   373                    amLaserSight: cLaserSighting:= true;
   396                    amLaserSight: cLaserSighting:= true;
   388                   amResurrector: begin
   411                   amResurrector: begin
   389                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtResurrector, 0, _0, _0, 0);
   412                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtResurrector, 0, _0, _0, 0);
   390                                  newGear^.SoundChannel := LoopSound(sndResurrector);
   413                                  newGear^.SoundChannel := LoopSound(sndResurrector);
   391                                  end;
   414                                  end;
   392                     //amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
   415                     //amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
   393                        amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
   416                        amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 0);
   394                        amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
   417                        amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
   395             end;
   418             end;
   396             if altUse and (newGear <> nil) and 
   419             if altUse and (newGear <> nil) and 
   397                ((CurAmmoGear = nil) or (CurAmmoGear^.AmmoType <> amJetpack) or (Gear^.Message and gmPrecise = 0)) then
   420                ((CurAmmoGear = nil) or (CurAmmoGear^.AmmoType <> amJetpack) or (Gear^.Message and gmPrecise = 0)) then
   398                begin
   421                begin
   423                    amSeduction, amBallgun,
   446                    amSeduction, amBallgun,
   424                      amJetpack, amBirdy,
   447                      amJetpack, amBirdy,
   425                 amFlamethrower, amLandGun,
   448                 amFlamethrower, amLandGun,
   426                  amResurrector, //amStructure,
   449                  amResurrector, //amStructure,
   427                       amTardis, amPiano,
   450                       amTardis, amPiano,
   428                       amIceGun: CurAmmoGear:= newGear;
   451                       amIceGun, amRubber: CurAmmoGear:= newGear;
   429             end;
   452             end;
   430 
   453 
   431             if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then
   454             if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then
   432                 newGear^.FlightTime:= GameTicks + 1000
   455                 newGear^.FlightTime:= GameTicks + 1000
   433             else if CurAmmoType = amDrill then
   456             else if CurAmmoType = amDrill then
   745     if ((Gear^.Message and gmLJump ) <> 0) then
   768     if ((Gear^.Message and gmLJump ) <> 0) then
   746         begin
   769         begin
   747         Gear^.Message:= Gear^.Message and (not gmLJump);
   770         Gear^.Message:= Gear^.Message and (not gmLJump);
   748         DeleteCI(Gear);
   771         DeleteCI(Gear);
   749         if TestCollisionYwithGear(Gear, -1) = 0 then
   772         if TestCollisionYwithGear(Gear, -1) = 0 then
   750             if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then
   773             if TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) = 0 then
   751                 Gear^.Y:= Gear^.Y - _2
   774                 Gear^.Y:= Gear^.Y - _2
   752             else
   775             else
   753                 if not TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) then
   776                 if TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) = 0 then
   754                     Gear^.Y:= Gear^.Y - _1;
   777                     Gear^.Y:= Gear^.Y - _1;
   755             if not (TestCollisionXwithGear(Gear, hwSign(Gear^.dX))
   778             if (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) = 0) and
   756             or   (TestCollisionYwithGear(Gear, -1) <> 0)) then
   779                (TestCollisionYwithGear(Gear, -1) = 0) then
   757                 begin
   780                 begin
   758                 Gear^.dY:= -_0_15;
   781                 Gear^.dY:= -_0_15;
   759                 if not cArtillery then
   782                 if not cArtillery then
   760                     Gear^.dX:= SignAs(_0_15, Gear^.dX);
   783                     Gear^.dX:= SignAs(_0_15, Gear^.dX);
   761                 Gear^.State:= Gear^.State or gstMoving or gstHHJumping;
   784                 Gear^.State:= Gear^.State or gstMoving or gstHHJumping;
   839     Gear^.dY:= _0;
   862     Gear^.dY:= _0;
   840     Gear^.dX:= _0;
   863     Gear^.dX:= _0;
   841     Gear^.State:= Gear^.State and (not gstMoving);
   864     Gear^.State:= Gear^.State and (not gstMoving);
   842     exit
   865     exit
   843     end;
   866     end;
   844 isFalling:= (Gear^.dY.isNegative) or (not TestCollisionYKick(Gear, 1));
   867 isFalling:= (Gear^.dY.isNegative) or (TestCollisionYKick(Gear, 1) = 0);
   845 if isFalling then
   868 if isFalling then
   846     begin
   869     begin
   847     if (Gear^.dY.isNegative) and TestCollisionYKick(Gear, -1) then
   870     land:= TestCollisionYKick(Gear, -1);
   848         Gear^.dY:= _0;
   871     if (Gear^.dY.isNegative) and (land <> 0) then
       
   872         begin
       
   873         if land and lfBouncy <> 0 then
       
   874             begin
       
   875             doStepFallingGear(Gear);
       
   876             Gear^.dX:= Gear^.dX * _0_8
       
   877             end;
       
   878         if (land and lfBouncy = 0) or (Gear^.State and gstCollision <> 0) then
       
   879             Gear^.dY:= _0;
       
   880         Gear^.State:= Gear^.State and not gstCollision 
       
   881         end;
   849     Gear^.State:= Gear^.State or gstMoving;
   882     Gear^.State:= Gear^.State or gstMoving;
   850     if (CurrentHedgehog^.Gear = Gear) and (CurrentHedgehog^.Gear^.State and gstHHDriven <> 0) and
   883     if (CurrentHedgehog^.Gear = Gear) and (CurrentHedgehog^.Gear^.State and gstHHDriven <> 0) and
   851        (not CurrentTeam^.ExtDriven) and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then
   884        (not CurrentTeam^.ExtDriven) and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then
   852         begin
   885         begin
   853         // TODO: why so aggressive at setting FollowGear when falling?
   886         // TODO: why so aggressive at setting FollowGear when falling?
   868         end
   901         end
   869     end
   902     end
   870 else
   903 else
   871     begin
   904     begin
   872     land:= TestCollisionYwithGear(Gear, 1);
   905     land:= TestCollisionYwithGear(Gear, 1);
   873     if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_55.QWordValue) and ((land and lfIce) = 0)
   906     if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_55.QWordValue) and ((land and lfIce) = 0) 
       
   907     and ((land and lfBouncy = 0) or (Gear^.State and gstCollision <> 0)) 
   874     and ((Gear^.State and gstHHJumping) <> 0) then
   908     and ((Gear^.State and gstHHJumping) <> 0) then
   875         SetLittle(Gear^.dX);
   909         SetLittle(Gear^.dX);
   876 
   910 
   877     if not Gear^.dY.isNegative then
   911     if not Gear^.dY.isNegative then
   878         begin
   912         begin
       
   913         if land and lfBouncy <> 0 then
       
   914             begin
       
   915             doStepFallingGear(Gear);
       
   916             // hogs for some reason have very low friction. slippery little buggers
       
   917             Gear^.dX:= Gear^.dX * _0_8
       
   918             end;
       
   919 
   879         CheckHHDamage(Gear);
   920         CheckHHDamage(Gear);
   880 
   921 
   881         if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery)
   922         if (land and lfBouncy = 0) or (Gear^.State and gstCollision <> 0) then
   882         and (Gear^.dX.QWordValue < _0_02.QWordValue) then
   923             begin
   883             Gear^.dX.isNegative:= not Gear^.dX.isNegative; // landing after high jump
   924             if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery)
   884         Gear^.State:= Gear^.State and (not (gstHHJumping or gstHHHJump));
   925             and (Gear^.dX.QWordValue < _0_02.QWordValue) then
   885         Gear^.dY:= _0;
   926                 begin
       
   927                 if land and lfBouncy <> 0 then
       
   928                     Gear^.dY:= _0;
       
   929                 Gear^.dX.isNegative:= not Gear^.dX.isNegative // landing after high jump
       
   930                 end;
       
   931             Gear^.State:= Gear^.State and (not (gstHHJumping or gstHHHJump));
       
   932             if (land and lfBouncy = 0) or (Gear^.dX.QWordValue < _0_02.QWordValue) then
       
   933                 Gear^.dY:= _0
       
   934             end;
       
   935         Gear^.State:= Gear^.State and not gstCollision 
   886         end
   936         end
   887     else
   937     else
   888         Gear^.dY:= Gear^.dY + cGravity;
   938         Gear^.dY:= Gear^.dY + cGravity;
   889 
   939 
   890     if ((Gear^.State and gstMoving) <> 0) then
   940     if ((Gear^.State and gstMoving) <> 0) then
   906    Gear^.dY:= Gear^.dY * _0_999;
   956    Gear^.dY:= Gear^.dY * _0_999;
   907    Gear^.dX:= Gear^.dX * _0_999;
   957    Gear^.dX:= Gear^.dX * _0_999;
   908    end;
   958    end;
   909 
   959 
   910 if (Gear^.State and gstMoving) <> 0 then
   960 if (Gear^.State and gstMoving) <> 0 then
   911     if TestCollisionXKick(Gear, hwSign(Gear^.dX)) then
   961     if TestCollisionXKick(Gear, hwSign(Gear^.dX)) <> 0 then
   912         if not isFalling then
   962         if not isFalling then
   913             if hwAbs(Gear^.dX) > _0_01 then
   963             if hwAbs(Gear^.dX) > _0_01 then
   914                 if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -1, hwSign(Gear^.dX)) or
   964                 if  (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -1, hwSign(Gear^.dX)) = 0) and
   915                 (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
   965                     (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1) = 0) then
   916                     begin
   966                     begin
   917                     Gear^.X:= Gear^.X + Gear^.dX;
   967                     Gear^.X:= Gear^.X + Gear^.dX;
   918                     Gear^.dX:= Gear^.dX * _0_96;
   968                     Gear^.dX:= Gear^.dX * _0_96;
   919                     Gear^.Y:= Gear^.Y - _1
   969                     Gear^.Y:= Gear^.Y - _1
   920                     end
   970                     end
   921                 else
   971                 else
   922                     if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) or
   972                     if  (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) = 0) and
   923                         (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
   973                         (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1) = 0) then
   924                         begin
   974                         begin
   925                         Gear^.X:= Gear^.X + Gear^.dX;
   975                         Gear^.X:= Gear^.X + Gear^.dX;
   926                         Gear^.dX:= Gear^.dX * _0_93;
   976                         Gear^.dX:= Gear^.dX * _0_93;
   927                         Gear^.Y:= Gear^.Y - _2
   977                         Gear^.Y:= Gear^.Y - _2
   928                         end
   978                         end
   929                     else
   979                     else
   930                     if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) or
   980                     if  (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) = 0) and
   931                         (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
   981                         (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1) = 0) then
   932                         begin
   982                         begin
   933                         Gear^.X:= Gear^.X + Gear^.dX;
   983                         Gear^.X:= Gear^.X + Gear^.dX;
   934                         Gear^.dX:= Gear^.dX * _0_9 ;
   984                         Gear^.dX:= Gear^.dX * _0_9 ;
   935                         Gear^.Y:= Gear^.Y - _3
   985                         Gear^.Y:= Gear^.Y - _3
   936                         end
   986                         end
   937                     else
   987                     else
   938                         if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -4, hwSign(Gear^.dX)) or
   988                         if (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -4, hwSign(Gear^.dX)) = 0) and
   939                         (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
   989                            (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1) = 0) then
   940                             begin
   990                             begin
   941                             Gear^.X:= Gear^.X + Gear^.dX;
   991                             Gear^.X:= Gear^.X + Gear^.dX;
   942                             Gear^.dX:= Gear^.dX * _0_87;
   992                             Gear^.dX:= Gear^.dX * _0_87;
   943                             Gear^.Y:= Gear^.Y - _4
   993                             Gear^.Y:= Gear^.Y - _4
   944                             end
   994                             end
   945                     else
   995                     else
   946                         if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -5, hwSign(Gear^.dX)) or
   996                         if (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -5, hwSign(Gear^.dX)) = 0) and
   947                         (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
   997                            (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1) = 0) then
   948                             begin
   998                             begin
   949                             Gear^.X:= Gear^.X + Gear^.dX;
   999                             Gear^.X:= Gear^.X + Gear^.dX;
   950                             Gear^.dX:= Gear^.dX * _0_84;
  1000                             Gear^.dX:= Gear^.dX * _0_84;
   951                             Gear^.Y:= Gear^.Y - _5
  1001                             Gear^.Y:= Gear^.Y - _5
   952                             end
  1002                             end
   976 if (not isFalling)
  1026 if (not isFalling)
   977   and (hwAbs(Gear^.dX) + hwAbs(Gear^.dY) < _0_03) then
  1027   and (hwAbs(Gear^.dX) + hwAbs(Gear^.dY) < _0_03) then
   978     begin
  1028     begin
   979     Gear^.State:= Gear^.State and (not gstWinner);
  1029     Gear^.State:= Gear^.State and (not gstWinner);
   980     Gear^.State:= Gear^.State and (not gstMoving);
  1030     Gear^.State:= Gear^.State and (not gstMoving);
   981     while (TestCollisionYWithGear(Gear,1) = 0) and (not CheckGearDrowning(Gear)) and (Gear <> nil) do
  1031     while (not CheckGearDrowning(Gear)) and (Gear <> nil) and (TestCollisionYWithGear(Gear,1) = 0) do
   982         Gear^.Y:= Gear^.Y + _1;
  1032         Gear^.Y:= Gear^.Y + _1;
   983 
  1033 
   984     // could become nil in CheckGearDrowning if ai's hog fails to respawn in ai survival
  1034     // could become nil in CheckGearDrowning if ai's hog fails to respawn in ai survival
   985     if Gear = nil then exit;
  1035     if Gear = nil then exit;
   986     SetLittle(Gear^.dX);
  1036     SetLittle(Gear^.dX);
   993     begin
  1043     begin
   994     Gear^.State:= Gear^.State and (not gstAnimation);
  1044     Gear^.State:= Gear^.State and (not gstAnimation);
   995 // ARTILLERY but not being moved by explosions
  1045 // ARTILLERY but not being moved by explosions
   996     Gear^.X:= Gear^.X + Gear^.dX;
  1046     Gear^.X:= Gear^.X + Gear^.dX;
   997     Gear^.Y:= Gear^.Y + Gear^.dY;
  1047     Gear^.Y:= Gear^.Y + Gear^.dY;
   998     if (not Gear^.dY.isNegative) and (not TestCollisionYKick(Gear, 1))
  1048     if (not Gear^.dY.isNegative) and (TestCollisionYKick(Gear, 1) = 0) then
   999     and TestCollisionYwithXYShift(Gear, 0, 1, 1) then
  1049         begin
  1000         begin
  1050         land:= TestCollisionYwithXYShift(Gear, 0, 1, 1);
  1001         CheckHHDamage(Gear);
  1051         if land and lfBouncy <> 0 then
  1002         Gear^.dY:= _0;
  1052             doStepFallingGear(Gear);
  1003         Gear^.Y:= Gear^.Y + _1
  1053 
  1004         end;
  1054         if (land <> 0) and ((land and lfBouncy = 0) or (Gear^.State and gstCollision <> 0)) then
  1005 
  1055             begin
  1006     CheckGearDrowning(Gear);
  1056             CheckHHDamage(Gear);
       
  1057             Gear^.dY:= _0;
       
  1058             Gear^.Y:= Gear^.Y + _1
       
  1059             end;
       
  1060         Gear^.State:= Gear^.State and not gstCollision 
       
  1061         end;
       
  1062 
  1007     // could become nil if ai's hog fails to respawn in ai survival
  1063     // could become nil if ai's hog fails to respawn in ai survival
  1008     if Gear = nil then exit;
  1064     if Gear = nil then exit;
  1009     // hide target cursor if current hog is drowning
  1065     // hide target cursor if current hog is drowning
  1010     if (Gear^.State and gstDrowning) <> 0 then
  1066     if (Gear^.State and gstDrowning) <> 0 then
  1011         if (CurrentHedgehog^.Gear = Gear) then
  1067         if (CurrentHedgehog^.Gear = Gear) then
  1058     if HHGear^.Damage > 0 then
  1114     if HHGear^.Damage > 0 then
  1059         HHGear^.State:= HHGear^.State and (not (gstHHJumping or gstHHHJump));
  1115         HHGear^.State:= HHGear^.State and (not (gstHHJumping or gstHHHJump));
  1060     exit
  1116     exit
  1061     end;
  1117     end;
  1062 
  1118 
       
  1119 if isAFK and (not CurrentTeam^.ExtDriven) and (CurrentHedgehog^.BotLevel = 0) then
       
  1120     begin
       
  1121     AFKSkip;
       
  1122     exit
       
  1123     end;
       
  1124 
  1063 if (HHGear^.State and gstAnimation) <> 0 then
  1125 if (HHGear^.State and gstAnimation) <> 0 then
  1064     begin
  1126     begin
  1065     HHGear^.Message:= 0;
  1127     HHGear^.Message:= 0;
  1066     if (HHGear^.Pos = Wavez[TWave(HHGear^.Tag)].VoiceDelay) and (HHGear^.Timer = 0) then
  1128     if (HHGear^.Pos = Wavez[TWave(HHGear^.Tag)].VoiceDelay) and (HHGear^.Timer = 0) then
  1067         PlaySoundV(Wavez[TWave(HHGear^.Tag)].Voice, Hedgehog^.Team^.voicepack);
  1129         PlaySoundV(Wavez[TWave(HHGear^.Tag)].Voice, Hedgehog^.Team^.voicepack);
  1141             PlaySoundV(sndJump2, Hedgehog^.Team^.voicepack)
  1203             PlaySoundV(sndJump2, Hedgehog^.Team^.voicepack)
  1142             end;
  1204             end;
  1143 
  1205 
  1144     HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
  1206     HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
  1145 
  1207 
  1146     if (not cArtillery) and wasJumping and TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
  1208     if (not cArtillery) and wasJumping and (TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) <> 0) then
  1147         SetLittle(HHGear^.dX);
  1209         SetLittle(HHGear^.dX);
  1148 
  1210 
  1149     if Hedgehog^.Gear <> nil then
  1211     if Hedgehog^.Gear <> nil then
  1150         doStepHedgehogMoving(HHGear);
  1212         doStepHedgehogMoving(HHGear);
  1151 
  1213 
  1250 var slope: hwFloat;
  1312 var slope: hwFloat;
  1251 begin
  1313 begin
  1252     if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0)
  1314     if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0)
  1253     and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0)
  1315     and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0)
  1254     and ((Gear^.Hedgehog = nil) or ((Gear^.Hedgehog^.Effects[heFrozen] = 0) or (Gear^.Hedgehog^.Effects[heFrozen] > 255)))
  1316     and ((Gear^.Hedgehog = nil) or ((Gear^.Hedgehog^.Effects[heFrozen] = 0) or (Gear^.Hedgehog^.Effects[heFrozen] > 255)))
  1255     and (not Gear^.dY.isNegative) and (TurnTimeLeft > 0) and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
  1317     and (not Gear^.dY.isNegative) and TurnClockActive and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
  1256         begin
  1318         begin
  1257         slope:= CalcSlopeBelowGear(Gear);
  1319         slope:= CalcSlopeBelowGear(Gear);
  1258         if slope.QWordValue > 730144440 then // ignore mild slopes
  1320         if slope.QWordValue > 730144440 then // ignore mild slopes
  1259             begin
  1321             begin
  1260             Gear^.dX:=Gear^.dX+slope*cGravity*_256;
  1322             Gear^.dX:=Gear^.dX+slope*cGravity*_256;
  1277     AddVisualGear(x + hwRound(_50 * slope), y - hwRound(_50 * slope), vgtSmokeTrace); *)
  1339     AddVisualGear(x + hwRound(_50 * slope), y - hwRound(_50 * slope), vgtSmokeTrace); *)
  1278 end;
  1340 end;
  1279 
  1341 
  1280 ////////////////////////////////////////////////////////////////////////////////
  1342 ////////////////////////////////////////////////////////////////////////////////
  1281 procedure doStepHedgehog(Gear: PGear);
  1343 procedure doStepHedgehog(Gear: PGear);
  1282 begin
  1344 var tX: hwFloat;
  1283 if WorldWrap(Gear) and (WorldEdge <> weBounce) and 
  1345 begin
  1284   (Gear = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.Kind =gtRope) then
  1346 CheckGearDrowning(Gear);
  1285    CurAmmoGear^.PortalCounter:= 1;
  1347 if Gear = nil then exit;
       
  1348 tX:= Gear^.X;
       
  1349 if WorldWrap(Gear) then
       
  1350     begin
       
  1351     if (WorldEdge <> weBounce) and (Gear = CurrentHedgehog^.Gear) and 
       
  1352        (CurAmmoGear <> nil) and (CurAmmoGear^.Kind =gtRope) and (CurAmmoGear^.Elasticity <> _0) then
       
  1353        CurAmmoGear^.PortalCounter:= 1;
       
  1354     if (WorldEdge = weWrap) and ((TestCollisionXwithGear(Gear, 1) <> 0) or (TestCollisionXwithGear(Gear, -1) <> 0))  then
       
  1355         begin
       
  1356         Gear^.X:= tX;
       
  1357         Gear^.dX.isNegative:= (hwRound(tX) > LongInt(leftX) + Gear^.Radius * 2)
       
  1358         end
       
  1359     end;
  1286 
  1360 
  1287 CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel;
  1361 CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel;
  1288 if (Gear^.Message and gmDestroy) <> 0 then
  1362 if (Gear^.Message and gmDestroy) <> 0 then
  1289     begin
  1363     begin
  1290     DeleteGear(Gear);
  1364     DeleteGear(Gear);
  1291     exit
  1365     exit
  1292     end;
  1366     end;
  1293 if GameTicks mod 100 = 0 then CheckIce(Gear);
  1367 if GameTicks mod 128 = 0 then CheckIce(Gear);
  1294 (*
  1368 (*
  1295 if Gear^.Hedgehog^.Effects[heFrozen] > 0 then
  1369 if Gear^.Hedgehog^.Effects[heFrozen] > 0 then
  1296     begin
  1370     begin
  1297     if (Gear^.Hedgehog^.Effects[heFrozen] > 256) and (CurrentHedgehog^.Team^.Clan <> Gear^.Hedgehog^.Team^.Clan) then
  1371     if (Gear^.Hedgehog^.Effects[heFrozen] > 256) and (CurrentHedgehog^.Team^.Clan <> Gear^.Hedgehog^.Team^.Clan) then
  1298         dec(Gear^.Hedgehog^.Effects[heFrozen])
  1372         dec(Gear^.Hedgehog^.Effects[heFrozen])