hedgewars/uGearsHedgehog.pas
changeset 8795 b5b79a8f9354
parent 8774 39754516eee6
child 8818 8f317ba10675
equal deleted inserted replaced
8793:43e106417a05 8795:b5b79a8f9354
    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 procedure CheckIce(Gear: PGear); inline;
    32 procedure CheckIce(Gear: PGear); inline;
    33 
    33 
    34 implementation
    34 implementation
    35 uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions, 
    35 uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions,
    36     uCommands, uLocale, uUtils, uVisualGears, uStats, uIO, uScript,
    36     uCommands, uLocale, uUtils, uVisualGears, uStats, uIO, uScript,
    37     uGearsList, uGears, uCollisions, uRandom, uStore, uTeams, 
    37     uGearsList, uGears, uCollisions, uRandom, uStore, uTeams,
    38     uGearsUtils;
    38     uGearsUtils;
    39 
    39 
    40 var GHStepTicks: LongWord = 0;
    40 var GHStepTicks: LongWord = 0;
    41 
    41 
    42 // Shouldn't more of this ammo switching stuff be moved to uAmmos ?
    42 // Shouldn't more of this ammo switching stuff be moved to uAmmos ?
    73         else OnUsedAmmo(HHGear^.Hedgehog^)
    73         else OnUsedAmmo(HHGear^.Hedgehog^)
    74         end;
    74         end;
    75 
    75 
    76     MultiShootAttacks:= 0;
    76     MultiShootAttacks:= 0;
    77     HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
    77     HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
    78     
    78 
    79     if Ammoz[CurAmmoType].Slot = slot then
    79     if Ammoz[CurAmmoType].Slot = slot then
    80         begin
    80         begin
    81         i:= 0;
    81         i:= 0;
    82         repeat
    82         repeat
    83         inc(ammoidx);
    83         inc(ammoidx);
    88             ammoidx:= -1;
    88             ammoidx:= -1;
    89             //TryDo(i < 2, 'Engine bug: no ammo in current slot', true)
    89             //TryDo(i < 2, 'Engine bug: no ammo in current slot', true)
    90             end;
    90             end;
    91         until (i = 1) or ((Ammo^[slot, ammoidx].Count > 0)
    91         until (i = 1) or ((Ammo^[slot, ammoidx].Count > 0)
    92         and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns))
    92         and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns))
    93         
    93 
    94         end 
    94         end
    95     else
    95     else
    96         begin
    96         begin
    97         i:= 0;
    97         i:= 0;
    98         // check whether there is ammo in slot
    98         // check whether there is ammo in slot
    99         while (i <= cMaxSlotAmmoIndex) and ((Ammo^[slot, i].Count = 0)
    99         while (i <= cMaxSlotAmmoIndex) and ((Ammo^[slot, i].Count = 0)
   112             LoadHedgehogHat(HHGear^.Hedgehog^, 'Reserved/chef')
   112             LoadHedgehogHat(HHGear^.Hedgehog^, 'Reserved/chef')
   113         else if prevAmmo = amKnife then
   113         else if prevAmmo = amKnife then
   114             LoadHedgehogHat(HHGear^.Hedgehog^, Hat);
   114             LoadHedgehogHat(HHGear^.Hedgehog^, Hat);
   115         end;
   115         end;
   116     // Try again in the next slot
   116     // Try again in the next slot
   117     if CurAmmoType = prevAmmo then 
   117     if CurAmmoType = prevAmmo then
   118         begin
   118         begin
   119         if slot >= cMaxSlotIndex then slot:= 0 else inc(slot);
   119         if slot >= cMaxSlotIndex then slot:= 0 else inc(slot);
   120         HHGear^.MsgParam:= slot;
   120         HHGear^.MsgParam:= slot;
   121         ChangeAmmo(HHGear)
   121         ChangeAmmo(HHGear)
   122         end
   122         end
   211     Gear^.Hedgehog^ do
   211     Gear^.Hedgehog^ do
   212         begin
   212         begin
   213         if ((State and gstHHDriven) <> 0) and ((State and (gstAttacked or gstHHChooseTarget)) = 0) and (((State and gstMoving) = 0)
   213         if ((State and gstHHDriven) <> 0) and ((State and (gstAttacked or gstHHChooseTarget)) = 0) and (((State and gstMoving) = 0)
   214         or (Power > 0)
   214         or (Power > 0)
   215         or (CurAmmoType = amTeleport)
   215         or (CurAmmoType = amTeleport)
   216         or 
   216         or
   217         // Allow attacks while moving on ammo with AltAttack
   217         // Allow attacks while moving on ammo with AltAttack
   218         ((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0))
   218         ((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0))
   219         or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0))
   219         or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0))
   220         and ((TargetPoint.X <> NoPointX) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) = 0)) then
   220         and ((TargetPoint.X <> NoPointX) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) = 0)) then
   221             begin
   221             begin
   255             if  (CurAmmoGear <> nil)
   255             if  (CurAmmoGear <> nil)
   256             and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
   256             and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
   257             and ((Gear^.Message and gmLJump) <> 0)
   257             and ((Gear^.Message and gmLJump) <> 0)
   258             and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
   258             and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
   259                 begin
   259                 begin
   260                 newDx:= dX; 
   260                 newDx:= dX;
   261                 newDy:= dY;
   261                 newDy:= dY;
   262                 altUse:= true
   262                 altUse:= true
   263                 end
   263                 end
   264             else
   264             else
   265                 begin
   265                 begin
   283                    amPickHammer: newGear:= AddGear(hwRound(lx), hwRound(ly) + cHHRadius, gtPickHammer, 0, _0, _0, 0);
   283                    amPickHammer: newGear:= AddGear(hwRound(lx), hwRound(ly) + cHHRadius, gtPickHammer, 0, _0, _0, 0);
   284                          amSkip: ParseCommand('/skip', true);
   284                          amSkip: ParseCommand('/skip', true);
   285                          amRope: newGear:= AddGear(hwRound(lx), hwRound(ly), gtRope, 0, xx, yy, 0);
   285                          amRope: newGear:= AddGear(hwRound(lx), hwRound(ly), gtRope, 0, xx, yy, 0);
   286                          amMine: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000);
   286                          amMine: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000);
   287                         amSMine: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSMine,    0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
   287                         amSMine: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSMine,    0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
   288                         amKnife: begin 
   288                         amKnife: begin
   289                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtKnife,    0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
   289                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtKnife,    0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
   290                                  newGear^.State:= newGear^.State or gstMoving; 
   290                                  newGear^.State:= newGear^.State or gstMoving;
   291                                  newGear^.Radius:= 4 // temporarily shrink so it doesn't instantly embed in the ground
   291                                  newGear^.Radius:= 4 // temporarily shrink so it doesn't instantly embed in the ground
   292                                  end;
   292                                  end;
   293                        amDEagle: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0);
   293                        amDEagle: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0);
   294                       amSineGun: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSineGunShot, 0, xx * _0_5, yy * _0_5, 0);
   294                       amSineGun: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSineGunShot, 0, xx * _0_5, yy * _0_5, 0);
   295                     amPortalGun: begin
   295                     amPortalGun: begin
   296                                  newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtPortal, 0, xx * _0_6, yy * _0_6, 
   296                                  newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtPortal, 0, xx * _0_6, yy * _0_6,
   297                                  // set selected color
   297                                  // set selected color
   298                                  CurWeapon^.Pos);
   298                                  CurWeapon^.Pos);
   299                                  end;
   299                                  end;
   300                   amSniperRifle: begin
   300                   amSniperRifle: begin
   301                                  PlaySound(sndSniperReload);
   301                                  PlaySound(sndSniperReload);
   351                    amLowGravity: begin
   351                    amLowGravity: begin
   352                                  PlaySound(sndLowGravity);
   352                                  PlaySound(sndLowGravity);
   353                                  cGravity:= cMaxWindSpeed;
   353                                  cGravity:= cMaxWindSpeed;
   354                                  cGravityf:= 0.00025
   354                                  cGravityf:= 0.00025
   355                                  end;
   355                                  end;
   356                   amExtraDamage: begin 
   356                   amExtraDamage: begin
   357                                  PlaySound(sndHellishImpact4);
   357                                  PlaySound(sndHellishImpact4);
   358                                  cDamageModifier:= _1_5
   358                                  cDamageModifier:= _1_5
   359                                  end;
   359                                  end;
   360                  amInvulnerable: Invulnerable:= true;
   360                  amInvulnerable: Invulnerable:= true;
   361                     amExtraTime: begin
   361                     amExtraTime: begin
   381                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtResurrector, 0, _0, _0, 0);
   381                                  newGear:= AddGear(hwRound(lx), hwRound(ly), gtResurrector, 0, _0, _0, 0);
   382                                  newGear^.SoundChannel := LoopSound(sndResurrector);
   382                                  newGear^.SoundChannel := LoopSound(sndResurrector);
   383                                  end;
   383                                  end;
   384                     //amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
   384                     //amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
   385                        amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
   385                        amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
   386                        amIceGun: begin
   386                        amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
   387                        newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
       
   388                        newGear^.radius := 8;
       
   389                        end;
       
   390             end;
   387             end;
   391             if altUse and (newGear <> nil) then
   388             if altUse and (newGear <> nil) then
   392                begin
   389                begin
   393                newGear^.dX:= newDx / newGear^.Density;
   390                newGear^.dX:= newDx / newGear^.Density;
   394                newGear^.dY:= newDY / newGear^.Density
   391                newGear^.dY:= newDY / newGear^.Density
   395                end;
   392                end;
   396              
   393 
   397             case CurAmmoType of
   394             case CurAmmoType of
   398                      amGrenade, amMolotov, 
   395                      amGrenade, amMolotov,
   399                  amClusterBomb, amGasBomb, 
   396                  amClusterBomb, amGasBomb,
   400                      amBazooka, amSnowball, 
   397                      amBazooka, amSnowball,
   401                          amBee, amSMine,
   398                          amBee, amSMine,
   402                       amMortar, amWatermelon,
   399                       amMortar, amWatermelon,
   403                  amHellishBomb, amDrill: FollowGear:= newGear;
   400                  amHellishBomb, amDrill: FollowGear:= newGear;
   404 
   401 
   405                      amShotgun, amPickHammer,
   402                      amShotgun, amPickHammer,
   416                 amFlamethrower, amLandGun,
   413                 amFlamethrower, amLandGun,
   417                  amResurrector, //amStructure,
   414                  amResurrector, //amStructure,
   418                       amTardis, amPiano,
   415                       amTardis, amPiano,
   419                       amIceGun: CurAmmoGear:= newGear;
   416                       amIceGun: CurAmmoGear:= newGear;
   420             end;
   417             end;
   421              
   418 
   422             if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then
   419             if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then
   423                 newGear^.FlightTime:= GameTicks + 1000
   420                 newGear^.FlightTime:= GameTicks + 1000
   424             else if CurAmmoType = amDrill then
   421             else if CurAmmoType = amDrill then
   425                 newGear^.FlightTime:= GameTicks + 250;
   422                 newGear^.FlightTime:= GameTicks + 250;
   426             if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
   423             if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
   440 
   437 
   441                 if elastic < _1 then
   438                 if elastic < _1 then
   442                     newGear^.Elasticity:= newGear^.Elasticity * elastic
   439                     newGear^.Elasticity:= newGear^.Elasticity * elastic
   443                 else if elastic > _1 then
   440                 else if elastic > _1 then
   444                     newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
   441                     newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
   445     (* Experimented with friction modifier. Didn't seem helpful 
   442     (* Experimented with friction modifier. Didn't seem helpful
   446                 fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
   443                 fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
   447                 if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
   444                 if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
   448                 else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
   445                 else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
   449                 end;
   446                 end;
   450 
   447 
   476                 and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then
   473                 and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then
   477                     SendIPC(_S'a');
   474                     SendIPC(_S'a');
   478                 AfterAttack;
   475                 AfterAttack;
   479                 end
   476                 end
   480             end
   477             end
   481         else 
   478         else
   482             Message:= Message and (not gmAttack);
   479             Message:= Message and (not gmAttack);
   483     end;
   480     end;
   484     TargetPoint.X := NoPointX;
   481     TargetPoint.X := NoPointX;
   485     ScriptCall('onHogAttack');
   482     ScriptCall('onHogAttack');
   486 end;
   483 end;
   496     a:= CurAmmoType;
   493     a:= CurAmmoType;
   497     if HHGear <> nil then HHGear^.State:= HHGear^.State and (not gstAttacking);
   494     if HHGear <> nil then HHGear^.State:= HHGear^.State and (not gstAttacking);
   498     if (Ammoz[a].Ammo.Propz and ammoprop_Effect) = 0 then
   495     if (Ammoz[a].Ammo.Propz and ammoprop_Effect) = 0 then
   499         begin
   496         begin
   500         Inc(MultiShootAttacks);
   497         Inc(MultiShootAttacks);
   501         
   498 
   502         if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) then
   499         if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) then
   503             begin
   500             begin
   504             s:= inttostr(Ammoz[a].Ammo.NumPerTurn - MultiShootAttacks + 1);
   501             s:= inttostr(Ammoz[a].Ammo.NumPerTurn - MultiShootAttacks + 1);
   505             AddCaption(format(trmsg[sidRemaining], s), cWhiteColor, capgrpAmmostate);
   502             AddCaption(format(trmsg[sidRemaining], s), cWhiteColor, capgrpAmmostate);
   506             end;
   503             end;
   507         
   504 
   508         if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks)
   505         if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks)
   509         or ((GameFlags and gfMultiWeapon) <> 0) then
   506         or ((GameFlags and gfMultiWeapon) <> 0) then
   510             begin
   507             begin
   511             isInMultiShoot:= true
   508             isInMultiShoot:= true
   512             end
   509             end
   517                 begin
   514                 begin
   518                 if TagTurnTimeLeft = 0 then
   515                 if TagTurnTimeLeft = 0 then
   519                     TagTurnTimeLeft:= TurnTimeLeft;
   516                     TagTurnTimeLeft:= TurnTimeLeft;
   520                 TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100;
   517                 TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100;
   521                 end;
   518                 end;
   522             if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (HHGear <> nil) then 
   519             if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (HHGear <> nil) then
   523                 HHGear^.State:= HHGear^.State or gstAttacked;
   520                 HHGear^.State:= HHGear^.State or gstAttacked;
   524             if (Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) <> 0 then
   521             if (Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) <> 0 then
   525                 ApplyAmmoChanges(CurrentHedgehog^)
   522                 ApplyAmmoChanges(CurrentHedgehog^)
   526             end;
   523             end;
   527         end
   524         end
   545     begin
   542     begin
   546     AllInactive:= false;
   543     AllInactive:= false;
   547     dec(Gear^.Timer);
   544     dec(Gear^.Timer);
   548     if (Gear^.Timer mod frametime) = 0 then
   545     if (Gear^.Timer mod frametime) = 0 then
   549         inc(Gear^.Pos)
   546         inc(Gear^.Pos)
   550     end 
   547     end
   551 else if Gear^.Timer = 1 then
   548 else if Gear^.Timer = 1 then
   552     begin
   549     begin
   553     Gear^.State:= Gear^.State or gstNoDamage;
   550     Gear^.State:= Gear^.State or gstNoDamage;
   554     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound);
   551     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound);
   555     AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
   552     AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
   556     DeleteGear(Gear);
   553     DeleteGear(Gear);
   557     SetAllToActive
   554     SetAllToActive
   558     end 
   555     end
   559 else // Gear^.Timer = 0
   556 else // Gear^.Timer = 0
   560     begin
   557     begin
   561     AllInactive:= false;
   558     AllInactive:= false;
   562     Gear^.Z:= cCurrHHZ;
   559     Gear^.Z:= cCurrHHZ;
   563     RemoveGearFromList(Gear);
   560     RemoveGearFromList(Gear);
   606     vga: PVisualGear;
   603     vga: PVisualGear;
   607 begin
   604 begin
   608     if cnt <> 0 then AddAmmo(HH, ammo, cnt)
   605     if cnt <> 0 then AddAmmo(HH, ammo, cnt)
   609     else AddAmmo(HH, ammo);
   606     else AddAmmo(HH, ammo);
   610 
   607 
   611     if (not (HH.Team^.ExtDriven 
   608     if (not (HH.Team^.ExtDriven
   612     or (HH.BotLevel > 0)))
   609     or (HH.BotLevel > 0)))
   613     or (HH.Team^.Clan^.ClanIndex = LocalClan)
   610     or (HH.Team^.Clan^.ClanIndex = LocalClan)
   614     or (GameType = gmtDemo)  then
   611     or (GameType = gmtDemo)  then
   615         begin
   612         begin
   616         if cnt <> 0 then
   613         if cnt <> 0 then
   644 else
   641 else
   645 case Gear^.Pos of
   642 case Gear^.Pos of
   646        posCaseUtility,
   643        posCaseUtility,
   647        posCaseAmmo: begin
   644        posCaseAmmo: begin
   648                     PlaySound(sndShotgunReload);
   645                     PlaySound(sndShotgunReload);
   649                     if Gear^.AmmoType <> amNothing then 
   646                     if Gear^.AmmoType <> amNothing then
   650                         begin
   647                         begin
   651                         AddPickup(HH^.Hedgehog^, Gear^.AmmoType, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y));
   648                         AddPickup(HH^.Hedgehog^, Gear^.AmmoType, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y));
   652                         end
   649                         end
   653                     else
   650                     else
   654                         begin
   651                         begin
   655 // Add spawning here...
   652 // Add spawning here...
   656                         AddRandomness(GameTicks);
   653                         AddRandomness(GameTicks);
   657                         
   654 
   658                         gi := GearsList;
   655                         gi := GearsList;
   659                         while gi <> nil do
   656                         while gi <> nil do
   660                             begin
   657                             begin
   661                             if (gi^.Kind = gtGenericFaller) and (gi^.State and gstInvisible <> 0) then
   658                             if (gi^.Kind = gtGenericFaller) and (gi^.State and gstInvisible <> 0) then
   662                                 begin
   659                                 begin
   767 
   764 
   768     PrevdX:= hwSign(Gear^.dX);
   765     PrevdX:= hwSign(Gear^.dX);
   769     if (Gear^.Message and gmLeft  )<>0 then
   766     if (Gear^.Message and gmLeft  )<>0 then
   770         Gear^.dX:= -cLittle else
   767         Gear^.dX:= -cLittle else
   771     if (Gear^.Message and gmRight )<>0 then
   768     if (Gear^.Message and gmRight )<>0 then
   772         Gear^.dX:=  cLittle 
   769         Gear^.dX:=  cLittle
   773         else exit;
   770         else exit;
   774 
   771 
   775     StepSoundTimer:= cHHStepTicks;
   772     StepSoundTimer:= cHHStepTicks;
   776 
   773 
   777     GHStepTicks:= cHHStepTicks;
   774     GHStepTicks:= cHHStepTicks;
   834     begin
   831     begin
   835     if (Gear^.dY.isNegative) and TestCollisionYKick(Gear, -1) then
   832     if (Gear^.dY.isNegative) and TestCollisionYKick(Gear, -1) then
   836         Gear^.dY:= _0;
   833         Gear^.dY:= _0;
   837     Gear^.State:= Gear^.State or gstMoving;
   834     Gear^.State:= Gear^.State or gstMoving;
   838     if (CurrentHedgehog^.Gear = Gear)
   835     if (CurrentHedgehog^.Gear = Gear)
   839         and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then 
   836         and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then
   840         begin
   837         begin
   841         // TODO: why so aggressive at setting FollowGear when falling?
   838         // TODO: why so aggressive at setting FollowGear when falling?
   842         FollowGear:= Gear;
   839         FollowGear:= Gear;
   843         end;
   840         end;
   844     if isUnderwater then
   841     if isUnderwater then
   850         if ((GameFlags and gfMoreWind) <> 0) and (((Gear^.Damage <> 0)
   847         if ((GameFlags and gfMoreWind) <> 0) and (((Gear^.Damage <> 0)
   851         or ((CurAmmoGear <> nil) and ((CurAmmoGear^.AmmoType = amJetpack) or (CurAmmoGear^.AmmoType = amBirdy)))
   848         or ((CurAmmoGear <> nil) and ((CurAmmoGear^.AmmoType = amJetpack) or (CurAmmoGear^.AmmoType = amBirdy)))
   852         or ((Gear^.dY.QWordValue + Gear^.dX.QWordValue) > _0_55.QWordValue))) then
   849         or ((Gear^.dY.QWordValue + Gear^.dX.QWordValue) > _0_55.QWordValue))) then
   853             Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
   850             Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
   854         end
   851         end
   855     end 
   852     end
   856 else
   853 else
   857     begin
   854     begin
   858     land:= TestCollisionYwithGear(Gear, 1);
   855     land:= TestCollisionYwithGear(Gear, 1);
   859     if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_55.QWordValue) and ((land and lfIce) = 0)
   856     if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_55.QWordValue) and ((land and lfIce) = 0)
   860     and ((Gear^.State and gstHHJumping) <> 0) then
   857     and ((Gear^.State and gstHHJumping) <> 0) then
   909                         (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
   906                         (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
   910                         begin
   907                         begin
   911                         Gear^.X:= Gear^.X + Gear^.dX;
   908                         Gear^.X:= Gear^.X + Gear^.dX;
   912                         Gear^.dX:= Gear^.dX * _0_93;
   909                         Gear^.dX:= Gear^.dX * _0_93;
   913                         Gear^.Y:= Gear^.Y - _2
   910                         Gear^.Y:= Gear^.Y - _2
   914                         end 
   911                         end
   915                     else
   912                     else
   916                     if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) or
   913                     if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) or
   917                         (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
   914                         (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
   918                         begin
   915                         begin
   919                         Gear^.X:= Gear^.X + Gear^.dX;
   916                         Gear^.X:= Gear^.X + Gear^.dX;
   976     begin
   973     begin
   977     Gear^.State:= Gear^.State and (not gstAnimation);
   974     Gear^.State:= Gear^.State and (not gstAnimation);
   978 // ARTILLERY but not being moved by explosions
   975 // ARTILLERY but not being moved by explosions
   979     Gear^.X:= Gear^.X + Gear^.dX;
   976     Gear^.X:= Gear^.X + Gear^.dX;
   980     Gear^.Y:= Gear^.Y + Gear^.dY;
   977     Gear^.Y:= Gear^.Y + Gear^.dY;
   981     if (not Gear^.dY.isNegative) and (not TestCollisionYKick(Gear, 1)) 
   978     if (not Gear^.dY.isNegative) and (not TestCollisionYKick(Gear, 1))
   982     and TestCollisionYwithXYShift(Gear, 0, 1, 1) then
   979     and TestCollisionYwithXYShift(Gear, 0, 1, 1) then
   983         begin
   980         begin
   984         CheckHHDamage(Gear);
   981         CheckHHDamage(Gear);
   985         Gear^.dY:= _0;
   982         Gear^.dY:= _0;
   986         Gear^.Y:= Gear^.Y + _1
   983         Gear^.Y:= Gear^.Y + _1
  1069 if (CurAmmoGear = nil) then
  1066 if (CurAmmoGear = nil) then
  1070     if (((HHGear^.Message and gmAttack) <> 0)
  1067     if (((HHGear^.Message and gmAttack) <> 0)
  1071     or ((HHGear^.State and gstAttacking) <> 0)) then
  1068     or ((HHGear^.State and gstAttacking) <> 0)) then
  1072         Attack(HHGear) // should be before others to avoid desync with '/put' msg and changing weapon msgs
  1069         Attack(HHGear) // should be before others to avoid desync with '/put' msg and changing weapon msgs
  1073     else
  1070     else
  1074 else 
  1071 else
  1075     with Hedgehog^ do
  1072     with Hedgehog^ do
  1076         if ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
  1073         if ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
  1077         and ((HHGear^.Message and gmLJump) <> 0)
  1074         and ((HHGear^.Message and gmLJump) <> 0)
  1078         and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
  1075         and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
  1079             begin
  1076             begin
  1174             Gear^.Hedgehog^.Effects[hePoisoned] := 0;
  1171             Gear^.Hedgehog^.Effects[hePoisoned] := 0;
  1175             if Gear^.Hedgehog^.Effects[heResurrectable] <> 0 then
  1172             if Gear^.Hedgehog^.Effects[heResurrectable] <> 0 then
  1176                 begin
  1173                 begin
  1177                 ResurrectHedgehog(Gear);
  1174                 ResurrectHedgehog(Gear);
  1178                 end
  1175                 end
  1179             else 
  1176             else
  1180                 begin
  1177                 begin
  1181                 Gear^.State:= (Gear^.State or gstHHDeath) and (not gstAnimation);
  1178                 Gear^.State:= (Gear^.State or gstHHDeath) and (not gstAnimation);
  1182                 Gear^.doStep:= @doStepHedgehogDead;
  1179                 Gear^.doStep:= @doStepHedgehogDead;
  1183                 // Death message
  1180                 // Death message
  1184                 AddCaption(Format(GetEventString(eidDied), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
  1181                 AddCaption(Format(GetEventString(eidDied), Gear^.Hedgehog^.Name), cWhiteColor, capgrpMessage);
  1218 end;
  1215 end;
  1219 
  1216 
  1220 procedure CheckIce(Gear: PGear); inline;
  1217 procedure CheckIce(Gear: PGear); inline;
  1221 (*
  1218 (*
  1222 var x,y,tx,ty: LongInt;
  1219 var x,y,tx,ty: LongInt;
  1223     tdX, tdY, slope: hwFloat; 
  1220     tdX, tdY, slope: hwFloat;
  1224     land: Word; *)
  1221     land: Word; *)
  1225 var slope: hwFloat; 
  1222 var slope: hwFloat;
  1226 begin
  1223 begin
  1227     if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0)
  1224     if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0)
  1228     and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0)
  1225     and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0)
  1229     and ((Gear^.Hedgehog = nil) or ((Gear^.Hedgehog^.Effects[heFrozen] = 0) or (Gear^.Hedgehog^.Effects[heFrozen] > 255)))
  1226     and ((Gear^.Hedgehog = nil) or ((Gear^.Hedgehog^.Effects[heFrozen] = 0) or (Gear^.Hedgehog^.Effects[heFrozen] > 255)))
  1230     and (not Gear^.dY.isNegative) and (TurnTimeLeft > 0) and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
  1227     and (not Gear^.dY.isNegative) and (TurnTimeLeft > 0) and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
  1261     DeleteGear(Gear);
  1258     DeleteGear(Gear);
  1262     exit
  1259     exit
  1263     end;
  1260     end;
  1264 if GameTicks mod 100 = 0 then CheckIce(Gear);
  1261 if GameTicks mod 100 = 0 then CheckIce(Gear);
  1265 (*
  1262 (*
  1266 if Gear^.Hedgehog^.Effects[heFrozen] > 0 then 
  1263 if Gear^.Hedgehog^.Effects[heFrozen] > 0 then
  1267     begin
  1264     begin
  1268     if (Gear^.Hedgehog^.Effects[heFrozen] > 256) and (CurrentHedgehog^.Team^.Clan <> Gear^.Hedgehog^.Team^.Clan) then
  1265     if (Gear^.Hedgehog^.Effects[heFrozen] > 256) and (CurrentHedgehog^.Team^.Clan <> Gear^.Hedgehog^.Team^.Clan) then
  1269         dec(Gear^.Hedgehog^.Effects[heFrozen])
  1266         dec(Gear^.Hedgehog^.Effects[heFrozen])
  1270     else if GameTicks mod 10 = 0 then
  1267     else if GameTicks mod 10 = 0 then
  1271         dec(Gear^.Hedgehog^.Effects[heFrozen])
  1268         dec(Gear^.Hedgehog^.Effects[heFrozen])
  1272     end;
  1269     end;
  1273 *)
  1270 *)
  1274 if (GameTicks mod 10 = 0) and (Gear^.Hedgehog^.Effects[heFrozen] > 0) and (Gear^.Hedgehog^.Effects[heFrozen] < 256) then 
  1271 if (GameTicks mod 10 = 0) and (Gear^.Hedgehog^.Effects[heFrozen] > 0) and (Gear^.Hedgehog^.Effects[heFrozen] < 256) then
  1275     dec(Gear^.Hedgehog^.Effects[heFrozen]);
  1272     dec(Gear^.Hedgehog^.Effects[heFrozen]);
  1276 if (Gear^.State and gstHHDriven) = 0 then
  1273 if (Gear^.State and gstHHDriven) = 0 then
  1277     doStepHedgehogFree(Gear)
  1274     doStepHedgehogFree(Gear)
  1278 else
  1275 else
  1279     begin
  1276     begin