hedgewars/uGearsHedgehog.pas
branchwebgl
changeset 8833 c13ebed437cb
parent 8444 75db7bb8dce8
parent 8818 8f317ba10675
child 9127 e350500c4edb
equal deleted inserted replaced
8450:404ddce27b23 8833:c13ebed437cb
    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 
    33 
    33 implementation
    34 implementation
    34 uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions,
    35 uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions,
    35     uCommands, uLocale, uUtils, uVisualGears, uStats, uIO, uScript,
    36     uCommands, uLocale, uUtils, uVisualGears, uStats, uIO, uScript,
    36     uGearsList, uGears, uCollisions, uRandom, uStore, uTeams,
    37     uGearsList, uGears, uCollisions, uRandom, uStore, uTeams,
    51     begin
    52     begin
    52     HHGear^.Message:= HHGear^.Message and (not gmSlot);
    53     HHGear^.Message:= HHGear^.Message and (not gmSlot);
    53     prevAmmo:= CurAmmoType;
    54     prevAmmo:= CurAmmoType;
    54     ammoidx:= 0;
    55     ammoidx:= 0;
    55     if ((HHGear^.State and (gstAttacking or gstAttacked)) <> 0)
    56     if ((HHGear^.State and (gstAttacking or gstAttacked)) <> 0)
    56     or ((MultiShootAttacks > 0) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) = 0))
       
    57     or ((HHGear^.State and gstHHDriven) = 0) then
    57     or ((HHGear^.State and gstHHDriven) = 0) then
    58         exit;
    58         exit;
    59     ChangeAmmo:= true;
    59     ChangeAmmo:= true;
    60 
    60 
    61     while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> CurAmmoType) do
    61     while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> CurAmmoType) do
    62         inc(ammoidx);
    62         inc(ammoidx);
    63 
    63 
    64     if ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) and (MultiShootAttacks > 0) then
    64     if (MultiShootAttacks > 0) then
    65         OnUsedAmmo(HHGear^.Hedgehog^);
    65         begin
       
    66         if (CurAmmoType = amSniperRifle) and ((GameFlags and gfArtillery) = 0) then
       
    67             cArtillery := false;
       
    68         if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) = 0 then
       
    69             begin
       
    70             MultiShootAttacks:= Ammoz[CurAmmoType].Ammo.NumPerTurn;
       
    71             AfterAttack
       
    72             end
       
    73         else OnUsedAmmo(HHGear^.Hedgehog^)
       
    74         end;
    66 
    75 
    67     MultiShootAttacks:= 0;
    76     MultiShootAttacks:= 0;
    68     HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
    77     HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
    69 
    78 
    70     if Ammoz[CurAmmoType].Slot = slot then
    79     if Ammoz[CurAmmoType].Slot = slot then
   209         ((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))
   210         or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0))
   219         or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0))
   211         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
   212             begin
   221             begin
   213             State:= State or gstAttacking;
   222             State:= State or gstAttacking;
   214             if Power = cMaxPower then
   223             if (Power = cMaxPower) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) = 0) then
   215                 Message:= Message and (not gmAttack)
       
   216             else if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) = 0 then
       
   217                 Message:= Message and (not gmAttack)
   224                 Message:= Message and (not gmAttack)
   218             else
   225             else
   219                 begin
   226                 begin
   220                 if Power = 0 then
   227                 if Power = 0 then
   221                     begin
   228                     begin
   222                     AttackBar:= CurrentTeam^.AttackBar;
   229                     AttackBar:= CurrentTeam^.AttackBar;
   223                     PlaySound(sndThrowPowerUp)
   230                     PlaySound(sndThrowPowerUp)
   224                     end;
   231                     end;
   225                 inc(Power)
   232                 inc(Power)
   226                 end;
   233                 end;
   227         if ((Message and gmAttack) <> 0) then
   234             if ((Message and gmAttack) <> 0) then
   228             exit;
   235                 exit;
   229 
   236 
   230         if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0 then
   237             if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0 then
   231             begin
   238                 begin
   232             StopSound(sndThrowPowerUp);
   239                 StopSound(sndThrowPowerUp);
   233             PlaySound(sndThrowRelease);
   240                 PlaySound(sndThrowRelease);
   234             end;
   241                 end;
   235 
   242 
   236         xx:= SignAs(AngleSin(Angle), dX);
   243             xx:= SignAs(AngleSin(Angle), dX);
   237         yy:= -AngleCos(Angle);
   244             yy:= -AngleCos(Angle);
   238 
   245 
   239         lx:= X + int2hwfloat(round(GetLaunchX(CurAmmoType, hwSign(dX), Angle)));
   246             lx:= X + int2hwfloat(round(GetLaunchX(CurAmmoType, hwSign(dX), Angle)));
   240         ly:= Y + int2hwfloat(round(GetLaunchY(CurAmmoType, Angle)));
   247             ly:= Y + int2hwfloat(round(GetLaunchY(CurAmmoType, Angle)));
   241 
   248 
   242         if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then
   249             if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then
   243             xx:= - xx;
   250                 xx:= - xx;
   244         if Ammoz[CurAmmoType].Ammo.AttackVoice <> sndNone then
   251             if Ammoz[CurAmmoType].Ammo.AttackVoice <> sndNone then
   245             AddVoice(Ammoz[CurAmmoType].Ammo.AttackVoice, CurrentTeam^.voicepack);
   252                 AddVoice(Ammoz[CurAmmoType].Ammo.AttackVoice, CurrentTeam^.voicepack);
   246 
   253 
   247 // Initiating alt attack
   254 // Initiating alt attack
   248         if  (CurAmmoGear <> nil)
   255             if  (CurAmmoGear <> nil)
   249         and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
   256             and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
   250         and ((Gear^.Message and gmLJump) <> 0)
   257             and ((Gear^.Message and gmLJump) <> 0)
   251         and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
   258             and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
   252             begin
   259                 begin
   253             newDx:= dX;
   260                 newDx:= dX;
   254             newDy:= dY;
   261                 newDy:= dY;
   255             altUse:= true
   262                 altUse:= true
   256             end
   263                 end
   257         else
   264             else
   258             begin
   265                 begin
   259             newDx:= xx*Power/cPowerDivisor;
   266                 newDx:= xx*Power/cPowerDivisor;
   260             newDy:= yy*Power/cPowerDivisor;
   267                 newDy:= yy*Power/cPowerDivisor;
   261             altUse:= false
   268                 altUse:= false
   262             end;
   269                 end;
   263 
   270 
   264              case CurAmmoType of
   271             case CurAmmoType of
   265                       amGrenade: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGrenade,         0, newDx, newDy, CurWeapon^.Timer);
   272                       amGrenade: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGrenade,         0, newDx, newDy, CurWeapon^.Timer);
   266                       amMolotov: newGear:= AddGear(hwRound(lx), hwRound(ly), gtMolotov,      0, newDx, newDy, 0);
   273                       amMolotov: newGear:= AddGear(hwRound(lx), hwRound(ly), gtMolotov,      0, newDx, newDy, 0);
   267                   amClusterBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtClusterBomb,  0, newDx, newDy, CurWeapon^.Timer);
   274                   amClusterBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtClusterBomb,  0, newDx, newDy, CurWeapon^.Timer);
   268                       amGasBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGasBomb,      0, newDx, newDy, CurWeapon^.Timer);
   275                       amGasBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGasBomb,      0, newDx, newDy, CurWeapon^.Timer);
   269                       amBazooka: newGear:= AddGear(hwRound(lx), hwRound(ly), gtShell,        0, newDx, newDy, 0);
   276                       amBazooka: newGear:= AddGear(hwRound(lx), hwRound(ly), gtShell,        0, newDx, newDy, 0);
   279                          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);
   280                         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);
   281                         amKnife: begin
   288                         amKnife: begin
   282                                  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);
   283                                  newGear^.State:= newGear^.State or gstMoving;
   290                                  newGear^.State:= newGear^.State or gstMoving;
   284                                  newGear^.Radius:= 6 // 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
   285                                  end;
   292                                  end;
   286                        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);
   287                       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);
   288                     amPortalGun: begin
   295                     amPortalGun: begin
   289                                  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,
   375                                  newGear^.SoundChannel := LoopSound(sndResurrector);
   382                                  newGear^.SoundChannel := LoopSound(sndResurrector);
   376                                  end;
   383                                  end;
   377                     //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);
   378                        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);
   379                        amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
   386                        amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
   380              end;
   387             end;
   381              if altUse and (newGear <> nil) then
   388             if altUse and (newGear <> nil) then
   382                 begin
   389                begin
   383                 newGear^.dX:= newDx / newGear^.Density;
   390                newGear^.dX:= newDx / newGear^.Density;
   384                 newGear^.dY:= newDY / newGear^.Density
   391                newGear^.dY:= newDY / newGear^.Density
   385                 end;
   392                end;
   386 
   393 
   387              case CurAmmoType of
   394             case CurAmmoType of
   388                       amGrenade, amMolotov,
   395                      amGrenade, amMolotov,
   389                   amClusterBomb, amGasBomb,
   396                  amClusterBomb, amGasBomb,
   390                       amBazooka, amSnowball,
   397                      amBazooka, amSnowball,
   391                           amBee, amSMine,
   398                          amBee, amSMine,
   392                        amMortar, amWatermelon,
   399                       amMortar, amWatermelon,
   393                   amHellishBomb, amDrill: FollowGear:= newGear;
   400                  amHellishBomb, amDrill: FollowGear:= newGear;
   394 
   401 
   395                       amShotgun, amPickHammer,
   402                      amShotgun, amPickHammer,
   396                          amRope, amDEagle,
   403                         amRope, amDEagle,
   397                       amSineGun, amSniperRifle,
   404                      amSineGun, amSniperRifle,
   398                     amFirePunch, amWhip,
   405                    amFirePunch, amWhip,
   399                        amHammer, amBaseballBat,
   406                       amHammer, amBaseballBat,
   400                     amParachute, amBlowTorch,
   407                    amParachute, amBlowTorch,
   401                        amGirder, amTeleport,
   408                       amGirder, amTeleport,
   402                        amSwitch, amRCPlane,
   409                       amSwitch, amRCPlane,
   403                      amKamikaze, amCake,
   410                     amKamikaze, amCake,
   404                     amSeduction, amBallgun,
   411                    amSeduction, amBallgun,
   405                       amJetpack, amBirdy,
   412                      amJetpack, amBirdy,
   406                  amFlamethrower, amLandGun,
   413                 amFlamethrower, amLandGun,
   407                   amResurrector, //amStructure,
   414                  amResurrector, //amStructure,
   408                        amTardis, amPiano,
   415                       amTardis, amPiano,
   409                        amIceGun: CurAmmoGear:= newGear;
   416                       amIceGun: CurAmmoGear:= newGear;
   410              end;
   417             end;
   411 
   418 
   412             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
   413                 newGear^.FlightTime:= GameTicks + 1000
   420                 newGear^.FlightTime:= GameTicks + 1000
   414             else if CurAmmoType = amDrill then
   421             else if CurAmmoType = amDrill then
   415                 newGear^.FlightTime:= GameTicks + 250;
   422                 newGear^.FlightTime:= GameTicks + 250;
   416         if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
   423             if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
   417             begin
   424                 begin
   418             newGear^.Target.X:= TargetPoint.X;
   425                 newGear^.Target.X:= TargetPoint.X;
   419             newGear^.Target.Y:= TargetPoint.Y
   426                 newGear^.Target.Y:= TargetPoint.Y
   420             end;
   427                 end;
   421         if (newGear <> nil) and (newGear^.CollisionMask and $80 <> 0) then newGear^.CollisionMask:= newGear^.CollisionMask and (not $80);
   428             if (newGear <> nil) and (newGear^.CollisionMask and lfCurrentHog <> 0) then newGear^.CollisionMask:= newGear^.CollisionMask and (not lfCurrentHog);
   422 
   429 
   423         // Clear FollowGear if using on a rope/parachute/saucer etc so focus stays with the hog's movement
   430             // Clear FollowGear if using on a rope/parachute/saucer etc so focus stays with the hog's movement
   424         if altUse then
   431             if altUse then
   425             FollowGear:= nil;
   432                 FollowGear:= nil;
   426 
   433 
   427         if (newGear <> nil) and ((Ammoz[newGear^.AmmoType].Ammo.Propz and ammoprop_SetBounce) <> 0) then
   434             if (newGear <> nil) and ((Ammoz[newGear^.AmmoType].Ammo.Propz and ammoprop_SetBounce) <> 0) then
   428             begin
   435                 begin
   429             elastic:=  int2hwfloat(CurWeapon^.Bounciness) / _1000;
   436                 elastic:=  int2hwfloat(CurWeapon^.Bounciness) / _1000;
   430 
   437 
   431             if elastic < _1 then
   438             if elastic < _1 then
   432                 newGear^.Elasticity:= newGear^.Elasticity * elastic
   439                 newGear^.Elasticity:= newGear^.Elasticity * elastic
   433             else if elastic > _1 then
   440             else if elastic > _1 then
   434                 newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
   441                 newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
   437             if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
   444             if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
   438             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)*)
   439             end;
   446             end;
   440 
   447 
   441 
   448 
   442         uStats.AmmoUsed(CurAmmoType);
   449             uStats.AmmoUsed(CurAmmoType);
   443 
   450 
   444         if not (SpeechText = '') then
   451             if not (SpeechText = '') then
   445             begin
   452                 begin
   446             speech:= AddVisualGear(0, 0, vgtSpeechBubble);
   453                 speech:= AddVisualGear(0, 0, vgtSpeechBubble);
   447             if speech <> nil then
   454                 if speech <> nil then
   448                 begin
   455                     begin
   449                 speech^.Text:= SpeechText;
   456                     speech^.Text:= SpeechText;
   450                 speech^.Hedgehog:= Gear^.Hedgehog;
   457                     speech^.Hedgehog:= Gear^.Hedgehog;
   451                 speech^.FrameTicks:= SpeechType;
   458                     speech^.FrameTicks:= SpeechType;
       
   459                     end;
       
   460                 SpeechText:= ''
   452                 end;
   461                 end;
   453             SpeechText:= ''
   462 
   454             end;
   463             Power:= 0;
   455 
   464             if (CurAmmoGear <> nil) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then
   456         Power:= 0;
   465                 begin
   457         if (CurAmmoGear <> nil)
   466                 if CurAmmoType in [amRope,amResurrector] then
   458             and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then
   467                     Message:= Message or gmAttack;
   459             begin
   468                 CurAmmoGear^.Message:= Message
   460             Message:= Message or gmAttack;
   469                 end
   461             CurAmmoGear^.Message:= Message
   470             else
       
   471                 begin
       
   472                 if (not CurrentTeam^.ExtDriven) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then
       
   473                     SendIPC(_S'a');
       
   474                 AfterAttack;
       
   475                 end
   462             end
   476             end
   463         else
   477         else
   464             begin
   478             Message:= Message and (not gmAttack);
   465             if not CurrentTeam^.ExtDriven
       
   466             and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then
       
   467                 SendIPC(_S'a');
       
   468             AfterAttack;
       
   469             end
       
   470         end
       
   471     else
       
   472         Message:= Message and (not gmAttack);
       
   473     end;
   479     end;
   474     TargetPoint.X := NoPointX;
   480     TargetPoint.X := NoPointX;
   475     ScriptCall('onHogAttack');
   481     ScriptCall('onHogAttack');
   476 end;
   482 end;
   477 
   483 
   775     Gear^.Hedgehog^.visStepPos:= (Gear^.Hedgehog^.visStepPos + 1) and 7;
   781     Gear^.Hedgehog^.visStepPos:= (Gear^.Hedgehog^.visStepPos + 1) and 7;
   776 
   782 
   777     if (not cArtillery) and ((Gear^.Message and gmPrecise) = 0) then
   783     if (not cArtillery) and ((Gear^.Message and gmPrecise) = 0) then
   778         MakeHedgehogsStep(Gear);
   784         MakeHedgehogsStep(Gear);
   779 
   785 
   780     SetAllHHToActive;
   786     SetAllHHToActive(false);
   781     AddGearCI(Gear)
   787     AddGearCI(Gear)
   782     end
   788     end
   783 end;
   789 end;
   784 
   790 
   785 procedure HedgehogChAngle(HHGear: PGear);
   791 procedure HedgehogChAngle(HHGear: PGear);
   786 var da: LongWord;
   792 var da: LongWord;
   787 begin
   793 begin
   788 with HHGear^.Hedgehog^ do
   794 with HHGear^.Hedgehog^ do
   789     if ((CurAmmoType = amRope) and ((HHGear^.State and (gstMoving or gstHHJumping)) = gstMoving))
   795     if ((CurAmmoGear <> nil) and (CurAmmoGear^.AmmoType = amRope) and ((HHGear^.State and (gstMoving or gstHHJumping)) = gstMoving))
   790     or ((CurAmmoType = amPortalGun) and ((HHGear^.State and gstMoving) <> 0)) then
   796     or ((CurAmmoType = amPortalGun) and ((HHGear^.State and gstMoving) <> 0)) then
   791         da:= 2
   797         da:= 2
   792     else da:= 1;
   798     else da:= 1;
   793 
   799 
   794 if (((HHGear^.Message and gmPrecise) = 0) or ((GameTicks mod 5) = 1)) then
   800 if (((HHGear^.Message and gmPrecise) = 0) or ((GameTicks mod 5) = 1)) then
   885 
   891 
   886 if (Gear^.State and gstMoving) <> 0 then
   892 if (Gear^.State and gstMoving) <> 0 then
   887     if TestCollisionXKick(Gear, hwSign(Gear^.dX)) then
   893     if TestCollisionXKick(Gear, hwSign(Gear^.dX)) then
   888         if not isFalling then
   894         if not isFalling then
   889             if hwAbs(Gear^.dX) > _0_01 then
   895             if hwAbs(Gear^.dX) > _0_01 then
   890                 if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -1, hwSign(Gear^.dX)) then
   896                 if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -1, hwSign(Gear^.dX)) or
       
   897                 (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
   891                     begin
   898                     begin
   892                     Gear^.X:= Gear^.X + Gear^.dX;
   899                     Gear^.X:= Gear^.X + Gear^.dX;
   893                     Gear^.dX:= Gear^.dX * _0_96;
   900                     Gear^.dX:= Gear^.dX * _0_96;
   894                     Gear^.Y:= Gear^.Y - _1
   901                     Gear^.Y:= Gear^.Y - _1
   895                     end
   902                     end
   896                 else
   903                 else
   897                     if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) then
   904                     if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) or
       
   905                         (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
   898                         begin
   906                         begin
   899                         Gear^.X:= Gear^.X + Gear^.dX;
   907                         Gear^.X:= Gear^.X + Gear^.dX;
   900                         Gear^.dX:= Gear^.dX * _0_93;
   908                         Gear^.dX:= Gear^.dX * _0_93;
   901                         Gear^.Y:= Gear^.Y - _2
   909                         Gear^.Y:= Gear^.Y - _2
   902                         end
   910                         end
   903                     else
   911                     else
   904                         if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) then
   912                     if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) or
       
   913                         (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
   905                         begin
   914                         begin
   906                         Gear^.X:= Gear^.X + Gear^.dX;
   915                         Gear^.X:= Gear^.X + Gear^.dX;
   907                         Gear^.dX:= Gear^.dX * _0_9 ;
   916                         Gear^.dX:= Gear^.dX * _0_9 ;
   908                         Gear^.Y:= Gear^.Y - _3
   917                         Gear^.Y:= Gear^.Y - _3
   909                         end
   918                         end
   910                     else
   919                     else
   911                         if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -4, hwSign(Gear^.dX)) then
   920                         if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -4, hwSign(Gear^.dX)) or
       
   921                         (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
   912                             begin
   922                             begin
   913                             Gear^.X:= Gear^.X + Gear^.dX;
   923                             Gear^.X:= Gear^.X + Gear^.dX;
   914                             Gear^.dX:= Gear^.dX * _0_87;
   924                             Gear^.dX:= Gear^.dX * _0_87;
   915                             Gear^.Y:= Gear^.Y - _4
   925                             Gear^.Y:= Gear^.Y - _4
   916                             end
   926                             end
   917                     else
   927                     else
   918                         if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -5, hwSign(Gear^.dX)) then
   928                         if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -5, hwSign(Gear^.dX)) or
       
   929                         (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
   919                             begin
   930                             begin
   920                             Gear^.X:= Gear^.X + Gear^.dX;
   931                             Gear^.X:= Gear^.X + Gear^.dX;
   921                             Gear^.dX:= Gear^.dX * _0_84;
   932                             Gear^.dX:= Gear^.dX * _0_84;
   922                             Gear^.Y:= Gear^.Y - _5
   933                             Gear^.Y:= Gear^.Y - _5
   923                             end
   934                             end
   998 var t: PGear;
  1009 var t: PGear;
   999     wasJumping: boolean;
  1010     wasJumping: boolean;
  1000     Hedgehog: PHedgehog;
  1011     Hedgehog: PHedgehog;
  1001 begin
  1012 begin
  1002 Hedgehog:= HHGear^.Hedgehog;
  1013 Hedgehog:= HHGear^.Hedgehog;
  1003 if isInMultiShoot then
  1014 if not isInMultiShoot then
       
  1015     AllInactive:= false
       
  1016 else if Hedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle] then
  1004     HHGear^.Message:= 0;
  1017     HHGear^.Message:= 0;
  1005 
  1018 
  1006 if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Utility) <> 0) and isInMultiShoot then
  1019 if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Utility) <> 0) and isInMultiShoot then
  1007     AllInactive:= true
  1020     AllInactive:= true
  1008 else if not isInMultiShoot then
  1021 else if not isInMultiShoot then
  1009     AllInactive:= false;
  1022     AllInactive:= false;
  1010 
  1023 
  1011 if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) then
  1024 if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) then
  1012     begin
  1025     begin
       
  1026     if (Hedgehog^.CurAmmoType = amKnife) then
       
  1027        LoadHedgehogHat(Hedgehog^, Hedgehog^.Hat);
  1013     if TagTurnTimeLeft = 0 then
  1028     if TagTurnTimeLeft = 0 then
  1014         TagTurnTimeLeft:= TurnTimeLeft;
  1029         TagTurnTimeLeft:= TurnTimeLeft;
  1015     TurnTimeLeft:= 0;
  1030     TurnTimeLeft:= 0;
  1016     isCursorVisible:= false;
  1031     isCursorVisible:= false;
  1017     HHGear^.State:= HHGear^.State and (not (gstHHDriven or gstAnimation or gstAttacking));
  1032     HHGear^.State:= HHGear^.State and (not (gstHHDriven or gstAnimation or gstAttacking));
  1084     begin
  1099     begin
  1085     CurAmmoGear^.Message:= HHGear^.Message;
  1100     CurAmmoGear^.Message:= HHGear^.Message;
  1086     exit
  1101     exit
  1087     end;
  1102     end;
  1088 
  1103 
  1089 if not isInMultiShoot then
       
  1090     HedgehogChAngle(HHGear);
  1104     HedgehogChAngle(HHGear);
  1091 
  1105 
  1092 if (HHGear^.State and gstMoving) <> 0 then
  1106 if (HHGear^.State and gstMoving) <> 0 then
  1093     begin
  1107     begin
  1094     wasJumping:= ((HHGear^.State and gstHHJumping) <> 0);
  1108     wasJumping:= ((HHGear^.State and gstHHJumping) <> 0);
  1120             GHStepTicks:= 95
  1134             GHStepTicks:= 95
  1121         end;
  1135         end;
  1122     exit
  1136     exit
  1123     end;
  1137     end;
  1124 
  1138 
  1125     if (not isInMultiShoot) and (Hedgehog^.Gear <> nil) then
  1139     if not(isInMultiShoot and (Hedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle])) and (Hedgehog^.Gear <> nil) then
  1126         begin
  1140         begin
  1127         if GHStepTicks > 0 then
  1141         if GHStepTicks > 0 then
  1128             dec(GHStepTicks);
  1142             dec(GHStepTicks);
  1129         if (GHStepTicks = 0) then
  1143         if (GHStepTicks = 0) then
  1130             HedgehogStep(HHGear)
  1144             HedgehogStep(HHGear)
  1192 else
  1206 else
  1193     begin
  1207     begin
  1194     if Gear^.Timer = 0 then
  1208     if Gear^.Timer = 0 then
  1195         begin
  1209         begin
  1196         Gear^.State:= Gear^.State and (not (gstWait or gstLoser or gstWinner or gstAttacked or gstNotKickable or gstHHChooseTarget));
  1210         Gear^.State:= Gear^.State and (not (gstWait or gstLoser or gstWinner or gstAttacked or gstNotKickable or gstHHChooseTarget));
  1197         Gear^.Active:= false;
  1211         if Gear^.Hedgehog^.Effects[heFrozen] = 0 then Gear^.Active:= false;
  1198         AddGearCI(Gear);
  1212         AddGearCI(Gear);
  1199         exit
  1213         exit
  1200         end
  1214         end
  1201     else dec(Gear^.Timer)
  1215     else dec(Gear^.Timer)
  1202     end;
  1216     end;
  1203 
  1217 
  1204 AllInactive:= false
  1218 AllInactive:= false
  1205 end;
  1219 end;
  1206 
  1220 
  1207 ////////////////////////////////////////////////////////////////////////////////
  1221 procedure CheckIce(Gear: PGear); inline;
  1208 procedure doStepHedgehog(Gear: PGear);
       
  1209 (*
  1222 (*
  1210 var x,y,tx,ty: LongInt;
  1223 var x,y,tx,ty: LongInt;
  1211     tdX, tdY, slope: hwFloat;
  1224     tdX, tdY, slope: hwFloat;
  1212     land: Word; *)
  1225     land: Word; *)
  1213 var slope: hwFloat;
  1226 var slope: hwFloat;
  1214 begin
  1227 begin
  1215 CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel;
  1228     if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0)
  1216 if (Gear^.Message and gmDestroy) <> 0 then
  1229     and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0)
  1217     begin
  1230     and ((Gear^.Hedgehog = nil) or ((Gear^.Hedgehog^.Effects[heFrozen] = 0) or (Gear^.Hedgehog^.Effects[heFrozen] > 255)))
  1218     DeleteGear(Gear);
  1231     and (not Gear^.dY.isNegative) and (TurnTimeLeft > 0) and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
  1219     exit
  1232         begin
  1220     end;
  1233         slope:= CalcSlopeBelowGear(Gear);
  1221 
  1234         if slope.QWordValue > 730144440 then // ignore mild slopes
  1222 if (Gear^.State and gstHHDriven) = 0 then
  1235             begin
  1223     doStepHedgehogFree(Gear)
  1236             Gear^.dX:=Gear^.dX+slope*cGravity*_256;
  1224 else
  1237             Gear^.State:= Gear^.State or gstMoving
  1225     begin
  1238             end
  1226     with Gear^.Hedgehog^ do
  1239         end;
  1227         if Team^.hasGone then
       
  1228             TeamGoneEffect(Team^)
       
  1229         else
       
  1230             doStepHedgehogDriven(Gear)
       
  1231     end;
       
  1232 if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0)
       
  1233 and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0)
       
  1234 and (not Gear^.dY.isNegative) and (GameTicks mod (100*LongWOrd(hwRound(cMaxWindSpeed*2/cGravity))) = 0)
       
  1235 and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
       
  1236     begin
       
  1237     slope:= CalcSlopeBelowGear(Gear);
       
  1238     Gear^.dX:=Gear^.dX+slope*_0_07;
       
  1239     if slope.QWordValue <> 0 then
       
  1240         Gear^.State:= Gear^.State or gstMoving;
       
  1241 (*
  1240 (*
  1242     x:= hwRound(Gear^.X);
  1241     x:= hwRound(Gear^.X);
  1243     y:= hwRound(Gear^.Y);
  1242     y:= hwRound(Gear^.Y);
  1244     AddVisualGear(x, y, vgtSmokeTrace);
  1243     AddVisualGear(x, y, vgtSmokeTrace);
  1245     AddVisualGear(x - hwRound(_5*slope), y + hwRound(_5*slope), vgtSmokeTrace);
  1244     AddVisualGear(x - hwRound(_5*slope), y + hwRound(_5*slope), vgtSmokeTrace);
  1250     AddVisualGear(x + hwRound(_30 * slope), y - hwRound(_30 * slope), vgtSmokeTrace);
  1249     AddVisualGear(x + hwRound(_30 * slope), y - hwRound(_30 * slope), vgtSmokeTrace);
  1251     AddVisualGear(x - hwRound(_40 * slope), y + hwRound(_40 * slope), vgtSmokeTrace);
  1250     AddVisualGear(x - hwRound(_40 * slope), y + hwRound(_40 * slope), vgtSmokeTrace);
  1252     AddVisualGear(x + hwRound(_40 * slope), y - hwRound(_40 * slope), vgtSmokeTrace);
  1251     AddVisualGear(x + hwRound(_40 * slope), y - hwRound(_40 * slope), vgtSmokeTrace);
  1253     AddVisualGear(x - hwRound(_50 * slope), y + hwRound(_50 * slope), vgtSmokeTrace);
  1252     AddVisualGear(x - hwRound(_50 * slope), y + hwRound(_50 * slope), vgtSmokeTrace);
  1254     AddVisualGear(x + hwRound(_50 * slope), y - hwRound(_50 * slope), vgtSmokeTrace); *)
  1253     AddVisualGear(x + hwRound(_50 * slope), y - hwRound(_50 * slope), vgtSmokeTrace); *)
  1255     end
  1254 end;
       
  1255 
       
  1256 ////////////////////////////////////////////////////////////////////////////////
       
  1257 procedure doStepHedgehog(Gear: PGear);
       
  1258 begin
       
  1259 CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel;
       
  1260 if (Gear^.Message and gmDestroy) <> 0 then
       
  1261     begin
       
  1262     DeleteGear(Gear);
       
  1263     exit
       
  1264     end;
       
  1265 if GameTicks mod 100 = 0 then CheckIce(Gear);
       
  1266 (*
       
  1267 if Gear^.Hedgehog^.Effects[heFrozen] > 0 then
       
  1268     begin
       
  1269     if (Gear^.Hedgehog^.Effects[heFrozen] > 256) and (CurrentHedgehog^.Team^.Clan <> Gear^.Hedgehog^.Team^.Clan) then
       
  1270         dec(Gear^.Hedgehog^.Effects[heFrozen])
       
  1271     else if GameTicks mod 10 = 0 then
       
  1272         dec(Gear^.Hedgehog^.Effects[heFrozen])
       
  1273     end;
       
  1274 *)
       
  1275 if (GameTicks mod 10 = 0) and (Gear^.Hedgehog^.Effects[heFrozen] > 0) and (Gear^.Hedgehog^.Effects[heFrozen] < 256) then
       
  1276     dec(Gear^.Hedgehog^.Effects[heFrozen]);
       
  1277 if (Gear^.State and gstHHDriven) = 0 then
       
  1278     doStepHedgehogFree(Gear)
       
  1279 else
       
  1280     begin
       
  1281     with Gear^.Hedgehog^ do
       
  1282         if Team^.hasGone then
       
  1283             TeamGoneEffect(Team^)
       
  1284         else
       
  1285             doStepHedgehogDriven(Gear)
       
  1286     end;
  1256 end;
  1287 end;
  1257 
  1288 
  1258 end.
  1289 end.