hedgewars/uGearsHedgehog.pas
changeset 6580 6155187bf599
parent 6543 697e9b730189
child 6581 e510d1245bd7
equal deleted inserted replaced
6579:fc52f7c22c9b 6580:6155187bf599
    45 
    45 
    46 with HHGear^.Hedgehog^ do
    46 with HHGear^.Hedgehog^ do
    47     begin
    47     begin
    48     HHGear^.Message:= HHGear^.Message and (not gmSlot);
    48     HHGear^.Message:= HHGear^.Message and (not gmSlot);
    49     ammoidx:= 0;
    49     ammoidx:= 0;
    50     if ((HHGear^.State and (gstAttacking or gstAttacked)) <> 0) or
    50     if ((HHGear^.State and (gstAttacking or gstAttacked)) <> 0)
    51        ((MultiShootAttacks > 0) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) = 0)) or
    51     or ((MultiShootAttacks > 0) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) = 0))
    52        ((HHGear^.State and gstHHDriven) = 0) then exit;
    52     or ((HHGear^.State and gstHHDriven) = 0) then
       
    53         exit;
    53     ChangeAmmo:= true;
    54     ChangeAmmo:= true;
    54 
    55 
    55     while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> CurAmmoType) do inc(ammoidx);
    56     while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> CurAmmoType) do
    56 
    57         inc(ammoidx);
    57     if ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) and (MultiShootAttacks > 0) then OnUsedAmmo(HHGear^.Hedgehog^);
    58 
       
    59     if ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) and (MultiShootAttacks > 0) then
       
    60         OnUsedAmmo(HHGear^.Hedgehog^);
    58 
    61 
    59     MultiShootAttacks:= 0;
    62     MultiShootAttacks:= 0;
    60     HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
    63     HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
    61     
    64     
    62     if Ammoz[CurAmmoType].Slot = slot then
    65     if Ammoz[CurAmmoType].Slot = slot then
    69             inc(i);
    72             inc(i);
    70             CurAmmoType:= amNothing;
    73             CurAmmoType:= amNothing;
    71             ammoidx:= -1;
    74             ammoidx:= -1;
    72             //TryDo(i < 2, 'Engine bug: no ammo in current slot', true)
    75             //TryDo(i < 2, 'Engine bug: no ammo in current slot', true)
    73             end;
    76             end;
    74         until (i = 1) or ((Ammo^[slot, ammoidx].Count > 0) and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns))
    77         until (i = 1) or ((Ammo^[slot, ammoidx].Count > 0)
       
    78         and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns))
       
    79         
    75         end 
    80         end 
    76     else
    81     else
    77         begin
    82         begin
    78         i:= 0;
    83         i:= 0;
    79         // check whether there is ammo in slot
    84         // check whether there is ammo in slot
    80         while (i <= cMaxSlotAmmoIndex)
    85         while (i <= cMaxSlotAmmoIndex) and ((Ammo^[slot, i].Count = 0)
    81           and ((Ammo^[slot, i].Count = 0)
    86         or (Team^.Clan^.TurnNumber <= Ammoz[Ammo^[slot, i].AmmoType].SkipTurns))
    82                or (Team^.Clan^.TurnNumber <= Ammoz[Ammo^[slot, i].AmmoType].SkipTurns)) do inc(i);
    87             do inc(i);
    83 
    88 
    84         if i <= cMaxSlotAmmoIndex then ammoidx:= i
    89         if i <= cMaxSlotAmmoIndex then
       
    90             ammoidx:= i
    85         else ammoidx:= -1
    91         else ammoidx:= -1
    86         end;
    92         end;
    87         if ammoidx >= 0 then CurAmmoType:= Ammo^[slot, ammoidx].AmmoType;
    93         if ammoidx >= 0 then
       
    94             CurAmmoType:= Ammo^[slot, ammoidx].AmmoType;
    88     end
    95     end
    89 end;
    96 end;
    90 
    97 
    91 procedure HHSetWeapon(HHGear: PGear);
    98 procedure HHSetWeapon(HHGear: PGear);
    92 var t: LongInt;
    99 var t: LongInt;
    97 s:= false;
   104 s:= false;
    98 
   105 
    99 weap:= TAmmoType(HHGear^.MsgParam);
   106 weap:= TAmmoType(HHGear^.MsgParam);
   100 Hedgehog:= HHGear^.Hedgehog;
   107 Hedgehog:= HHGear^.Hedgehog;
   101 
   108 
   102 if Hedgehog^.Team^.Clan^.TurnNumber <= Ammoz[weap].SkipTurns then exit; // weapon is not activated yet
   109 if Hedgehog^.Team^.Clan^.TurnNumber <= Ammoz[weap].SkipTurns then
       
   110     exit; // weapon is not activated yet
   103 
   111 
   104 HHGear^.MsgParam:= Ammoz[weap].Slot;
   112 HHGear^.MsgParam:= Ammoz[weap].Slot;
   105 
   113 
   106 t:= cMaxSlotAmmoIndex;
   114 t:= cMaxSlotAmmoIndex;
   107 
   115 
   112         begin
   120         begin
   113         s:= ChangeAmmo(HHGear);
   121         s:= ChangeAmmo(HHGear);
   114         dec(t)
   122         dec(t)
   115         end;
   123         end;
   116 
   124 
   117 if s then ApplyAmmoChanges(HHGear^.Hedgehog^)
   125 if s then
       
   126     ApplyAmmoChanges(HHGear^.Hedgehog^)
   118 end;
   127 end;
   119 
   128 
   120 procedure HHSetTimer(Gear: PGear);
   129 procedure HHSetTimer(Gear: PGear);
   121 var CurWeapon: PAmmo;
   130 var CurWeapon: PAmmo;
   122     color: LongWord;
   131     color: LongWord;
   169 begin
   178 begin
   170 newGear:= nil;
   179 newGear:= nil;
   171 bShowFinger:= false;
   180 bShowFinger:= false;
   172 CurWeapon:= GetAmmoEntry(Gear^.Hedgehog^);
   181 CurWeapon:= GetAmmoEntry(Gear^.Hedgehog^);
   173 with Gear^,
   182 with Gear^,
   174      Gear^.Hedgehog^ do
   183     Gear^.Hedgehog^ do
   175      begin
   184         begin
   176      if ((State and gstHHDriven) <> 0)and
   185         if ((State and gstHHDriven) <> 0) and ((State and (gstAttacked or gstHHChooseTarget)) = 0) and (((State and gstMoving) = 0)
   177         ((State and (gstAttacked or gstHHChooseTarget)) = 0) and
   186         or (Power > 0)
   178         (((State and gstMoving) = 0) or
   187         or (CurAmmoType = amTeleport)
   179             (Power > 0) or
   188         or 
   180             (CurAmmoType = amTeleport) or 
   189         // Allow attacks while moving on ammo with AltAttack
   181             // Allow attacks while moving on ammo with AltAttack
   190         ((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0))
   182             ((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)) or
   191         or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0))
   183             ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0)) and
   192         and ((TargetPoint.X <> NoPointX) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) = 0)) then
   184         ((TargetPoint.X <> NoPointX) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) = 0)) then
   193             begin
   185         begin
   194             State:= State or gstAttacking;
   186         State:= State or gstAttacking;
   195             if Power = cMaxPower then
   187         if Power = cMaxPower then Message:= Message and (not gmAttack)
   196                 Message:= Message and (not gmAttack)
   188         else if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) = 0 then Message:= Message and (not gmAttack)
   197             else if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) = 0 then
   189         else begin
   198                 Message:= Message and (not gmAttack)
   190              if Power = 0 then
   199             else
   191                 begin
   200                 begin
   192                 AttackBar:= CurrentTeam^.AttackBar;
   201                 if Power = 0 then
   193                 PlaySound(sndThrowPowerUp)
   202                     begin
       
   203                     AttackBar:= CurrentTeam^.AttackBar;
       
   204                     PlaySound(sndThrowPowerUp)
       
   205                     end;
       
   206                 inc(Power)
   194                 end;
   207                 end;
   195              inc(Power)
   208         if ((Message and gmAttack) <> 0) then
   196              end;
   209             exit;
   197         if ((Message and gmAttack) <> 0) then exit;
       
   198 
   210 
   199         if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0 then
   211         if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0 then
   200            begin
   212             begin
   201            StopSound(sndThrowPowerUp);
   213             StopSound(sndThrowPowerUp);
   202            PlaySound(sndThrowRelease);
   214             PlaySound(sndThrowRelease);
   203            end;
   215             end;
   204 
   216 
   205         xx:= SignAs(AngleSin(Angle), dX);
   217         xx:= SignAs(AngleSin(Angle), dX);
   206         yy:= -AngleCos(Angle);
   218         yy:= -AngleCos(Angle);
   207 
   219 
   208         lx:= X + int2hwfloat(round(GetLaunchX(CurAmmoType, hwSign(dX), Angle)));
   220         lx:= X + int2hwfloat(round(GetLaunchX(CurAmmoType, hwSign(dX), Angle)));
   209         ly:= Y + int2hwfloat(round(GetLaunchY(CurAmmoType, Angle)));
   221         ly:= Y + int2hwfloat(round(GetLaunchY(CurAmmoType, Angle)));
   210 
   222 
   211         if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then xx:= - xx;
   223         if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then
       
   224             xx:= - xx;
   212         if Ammoz[CurAmmoType].Ammo.AttackVoice <> sndNone then
   225         if Ammoz[CurAmmoType].Ammo.AttackVoice <> sndNone then
   213            AddVoice(Ammoz[CurAmmoType].Ammo.AttackVoice, CurrentTeam^.voicepack);
   226             AddVoice(Ammoz[CurAmmoType].Ammo.AttackVoice, CurrentTeam^.voicepack);
   214 
   227 
   215 // Initiating alt attack
   228 // Initiating alt attack
   216         if  (CurAmmoGear <> nil) and
   229         if  (CurAmmoGear <> nil)
   217             ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) and
   230         and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
   218             ((Gear^.Message and gmLJump) <> 0) and
   231         and ((Gear^.Message and gmLJump) <> 0)
   219             ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
   232         and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
   220             begin
   233             begin
   221             newDx:= dX / _2; 
   234             newDx:= dX / _2; 
   222             newDy:= dY / _2;
   235             newDy:= dY / _2;
   223             altUse:= true;
   236             altUse:= true;
   224             end
   237             end
   243                                  end;
   256                                  end;
   244                    amPickHammer: newGear:= AddGear(hwRound(lx), hwRound(ly) + cHHRadius, gtPickHammer, 0, _0, _0, 0);
   257                    amPickHammer: newGear:= AddGear(hwRound(lx), hwRound(ly) + cHHRadius, gtPickHammer, 0, _0, _0, 0);
   245                          amSkip: ParseCommand('/skip', true);
   258                          amSkip: ParseCommand('/skip', true);
   246                          amRope: newGear:= AddGear(hwRound(lx), hwRound(ly), gtRope, 0, xx, yy, 0);
   259                          amRope: newGear:= AddGear(hwRound(lx), hwRound(ly), gtRope, 0, xx, yy, 0);
   247                          amMine: if altUse then
   260                          amMine: if altUse then
   248                                     newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, newDx, newDy, 3000)
   261                                      newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, newDx, newDy, 3000)
   249                                  else
   262                                  else
   250                                     newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000);
   263                                      newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000);
   251                         amSMine: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSMine,    0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
   264                         amSMine: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSMine,    0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
   252                        amDEagle: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0);
   265                        amDEagle: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0);
   253                       amSineGun: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSineGunShot, 0, xx * _0_5, yy * _0_5, 0);
   266                       amSineGun: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSineGunShot, 0, xx * _0_5, yy * _0_5, 0);
   254                     amPortalGun: begin
   267                     amPortalGun: begin
   255                                  newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtPortal, 0, xx * _0_6, yy * _0_6, 
   268                                  newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtPortal, 0, xx * _0_6, yy * _0_6, 
   293                                  end;
   306                                  end;
   294                       amRCPlane: begin
   307                       amRCPlane: begin
   295                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtRCPlane,  0, xx * cMaxPower / cPowerDivisor / 4, yy * cMaxPower / cPowerDivisor / 4, 0);
   308                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtRCPlane,  0, xx * cMaxPower / cPowerDivisor / 4, yy * cMaxPower / cPowerDivisor / 4, 0);
   296                                  newGear^.SoundChannel:= LoopSound(sndRCPlane, nil)
   309                                  newGear^.SoundChannel:= LoopSound(sndRCPlane, nil)
   297                                  end;
   310                                  end;
   298                        amKamikaze: newGear:= AddGear(hwRound(lx), hwRound(ly), gtKamikaze, 0, xx * _0_5, yy * _0_5, 0);
   311                      amKamikaze: newGear:= AddGear(hwRound(lx), hwRound(ly), gtKamikaze, 0, xx * _0_5, yy * _0_5, 0);
   299                          amCake: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 3, hwRound(ly), gtCake, 0, xx, _0, 0);
   312                          amCake: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 3, hwRound(ly), gtCake, 0, xx, _0, 0);
   300                     amSeduction: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSeduction, 0, _0, _0, 0);
   313                     amSeduction: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSeduction, 0, _0, _0, 0);
   301                    amWatermelon: newGear:= AddGear(hwRound(lx), hwRound(ly), gtWatermelon,  0, newDx, newDy, CurWeapon^.Timer);
   314                    amWatermelon: newGear:= AddGear(hwRound(lx), hwRound(ly), gtWatermelon,  0, newDx, newDy, CurWeapon^.Timer);
   302                   amHellishBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtHellishBomb,    0, newDx, newDy, 0);
   315                   amHellishBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtHellishBomb,    0, newDx, newDy, 0);
   303                         amDrill: newGear:= AddGear(hwRound(lx), hwRound(ly), gtDrill, 0, newDx, newDy, 0);
   316                         amDrill: newGear:= AddGear(hwRound(lx), hwRound(ly), gtDrill, 0, newDx, newDy, 0);
   304                       amBallgun: newGear:= AddGear(hwRound(X), hwRound(Y), gtBallgun,  0, xx * _0_5, yy * _0_5, 0);
   317                       amBallgun: newGear:= AddGear(hwRound(X), hwRound(Y), gtBallgun,  0, xx * _0_5, yy * _0_5, 0);
   305                     amJetpack: newGear:= AddGear(hwRound(lx), hwRound(ly), gtJetpack, 0, _0, _0, 0);
   318                       amJetpack: newGear:= AddGear(hwRound(lx), hwRound(ly), gtJetpack, 0, _0, _0, 0);
   306                     amBirdy: begin
   319                         amBirdy: begin
   307                              PlaySound(sndWhistle);
   320                              PlaySound(sndWhistle);
   308                              newGear:= AddGear(hwRound(lx), hwRound(ly) - 32, gtBirdy, 0, _0, _0, 0);
   321                              newGear:= AddGear(hwRound(lx), hwRound(ly) - 32, gtBirdy, 0, _0, _0, 0);
   309                              end;
   322                              end;
   310                       amLowGravity: begin
   323                    amLowGravity: begin
   311                                     PlaySound(sndLowGravity);
   324                                  PlaySound(sndLowGravity);
   312                                     cGravity:= cMaxWindSpeed;
   325                                  cGravity:= cMaxWindSpeed;
   313                                     cGravityf:= 0.00025
   326                                  cGravityf:= 0.00025
   314                                     end;
   327                                  end;
   315                       amExtraDamage:begin 
   328                   amExtraDamage: begin 
   316                                     PlaySound(sndHellishImpact4);
   329                                  PlaySound(sndHellishImpact4);
   317                                     cDamageModifier:= _1_5
   330                                  cDamageModifier:= _1_5
   318                                     end;
   331                                  end;
   319                       amInvulnerable: Invulnerable:= true;
   332                  amInvulnerable: Invulnerable:= true;
   320                       amExtraTime:  begin
   333                     amExtraTime: begin
   321                                     PlaySound(sndSwitchHog);
   334                                  PlaySound(sndSwitchHog);
   322                                     TurnTimeLeft:= TurnTimeLeft + 30000
   335                                  TurnTimeLeft:= TurnTimeLeft + 30000
   323                                     end;
   336                                  end;
   324                       amLaserSight: cLaserSighting:= true;
   337                    amLaserSight: cLaserSighting:= true;
   325                       amVampiric: begin
   338                      amVampiric: begin
   326                                   PlaySound(sndOw1, Team^.voicepack);
   339                                  PlaySound(sndOw1, Team^.voicepack);
   327                                   cVampiric:= true;
   340                                  cVampiric:= true;
   328                                   end;
   341                                  end;
   329                       amPiano: begin
   342                         amPiano: begin
   330                                // Tuck the hedgehog away until the piano attack is completed
   343                                  // Tuck the hedgehog away until the piano attack is completed
   331                                Unplaced:= true;
   344                                  Unplaced:= true;
   332                                X:= _0;
   345                                  X:= _0;
   333                                Y:= _0;
   346                                  Y:= _0;
   334                                newGear:= AddGear(TargetPoint.X, 0, gtPiano, 0, _0, _0, 0);
   347                                  newGear:= AddGear(TargetPoint.X, 0, gtPiano, 0, _0, _0, 0);
   335                                PauseMusic
   348                                  PauseMusic
   336                                end;
   349                                  end;
   337                       amFlamethrower: newGear:= AddGear(hwRound(X), hwRound(Y), gtFlamethrower,  0, xx * _0_5, yy * _0_5, 0);
   350                  amFlamethrower: newGear:= AddGear(hwRound(X), hwRound(Y), gtFlamethrower,  0, xx * _0_5, yy * _0_5, 0);
   338                       amLandGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtLandGun,  0, xx * _0_5, yy * _0_5, 0);
   351                       amLandGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtLandGun,  0, xx * _0_5, yy * _0_5, 0);
   339                     amResurrector: begin
   352                   amResurrector: begin
   340                         newGear:= AddGear(hwRound(lx), hwRound(ly),
   353                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtResurrector, 0, _0, _0, 0);
   341                                 gtResurrector, 0, _0, _0, 0);
   354                                  newGear^.SoundChannel := LoopSound(sndResurrector);
   342                         newGear^.SoundChannel := LoopSound(sndResurrector);
   355                                  end;
   343                     end;
   356                                  //amMelonStrike: AddGear(CurWeapon^.Pos, 0, gtAirAttack, 4, _0, _0, 0);
   344                    //amMelonStrike: AddGear(CurWeapon^.Pos, 0, gtAirAttack, 4, _0, _0, 0);
   357                     amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
   345                      amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
   358                        amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
   346                         amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
   359              end;
   347                   end;
   360              
   348              case CurAmmoType of
   361              case CurAmmoType of
   349                       amGrenade, amMolotov, 
   362                       amGrenade, amMolotov, 
   350                   amClusterBomb, amGasBomb, 
   363                   amClusterBomb, amGasBomb, 
   351                       amBazooka, amSnowball, 
   364                       amBazooka, amSnowball, 
   352                           amBee, amSMine,
   365                           amBee, amSMine,
   365                     amSeduction, amBallgun,
   378                     amSeduction, amBallgun,
   366                       amJetpack, amBirdy,
   379                       amJetpack, amBirdy,
   367                  amFlamethrower, amLandGun,
   380                  amFlamethrower, amLandGun,
   368                   amResurrector, amStructure,
   381                   amResurrector, amStructure,
   369                        amTardis, amPiano: CurAmmoGear:= newGear;
   382                        amTardis, amPiano: CurAmmoGear:= newGear;
   370                   end;
   383              end;
   371               if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then
   384              
   372                  newGear^.FlightTime:= GameTicks + 1000
   385             if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then
   373               else if CurAmmoType = amDrill then newGear^.FlightTime:= GameTicks + 250;
   386                 newGear^.FlightTime:= GameTicks + 1000
       
   387             else if CurAmmoType = amDrill then
       
   388                 newGear^.FlightTime:= GameTicks + 250;
   374         if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
   389         if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
   375             begin
   390             begin
   376             newGear^.Target.X:= TargetPoint.X;
   391             newGear^.Target.X:= TargetPoint.X;
   377             newGear^.Target.Y:= TargetPoint.Y
   392             newGear^.Target.Y:= TargetPoint.Y
   378             end;
   393             end;
   379 
   394 
   380         // Clear FollowGear if using on a rope/parachute/saucer etc so focus stays with the hog's movement
   395         // Clear FollowGear if using on a rope/parachute/saucer etc so focus stays with the hog's movement
   381         if altUse then FollowGear:= nil;
   396         if altUse then
       
   397             FollowGear:= nil;
   382 
   398 
   383         if (newGear <> nil) and ((Ammoz[newGear^.AmmoType].Ammo.Propz and ammoprop_SetBounce) <> 0) then
   399         if (newGear <> nil) and ((Ammoz[newGear^.AmmoType].Ammo.Propz and ammoprop_SetBounce) <> 0) then
   384             begin
   400             begin
   385             elastic:=  int2hwfloat(CurWeapon^.Bounciness) / _1000;
   401             elastic:=  int2hwfloat(CurWeapon^.Bounciness) / _1000;
   386 
   402 
   387             if elastic < _1 then newGear^.Elasticity:= newGear^.Elasticity * elastic
   403             if elastic < _1 then
   388             else if elastic > _1 then newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
   404                 newGear^.Elasticity:= newGear^.Elasticity * elastic
       
   405             else if elastic > _1 then
       
   406                 newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
   389 (* Experimented with friction modifier. Didn't seem helpful 
   407 (* Experimented with friction modifier. Didn't seem helpful 
   390             fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
   408             fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
   391             if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
   409             if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
   392             else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
   410             else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
   393             end;
   411             end;
   397 
   415 
   398         if not (SpeechText = '') then
   416         if not (SpeechText = '') then
   399             begin
   417             begin
   400             speech:= AddVisualGear(0, 0, vgtSpeechBubble);
   418             speech:= AddVisualGear(0, 0, vgtSpeechBubble);
   401             if speech <> nil then
   419             if speech <> nil then
   402                begin
   420                 begin
   403                speech^.Text:= SpeechText;
   421                 speech^.Text:= SpeechText;
   404                speech^.Hedgehog:= Gear^.Hedgehog;
   422                 speech^.Hedgehog:= Gear^.Hedgehog;
   405                speech^.FrameTicks:= SpeechType;
   423                 speech^.FrameTicks:= SpeechType;
   406                end;
   424                 end;
   407             SpeechText:= ''
   425             SpeechText:= ''
   408             end;
   426             end;
   409 
   427 
   410         Power:= 0;
   428         Power:= 0;
   411         if (CurAmmoGear <> nil)
   429         if (CurAmmoGear <> nil)
   412            and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then
   430             and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then
   413            begin
   431             begin
   414            Message:= Message or gmAttack;
   432             Message:= Message or gmAttack;
   415            CurAmmoGear^.Message:= Message
   433             CurAmmoGear^.Message:= Message
   416            end else begin
   434             end
   417            if not CurrentTeam^.ExtDriven and
   435         else
   418              ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then SendIPC('a');
   436             begin
   419            AfterAttack;
   437             if not CurrentTeam^.ExtDriven
   420            end
   438             and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then
   421         end else Message:= Message and (not gmAttack);
   439                 SendIPC('a');
   422      end;
   440             AfterAttack;
   423      TargetPoint.X := NoPointX;
   441             end
   424      ScriptCall('onHogAttack');
   442         end
       
   443     else 
       
   444         Message:= Message and (not gmAttack);
       
   445     end;
       
   446     TargetPoint.X := NoPointX;
       
   447     ScriptCall('onHogAttack');
   425 end;
   448 end;
   426 
   449 
   427 procedure AfterAttack;
   450 procedure AfterAttack;
   428 var s: shortstring;
   451 var s: shortstring;
   429     a: TAmmoType;
   452     a: TAmmoType;
   430 begin
   453 begin
   431 with CurrentHedgehog^.Gear^,
   454 with CurrentHedgehog^.Gear^, CurrentHedgehog^ do
   432         CurrentHedgehog^ do
       
   433     begin
   455     begin
   434     a:= CurAmmoType;
   456     a:= CurAmmoType;
   435     State:= State and (not gstAttacking);
   457     State:= State and (not gstAttacking);
   436     if (Ammoz[a].Ammo.Propz and ammoprop_Effect) = 0 then
   458     if (Ammoz[a].Ammo.Propz and ammoprop_Effect) = 0 then
   437         begin
   459         begin
   441             begin
   463             begin
   442             s:= inttostr(Ammoz[a].Ammo.NumPerTurn - MultiShootAttacks + 1);
   464             s:= inttostr(Ammoz[a].Ammo.NumPerTurn - MultiShootAttacks + 1);
   443             AddCaption(format(trmsg[sidRemaining], s), cWhiteColor, capgrpAmmostate);
   465             AddCaption(format(trmsg[sidRemaining], s), cWhiteColor, capgrpAmmostate);
   444             end;
   466             end;
   445         
   467         
   446         if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) or
   468         if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks)
   447             ((GameFlags and gfMultiWeapon) <> 0) then
   469         or ((GameFlags and gfMultiWeapon) <> 0) then
   448             begin
   470             begin
   449             isInMultiShoot:= true
   471             isInMultiShoot:= true
   450             end
   472             end
   451         else
   473         else
   452             begin
   474             begin
   453             OnUsedAmmo(CurrentHedgehog^);
   475             OnUsedAmmo(CurrentHedgehog^);
   454             if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (((GameFlags and gfInfAttack) = 0) or PlacingHogs) then
   476             if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (((GameFlags and gfInfAttack) = 0) or PlacingHogs) then
   455                 begin
   477                 begin
   456                 if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft;
   478                 if TagTurnTimeLeft = 0 then
       
   479                     TagTurnTimeLeft:= TurnTimeLeft;
   457                 TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100;
   480                 TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100;
   458                 end;
   481                 end;
   459             if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) then State:= State or gstAttacked;
   482             if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) then
   460             if (Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) <> 0 then ApplyAmmoChanges(CurrentHedgehog^)
   483                 State:= State or gstAttacked;
       
   484             if (Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) <> 0 then
       
   485                 ApplyAmmoChanges(CurrentHedgehog^)
   461             end;
   486             end;
   462         end
   487         end
   463     else
   488     else
   464         begin
   489         begin
   465         OnUsedAmmo(CurrentHedgehog^);
   490         OnUsedAmmo(CurrentHedgehog^);
   472 ////////////////////////////////////////////////////////////////////////////////
   497 ////////////////////////////////////////////////////////////////////////////////
   473 procedure doStepHedgehogDead(Gear: PGear);
   498 procedure doStepHedgehogDead(Gear: PGear);
   474 const frametime = 200;
   499 const frametime = 200;
   475       timertime = frametime * 6;
   500       timertime = frametime * 6;
   476 begin
   501 begin
   477 if Gear^.Hedgehog^.Unplaced then exit;
   502 if Gear^.Hedgehog^.Unplaced then
       
   503     exit;
   478 if Gear^.Timer > 1 then
   504 if Gear^.Timer > 1 then
   479     begin
   505     begin
   480     AllInactive:= false;
   506     AllInactive:= false;
   481     dec(Gear^.Timer);
   507     dec(Gear^.Timer);
   482     if (Gear^.Timer mod frametime) = 0 then inc(Gear^.Pos)
   508     if (Gear^.Timer mod frametime) = 0 then
       
   509         inc(Gear^.Pos)
   483     end 
   510     end 
   484 else if Gear^.Timer = 1 then
   511 else if Gear^.Timer = 1 then
   485     begin
   512     begin
   486     Gear^.State:= Gear^.State or gstNoDamage;
   513     Gear^.State:= Gear^.State or gstNoDamage;
   487     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound);
   514     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound);
   504 ////////////////////////////////////////////////////////////////////////////////
   531 ////////////////////////////////////////////////////////////////////////////////
   505 procedure doStepHedgehogGone(Gear: PGear);
   532 procedure doStepHedgehogGone(Gear: PGear);
   506 const frametime = 65;
   533 const frametime = 65;
   507       timertime = frametime * 11;
   534       timertime = frametime * 11;
   508 begin
   535 begin
   509 if Gear^.Hedgehog^.Unplaced then exit;
   536 if Gear^.Hedgehog^.Unplaced then
       
   537     exit;
   510 if Gear^.Timer > 1 then
   538 if Gear^.Timer > 1 then
   511     begin
   539     begin
   512     AllInactive:= false;
   540     AllInactive:= false;
   513     dec(Gear^.Timer);
   541     dec(Gear^.Timer);
   514     if (Gear^.Timer mod frametime) = 0 then inc(Gear^.Pos)
   542     if (Gear^.Timer mod frametime) = 0 then
   515     end else
   543         inc(Gear^.Pos)
       
   544     end
       
   545 else
   516 if Gear^.Timer = 1 then
   546 if Gear^.Timer = 1 then
   517     begin
   547     begin
   518     DeleteGear(Gear);
   548     DeleteGear(Gear);
   519     SetAllToActive
   549     SetAllToActive
   520     end else // Gear^.Timer = 0
   550     end
       
   551 else // Gear^.Timer = 0
   521     begin
   552     begin
   522     AllInactive:= false;
   553     AllInactive:= false;
   523     Gear^.Z:= cCurrHHZ;
   554     Gear^.Z:= cCurrHHZ;
   524     RemoveGearFromList(Gear);
   555     RemoveGearFromList(Gear);
   525     InsertGearToList(Gear);
   556     InsertGearToList(Gear);
   551        posCaseUtility,
   582        posCaseUtility,
   552        posCaseAmmo: begin
   583        posCaseAmmo: begin
   553                     if Gear^.AmmoType <> amNothing then a:= Gear^.AmmoType 
   584                     if Gear^.AmmoType <> amNothing then a:= Gear^.AmmoType 
   554                     else
   585                     else
   555                         begin
   586                         begin
   556                         for i:= 0 to GameTicks and $7F do GetRandom(2); // Burn some random numbers
   587                         for i:= 0 to GameTicks and $7F do
   557                         if Gear^.Pos = posCaseUtility then a:= GetUtility(HH^.Hedgehog)
   588                             GetRandom(2); // Burn some random numbers
   558                         else a:= GetAmmo(HH^.Hedgehog)
   589                         if Gear^.Pos = posCaseUtility then
       
   590                             a:= GetUtility(HH^.Hedgehog)
       
   591                         else
       
   592                             a:= GetAmmo(HH^.Hedgehog)
   559                         end;
   593                         end;
   560                     AddAmmo(HH^.Hedgehog^, a);
   594                     AddAmmo(HH^.Hedgehog^, a);
   561 // Possibly needs to check shared clan ammo game flag once added.
   595 // Possibly needs to check shared clan ammo game flag once added.
   562 // On the other hand, no obvious reason that clan members shouldn't know what ammo another clan member picked up
   596 // On the other hand, no obvious reason that clan members shouldn't know what ammo another clan member picked up
   563                     if (not (HH^.Hedgehog^.Team^.ExtDriven 
   597                     if (not (HH^.Hedgehog^.Team^.ExtDriven 
   564                       or (HH^.Hedgehog^.BotLevel > 0)))
   598                     or (HH^.Hedgehog^.BotLevel > 0)))
   565                       or (HH^.Hedgehog^.Team^.Clan^.ClanIndex = LocalClan)
   599                     or (HH^.Hedgehog^.Team^.Clan^.ClanIndex = LocalClan)
   566                       or (GameType = gmtDemo)  then
   600                     or (GameType = gmtDemo)  then
   567                         begin
   601                         begin
   568                         s:= trammo[Ammoz[a].NameId] + ' (+' + IntToStr(Ammoz[a].NumberInCase) + ')';
   602                         s:= trammo[Ammoz[a].NameId] + ' (+' + IntToStr(Ammoz[a].NumberInCase) + ')';
   569                         AddCaption(s, HH^.Hedgehog^.Team^.Clan^.Color, capgrpAmmoinfo);
   603                         AddCaption(s, HH^.Hedgehog^.Team^.Clan^.Color, capgrpAmmoinfo);
   570 
   604 
   571                         // show ammo icon
   605                         // show ammo icon
   606 var PrevdX: LongInt;
   640 var PrevdX: LongInt;
   607     CurWeapon: PAmmo;
   641     CurWeapon: PAmmo;
   608 begin
   642 begin
   609 CurWeapon:= GetAmmoEntry(Gear^.Hedgehog^);
   643 CurWeapon:= GetAmmoEntry(Gear^.Hedgehog^);
   610 if ((Gear^.State and (gstAttacking or gstMoving)) = 0) then
   644 if ((Gear^.State and (gstAttacking or gstMoving)) = 0) then
   611    begin
   645     begin
   612    if isCursorVisible then
   646     if isCursorVisible then
   613       with Gear^.Hedgehog^ do
   647         with Gear^.Hedgehog^ do
   614         with CurWeapon^ do
   648             with CurWeapon^ do
   615           begin
   649                 begin
   616           if (Gear^.Message and gmLeft  ) <> 0 then
   650                 if (Gear^.Message and gmLeft  ) <> 0 then
   617              Pos:= (Pos - 1 + Ammoz[AmmoType].PosCount) mod Ammoz[AmmoType].PosCount
   651                     Pos:= (Pos - 1 + Ammoz[AmmoType].PosCount) mod Ammoz[AmmoType].PosCount
   618           else
   652                 else
   619           if (Gear^.Message and gmRight ) <> 0 then
   653                     if (Gear^.Message and gmRight ) <> 0 then
   620              Pos:= (Pos + 1) mod Ammoz[AmmoType].PosCount
   654                         Pos:= (Pos + 1) mod Ammoz[AmmoType].PosCount
   621           else exit;
   655     else
   622           StepTicks:= 200;
   656         exit;
   623           exit
   657     StepTicks:= 200;
   624           end;
   658     exit
       
   659     end;
   625 
   660 
   626     if ((Gear^.Message and gmAnimate) <> 0) then
   661     if ((Gear^.Message and gmAnimate) <> 0) then
   627         begin
   662         begin
   628         Gear^.Message:= 0;
   663         Gear^.Message:= 0;
   629         Gear^.State:= Gear^.State or gstAnimation;
   664         Gear^.State:= Gear^.State or gstAnimation;
   630         Gear^.Tag:= Gear^.MsgParam;
   665         Gear^.Tag:= Gear^.MsgParam;
   631         Gear^.Timer:= 0;
   666         Gear^.Timer:= 0;
   632         Gear^.Pos:= 0
   667         Gear^.Pos:= 0
   633         end;
   668         end;
   634 
   669 
   635    if ((Gear^.Message and gmLJump ) <> 0) then
   670     if ((Gear^.Message and gmLJump ) <> 0) then
   636       begin
   671         begin
   637       Gear^.Message:= Gear^.Message and (not gmLJump);
   672         Gear^.Message:= Gear^.Message and (not gmLJump);
   638       DeleteCI(Gear);
   673         DeleteCI(Gear);
   639       if TestCollisionYwithGear(Gear, -1) = 0 then
   674         if TestCollisionYwithGear(Gear, -1) = 0 then
   640          if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then Gear^.Y:= Gear^.Y - _2 else
   675             if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then
   641          if not TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) then Gear^.Y:= Gear^.Y - _1;
   676                 Gear^.Y:= Gear^.Y - _2
   642       if not (TestCollisionXwithGear(Gear, hwSign(Gear^.dX))
   677             else
   643          or   (TestCollisionYwithGear(Gear, -1) <> 0)) then
   678                 if not TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) then
   644          begin
   679                     Gear^.Y:= Gear^.Y - _1;
   645          Gear^.dY:= -_0_15;
   680             if not (TestCollisionXwithGear(Gear, hwSign(Gear^.dX))
   646          if not cArtillery then Gear^.dX:= SignAs(_0_15, Gear^.dX);
   681             or   (TestCollisionYwithGear(Gear, -1) <> 0)) then
   647          Gear^.State:= Gear^.State or gstMoving or gstHHJumping;
   682                 begin
   648          PlaySound(sndJump1, Gear^.Hedgehog^.Team^.voicepack);
   683                 Gear^.dY:= -_0_15;
   649          exit
   684                 if not cArtillery then
   650          end;
   685                     Gear^.dX:= SignAs(_0_15, Gear^.dX);
   651       end;
   686                 Gear^.State:= Gear^.State or gstMoving or gstHHJumping;
   652 
   687                 PlaySound(sndJump1, Gear^.Hedgehog^.Team^.voicepack);
   653    if ((Gear^.Message and gmHJump ) <> 0) then
   688         exit
   654       begin
   689         end;
   655       DeleteCI(Gear);
   690     end;
   656       Gear^.Message:= Gear^.Message and (not gmHJump);
   691 
   657 
   692     if ((Gear^.Message and gmHJump ) <> 0) then
   658       Gear^.dY:= -_0_2;
   693         begin
   659       SetLittle(Gear^.dX);
   694         DeleteCI(Gear);
   660       Gear^.State:= Gear^.State or gstMoving or gstHHJumping;
   695         Gear^.Message:= Gear^.Message and (not gmHJump);
   661       PlaySound(sndJump3, Gear^.Hedgehog^.Team^.voicepack);
   696 
   662       exit
   697         Gear^.dY:= -_0_2;
   663       end;
   698         SetLittle(Gear^.dX);
   664 
   699         Gear^.State:= Gear^.State or gstMoving or gstHHJumping;
   665    PrevdX:= hwSign(Gear^.dX);
   700         PlaySound(sndJump3, Gear^.Hedgehog^.Team^.voicepack);
   666    if (Gear^.Message and gmLeft  )<>0 then Gear^.dX:= -cLittle else
   701         exit
   667    if (Gear^.Message and gmRight )<>0 then Gear^.dX:=  cLittle else exit;
   702         end;
   668 
   703 
   669    if (Gear^.Message and (gmLeft or gmRight)) <> 0 then
   704     PrevdX:= hwSign(Gear^.dX);
   670       begin
   705     if (Gear^.Message and gmLeft  )<>0 then
   671       StepSoundTimer:= cHHStepTicks;
   706         Gear^.dX:= -cLittle else
   672       end;
   707     if (Gear^.Message and gmRight )<>0 then
       
   708         Gear^.dX:=  cLittle else exit;
       
   709 
       
   710     if (Gear^.Message and (gmLeft or gmRight)) <> 0 then
       
   711         begin
       
   712         StepSoundTimer:= cHHStepTicks;
       
   713         end;
   673    
   714    
   674    StepTicks:= cHHStepTicks;
   715     StepTicks:= cHHStepTicks;
   675    if PrevdX <> hwSign(Gear^.dX) then
   716     if PrevdX <> hwSign(Gear^.dX) then
   676       begin
   717         begin
   677       FollowGear:= Gear;
   718         FollowGear:= Gear;
   678       exit
   719         exit
   679       end;
   720         end;
   680    DeleteCI(Gear); // must be after exit!! (see previous line)
   721     DeleteCI(Gear); // must be after exit!! (see previous line)
   681 
   722 
   682    Gear^.Hedgehog^.visStepPos:= (Gear^.Hedgehog^.visStepPos + 1) and 7;
   723     Gear^.Hedgehog^.visStepPos:= (Gear^.Hedgehog^.visStepPos + 1) and 7;
   683    if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
   724     if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
   684       begin
   725         begin
   685       if not (TestCollisionXwithXYShift(Gear, _0, -6, hwSign(Gear^.dX))
   726         if not (TestCollisionXwithXYShift(Gear, _0, -6, hwSign(Gear^.dX))
   686          or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
   727         or (TestCollisionYwithGear(Gear, -1) <> 0)) then
   687       if not (TestCollisionXwithXYShift(Gear, _0, -5, hwSign(Gear^.dX))
   728             Gear^.Y:= Gear^.Y - _1;
   688          or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
   729         if not (TestCollisionXwithXYShift(Gear, _0, -5, hwSign(Gear^.dX))
   689       if not (TestCollisionXwithXYShift(Gear, _0, -4, hwSign(Gear^.dX))
   730         or (TestCollisionYwithGear(Gear, -1) <> 0)) then
   690          or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
   731             Gear^.Y:= Gear^.Y - _1;
   691       if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX))
   732         if not (TestCollisionXwithXYShift(Gear, _0, -4, hwSign(Gear^.dX))
   692          or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
   733         or (TestCollisionYwithGear(Gear, -1) <> 0)) then
   693       if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX))
   734             Gear^.Y:= Gear^.Y - _1;
   694          or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
   735         if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX))
   695       if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX))
   736         or (TestCollisionYwithGear(Gear, -1) <> 0)) then
   696          or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1;
   737             Gear^.Y:= Gear^.Y - _1;
   697       end;
   738         if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX))
   698 
   739         or (TestCollisionYwithGear(Gear, -1) <> 0)) then
   699    if (not cArtillery) and ((Gear^.Message and gmPrecise) = 0) and (not TestCollisionXwithGear(Gear, hwSign(Gear^.dX))) then
   740             Gear^.Y:= Gear^.Y - _1;
   700       Gear^.X:= Gear^.X + SignAs(_1, Gear^.dX);
   741         if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX))
       
   742         or (TestCollisionYwithGear(Gear, -1) <> 0)) then
       
   743             Gear^.Y:= Gear^.Y - _1;
       
   744         end;
       
   745 
       
   746     if (not cArtillery) and ((Gear^.Message and gmPrecise) = 0) and (not TestCollisionXwithGear(Gear, hwSign(Gear^.dX))) then
       
   747         Gear^.X:= Gear^.X + SignAs(_1, Gear^.dX);
   701 
   748 
   702    SetAllHHToActive;
   749    SetAllHHToActive;
   703 
   750 
   704    if TestCollisionYwithGear(Gear, 1) = 0 then
   751     if TestCollisionYwithGear(Gear, 1) = 0 then
   705    begin
   752         begin
   706    Gear^.Y:= Gear^.Y + _1;
   753         Gear^.Y:= Gear^.Y + _1;
   707    if TestCollisionYwithGear(Gear, 1) = 0 then
   754     if TestCollisionYwithGear(Gear, 1) = 0 then
   708    begin
   755         begin
   709    Gear^.Y:= Gear^.Y + _1;
   756         Gear^.Y:= Gear^.Y + _1;
   710    if TestCollisionYwithGear(Gear, 1) = 0 then
   757     if TestCollisionYwithGear(Gear, 1) = 0 then
   711    begin
   758         begin
   712    Gear^.Y:= Gear^.Y + _1;
   759         Gear^.Y:= Gear^.Y + _1;
   713    if TestCollisionYwithGear(Gear, 1) = 0 then
   760     if TestCollisionYwithGear(Gear, 1) = 0 then
   714    begin
   761         begin
   715    Gear^.Y:= Gear^.Y + _1;
   762         Gear^.Y:= Gear^.Y + _1;
   716    if TestCollisionYwithGear(Gear, 1) = 0 then
   763     if TestCollisionYwithGear(Gear, 1) = 0 then
   717    begin
   764         begin
   718    Gear^.Y:= Gear^.Y + _1;
   765         Gear^.Y:= Gear^.Y + _1;
   719    if TestCollisionYwithGear(Gear, 1) = 0 then
   766     if TestCollisionYwithGear(Gear, 1) = 0 then
   720    begin
   767         begin
   721    Gear^.Y:= Gear^.Y + _1;
   768         Gear^.Y:= Gear^.Y + _1;
   722    if TestCollisionYwithGear(Gear, 1) = 0 then
   769     if TestCollisionYwithGear(Gear, 1) = 0 then
   723       begin
   770         begin
   724       Gear^.Y:= Gear^.Y - _6;
   771         Gear^.Y:= Gear^.Y - _6;
   725       Gear^.dY:= _0;
   772         Gear^.dY:= _0;
   726       Gear^.State:= Gear^.State or gstMoving;
   773         Gear^.State:= Gear^.State or gstMoving;
   727       exit
   774         exit
   728       end;
   775         end;
   729    end
   776         end
   730    end
   777         end
   731    end
   778         end
   732    end
   779         end
   733    end
   780         end
   734    end;
   781         end;
   735    AddGearCI(Gear)
   782     AddGearCI(Gear)
   736    end
   783     end
   737 end;
   784 end;
   738 
   785 
   739 procedure HedgehogChAngle(HHGear: PGear);
   786 procedure HedgehogChAngle(HHGear: PGear);
   740 var da: LongWord;
   787 var da: LongWord;
   741 begin
   788 begin
   742 with HHGear^.Hedgehog^ do
   789 with HHGear^.Hedgehog^ do
   743     if ((CurAmmoType = amRope) and 
   790     if ((CurAmmoType = amRope) and ((HHGear^.State and (gstMoving or gstHHJumping)) = gstMoving))
   744         ((HHGear^.State and (gstMoving or gstHHJumping)) = gstMoving)) or
   791     or ((CurAmmoType = amPortalGun) and ((HHGear^.State and gstMoving) <> 0)) then
   745        ((CurAmmoType = amPortalGun) and 
   792         da:= 2
   746         ((HHGear^.State and gstMoving) <> 0)) then da:= 2
       
   747     else da:= 1;
   793     else da:= 1;
   748 
   794 
   749 if (((HHGear^.Message and gmPrecise) = 0) or ((GameTicks mod 5) = 1)) then
   795 if (((HHGear^.Message and gmPrecise) = 0) or ((GameTicks mod 5) = 1)) then
   750     if ((HHGear^.Message and gmUp) <> 0) and (HHGear^.Angle >= CurMinAngle + da) then dec(HHGear^.Angle, da)
   796     if ((HHGear^.Message and gmUp) <> 0) and (HHGear^.Angle >= CurMinAngle + da) then
       
   797         dec(HHGear^.Angle, da)
   751     else
   798     else
   752     if ((HHGear^.Message and gmDown) <> 0) and (HHGear^.Angle + da <= CurMaxAngle) then inc(HHGear^.Angle, da)
   799         if ((HHGear^.Message and gmDown) <> 0) and (HHGear^.Angle + da <= CurMaxAngle) then
       
   800             inc(HHGear^.Angle, da)
   753 end;
   801 end;
   754 
   802 
   755 
   803 
   756 ////////////////////////////////////////////////////////////////////////////////
   804 ////////////////////////////////////////////////////////////////////////////////
   757 procedure doStepHedgehogMoving(Gear: PGear);
   805 procedure doStepHedgehogMoving(Gear: PGear);
   758 var isFalling, isUnderwater: boolean;
   806 var isFalling, isUnderwater: boolean;
   759     land: Word;
   807     land: Word;
   760 begin
   808 begin
   761 land:= 0;
   809 land:= 0;
   762 isUnderwater:= cWaterLine < hwRound(Gear^.Y) + Gear^.Radius;
   810 isUnderwater:= cWaterLine < hwRound(Gear^.Y) + Gear^.Radius;
   763 if Gear^.dX.QWordValue > 8160437862 then Gear^.dX.QWordValue:= 8160437862;
   811 if Gear^.dX.QWordValue > 8160437862 then
   764 if Gear^.dY.QWordValue > 8160437862 then Gear^.dY.QWordValue:= 8160437862;
   812     Gear^.dX.QWordValue:= 8160437862;
       
   813 if Gear^.dY.QWordValue > 8160437862 then
       
   814     Gear^.dY.QWordValue:= 8160437862;
   765 
   815 
   766 if Gear^.Hedgehog^.Unplaced then
   816 if Gear^.Hedgehog^.Unplaced then
   767    begin
   817     begin
   768    Gear^.dY:= _0;
   818     Gear^.dY:= _0;
   769    Gear^.dX:= _0;
   819     Gear^.dX:= _0;
   770    Gear^.State:= Gear^.State and (not gstMoving);
   820     Gear^.State:= Gear^.State and (not gstMoving);
   771    exit
   821     exit
   772    end;
   822     end;
   773 isFalling:= (Gear^.dY.isNegative) or not TestCollisionYKick(Gear, 1);
   823 isFalling:= (Gear^.dY.isNegative) or not TestCollisionYKick(Gear, 1);
   774 if isFalling then
   824 if isFalling then
   775    begin
   825     begin
   776    if (Gear^.dY.isNegative) and TestCollisionYKick(Gear, -1) then Gear^.dY:= _0;
   826     if (Gear^.dY.isNegative) and TestCollisionYKick(Gear, -1) then
   777    Gear^.State:= Gear^.State or gstMoving;
   827         Gear^.dY:= _0;
   778    if (CurrentHedgehog^.Gear = Gear)
   828     Gear^.State:= Gear^.State or gstMoving;
       
   829     if (CurrentHedgehog^.Gear = Gear)
   779         and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then 
   830         and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then 
   780         begin
   831         begin
   781         FollowGear:= Gear;
   832         FollowGear:= Gear;
   782         end;
   833         end;
   783    if isUnderwater then Gear^.dY:= Gear^.dY + cGravity / _2
   834     if isUnderwater then
   784    else
   835        Gear^.dY:= Gear^.dY + cGravity / _2
   785        begin
   836     else
   786        Gear^.dY:= Gear^.dY + cGravity;
   837         begin
       
   838         Gear^.dY:= Gear^.dY + cGravity;
   787 // this set of circumstances could be less complex if jumping was more clearly identified
   839 // this set of circumstances could be less complex if jumping was more clearly identified
   788        if ((GameFlags and gfMoreWind) <> 0) and 
   840         if ((GameFlags and gfMoreWind) <> 0) and (((Gear^.Damage <> 0)
   789           (((Gear^.Damage <> 0) or
   841         or ((CurAmmoGear <> nil) and ((CurAmmoGear^.AmmoType = amJetpack) or (CurAmmoGear^.AmmoType = amBirdy)))
   790           ((CurAmmoGear <> nil) and
   842         or ((Gear^.dY.QWordValue + Gear^.dX.QWordValue) > _0_55.QWordValue))) then
   791             ((CurAmmoGear^.AmmoType = amJetpack) or
   843             Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
   792             (CurAmmoGear^.AmmoType = amBirdy))) or
   844         end
   793           ((Gear^.dY.QWordValue + Gear^.dX.QWordValue) > _0_55.QWordValue)))
   845     end 
   794           then Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
       
   795        end
       
   796    end 
       
   797 else
   846 else
   798    begin
   847     begin
   799    land:= TestCollisionYwithGear(Gear, 1);
   848     land:= TestCollisionYwithGear(Gear, 1);
   800    if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_55.QWordValue) and ((land and lfIce) = 0)
   849     if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_55.QWordValue) and ((land and lfIce) = 0)
   801       and ((Gear^.State and gstHHJumping) <> 0) then SetLittle(Gear^.dX);
   850     and ((Gear^.State and gstHHJumping) <> 0) then
   802 
   851         SetLittle(Gear^.dX);
   803    if not Gear^.dY.isNegative then
   852 
   804       begin
   853     if not Gear^.dY.isNegative then
   805       CheckHHDamage(Gear);
   854         begin
   806 
   855         CheckHHDamage(Gear);
   807       if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) and
   856 
   808          (Gear^.dX.QWordValue < _0_02.QWordValue) then Gear^.dX.isNegative:= not Gear^.dX.isNegative; // landing after high jump
   857         if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery)
   809 
   858         and (Gear^.dX.QWordValue < _0_02.QWordValue) then
   810       Gear^.State:= Gear^.State and (not (gstHHJumping or gstHHHJump));
   859             Gear^.dX.isNegative:= not Gear^.dX.isNegative; // landing after high jump
   811       Gear^.dY:= _0;
   860         Gear^.State:= Gear^.State and (not (gstHHJumping or gstHHHJump));
   812       end else Gear^.dY:= Gear^.dY + cGravity;
   861         Gear^.dY:= _0;
   813 
   862         end
   814    if ((Gear^.State and gstMoving) <> 0) then
   863     else
   815        begin
   864         Gear^.dY:= Gear^.dY + cGravity;
   816        if land and lfIce <> 0 then
   865 
   817            begin
   866     if ((Gear^.State and gstMoving) <> 0) then
   818            Gear^.dX:= Gear^.dX * (_1 - (_1 - Gear^.Friction) / _2)
   867         begin
   819            end
   868         if land and lfIce <> 0 then
   820        else Gear^.dX:= Gear^.dX * Gear^.Friction;
   869             begin
   821        end
   870             Gear^.dX:= Gear^.dX * (_1 - (_1 - Gear^.Friction) / _2)
   822    end;
   871             end
   823 
   872         else
   824 if (Gear^.State <> 0) then DeleteCI(Gear);
   873             Gear^.dX:= Gear^.dX * Gear^.Friction;
       
   874         end
       
   875     end;
       
   876 
       
   877 if (Gear^.State <> 0) then
       
   878     DeleteCI(Gear);
   825 
   879 
   826 if isUnderwater then
   880 if isUnderwater then
   827    begin
   881    begin
   828    Gear^.dY:= Gear^.dY * _0_999;
   882    Gear^.dY:= Gear^.dY * _0_999;
   829    Gear^.dX:= Gear^.dX * _0_999;
   883    Gear^.dX:= Gear^.dX * _0_999;
   830    end;
   884    end;
   831 
   885 
   832 if (Gear^.State and gstMoving) <> 0 then
   886 if (Gear^.State and gstMoving) <> 0 then
   833    if TestCollisionXKick(Gear, hwSign(Gear^.dX)) then
   887     if TestCollisionXKick(Gear, hwSign(Gear^.dX)) then
   834       if not isFalling then
   888         if not isFalling then
   835          if hwAbs(Gear^.dX) > _0_01 then
   889             if hwAbs(Gear^.dX) > _0_01 then
   836             if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -1, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_96; Gear^.Y:= Gear^.Y - _1 end else
   890                 if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -1, hwSign(Gear^.dX)) then
   837             if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_93; Gear^.Y:= Gear^.Y - _2 end else
   891                     begin
   838             if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_9 ; Gear^.Y:= Gear^.Y - _3 end else
   892                     Gear^.X:= Gear^.X + Gear^.dX;
   839             if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -4, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_87; Gear^.Y:= Gear^.Y - _4 end else
   893                     Gear^.dX:= Gear^.dX * _0_96;
   840             if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -5, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_84; Gear^.Y:= Gear^.Y - _5 end else
   894                     Gear^.Y:= Gear^.Y - _1
   841             if hwAbs(Gear^.dX) > _0_02 then Gear^.dX:= -Gear^.Elasticity * Gear^.dX
   895                     end
   842                                    else begin
   896                 else
   843                                         Gear^.State:= Gear^.State and (not gstMoving);
   897                     if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) then
   844                                         while TestCollisionYWithGear(Gear,1) = 0 do Gear^.Y:= Gear^.Y+_1;
   898                         begin
   845                                         SetLittle(Gear^.dX)
   899                         Gear^.X:= Gear^.X + Gear^.dX;
   846                                         end
   900                         Gear^.dX:= Gear^.dX * _0_93;
   847             else begin
   901                         Gear^.Y:= Gear^.Y - _2
   848                  Gear^.State:= Gear^.State and (not gstMoving);
   902                         end 
   849                  while TestCollisionYWithGear(Gear,1) = 0 do Gear^.Y:= Gear^.Y+_1;
   903                     else
   850                  SetLittle(Gear^.dX)
   904                         if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) then
   851                  end
   905                         begin
   852          else if (hwAbs(Gear^.dX) > cLittle)
   906                         Gear^.X:= Gear^.X + Gear^.dX;
   853                 and ((Gear^.State and gstHHJumping) = 0)
   907                         Gear^.dX:= Gear^.dX * _0_9 ;
   854                 then Gear^.dX:= -Gear^.Elasticity * Gear^.dX
   908                         Gear^.Y:= Gear^.Y - _3
   855                 else SetLittle(Gear^.dX);
   909                         end
   856 
   910                     else
   857 if (not isFalling) and
   911                         if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -4, hwSign(Gear^.dX)) then
   858    (hwAbs(Gear^.dX) + hwAbs(Gear^.dY) < _0_03) then
   912                             begin
   859    begin
   913                             Gear^.X:= Gear^.X + Gear^.dX;
   860    Gear^.State:= Gear^.State and (not gstWinner);
   914                             Gear^.dX:= Gear^.dX * _0_87;
   861    Gear^.State:= Gear^.State and (not gstMoving);
   915                             Gear^.Y:= Gear^.Y - _4
   862    while TestCollisionYWithGear(Gear,1) = 0 do Gear^.Y:= Gear^.Y+_1;
   916                             end
   863    SetLittle(Gear^.dX);
   917                     else
   864    Gear^.dY:= _0
   918                         if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -5, hwSign(Gear^.dX)) then
   865    end else Gear^.State:= Gear^.State or gstMoving;
   919                             begin
       
   920                             Gear^.X:= Gear^.X + Gear^.dX;
       
   921                             Gear^.dX:= Gear^.dX * _0_84;
       
   922                             Gear^.Y:= Gear^.Y - _5
       
   923                             end
       
   924                     else
       
   925                         if hwAbs(Gear^.dX) > _0_02 then
       
   926                             Gear^.dX:= -Gear^.Elasticity * Gear^.dX
       
   927                         else
       
   928                             begin
       
   929                             Gear^.State:= Gear^.State and (not gstMoving);
       
   930                             while TestCollisionYWithGear(Gear,1) = 0 do
       
   931                                 Gear^.Y:= Gear^.Y+_1;
       
   932                             SetLittle(Gear^.dX)
       
   933                             end
       
   934             else
       
   935                 begin
       
   936                 Gear^.State:= Gear^.State and (not gstMoving);
       
   937                 while TestCollisionYWithGear(Gear,1) = 0 do
       
   938                     Gear^.Y:= Gear^.Y+_1;
       
   939                 SetLittle(Gear^.dX)
       
   940                 end
       
   941         else if (hwAbs(Gear^.dX) > cLittle)
       
   942         and ((Gear^.State and gstHHJumping) = 0) then
       
   943             Gear^.dX:= -Gear^.Elasticity * Gear^.dX
       
   944         else
       
   945             SetLittle(Gear^.dX);
       
   946 
       
   947 if (not isFalling)
       
   948 and (hwAbs(Gear^.dX) + hwAbs(Gear^.dY) < _0_03) then
       
   949     begin
       
   950     Gear^.State:= Gear^.State and (not gstWinner);
       
   951     Gear^.State:= Gear^.State and (not gstMoving);
       
   952     while TestCollisionYWithGear(Gear,1) = 0 do
       
   953         Gear^.Y:= Gear^.Y+_1;
       
   954     SetLittle(Gear^.dX);
       
   955     Gear^.dY:= _0
       
   956     end
       
   957 else
       
   958     Gear^.State:= Gear^.State or gstMoving;
   866 
   959 
   867 if (Gear^.State and gstMoving) <> 0 then
   960 if (Gear^.State and gstMoving) <> 0 then
   868    begin
   961     begin
   869    Gear^.State:= Gear^.State and (not gstAnimation);
   962     Gear^.State:= Gear^.State and (not gstAnimation);
   870 // ARTILLERY but not being moved by explosions
   963 // ARTILLERY but not being moved by explosions
   871    Gear^.X:= Gear^.X + Gear^.dX;
   964     Gear^.X:= Gear^.X + Gear^.dX;
   872    Gear^.Y:= Gear^.Y + Gear^.dY;
   965     Gear^.Y:= Gear^.Y + Gear^.dY;
   873    if (not Gear^.dY.isNegative) and
   966     if (not Gear^.dY.isNegative) and (not TestCollisionYKick(Gear, 1)) 
   874       (not TestCollisionYKick(Gear, 1)) and
   967     and TestCollisionYwithXYShift(Gear, 0, 1, 1) then
   875        TestCollisionYwithXYShift(Gear, 0, 1, 1) then
   968         begin
   876       begin
   969         CheckHHDamage(Gear);
   877       CheckHHDamage(Gear);
   970         Gear^.dY:= _0;
   878       Gear^.dY:= _0;
   971         Gear^.Y:= Gear^.Y + _1
   879       Gear^.Y:= Gear^.Y + _1
   972         end;
   880       end;
   973     CheckGearDrowning(Gear);
   881    CheckGearDrowning(Gear);
   974     // hide target cursor if current hog is drowning
   882    // hide target cursor if current hog is drowning
   975     if (Gear^.State and gstDrowning) <> 0 then
   883    if (Gear^.State and gstDrowning) <> 0 then
   976         if (CurrentHedgehog^.Gear = Gear) then
   884        if (CurrentHedgehog^.Gear = Gear) then
   977             isCursorVisible:= false
   885           isCursorVisible:= false
   978     end;
   886    end;
       
   887 
   979 
   888 if (hwAbs(Gear^.dY) > _0) and (Gear^.FlightTime > 0) and ((GameFlags and gfLowGravity) = 0) then
   980 if (hwAbs(Gear^.dY) > _0) and (Gear^.FlightTime > 0) and ((GameFlags and gfLowGravity) = 0) then
   889     begin
   981     begin
   890     inc(Gear^.FlightTime);
   982     inc(Gear^.FlightTime);
   891     if Gear^.FlightTime = 3000 then
   983     if Gear^.FlightTime = 3000 then
   907     wasJumping: boolean;
   999     wasJumping: boolean;
   908     Hedgehog: PHedgehog;
  1000     Hedgehog: PHedgehog;
   909 begin
  1001 begin
   910 Hedgehog:= HHGear^.Hedgehog;
  1002 Hedgehog:= HHGear^.Hedgehog;
   911 if isInMultiShoot then
  1003 if isInMultiShoot then
   912    HHGear^.Message:= 0;
  1004     HHGear^.Message:= 0;
   913 
  1005 
   914 if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Utility) <> 0) and isInMultiShoot then 
  1006 if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Utility) <> 0) and isInMultiShoot then 
   915     AllInactive:= true
  1007     AllInactive:= true
   916 else if not isInMultiShoot then AllInactive:= false;
  1008 else if not isInMultiShoot then
       
  1009     AllInactive:= false;
   917 
  1010 
   918 if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) then
  1011 if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) then
   919     begin
  1012     begin
   920     if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft;
  1013     if TagTurnTimeLeft = 0 then
       
  1014         TagTurnTimeLeft:= TurnTimeLeft;
   921     TurnTimeLeft:= 0;
  1015     TurnTimeLeft:= 0;
   922     isCursorVisible:= false;
  1016     isCursorVisible:= false;
   923     HHGear^.State:= HHGear^.State and (not (gstHHDriven or gstAnimation or gstAttacking));
  1017     HHGear^.State:= HHGear^.State and (not (gstHHDriven or gstAnimation or gstAttacking));
   924     AttackBar:= 0;
  1018     AttackBar:= 0;
   925     if HHGear^.Damage > 0 then
  1019     if HHGear^.Damage > 0 then
   928     end;
  1022     end;
   929 
  1023 
   930 if (HHGear^.State and gstAnimation) <> 0 then
  1024 if (HHGear^.State and gstAnimation) <> 0 then
   931     begin
  1025     begin
   932     HHGear^.Message:= 0;
  1026     HHGear^.Message:= 0;
   933     if (HHGear^.Pos = Wavez[TWave(HHGear^.Tag)].VoiceDelay) and (HHGear^.Timer = 0) then PlaySound(Wavez[TWave(HHGear^.Tag)].Voice, Hedgehog^.Team^.voicepack);
  1027     if (HHGear^.Pos = Wavez[TWave(HHGear^.Tag)].VoiceDelay) and (HHGear^.Timer = 0) then
       
  1028         PlaySound(Wavez[TWave(HHGear^.Tag)].Voice, Hedgehog^.Team^.voicepack);
   934     inc(HHGear^.Timer);
  1029     inc(HHGear^.Timer);
   935     if HHGear^.Timer = Wavez[TWave(HHGear^.Tag)].Interval then
  1030     if HHGear^.Timer = Wavez[TWave(HHGear^.Tag)].Interval then
   936         begin
  1031         begin
   937         HHGear^.Timer:= 0;
  1032         HHGear^.Timer:= 0;
   938         inc(HHGear^.Pos);
  1033         inc(HHGear^.Pos);
   941         end;
  1036         end;
   942     exit
  1037     exit
   943     end;
  1038     end;
   944 
  1039 
   945 if ((HHGear^.State and gstMoving) <> 0)
  1040 if ((HHGear^.State and gstMoving) <> 0)
   946     or (StepTicks = cHHStepTicks)
  1041 or (StepTicks = cHHStepTicks)
   947     or (CurAmmoGear <> nil) then // we are moving
  1042 or (CurAmmoGear <> nil) then // we are moving
   948     begin
  1043     begin
   949     with Hedgehog^ do
  1044     with Hedgehog^ do
   950         if (CurAmmoGear = nil)
  1045         if (CurAmmoGear = nil)
   951         and (HHGear^.dY > _0_39)
  1046         and (HHGear^.dY > _0_39)
   952         and (CurAmmoType = amParachute) then HHGear^.Message:= HHGear^.Message or gmAttack;
  1047         and (CurAmmoType = amParachute) then
       
  1048             HHGear^.Message:= HHGear^.Message or gmAttack;
   953     // check for case with ammo
  1049     // check for case with ammo
   954     t:= CheckGearNear(HHGear, gtCase, 36, 36);
  1050     t:= CheckGearNear(HHGear, gtCase, 36, 36);
   955     if t <> nil then
  1051     if t <> nil then
   956         PickUp(HHGear, t)
  1052         PickUp(HHGear, t)
   957     end;
  1053     end;
   958 
  1054 
   959 if (CurAmmoGear = nil) then
  1055 if (CurAmmoGear = nil) then
   960     if (((HHGear^.Message and gmAttack) <> 0)
  1056     if (((HHGear^.Message and gmAttack) <> 0)
   961         or ((HHGear^.State and gstAttacking) <> 0)) then
  1057     or ((HHGear^.State and gstAttacking) <> 0)) then
   962         Attack(HHGear) // should be before others to avoid desync with '/put' msg and changing weapon msgs
  1058         Attack(HHGear) // should be before others to avoid desync with '/put' msg and changing weapon msgs
   963     else
  1059     else
   964 else 
  1060 else 
   965     with Hedgehog^ do
  1061     with Hedgehog^ do
   966         if ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
  1062         if ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
   967             and ((HHGear^.Message and gmLJump) <> 0)
  1063         and ((HHGear^.Message and gmLJump) <> 0)
   968             and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
  1064         and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
   969             begin
  1065             begin
   970             Attack(HHGear);
  1066             Attack(HHGear);
   971             HHGear^.Message:= HHGear^.Message and (not gmLJump)
  1067             HHGear^.Message:= HHGear^.Message and (not gmLJump)
   972             end;
  1068             end;
   973 
  1069 
   974 if (CurAmmoGear = nil)
  1070 if (CurAmmoGear = nil)
   975     or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) 
  1071 or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) 
   976     or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) then
  1072 or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) then
   977     begin
  1073     begin
   978     if ((HHGear^.Message and gmSlot) <> 0) then
  1074     if ((HHGear^.Message and gmSlot) <> 0) then
   979         if ChangeAmmo(HHGear) then ApplyAmmoChanges(Hedgehog^);
  1075         if ChangeAmmo(HHGear) then ApplyAmmoChanges(Hedgehog^);
   980 
  1076 
   981     if ((HHGear^.Message and gmWeapon) <> 0) then HHSetWeapon(HHGear);
  1077     if ((HHGear^.Message and gmWeapon) <> 0) then
   982 
  1078         HHSetWeapon(HHGear);
   983     if ((HHGear^.Message and gmTimer) <> 0) then HHSetTimer(HHGear);
  1079 
       
  1080     if ((HHGear^.Message and gmTimer) <> 0) then
       
  1081         HHSetTimer(HHGear);
   984     end;
  1082     end;
   985 
  1083 
   986 if CurAmmoGear <> nil then
  1084 if CurAmmoGear <> nil then
   987    begin
  1085     begin
   988    CurAmmoGear^.Message:= HHGear^.Message;
  1086     CurAmmoGear^.Message:= HHGear^.Message;
   989    exit
  1087     exit
   990    end;
  1088     end;
   991 
  1089 
   992 if not isInMultiShoot then
  1090 if not isInMultiShoot then
   993    HedgehogChAngle(HHGear);
  1091     HedgehogChAngle(HHGear);
   994 
  1092 
   995 if (HHGear^.State and gstMoving) <> 0 then
  1093 if (HHGear^.State and gstMoving) <> 0 then
   996     begin
  1094     begin
   997     wasJumping:= ((HHGear^.State and gstHHJumping) <> 0);
  1095     wasJumping:= ((HHGear^.State and gstHHJumping) <> 0);
   998 
  1096 
   999     if ((HHGear^.Message and gmHJump) <> 0) and
  1097     if ((HHGear^.Message and gmHJump) <> 0) and wasJumping and ((HHGear^.State and gstHHHJump) = 0) then
  1000         wasJumping and
       
  1001         ((HHGear^.State and gstHHHJump) = 0) then
       
  1002         if (not (hwAbs(HHGear^.dX) > cLittle)) and (HHGear^.dY < -_0_02) then
  1098         if (not (hwAbs(HHGear^.dX) > cLittle)) and (HHGear^.dY < -_0_02) then
  1003             begin
  1099             begin
  1004             HHGear^.State:= HHGear^.State or gstHHHJump;
  1100             HHGear^.State:= HHGear^.State or gstHHHJump;
  1005             HHGear^.dY:= -_0_25;
  1101             HHGear^.dY:= -_0_25;
  1006             if not cArtillery then HHGear^.dX:= -SignAs(_0_02, HHGear^.dX);
  1102             if not cArtillery then
       
  1103                 HHGear^.dX:= -SignAs(_0_02, HHGear^.dX);
  1007             PlaySound(sndJump2, Hedgehog^.Team^.voicepack)
  1104             PlaySound(sndJump2, Hedgehog^.Team^.voicepack)
  1008             end;
  1105             end;
  1009 
  1106 
  1010     HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
  1107     HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
  1011 
  1108 
  1012     if (not cArtillery) and wasJumping and
  1109     if (not cArtillery) and wasJumping and TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
  1013         TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX);
  1110         SetLittle(HHGear^.dX);
  1014 
  1111 
  1015     if Hedgehog^.Gear <> nil then doStepHedgehogMoving(HHGear);
  1112     if Hedgehog^.Gear <> nil then
       
  1113         doStepHedgehogMoving(HHGear);
  1016 
  1114 
  1017     if ((HHGear^.State and (gstMoving or gstDrowning)) = 0) then
  1115     if ((HHGear^.State and (gstMoving or gstDrowning)) = 0) then
  1018         begin
  1116         begin
  1019         AddGearCI(HHGear);
  1117         AddGearCI(HHGear);
  1020         if wasJumping then
  1118         if wasJumping then
  1025     exit
  1123     exit
  1026     end;
  1124     end;
  1027 
  1125 
  1028     if not isInMultiShoot and (Hedgehog^.Gear <> nil) then
  1126     if not isInMultiShoot and (Hedgehog^.Gear <> nil) then
  1029         begin
  1127         begin
  1030         if StepTicks > 0 then dec(StepTicks);
  1128         if StepTicks > 0 then
  1031         if (StepTicks = 0) then HedgehogStep(HHGear)
  1129             dec(StepTicks);
       
  1130         if (StepTicks = 0) then
       
  1131             HedgehogStep(HHGear)
  1032         end
  1132         end
  1033 end;
  1133 end;
  1034 
  1134 
  1035 ////////////////////////////////////////////////////////////////////////////////
  1135 ////////////////////////////////////////////////////////////////////////////////
  1036 procedure doStepHedgehogFree(Gear: PGear);
  1136 procedure doStepHedgehogFree(Gear: PGear);
  1040 
  1140 
  1041 doStepHedgehogMoving(Gear);
  1141 doStepHedgehogMoving(Gear);
  1042 
  1142 
  1043 if (Gear^.State and (gstMoving or gstDrowning)) <> 0 then
  1143 if (Gear^.State and (gstMoving or gstDrowning)) <> 0 then
  1044     begin
  1144     begin
  1045     if Gear^.Damage > 0 then CalcRotationDirAngle(Gear);
  1145     if Gear^.Damage > 0 then
       
  1146         CalcRotationDirAngle(Gear);
  1046     AllInactive:= false;
  1147     AllInactive:= false;
  1047     exit
  1148     exit
  1048     end;
  1149     end;
  1049 
  1150 
  1050 if (Gear^.Health = 0) then
  1151 if (Gear^.Health = 0) then
  1057         AllInactive:= false;
  1158         AllInactive:= false;
  1058 
  1159 
  1059         if (Gear^.State and gstHHGone) = 0 then
  1160         if (Gear^.State and gstHHGone) = 0 then
  1060             begin
  1161             begin
  1061             Gear^.Hedgehog^.Effects[hePoisoned] := false;
  1162             Gear^.Hedgehog^.Effects[hePoisoned] := false;
  1062             if Gear^.Hedgehog^.Effects[heResurrectable] then begin
  1163             if Gear^.Hedgehog^.Effects[heResurrectable] then
       
  1164                 begin
  1063                 ResurrectHedgehog(Gear);
  1165                 ResurrectHedgehog(Gear);
  1064             end else 
  1166                 end
       
  1167             else 
  1065                 begin
  1168                 begin
  1066                 Gear^.State:= (Gear^.State or gstHHDeath) and (not gstAnimation);
  1169                 Gear^.State:= (Gear^.State or gstHHDeath) and (not gstAnimation);
  1067                 Gear^.doStep:= @doStepHedgehogDead;
  1170                 Gear^.doStep:= @doStepHedgehogDead;
  1068                 // Death message
  1171                 // Death message
  1069                 AddCaption(Format(GetEventString(eidDied), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
  1172                 AddCaption(Format(GetEventString(eidDied), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
  1084 if ((Gear^.State and gstWait) = 0) and
  1187 if ((Gear^.State and gstWait) = 0) and
  1085     (prevState <> Gear^.State) then
  1188     (prevState <> Gear^.State) then
  1086     begin
  1189     begin
  1087     Gear^.State:= Gear^.State or gstWait;
  1190     Gear^.State:= Gear^.State or gstWait;
  1088     Gear^.Timer:= 150
  1191     Gear^.Timer:= 150
  1089     end else
  1192     end
       
  1193 else
  1090     begin
  1194     begin
  1091     if Gear^.Timer = 0 then
  1195     if Gear^.Timer = 0 then
  1092         begin
  1196         begin
  1093         Gear^.State:= Gear^.State and (not (gstWait or gstLoser or gstWinner or gstAttacked or gstNotKickable or gstHHChooseTarget));
  1197         Gear^.State:= Gear^.State and (not (gstWait or gstLoser or gstWinner or gstAttacked or gstNotKickable or gstHHChooseTarget));
  1094         Gear^.Active:= false;
  1198         Gear^.Active:= false;
  1095         AddGearCI(Gear);
  1199         AddGearCI(Gear);
  1096         exit
  1200         exit
  1097         end else dec(Gear^.Timer)
  1201         end
       
  1202     else dec(Gear^.Timer)
  1098     end;
  1203     end;
  1099 
  1204 
  1100 AllInactive:= false
  1205 AllInactive:= false
  1101 end;
  1206 end;
  1102 
  1207 
  1122         if Team^.hasGone then
  1227         if Team^.hasGone then
  1123             TeamGoneEffect(Team^)
  1228             TeamGoneEffect(Team^)
  1124         else
  1229         else
  1125             doStepHedgehogDriven(Gear)
  1230             doStepHedgehogDriven(Gear)
  1126     end;
  1231     end;
  1127 if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0) and
  1232 if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0)
  1128    (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0) and
  1233 and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0)
  1129    (not Gear^.dY.isNegative) and
  1234 and (not Gear^.dY.isNegative) and (GameTicks mod (100*LongWOrd(hwRound(cMaxWindSpeed*2/cGravity))) = 0)
  1130    (GameTicks mod (100*LongWOrd(hwRound(cMaxWindSpeed*2/cGravity))) = 0) and
  1235 and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
  1131    (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
       
  1132     begin
  1236     begin
  1133     slope:= CalcSlopeBelowGear(Gear);
  1237     slope:= CalcSlopeBelowGear(Gear);
  1134     Gear^.dX:=Gear^.dX+slope*_0_07;
  1238     Gear^.dX:=Gear^.dX+slope*_0_07;
  1135     if slope.QWordValue <> 0 then Gear^.State:= Gear^.State or gstMoving;
  1239     if slope.QWordValue <> 0 then
       
  1240         Gear^.State:= Gear^.State or gstMoving;
  1136 (*
  1241 (*
  1137     x:= hwRound(Gear^.X);
  1242     x:= hwRound(Gear^.X);
  1138     y:= hwRound(Gear^.Y);
  1243     y:= hwRound(Gear^.Y);
  1139     AddVisualGear(x, y, vgtSmokeTrace);
  1244     AddVisualGear(x, y, vgtSmokeTrace);
  1140     AddVisualGear(x - hwRound(_5*slope), y + hwRound(_5*slope), vgtSmokeTrace);
  1245     AddVisualGear(x - hwRound(_5*slope), y + hwRound(_5*slope), vgtSmokeTrace);