hedgewars/uGearsHedgehog.pas
branchwebgl
changeset 8330 aaefa587e277
parent 8096 453917e94e55
parent 8161 0b8beacff8a5
child 8444 75db7bb8dce8
equal deleted inserted replaced
8116:d24257910f8d 8330:aaefa587e277
    21 unit uGearsHedgehog;
    21 unit uGearsHedgehog;
    22 interface
    22 interface
    23 uses uTypes;
    23 uses uTypes;
    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);
    29 procedure HedgehogChAngle(HHGear: PGear); 
    29 procedure HedgehogChAngle(HHGear: PGear);
    30 procedure PickUp(HH, Gear: PGear);
    30 procedure PickUp(HH, Gear: PGear);
    31 procedure AddPickup(HH: THedgehog; ammo: TAmmoType; cnt, X, Y: LongWord);
    31 procedure AddPickup(HH: THedgehog; ammo: TAmmoType; cnt, X, Y: LongWord);
    32 
    32 
    33 implementation
    33 implementation
    34 uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions, 
    34 uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions,
    35     uCommands, uLocale, uUtils, uVisualGears, uStats, uIO, uScript,
    35     uCommands, uLocale, uUtils, uVisualGears, uStats, uIO, uScript,
    36     uGearsList, uGears, uCollisions, uRandom, uStore, uTeams, 
    36     uGearsList, uGears, uCollisions, uRandom, uStore, uTeams,
    37     uGearsUtils;
    37     uGearsUtils;
    38 
    38 
    39 var GHStepTicks: LongWord = 0;
    39 var GHStepTicks: LongWord = 0;
    40 
    40 
    41 // Shouldn't more of this ammo switching stuff be moved to uAmmos ?
    41 // Shouldn't more of this ammo switching stuff be moved to uAmmos ?
    64     if ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) and (MultiShootAttacks > 0) then
    64     if ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) and (MultiShootAttacks > 0) then
    65         OnUsedAmmo(HHGear^.Hedgehog^);
    65         OnUsedAmmo(HHGear^.Hedgehog^);
    66 
    66 
    67     MultiShootAttacks:= 0;
    67     MultiShootAttacks:= 0;
    68     HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
    68     HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
    69     
    69 
    70     if Ammoz[CurAmmoType].Slot = slot then
    70     if Ammoz[CurAmmoType].Slot = slot then
    71         begin
    71         begin
    72         i:= 0;
    72         i:= 0;
    73         repeat
    73         repeat
    74         inc(ammoidx);
    74         inc(ammoidx);
    79             ammoidx:= -1;
    79             ammoidx:= -1;
    80             //TryDo(i < 2, 'Engine bug: no ammo in current slot', true)
    80             //TryDo(i < 2, 'Engine bug: no ammo in current slot', true)
    81             end;
    81             end;
    82         until (i = 1) or ((Ammo^[slot, ammoidx].Count > 0)
    82         until (i = 1) or ((Ammo^[slot, ammoidx].Count > 0)
    83         and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns))
    83         and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns))
    84         
    84 
    85         end 
    85         end
    86     else
    86     else
    87         begin
    87         begin
    88         i:= 0;
    88         i:= 0;
    89         // check whether there is ammo in slot
    89         // check whether there is ammo in slot
    90         while (i <= cMaxSlotAmmoIndex) and ((Ammo^[slot, i].Count = 0)
    90         while (i <= cMaxSlotAmmoIndex) and ((Ammo^[slot, i].Count = 0)
   103             LoadHedgehogHat(HHGear^.Hedgehog^, 'Reserved/chef')
   103             LoadHedgehogHat(HHGear^.Hedgehog^, 'Reserved/chef')
   104         else if prevAmmo = amKnife then
   104         else if prevAmmo = amKnife then
   105             LoadHedgehogHat(HHGear^.Hedgehog^, Hat);
   105             LoadHedgehogHat(HHGear^.Hedgehog^, Hat);
   106         end;
   106         end;
   107     // Try again in the next slot
   107     // Try again in the next slot
   108     if CurAmmoType = prevAmmo then 
   108     if CurAmmoType = prevAmmo then
   109         begin
   109         begin
   110         if slot >= cMaxSlotIndex then slot:= 0 else inc(slot);
   110         if slot >= cMaxSlotIndex then slot:= 0 else inc(slot);
   111         HHGear^.MsgParam:= slot;
   111         HHGear^.MsgParam:= slot;
   112         ChangeAmmo(HHGear)
   112         ChangeAmmo(HHGear)
   113         end
   113         end
   202     Gear^.Hedgehog^ do
   202     Gear^.Hedgehog^ do
   203         begin
   203         begin
   204         if ((State and gstHHDriven) <> 0) and ((State and (gstAttacked or gstHHChooseTarget)) = 0) and (((State and gstMoving) = 0)
   204         if ((State and gstHHDriven) <> 0) and ((State and (gstAttacked or gstHHChooseTarget)) = 0) and (((State and gstMoving) = 0)
   205         or (Power > 0)
   205         or (Power > 0)
   206         or (CurAmmoType = amTeleport)
   206         or (CurAmmoType = amTeleport)
   207         or 
   207         or
   208         // Allow attacks while moving on ammo with AltAttack
   208         // Allow attacks while moving on ammo with AltAttack
   209         ((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0))
   209         ((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0))
   210         or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0))
   210         or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0))
   211         and ((TargetPoint.X <> NoPointX) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) = 0)) then
   211         and ((TargetPoint.X <> NoPointX) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) = 0)) then
   212             begin
   212             begin
   248         if  (CurAmmoGear <> nil)
   248         if  (CurAmmoGear <> nil)
   249         and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
   249         and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
   250         and ((Gear^.Message and gmLJump) <> 0)
   250         and ((Gear^.Message and gmLJump) <> 0)
   251         and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
   251         and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
   252             begin
   252             begin
   253             newDx:= dX; 
   253             newDx:= dX;
   254             newDy:= dY;
   254             newDy:= dY;
   255             altUse:= true
   255             altUse:= true
   256             end
   256             end
   257         else
   257         else
   258             begin
   258             begin
   276                    amPickHammer: newGear:= AddGear(hwRound(lx), hwRound(ly) + cHHRadius, gtPickHammer, 0, _0, _0, 0);
   276                    amPickHammer: newGear:= AddGear(hwRound(lx), hwRound(ly) + cHHRadius, gtPickHammer, 0, _0, _0, 0);
   277                          amSkip: ParseCommand('/skip', true);
   277                          amSkip: ParseCommand('/skip', true);
   278                          amRope: newGear:= AddGear(hwRound(lx), hwRound(ly), gtRope, 0, xx, yy, 0);
   278                          amRope: newGear:= AddGear(hwRound(lx), hwRound(ly), gtRope, 0, xx, yy, 0);
   279                          amMine: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000);
   279                          amMine: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000);
   280                         amSMine: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSMine,    0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
   280                         amSMine: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSMine,    0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
   281                         amKnife: begin 
   281                         amKnife: begin
   282                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtKnife,    0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
   282                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtKnife,    0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
   283                                  newGear^.State:= newGear^.State or gstMoving; 
   283                                  newGear^.State:= newGear^.State or gstMoving;
   284                                  newGear^.Radius:= 6 // temporarily shrink so it doesn't instantly embed in the ground
   284                                  newGear^.Radius:= 6 // temporarily shrink so it doesn't instantly embed in the ground
   285                                  end;
   285                                  end;
   286                        amDEagle: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0);
   286                        amDEagle: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0);
   287                       amSineGun: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSineGunShot, 0, xx * _0_5, yy * _0_5, 0);
   287                       amSineGun: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSineGunShot, 0, xx * _0_5, yy * _0_5, 0);
   288                     amPortalGun: begin
   288                     amPortalGun: begin
   289                                  newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtPortal, 0, xx * _0_6, yy * _0_6, 
   289                                  newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtPortal, 0, xx * _0_6, yy * _0_6,
   290                                  // set selected color
   290                                  // set selected color
   291                                  CurWeapon^.Pos);
   291                                  CurWeapon^.Pos);
   292                                  end;
   292                                  end;
   293                   amSniperRifle: begin
   293                   amSniperRifle: begin
   294                                  PlaySound(sndSniperReload);
   294                                  PlaySound(sndSniperReload);
   344                    amLowGravity: begin
   344                    amLowGravity: begin
   345                                  PlaySound(sndLowGravity);
   345                                  PlaySound(sndLowGravity);
   346                                  cGravity:= cMaxWindSpeed;
   346                                  cGravity:= cMaxWindSpeed;
   347                                  cGravityf:= 0.00025
   347                                  cGravityf:= 0.00025
   348                                  end;
   348                                  end;
   349                   amExtraDamage: begin 
   349                   amExtraDamage: begin
   350                                  PlaySound(sndHellishImpact4);
   350                                  PlaySound(sndHellishImpact4);
   351                                  cDamageModifier:= _1_5
   351                                  cDamageModifier:= _1_5
   352                                  end;
   352                                  end;
   353                  amInvulnerable: Invulnerable:= true;
   353                  amInvulnerable: Invulnerable:= true;
   354                     amExtraTime: begin
   354                     amExtraTime: begin
   372                       amLandGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtLandGun,  0, xx * _0_5, yy * _0_5, 0);
   372                       amLandGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtLandGun,  0, xx * _0_5, yy * _0_5, 0);
   373                   amResurrector: begin
   373                   amResurrector: begin
   374                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtResurrector, 0, _0, _0, 0);
   374                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtResurrector, 0, _0, _0, 0);
   375                                  newGear^.SoundChannel := LoopSound(sndResurrector);
   375                                  newGear^.SoundChannel := LoopSound(sndResurrector);
   376                                  end;
   376                                  end;
   377                     amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
   377                     //amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
   378                        amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
   378                        amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
   379                        amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
   379                        amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
   380              end;
   380              end;
   381              if altUse and (newGear <> nil) then
   381              if altUse and (newGear <> nil) then
   382                 begin
   382                 begin
   383                 newGear^.dX:= newDx / newGear^.Density;
   383                 newGear^.dX:= newDx / newGear^.Density;
   384                 newGear^.dY:= newDY / newGear^.Density
   384                 newGear^.dY:= newDY / newGear^.Density
   385                 end;
   385                 end;
   386              
   386 
   387              case CurAmmoType of
   387              case CurAmmoType of
   388                       amGrenade, amMolotov, 
   388                       amGrenade, amMolotov,
   389                   amClusterBomb, amGasBomb, 
   389                   amClusterBomb, amGasBomb,
   390                       amBazooka, amSnowball, 
   390                       amBazooka, amSnowball,
   391                           amBee, amSMine,
   391                           amBee, amSMine,
   392                        amMortar, amWatermelon,
   392                        amMortar, amWatermelon,
   393                   amHellishBomb, amDrill: FollowGear:= newGear;
   393                   amHellishBomb, amDrill: FollowGear:= newGear;
   394 
   394 
   395                       amShotgun, amPickHammer,
   395                       amShotgun, amPickHammer,
   402                        amSwitch, amRCPlane,
   402                        amSwitch, amRCPlane,
   403                      amKamikaze, amCake,
   403                      amKamikaze, amCake,
   404                     amSeduction, amBallgun,
   404                     amSeduction, amBallgun,
   405                       amJetpack, amBirdy,
   405                       amJetpack, amBirdy,
   406                  amFlamethrower, amLandGun,
   406                  amFlamethrower, amLandGun,
   407                   amResurrector, amStructure,
   407                   amResurrector, //amStructure,
   408                        amTardis, amPiano,
   408                        amTardis, amPiano,
   409                        amIceGun: CurAmmoGear:= newGear;
   409                        amIceGun: CurAmmoGear:= newGear;
   410              end;
   410              end;
   411              
   411 
   412             if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then
   412             if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then
   413                 newGear^.FlightTime:= GameTicks + 1000
   413                 newGear^.FlightTime:= GameTicks + 1000
   414             else if CurAmmoType = amDrill then
   414             else if CurAmmoType = amDrill then
   415                 newGear^.FlightTime:= GameTicks + 250;
   415                 newGear^.FlightTime:= GameTicks + 250;
   416         if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
   416         if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
   430 
   430 
   431             if elastic < _1 then
   431             if elastic < _1 then
   432                 newGear^.Elasticity:= newGear^.Elasticity * elastic
   432                 newGear^.Elasticity:= newGear^.Elasticity * elastic
   433             else if elastic > _1 then
   433             else if elastic > _1 then
   434                 newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
   434                 newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
   435 (* Experimented with friction modifier. Didn't seem helpful 
   435 (* Experimented with friction modifier. Didn't seem helpful
   436             fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
   436             fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
   437             if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
   437             if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
   438             else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
   438             else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
   439             end;
   439             end;
   440 
   440 
   466             and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then
   466             and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then
   467                 SendIPC(_S'a');
   467                 SendIPC(_S'a');
   468             AfterAttack;
   468             AfterAttack;
   469             end
   469             end
   470         end
   470         end
   471     else 
   471     else
   472         Message:= Message and (not gmAttack);
   472         Message:= Message and (not gmAttack);
   473     end;
   473     end;
   474     TargetPoint.X := NoPointX;
   474     TargetPoint.X := NoPointX;
   475     ScriptCall('onHogAttack');
   475     ScriptCall('onHogAttack');
   476 end;
   476 end;
   486     a:= CurAmmoType;
   486     a:= CurAmmoType;
   487     if HHGear <> nil then HHGear^.State:= HHGear^.State and (not gstAttacking);
   487     if HHGear <> nil then HHGear^.State:= HHGear^.State and (not gstAttacking);
   488     if (Ammoz[a].Ammo.Propz and ammoprop_Effect) = 0 then
   488     if (Ammoz[a].Ammo.Propz and ammoprop_Effect) = 0 then
   489         begin
   489         begin
   490         Inc(MultiShootAttacks);
   490         Inc(MultiShootAttacks);
   491         
   491 
   492         if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) then
   492         if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) then
   493             begin
   493             begin
   494             s:= inttostr(Ammoz[a].Ammo.NumPerTurn - MultiShootAttacks + 1);
   494             s:= inttostr(Ammoz[a].Ammo.NumPerTurn - MultiShootAttacks + 1);
   495             AddCaption(format(trmsg[sidRemaining], s), cWhiteColor, capgrpAmmostate);
   495             AddCaption(format(trmsg[sidRemaining], s), cWhiteColor, capgrpAmmostate);
   496             end;
   496             end;
   497         
   497 
   498         if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks)
   498         if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks)
   499         or ((GameFlags and gfMultiWeapon) <> 0) then
   499         or ((GameFlags and gfMultiWeapon) <> 0) then
   500             begin
   500             begin
   501             isInMultiShoot:= true
   501             isInMultiShoot:= true
   502             end
   502             end
   507                 begin
   507                 begin
   508                 if TagTurnTimeLeft = 0 then
   508                 if TagTurnTimeLeft = 0 then
   509                     TagTurnTimeLeft:= TurnTimeLeft;
   509                     TagTurnTimeLeft:= TurnTimeLeft;
   510                 TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100;
   510                 TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100;
   511                 end;
   511                 end;
   512             if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (HHGear <> nil) then 
   512             if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (HHGear <> nil) then
   513                 HHGear^.State:= HHGear^.State or gstAttacked;
   513                 HHGear^.State:= HHGear^.State or gstAttacked;
   514             if (Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) <> 0 then
   514             if (Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) <> 0 then
   515                 ApplyAmmoChanges(CurrentHedgehog^)
   515                 ApplyAmmoChanges(CurrentHedgehog^)
   516             end;
   516             end;
   517         end
   517         end
   535     begin
   535     begin
   536     AllInactive:= false;
   536     AllInactive:= false;
   537     dec(Gear^.Timer);
   537     dec(Gear^.Timer);
   538     if (Gear^.Timer mod frametime) = 0 then
   538     if (Gear^.Timer mod frametime) = 0 then
   539         inc(Gear^.Pos)
   539         inc(Gear^.Pos)
   540     end 
   540     end
   541 else if Gear^.Timer = 1 then
   541 else if Gear^.Timer = 1 then
   542     begin
   542     begin
   543     Gear^.State:= Gear^.State or gstNoDamage;
   543     Gear^.State:= Gear^.State or gstNoDamage;
   544     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound);
   544     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound);
   545     AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
   545     AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
   546     DeleteGear(Gear);
   546     DeleteGear(Gear);
   547     SetAllToActive
   547     SetAllToActive
   548     end 
   548     end
   549 else // Gear^.Timer = 0
   549 else // Gear^.Timer = 0
   550     begin
   550     begin
   551     AllInactive:= false;
   551     AllInactive:= false;
   552     Gear^.Z:= cCurrHHZ;
   552     Gear^.Z:= cCurrHHZ;
   553     RemoveGearFromList(Gear);
   553     RemoveGearFromList(Gear);
   596     vga: PVisualGear;
   596     vga: PVisualGear;
   597 begin
   597 begin
   598     if cnt <> 0 then AddAmmo(HH, ammo, cnt)
   598     if cnt <> 0 then AddAmmo(HH, ammo, cnt)
   599     else AddAmmo(HH, ammo);
   599     else AddAmmo(HH, ammo);
   600 
   600 
   601     if (not (HH.Team^.ExtDriven 
   601     if (not (HH.Team^.ExtDriven
   602     or (HH.BotLevel > 0)))
   602     or (HH.BotLevel > 0)))
   603     or (HH.Team^.Clan^.ClanIndex = LocalClan)
   603     or (HH.Team^.Clan^.ClanIndex = LocalClan)
   604     or (GameType = gmtDemo)  then
   604     or (GameType = gmtDemo)  then
   605         begin
   605         begin
   606         if cnt <> 0 then
   606         if cnt <> 0 then
   634 else
   634 else
   635 case Gear^.Pos of
   635 case Gear^.Pos of
   636        posCaseUtility,
   636        posCaseUtility,
   637        posCaseAmmo: begin
   637        posCaseAmmo: begin
   638                     PlaySound(sndShotgunReload);
   638                     PlaySound(sndShotgunReload);
   639                     if Gear^.AmmoType <> amNothing then 
   639                     if Gear^.AmmoType <> amNothing then
   640                         begin
   640                         begin
   641                         AddPickup(HH^.Hedgehog^, Gear^.AmmoType, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y));
   641                         AddPickup(HH^.Hedgehog^, Gear^.AmmoType, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y));
   642                         end
   642                         end
   643                     else
   643                     else
   644                         begin
   644                         begin
   645 // Add spawning here...
   645 // Add spawning here...
   646                         AddRandomness(GameTicks);
   646                         AddRandomness(GameTicks);
   647                         
   647 
   648                         gi := GearsList;
   648                         gi := GearsList;
   649                         while gi <> nil do
   649                         while gi <> nil do
   650                             begin
   650                             begin
   651                             if (gi^.Kind = gtGenericFaller) and (gi^.State and gstInvisible <> 0) then
   651                             if (gi^.Kind = gtGenericFaller) and (gi^.State and gstInvisible <> 0) then
   652                                 begin
   652                                 begin
   757 
   757 
   758     PrevdX:= hwSign(Gear^.dX);
   758     PrevdX:= hwSign(Gear^.dX);
   759     if (Gear^.Message and gmLeft  )<>0 then
   759     if (Gear^.Message and gmLeft  )<>0 then
   760         Gear^.dX:= -cLittle else
   760         Gear^.dX:= -cLittle else
   761     if (Gear^.Message and gmRight )<>0 then
   761     if (Gear^.Message and gmRight )<>0 then
   762         Gear^.dX:=  cLittle 
   762         Gear^.dX:=  cLittle
   763         else exit;
   763         else exit;
   764 
   764 
   765     StepSoundTimer:= cHHStepTicks;
   765     StepSoundTimer:= cHHStepTicks;
   766 
   766 
   767     GHStepTicks:= cHHStepTicks;
   767     GHStepTicks:= cHHStepTicks;
   824     begin
   824     begin
   825     if (Gear^.dY.isNegative) and TestCollisionYKick(Gear, -1) then
   825     if (Gear^.dY.isNegative) and TestCollisionYKick(Gear, -1) then
   826         Gear^.dY:= _0;
   826         Gear^.dY:= _0;
   827     Gear^.State:= Gear^.State or gstMoving;
   827     Gear^.State:= Gear^.State or gstMoving;
   828     if (CurrentHedgehog^.Gear = Gear)
   828     if (CurrentHedgehog^.Gear = Gear)
   829         and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then 
   829         and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then
   830         begin
   830         begin
   831         // TODO: why so aggressive at setting FollowGear when falling?
   831         // TODO: why so aggressive at setting FollowGear when falling?
   832         FollowGear:= Gear;
   832         FollowGear:= Gear;
   833         end;
   833         end;
   834     if isUnderwater then
   834     if isUnderwater then
   840         if ((GameFlags and gfMoreWind) <> 0) and (((Gear^.Damage <> 0)
   840         if ((GameFlags and gfMoreWind) <> 0) and (((Gear^.Damage <> 0)
   841         or ((CurAmmoGear <> nil) and ((CurAmmoGear^.AmmoType = amJetpack) or (CurAmmoGear^.AmmoType = amBirdy)))
   841         or ((CurAmmoGear <> nil) and ((CurAmmoGear^.AmmoType = amJetpack) or (CurAmmoGear^.AmmoType = amBirdy)))
   842         or ((Gear^.dY.QWordValue + Gear^.dX.QWordValue) > _0_55.QWordValue))) then
   842         or ((Gear^.dY.QWordValue + Gear^.dX.QWordValue) > _0_55.QWordValue))) then
   843             Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
   843             Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
   844         end
   844         end
   845     end 
   845     end
   846 else
   846 else
   847     begin
   847     begin
   848     land:= TestCollisionYwithGear(Gear, 1);
   848     land:= TestCollisionYwithGear(Gear, 1);
   849     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)
   850     and ((Gear^.State and gstHHJumping) <> 0) then
   850     and ((Gear^.State and gstHHJumping) <> 0) then
   897                     if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) then
   897                     if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) then
   898                         begin
   898                         begin
   899                         Gear^.X:= Gear^.X + Gear^.dX;
   899                         Gear^.X:= Gear^.X + Gear^.dX;
   900                         Gear^.dX:= Gear^.dX * _0_93;
   900                         Gear^.dX:= Gear^.dX * _0_93;
   901                         Gear^.Y:= Gear^.Y - _2
   901                         Gear^.Y:= Gear^.Y - _2
   902                         end 
   902                         end
   903                     else
   903                     else
   904                         if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) then
   904                         if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) then
   905                         begin
   905                         begin
   906                         Gear^.X:= Gear^.X + Gear^.dX;
   906                         Gear^.X:= Gear^.X + Gear^.dX;
   907                         Gear^.dX:= Gear^.dX * _0_9 ;
   907                         Gear^.dX:= Gear^.dX * _0_9 ;
   961     begin
   961     begin
   962     Gear^.State:= Gear^.State and (not gstAnimation);
   962     Gear^.State:= Gear^.State and (not gstAnimation);
   963 // ARTILLERY but not being moved by explosions
   963 // ARTILLERY but not being moved by explosions
   964     Gear^.X:= Gear^.X + Gear^.dX;
   964     Gear^.X:= Gear^.X + Gear^.dX;
   965     Gear^.Y:= Gear^.Y + Gear^.dY;
   965     Gear^.Y:= Gear^.Y + Gear^.dY;
   966     if (not Gear^.dY.isNegative) and (not TestCollisionYKick(Gear, 1)) 
   966     if (not Gear^.dY.isNegative) and (not TestCollisionYKick(Gear, 1))
   967     and TestCollisionYwithXYShift(Gear, 0, 1, 1) then
   967     and TestCollisionYwithXYShift(Gear, 0, 1, 1) then
   968         begin
   968         begin
   969         CheckHHDamage(Gear);
   969         CheckHHDamage(Gear);
   970         Gear^.dY:= _0;
   970         Gear^.dY:= _0;
   971         Gear^.Y:= Gear^.Y + _1
   971         Gear^.Y:= Gear^.Y + _1
  1001 begin
  1001 begin
  1002 Hedgehog:= HHGear^.Hedgehog;
  1002 Hedgehog:= HHGear^.Hedgehog;
  1003 if isInMultiShoot then
  1003 if isInMultiShoot then
  1004     HHGear^.Message:= 0;
  1004     HHGear^.Message:= 0;
  1005 
  1005 
  1006 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
  1007     AllInactive:= true
  1007     AllInactive:= true
  1008 else if not isInMultiShoot then
  1008 else if not isInMultiShoot then
  1009     AllInactive:= false;
  1009     AllInactive:= false;
  1010 
  1010 
  1011 if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) then
  1011 if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) then
  1055 if (CurAmmoGear = nil) then
  1055 if (CurAmmoGear = nil) then
  1056     if (((HHGear^.Message and gmAttack) <> 0)
  1056     if (((HHGear^.Message and gmAttack) <> 0)
  1057     or ((HHGear^.State and gstAttacking) <> 0)) then
  1057     or ((HHGear^.State and gstAttacking) <> 0)) then
  1058         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
  1059     else
  1059     else
  1060 else 
  1060 else
  1061     with Hedgehog^ do
  1061     with Hedgehog^ do
  1062         if ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
  1062         if ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
  1063         and ((HHGear^.Message and gmLJump) <> 0)
  1063         and ((HHGear^.Message and gmLJump) <> 0)
  1064         and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
  1064         and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
  1065             begin
  1065             begin
  1161             Gear^.Hedgehog^.Effects[hePoisoned] := 0;
  1161             Gear^.Hedgehog^.Effects[hePoisoned] := 0;
  1162             if Gear^.Hedgehog^.Effects[heResurrectable] <> 0 then
  1162             if Gear^.Hedgehog^.Effects[heResurrectable] <> 0 then
  1163                 begin
  1163                 begin
  1164                 ResurrectHedgehog(Gear);
  1164                 ResurrectHedgehog(Gear);
  1165                 end
  1165                 end
  1166             else 
  1166             else
  1167                 begin
  1167                 begin
  1168                 Gear^.State:= (Gear^.State or gstHHDeath) and (not gstAnimation);
  1168                 Gear^.State:= (Gear^.State or gstHHDeath) and (not gstAnimation);
  1169                 Gear^.doStep:= @doStepHedgehogDead;
  1169                 Gear^.doStep:= @doStepHedgehogDead;
  1170                 // Death message
  1170                 // Death message
  1171                 AddCaption(Format(GetEventString(eidDied), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
  1171                 AddCaption(Format(GetEventString(eidDied), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
  1206 
  1206 
  1207 ////////////////////////////////////////////////////////////////////////////////
  1207 ////////////////////////////////////////////////////////////////////////////////
  1208 procedure doStepHedgehog(Gear: PGear);
  1208 procedure doStepHedgehog(Gear: PGear);
  1209 (*
  1209 (*
  1210 var x,y,tx,ty: LongInt;
  1210 var x,y,tx,ty: LongInt;
  1211     tdX, tdY, slope: hwFloat; 
  1211     tdX, tdY, slope: hwFloat;
  1212     land: Word; *)
  1212     land: Word; *)
  1213 var slope: hwFloat; 
  1213 var slope: hwFloat;
  1214 begin
  1214 begin
  1215 CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel;
  1215 CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel;
  1216 if (Gear^.Message and gmDestroy) <> 0 then
  1216 if (Gear^.Message and gmDestroy) <> 0 then
  1217     begin
  1217     begin
  1218     DeleteGear(Gear);
  1218     DeleteGear(Gear);