hedgewars/GSHandlers.inc
branchwebgl
changeset 8330 aaefa587e277
parent 8105 d088be5ecdcb
parent 8204 9a6030d96273
child 8444 75db7bb8dce8
equal deleted inserted replaced
8116:d24257910f8d 8330:aaefa587e277
    51     if steps > 1 then
    51     if steps > 1 then
    52         begin
    52         begin
    53         sX:= dX / steps;
    53         sX:= dX / steps;
    54         sY:= dY / steps;
    54         sY:= dY / steps;
    55         end
    55         end
    56         
    56 
    57     else
    57     else
    58         begin
    58         begin
    59         sX:= dX;
    59         sX:= dX;
    60         sY:= dY;
    60         sY:= dY;
    61         end;
    61         end;
    73             break;
    73             break;
    74         end;
    74         end;
    75 end;
    75 end;
    76 
    76 
    77 procedure makeHogsWorry(x, y: hwFloat; r: LongInt);
    77 procedure makeHogsWorry(x, y: hwFloat; r: LongInt);
    78 var 
    78 var
    79     gi: PGear;
    79     gi: PGear;
    80     d: LongInt;
    80     d: LongInt;
    81 begin
    81 begin
    82     gi := GearsList;
    82     gi := GearsList;
    83     while gi <> nil do
    83     while gi <> nil do
    87             d := r - hwRound(Distance(gi^.X - x, gi^.Y - y));
    87             d := r - hwRound(Distance(gi^.X - x, gi^.Y - y));
    88             if (d > 1) and (not gi^.Invulnerable) and (GetRandom(2) = 0) then
    88             if (d > 1) and (not gi^.Invulnerable) and (GetRandom(2) = 0) then
    89                 begin
    89                 begin
    90                 if (CurrentHedgehog^.Gear = gi) then
    90                 if (CurrentHedgehog^.Gear = gi) then
    91                     PlaySoundV(sndOops, gi^.Hedgehog^.Team^.voicepack)
    91                     PlaySoundV(sndOops, gi^.Hedgehog^.Team^.voicepack)
    92                     
    92 
    93                 else
    93                 else
    94                     begin
    94                     begin
    95                     if (gi^.State and gstMoving) = 0 then
    95                     if (gi^.State and gstMoving) = 0 then
    96                         begin
    96                         begin
    97                         gi^.dX.isNegative:= X<gi^.X;
    97                         gi^.dX.isNegative:= X<gi^.X;
    98                         gi^.State := gi^.State or gstLoser;
    98                         gi^.State := gi^.State or gstLoser;
    99                         end;
    99                         end;
   100                         
   100 
   101                     if d > r div 2 then
   101                     if d > r div 2 then
   102                         PlaySoundV(sndNooo, gi^.Hedgehog^.Team^.voicepack) 
   102                         PlaySoundV(sndNooo, gi^.Hedgehog^.Team^.voicepack)
   103                     else
   103                     else
   104                         PlaySoundV(sndUhOh, gi^.Hedgehog^.Team^.voicepack);
   104                         PlaySoundV(sndUhOh, gi^.Hedgehog^.Team^.voicepack);
   105                     end;
   105                     end;
   106                 end;
   106                 end;
   107             end;
   107             end;
   108             
   108 
   109         gi := gi^.NextGear
   109         gi := gi^.NextGear
   110         end;
   110         end;
   111 end;
   111 end;
   112 
   112 
   113 procedure HideHog(HH: PHedgehog);
   113 procedure HideHog(HH: PHedgehog);
   114 begin
   114 begin
   115     ScriptCall('onHogHide', HH^.Gear^.Uid);
   115     ScriptCall('onHogHide', HH^.Gear^.Uid);
   116     DeleteCI(HH^.Gear);
   116     DeleteCI(HH^.Gear);
   117     if FollowGear = HH^.Gear then
   117     if FollowGear = HH^.Gear then
   118         FollowGear:= nil;
   118         FollowGear:= nil;
   119         
   119 
   120     if lastGearByUID = HH^.Gear then
   120     if lastGearByUID = HH^.Gear then
   121         lastGearByUID := nil;
   121         lastGearByUID := nil;
   122     
   122 
   123     HH^.Gear^.Message:= HH^.Gear^.Message or gmRemoveFromList;
   123     HH^.Gear^.Message:= HH^.Gear^.Message or gmRemoveFromList;
   124     with HH^.Gear^ do
   124     with HH^.Gear^ do
   125         begin
   125         begin
   126         Z := cHHZ;
   126         Z := cHHZ;
   127         HH^.Gear^.Active:= false;
   127         HH^.Gear^.Active:= false;
   163         DeleteGear(Gear);
   163         DeleteGear(Gear);
   164     end;
   164     end;
   165 
   165 
   166 ////////////////////////////////////////////////////////////////////////////////
   166 ////////////////////////////////////////////////////////////////////////////////
   167 procedure doStepFallingGear(Gear: PGear);
   167 procedure doStepFallingGear(Gear: PGear);
   168 var 
   168 var
   169     isFalling: boolean;
   169     isFalling: boolean;
   170     //tmp: QWord;
   170     //tmp: QWord;
   171     tdX, tdY: hwFloat;
   171     tdX, tdY: hwFloat;
   172     collV, collH: LongInt;
   172     collV, collH: LongInt;
   173     land: word;
   173     land: word;
   218             Gear^.State := Gear^.State or gstCollision
   218             Gear^.State := Gear^.State or gstCollision
   219             end
   219             end
   220         else if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, 1) <> 0) then
   220         else if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, 1) <> 0) then
   221             collV := 1;
   221             collV := 1;
   222         end
   222         end
   223     else 
   223     else
   224         begin // Gear^.dY.isNegative is false
   224         begin // Gear^.dY.isNegative is false
   225         land:= TestCollisionYwithGear(Gear, 1);
   225         land:= TestCollisionYwithGear(Gear, 1);
   226         if land <> 0 then
   226         if land <> 0 then
   227             begin
   227             begin
   228             collV := 1;
   228             collV := 1;
   229             isFalling := false;
   229             isFalling := false;
   230             if land and lfIce <> 0 then 
   230             if land and lfIce <> 0 then
   231                 Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1)
   231                 Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1)
   232             else 
   232             else
   233                 Gear^.dX := Gear^.dX * Gear^.Friction;
   233                 Gear^.dX := Gear^.dX * Gear^.Friction;
   234 
   234 
   235             Gear^.dY := - Gear^.dY * Gear^.Elasticity;
   235             Gear^.dY := - Gear^.dY * Gear^.Elasticity;
   236             Gear^.State := Gear^.State or gstCollision
   236             Gear^.State := Gear^.State or gstCollision
   237             end
   237             end
   250         Gear^.dX := - Gear^.dX * Gear^.Elasticity;
   250         Gear^.dX := - Gear^.dX * Gear^.Elasticity;
   251         Gear^.dY :=   Gear^.dY * Gear^.Elasticity;
   251         Gear^.dY :=   Gear^.dY * Gear^.Elasticity;
   252         Gear^.State := Gear^.State or gstCollision
   252         Gear^.State := Gear^.State or gstCollision
   253         end
   253         end
   254     else if (Gear^.AdvBounce=1) and TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)) then
   254     else if (Gear^.AdvBounce=1) and TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)) then
   255         collH := -hwSign(Gear^.dX); 
   255         collH := -hwSign(Gear^.dX);
   256     //if Gear^.AdvBounce and (collV <>0) and (collH <> 0) and (hwSqr(tdX) + hwSqr(tdY) > _0_08) then
   256     //if Gear^.AdvBounce and (collV <>0) and (collH <> 0) and (hwSqr(tdX) + hwSqr(tdY) > _0_08) then
   257     if (Gear^.AdvBounce=1) and (collV <>0) and (collH <> 0) and ((collV=-1)
   257     if (Gear^.AdvBounce=1) and (collV <>0) and (collH <> 0) and ((collV=-1)
   258     or ((tdX.QWordValue + tdY.QWordValue) > _0_2.QWordValue)) then
   258     or ((tdX.QWordValue + tdY.QWordValue) > _0_2.QWordValue)) then
   259         begin
   259         begin
   260         Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction;
   260         Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction;
   283     if (not isFalling) and ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) then
   283     if (not isFalling) and ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) then
   284         Gear^.State := Gear^.State and (not gstMoving)
   284         Gear^.State := Gear^.State and (not gstMoving)
   285     else
   285     else
   286         Gear^.State := Gear^.State or gstMoving;
   286         Gear^.State := Gear^.State or gstMoving;
   287 
   287 
   288     if (Gear^.nImpactSounds > 0) and 
   288     if (Gear^.nImpactSounds > 0) and
   289         (Gear^.State and gstCollision <> 0) and
   289         (Gear^.State and gstCollision <> 0) and
   290         (((Gear^.Kind <> gtMine) and (Gear^.Damage <> 0)) or (Gear^.State and gstMoving <> 0)) and
   290         (((Gear^.Kind <> gtMine) and (Gear^.Damage <> 0)) or (Gear^.State and gstMoving <> 0)) and
   291         (((Gear^.Radius < 3) and (Gear^.dY < -_0_1)) or
   291         (((Gear^.Radius < 3) and (Gear^.dY < -_0_1)) or
   292             ((Gear^.Radius >= 3) and 
   292             ((Gear^.Radius >= 3) and
   293                 ((Gear^.dX.QWordValue > _0_1.QWordValue) or (Gear^.dY.QWordValue > _0_1.QWordValue)))) then
   293                 ((Gear^.dX.QWordValue > _0_1.QWordValue) or (Gear^.dY.QWordValue > _0_1.QWordValue)))) then
   294         PlaySound(TSound(ord(Gear^.ImpactSound) + LongInt(GetRandom(Gear^.nImpactSounds))), true);
   294         PlaySound(TSound(ord(Gear^.ImpactSound) + LongInt(GetRandom(Gear^.nImpactSounds))), true);
   295 end;
   295 end;
   296 
   296 
   297 ////////////////////////////////////////////////////////////////////////////////
   297 ////////////////////////////////////////////////////////////////////////////////
   298 procedure doStepBomb(Gear: PGear);
   298 procedure doStepBomb(Gear: PGear);
   299 var 
   299 var
   300     i, x, y: LongInt;
   300     i, x, y: LongInt;
   301     dX, dY: hwFloat;
   301     dX, dY: hwFloat;
   302     vg: PVisualGear;
   302     vg: PVisualGear;
   303 begin
   303 begin
   304     AllInactive := false;
   304     AllInactive := false;
   305 
   305 
   306     doStepFallingGear(Gear);
   306     doStepFallingGear(Gear);
   307 
   307 
   308     dec(Gear^.Timer);
   308     dec(Gear^.Timer);
   309     if Gear^.Timer = 1000 then // might need adjustments
   309     if Gear^.Timer = 1000 then // might need adjustments
   310         case Gear^.Kind of 
   310         case Gear^.Kind of
   311             gtGrenade: makeHogsWorry(Gear^.X, Gear^.Y, 50);
   311             gtGrenade: makeHogsWorry(Gear^.X, Gear^.Y, 50);
   312             gtClusterBomb: makeHogsWorry(Gear^.X, Gear^.Y, 20);
   312             gtClusterBomb: makeHogsWorry(Gear^.X, Gear^.Y, 20);
   313             gtWatermelon: makeHogsWorry(Gear^.X, Gear^.Y, 75);
   313             gtWatermelon: makeHogsWorry(Gear^.X, Gear^.Y, 75);
   314             gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90);
   314             gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90);
   315             gtGasBomb: makeHogsWorry(Gear^.X, Gear^.Y, 50);
   315             gtGasBomb: makeHogsWorry(Gear^.X, Gear^.Y, 50);
   329             vg^.Tint:= $FFC0C000;
   329             vg^.Tint:= $FFC0C000;
   330         end;
   330         end;
   331 
   331 
   332     if Gear^.Timer = 0 then
   332     if Gear^.Timer = 0 then
   333         begin
   333         begin
   334         case Gear^.Kind of 
   334         case Gear^.Kind of
   335             gtGrenade: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
   335             gtGrenade: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
   336             gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, Gear^.Hedgehog, EXPLAutoSound);
   336             gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, Gear^.Hedgehog, EXPLAutoSound);
   337             gtClusterBomb: 
   337             gtClusterBomb:
   338                 begin
   338                 begin
   339                 x := hwRound(Gear^.X);
   339                 x := hwRound(Gear^.X);
   340                 y := hwRound(Gear^.Y);
   340                 y := hwRound(Gear^.Y);
   341                 doMakeExplosion(x, y, 20, Gear^.Hedgehog, EXPLAutoSound);
   341                 doMakeExplosion(x, y, 20, Gear^.Hedgehog, EXPLAutoSound);
   342                 for i:= 0 to 4 do
   342                 for i:= 0 to 4 do
   344                     dX := rndSign(GetRandomf * _0_1) + Gear^.dX / 5;
   344                     dX := rndSign(GetRandomf * _0_1) + Gear^.dX / 5;
   345                     dY := (GetRandomf - _3) * _0_08;
   345                     dY := (GetRandomf - _3) * _0_08;
   346                     FollowGear := AddGear(x, y, gtCluster, 0, dX, dY, 25)
   346                     FollowGear := AddGear(x, y, gtCluster, 0, dX, dY, 25)
   347                     end
   347                     end
   348                 end;
   348                 end;
   349             gtWatermelon: 
   349             gtWatermelon:
   350                 begin
   350                 begin
   351                 x := hwRound(Gear^.X);
   351                 x := hwRound(Gear^.X);
   352                 y := hwRound(Gear^.Y);
   352                 y := hwRound(Gear^.Y);
   353                 doMakeExplosion(x, y, 75, Gear^.Hedgehog, EXPLAutoSound);
   353                 doMakeExplosion(x, y, 75, Gear^.Hedgehog, EXPLAutoSound);
   354                 for i:= 0 to 5 do
   354                 for i:= 0 to 5 do
   357                     dY := (GetRandomf - _1_5) * _0_3;
   357                     dY := (GetRandomf - _1_5) * _0_3;
   358                     FollowGear:= AddGear(x, y, gtMelonPiece, 0, dX, dY, 75);
   358                     FollowGear:= AddGear(x, y, gtMelonPiece, 0, dX, dY, 75);
   359                     FollowGear^.DirAngle := i * 60
   359                     FollowGear^.DirAngle := i * 60
   360                     end
   360                     end
   361                 end;
   361                 end;
   362             gtHellishBomb: 
   362             gtHellishBomb:
   363                 begin
   363                 begin
   364                 x := hwRound(Gear^.X);
   364                 x := hwRound(Gear^.X);
   365                 y := hwRound(Gear^.Y);
   365                 y := hwRound(Gear^.Y);
   366                 doMakeExplosion(x, y, 90, Gear^.Hedgehog, EXPLAutoSound);
   366                 doMakeExplosion(x, y, 90, Gear^.Hedgehog, EXPLAutoSound);
   367 
   367 
   373                         begin
   373                         begin
   374                         AddGear(x, y, gtFlame, gstTmpFlag, dX, dY, 0);
   374                         AddGear(x, y, gtFlame, gstTmpFlag, dX, dY, 0);
   375                         AddGear(x, y, gtFlame, 0, dX, -dY, 0)
   375                         AddGear(x, y, gtFlame, 0, dX, -dY, 0)
   376                         end
   376                         end
   377                     else
   377                     else
   378                         begin 
   378                         begin
   379                         AddGear(x, y, gtFlame, 0, dX, dY, 0);
   379                         AddGear(x, y, gtFlame, 0, dX, dY, 0);
   380                         AddGear(x, y, gtFlame, gstTmpFlag, dX, -dY, 0)
   380                         AddGear(x, y, gtFlame, gstTmpFlag, dX, -dY, 0)
   381                         end;
   381                         end;
   382                     end
   382                     end
   383                 end;
   383                 end;
   413         end;
   413         end;
   414 end;
   414 end;
   415 
   415 
   416 ////////////////////////////////////////////////////////////////////////////////
   416 ////////////////////////////////////////////////////////////////////////////////
   417 procedure doStepMolotov(Gear: PGear);
   417 procedure doStepMolotov(Gear: PGear);
   418 var 
   418 var
   419     s: Longword;
   419     s: Longword;
   420     i, gX, gY: LongInt;
   420     i, gX, gY: LongInt;
   421     dX, dY: hwFloat;
   421     dX, dY: hwFloat;
   422     smoke, glass: PVisualGear;
   422     smoke, glass: PVisualGear;
   423 begin
   423 begin
   433         // adjust angle to match the texture
   433         // adjust angle to match the texture
   434         if Gear^.dX.isNegative then
   434         if Gear^.dX.isNegative then
   435             i:= 130
   435             i:= 130
   436         else
   436         else
   437             i:= 50;
   437             i:= 50;
   438             
   438 
   439         smoke:= AddVisualGear(hwRound(Gear^.X)-round(cos((Gear^.DirAngle+i) * pi / 180)*20), hwRound(Gear^.Y)-round(sin((Gear^.DirAngle+i) * pi / 180)*20), vgtSmoke);
   439         smoke:= AddVisualGear(hwRound(Gear^.X)-round(cos((Gear^.DirAngle+i) * pi / 180)*20), hwRound(Gear^.Y)-round(sin((Gear^.DirAngle+i) * pi / 180)*20), vgtSmoke);
   440         if smoke <> nil then
   440         if smoke <> nil then
   441             smoke^.Scale:= 0.75;
   441             smoke^.Scale:= 0.75;
   442         end;
   442         end;
   443 
   443 
   692                         end
   692                         end
   693                     else allpx:= false
   693                     else allpx:= false
   694                     end;
   694                     end;
   695                 p:= @(p^[s^.pitch shr 2])
   695                 p:= @(p^[s^.pitch shr 2])
   696                 end;
   696                 end;
   697             
   697 
   698             // Why is this here.  For one thing, there's no test on +1 being safe. 
   698             // Why is this here.  For one thing, there's no test on +1 being safe.
   699             //Land[py, px+1]:= lfBasic;
   699             //Land[py, px+1]:= lfBasic;
   700             
   700 
   701             if allpx then
   701             if allpx then
   702                 UpdateLandTexture(xx, Pred(s^.h), yy, Pred(s^.w), true)
   702                 UpdateLandTexture(xx, Pred(s^.h), yy, Pred(s^.w), true)
   703             else
   703             else
   704                 begin
   704                 begin
   705                 UpdateLandTexture(
   705                 UpdateLandTexture(
   760     Gear^.dY := Gear^.dY + cGravity
   760     Gear^.dY := Gear^.dY + cGravity
   761 end;
   761 end;
   762 
   762 
   763 ////////////////////////////////////////////////////////////////////////////////
   763 ////////////////////////////////////////////////////////////////////////////////
   764 procedure doStepBeeWork(Gear: PGear);
   764 procedure doStepBeeWork(Gear: PGear);
   765 var 
   765 var
   766     t: hwFloat;
   766     t: hwFloat;
   767     gX,gY,i: LongInt;
   767     gX,gY,i: LongInt;
   768     uw, nuw: boolean;
   768     uw, nuw: boolean;
   769     flower: PVisualGear;
   769     flower: PVisualGear;
   770 
   770 
   875     if Gear^.Timer = 0 then
   875     if Gear^.Timer = 0 then
   876         begin
   876         begin
   877         Gear^.Hedgehog^.Gear^.Message:= Gear^.Hedgehog^.Gear^.Message and (not gmAttack);
   877         Gear^.Hedgehog^.Gear^.Message:= Gear^.Hedgehog^.Gear^.Message and (not gmAttack);
   878         Gear^.Hedgehog^.Gear^.State:= Gear^.Hedgehog^.Gear^.State and (not gstAttacking);
   878         Gear^.Hedgehog^.Gear^.State:= Gear^.Hedgehog^.Gear^.State and (not gstAttacking);
   879         AttackBar:= 0;
   879         AttackBar:= 0;
   880         
   880 
   881         Gear^.SoundChannel := LoopSound(sndBee);
   881         Gear^.SoundChannel := LoopSound(sndBee);
   882         Gear^.Timer := 5000;
   882         Gear^.Timer := 5000;
   883         // save initial speed in otherwise unused Friction variable
   883         // save initial speed in otherwise unused Friction variable
   884         Gear^.Friction := Distance(Gear^.dX, Gear^.dY);
   884         Gear^.Friction := Distance(Gear^.dX, Gear^.dY);
   885         Gear^.doStep := @doStepBeeWork
   885         Gear^.doStep := @doStepBeeWork
   897         AfterAttack
   897         AfterAttack
   898         end
   898         end
   899 end;
   899 end;
   900 
   900 
   901 procedure doStepShotgunShot(Gear: PGear);
   901 procedure doStepShotgunShot(Gear: PGear);
   902 var 
   902 var
   903     i: LongWord;
   903     i: LongWord;
   904     shell: PVisualGear;
   904     shell: PVisualGear;
   905 begin
   905 begin
   906     AllInactive := false;
   906     AllInactive := false;
   907 
   907 
   973         oy:= Bullet^.Friction;
   973         oy:= Bullet^.Friction;
   974         end;
   974         end;
   975 
   975 
   976         // Bullet trail
   976         // Bullet trail
   977         VGear := AddVisualGear(hwRound(ox), hwRound(oy), vgtLineTrail);
   977         VGear := AddVisualGear(hwRound(ox), hwRound(oy), vgtLineTrail);
   978         
   978 
   979         if VGear <> nil then
   979         if VGear <> nil then
   980             begin
   980             begin
   981             VGear^.X:= hwFloat2Float(ox);
   981             VGear^.X:= hwFloat2Float(ox);
   982             VGear^.Y:= hwFloat2Float(oy);
   982             VGear^.Y:= hwFloat2Float(oy);
   983             VGear^.dX:= hwFloat2Float(Bullet^.X);
   983             VGear^.dX:= hwFloat2Float(Bullet^.X);
   996             VGear^.Timer := 200;
   996             VGear^.Timer := 200;
   997             end;
   997             end;
   998 end;
   998 end;
   999 
   999 
  1000 procedure doStepBulletWork(Gear: PGear);
  1000 procedure doStepBulletWork(Gear: PGear);
  1001 var 
  1001 var
  1002     i: LongInt;
  1002     i: LongInt;
  1003     x, y: LongWord;
  1003     x, y: LongWord;
  1004     oX, oY: hwFloat;
  1004     oX, oY: hwFloat;
  1005     VGear: PVisualGear;
  1005     VGear: PVisualGear;
  1006 begin
  1006 begin
  1012     repeat
  1012     repeat
  1013         Gear^.X := Gear^.X + Gear^.dX;
  1013         Gear^.X := Gear^.X + Gear^.dX;
  1014         Gear^.Y := Gear^.Y + Gear^.dY;
  1014         Gear^.Y := Gear^.Y + Gear^.dY;
  1015         x := hwRound(Gear^.X);
  1015         x := hwRound(Gear^.X);
  1016         y := hwRound(Gear^.Y);
  1016         y := hwRound(Gear^.Y);
  1017         
  1017 
  1018         if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] <> 0) then
  1018         if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] <> 0) then
  1019             inc(Gear^.Damage);
  1019             inc(Gear^.Damage);
  1020         // let's interrupt before a collision to give portals a chance to catch the bullet
  1020         // let's interrupt before a collision to give portals a chance to catch the bullet
  1021         if (Gear^.Damage = 1) and (Gear^.Tag = 0) and (Land[y, x] > 255) then
  1021         if (Gear^.Damage = 1) and (Gear^.Tag = 0) and (Land[y, x] > 255) then
  1022             begin
  1022             begin
  1034             if Gear^.AmmoType = amDEagle then
  1034             if Gear^.AmmoType = amDEagle then
  1035                 AmmoShove(Gear, 7, 20)
  1035                 AmmoShove(Gear, 7, 20)
  1036         else
  1036         else
  1037             AmmoShove(Gear, Gear^.Timer, 20);
  1037             AmmoShove(Gear, Gear^.Timer, 20);
  1038         CheckGearDrowning(Gear);
  1038         CheckGearDrowning(Gear);
  1039         dec(i) 
  1039         dec(i)
  1040     until (i = 0) or (Gear^.Damage > Gear^.Health) or ((Gear^.State and gstDrowning) <> 0);
  1040     until (i = 0) or (Gear^.Damage > Gear^.Health) or ((Gear^.State and gstDrowning) <> 0);
  1041 
  1041 
  1042     if Gear^.Damage > 0 then
  1042     if Gear^.Damage > 0 then
  1043         begin
  1043         begin
  1044         DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 82 - i, 1);
  1044         DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 82 - i, 1);
  1062             begin
  1062             begin
  1063             if (Gear^.Kind = gtSniperRifleShot) and ((GameFlags and gfLaserSight) = 0) then
  1063             if (Gear^.Kind = gtSniperRifleShot) and ((GameFlags and gfLaserSight) = 0) then
  1064                 cLaserSighting := false;
  1064                 cLaserSighting := false;
  1065             if (Ammoz[Gear^.AmmoType].Ammo.NumPerTurn <= CurrentHedgehog^.MultiShootAttacks) and ((GameFlags and gfArtillery) = 0) then
  1065             if (Ammoz[Gear^.AmmoType].Ammo.NumPerTurn <= CurrentHedgehog^.MultiShootAttacks) and ((GameFlags and gfArtillery) = 0) then
  1066                 cArtillery := false;
  1066                 cArtillery := false;
  1067         
  1067 
  1068         // Bullet Hit
  1068         // Bullet Hit
  1069             if (hwRound(Gear^.X) and LAND_WIDTH_MASK = 0) and (hwRound(Gear^.Y) and LAND_HEIGHT_MASK = 0) then
  1069             if (hwRound(Gear^.X) and LAND_WIDTH_MASK = 0) and (hwRound(Gear^.Y) and LAND_HEIGHT_MASK = 0) then
  1070                 begin
  1070                 begin
  1071                 VGear := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBulletHit);
  1071                 VGear := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBulletHit);
  1072                 if VGear <> nil then
  1072                 if VGear <> nil then
  1073                     begin
  1073                     begin
  1074                     VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY);
  1074                     VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY);
  1075                     end;
  1075                     end;
  1076                 end;
  1076                 end;
  1077        
  1077 
  1078             spawnBulletTrail(Gear);
  1078             spawnBulletTrail(Gear);
  1079             Gear^.doStep := @doStepShotIdle
  1079             Gear^.doStep := @doStepShotIdle
  1080             end;
  1080             end;
  1081 end;
  1081 end;
  1082 
  1082 
  1088     Gear^.Y := Gear^.Y + Gear^.dY * 3;
  1088     Gear^.Y := Gear^.Y + Gear^.dY * 3;
  1089     Gear^.doStep := @doStepBulletWork
  1089     Gear^.doStep := @doStepBulletWork
  1090 end;
  1090 end;
  1091 
  1091 
  1092 procedure doStepSniperRifleShot(Gear: PGear);
  1092 procedure doStepSniperRifleShot(Gear: PGear);
  1093 var 
  1093 var
  1094     HHGear: PGear;
  1094     HHGear: PGear;
  1095     shell: PVisualGear;
  1095     shell: PVisualGear;
  1096 begin
  1096 begin
  1097     cArtillery := true;
  1097     cArtillery := true;
  1098     HHGear := Gear^.Hedgehog^.Gear;
  1098     HHGear := Gear^.Hedgehog^.Gear;
  1119         Gear^.State := Gear^.State or gstAnimation;
  1119         Gear^.State := Gear^.State or gstAnimation;
  1120         Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _0_5;
  1120         Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _0_5;
  1121         Gear^.dY := -AngleCos(HHGear^.Angle) * _0_5;
  1121         Gear^.dY := -AngleCos(HHGear^.Angle) * _0_5;
  1122         PlaySound(sndGun);
  1122         PlaySound(sndGun);
  1123         // add 3 initial steps to avoid problem with ammoshove related to calculation of radius + 1 radius as gear widths, and also just weird angles
  1123         // add 3 initial steps to avoid problem with ammoshove related to calculation of radius + 1 radius as gear widths, and also just weird angles
  1124         Gear^.X := Gear^.X + Gear^.dX * 3;  
  1124         Gear^.X := Gear^.X + Gear^.dX * 3;
  1125         Gear^.Y := Gear^.Y + Gear^.dY * 3;
  1125         Gear^.Y := Gear^.Y + Gear^.dY * 3;
  1126         Gear^.doStep := @doStepBulletWork;
  1126         Gear^.doStep := @doStepBulletWork;
  1127         end
  1127         end
  1128     else
  1128     else
  1129         if (GameTicks mod 32) = 0 then
  1129         if (GameTicks mod 32) = 0 then
  1148 ////////////////////////////////////////////////////////////////////////////////
  1148 ////////////////////////////////////////////////////////////////////////////////
  1149 procedure doStepActionTimer(Gear: PGear);
  1149 procedure doStepActionTimer(Gear: PGear);
  1150 begin
  1150 begin
  1151 dec(Gear^.Timer);
  1151 dec(Gear^.Timer);
  1152 case Gear^.Kind of
  1152 case Gear^.Kind of
  1153     gtATStartGame: 
  1153     gtATStartGame:
  1154     begin
  1154     begin
  1155         AllInactive := false;
  1155         AllInactive := false;
  1156         if Gear^.Timer = 0 then
  1156         if Gear^.Timer = 0 then
  1157             begin
  1157             begin
  1158             AddCaption(trmsg[sidStartFight], cWhiteColor, capgrpGameState);
  1158             AddCaption(trmsg[sidStartFight], cWhiteColor, capgrpGameState);
  1159             end
  1159             end
  1160     end;
  1160     end;
  1161     gtATFinishGame: 
  1161     gtATFinishGame:
  1162     begin
  1162     begin
  1163         AllInactive := false;
  1163         AllInactive := false;
  1164         if Gear^.Timer = 1000 then
  1164         if Gear^.Timer = 1000 then
  1165             begin
  1165             begin
  1166             ScreenFade := sfToBlack;
  1166             ScreenFade := sfToBlack;
  1179     DeleteGear(Gear)
  1179     DeleteGear(Gear)
  1180 end;
  1180 end;
  1181 
  1181 
  1182 ////////////////////////////////////////////////////////////////////////////////
  1182 ////////////////////////////////////////////////////////////////////////////////
  1183 procedure doStepPickHammerWork(Gear: PGear);
  1183 procedure doStepPickHammerWork(Gear: PGear);
  1184 var 
  1184 var
  1185     i, ei, x, y: LongInt;
  1185     i, ei, x, y: LongInt;
  1186     HHGear: PGear;
  1186     HHGear: PGear;
  1187 begin
  1187 begin
  1188     AllInactive := false;
  1188     AllInactive := false;
  1189     HHGear := Gear^.Hedgehog^.Gear;
  1189     HHGear := Gear^.Hedgehog^.Gear;
  1270             Gear^.dX := _0_3
  1270             Gear^.dX := _0_3
  1271     else Gear^.dX := _0;
  1271     else Gear^.dX := _0;
  1272 end;
  1272 end;
  1273 
  1273 
  1274 procedure doStepPickHammer(Gear: PGear);
  1274 procedure doStepPickHammer(Gear: PGear);
  1275 var 
  1275 var
  1276     i, y: LongInt;
  1276     i, y: LongInt;
  1277     ar: TRangeArray;
  1277     ar: TRangeArray;
  1278     HHGear: PGear;
  1278     HHGear: PGear;
  1279 begin
  1279 begin
  1280     i := 0;
  1280     i := 0;
  1297     doStepPickHammerWork(Gear);
  1297     doStepPickHammerWork(Gear);
  1298     Gear^.doStep := @doStepPickHammerWork
  1298     Gear^.doStep := @doStepPickHammerWork
  1299 end;
  1299 end;
  1300 
  1300 
  1301 ////////////////////////////////////////////////////////////////////////////////
  1301 ////////////////////////////////////////////////////////////////////////////////
  1302 var 
  1302 var
  1303     BTPrevAngle, BTSteps: LongInt;
  1303     BTPrevAngle, BTSteps: LongInt;
  1304 
  1304 
  1305 procedure doStepBlowTorchWork(Gear: PGear);
  1305 procedure doStepBlowTorchWork(Gear: PGear);
  1306 var 
  1306 var
  1307     HHGear: PGear;
  1307     HHGear: PGear;
  1308     b: boolean;
  1308     b: boolean;
  1309     prevX: LongInt;
  1309     prevX: LongInt;
  1310 begin
  1310 begin
  1311     AllInactive := false;
  1311     AllInactive := false;
  1312     dec(Gear^.Timer);
  1312     dec(Gear^.Timer);
  1313     if ((GameFlags and gfInfAttack) <> 0) and (TurnTimeLeft > 0) then
  1313     if ((GameFlags and gfInfAttack) <> 0) and (TurnTimeLeft > 0) then
  1314         dec(TurnTimeLeft);
  1314         dec(TurnTimeLeft);
  1315     
  1315 
  1316     HHGear := Gear^.Hedgehog^.Gear;
  1316     HHGear := Gear^.Hedgehog^.Gear;
  1317 
  1317 
  1318     HedgehogChAngle(HHGear);
  1318     HedgehogChAngle(HHGear);
  1319 
  1319 
  1320     b := false;
  1320     b := false;
  1391         AfterAttack
  1391         AfterAttack
  1392         end
  1392         end
  1393 end;
  1393 end;
  1394 
  1394 
  1395 procedure doStepBlowTorch(Gear: PGear);
  1395 procedure doStepBlowTorch(Gear: PGear);
  1396 var 
  1396 var
  1397     HHGear: PGear;
  1397     HHGear: PGear;
  1398 begin
  1398 begin
  1399     BTPrevAngle := High(LongInt);
  1399     BTPrevAngle := High(LongInt);
  1400     BTSteps := 0;
  1400     BTSteps := 0;
  1401     HHGear := Gear^.Hedgehog^.Gear;
  1401     HHGear := Gear^.Hedgehog^.Gear;
  1431             inc(Gear^.Damage, hwRound(Gear^.dX * _70))
  1431             inc(Gear^.Damage, hwRound(Gear^.dX * _70))
  1432         else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
  1432         else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
  1433             inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
  1433             inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
  1434         else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
  1434         else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
  1435             inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
  1435             inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
  1436         
  1436 
  1437         if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then
  1437         if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then
  1438             begin
  1438             begin
  1439             vg:= AddVisualGear(hwRound(Gear^.X) - 4  + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
  1439             vg:= AddVisualGear(hwRound(Gear^.X) - 4  + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
  1440             if vg <> nil then
  1440             if vg <> nil then
  1441                 vg^.Scale:= 0.5
  1441                 vg^.Scale:= 0.5
  1493 
  1493 
  1494 ////////////////////////////////////////////////////////////////////////////////
  1494 ////////////////////////////////////////////////////////////////////////////////
  1495 procedure doStepSMine(Gear: PGear);
  1495 procedure doStepSMine(Gear: PGear);
  1496 begin
  1496 begin
  1497     // TODO: do real calculation?
  1497     // TODO: do real calculation?
  1498     if TestCollisionXwithGear(Gear, 2) 
  1498     if TestCollisionXwithGear(Gear, 2)
  1499     or (TestCollisionYwithGear(Gear, -2) <> 0) 
  1499     or (TestCollisionYwithGear(Gear, -2) <> 0)
  1500     or TestCollisionXwithGear(Gear, -2) 
  1500     or TestCollisionXwithGear(Gear, -2)
  1501     or (TestCollisionYwithGear(Gear, 2) <> 0) then
  1501     or (TestCollisionYwithGear(Gear, 2) <> 0) then
  1502         begin
  1502         begin
  1503         if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
  1503         if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
  1504             begin
  1504             begin
  1505             PlaySound(sndRopeAttach);
  1505             PlaySound(sndRopeAttach);
  1570 TODO
  1570 TODO
  1571 Increase damage as barrel smokes?
  1571 Increase damage as barrel smokes?
  1572 Try tweaking friction some more
  1572 Try tweaking friction some more
  1573 *)
  1573 *)
  1574 procedure doStepRollingBarrel(Gear: PGear);
  1574 procedure doStepRollingBarrel(Gear: PGear);
  1575 var 
  1575 var
  1576     i: LongInt;
  1576     i: LongInt;
  1577     particle: PVisualGear;
  1577     particle: PVisualGear;
  1578 begin
  1578 begin
  1579     if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then
  1579     if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then
  1580         SetLittle(Gear^.dY);
  1580         SetLittle(Gear^.dY);
  1581     Gear^.State := Gear^.State or gstAnimation;
  1581     Gear^.State := Gear^.State or gstAnimation;
  1582     
  1582 
  1583     if ((Gear^.dX.QWordValue <> 0)
  1583     if ((Gear^.dX.QWordValue <> 0)
  1584     or (Gear^.dY.QWordValue <> 0))  then
  1584     or (Gear^.dY.QWordValue <> 0))  then
  1585         begin
  1585         begin
  1586         DeleteCI(Gear);
  1586         DeleteCI(Gear);
  1587         AllInactive := false;
  1587         AllInactive := false;
  1596                     particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
  1596                     particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
  1597                 end
  1597                 end
  1598             end
  1598             end
  1599         else if (not Gear^.dX.isNegative) and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then
  1599         else if (not Gear^.dX.isNegative) and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then
  1600                 inc(Gear^.Damage, hwRound(Gear^.dX * _70))
  1600                 inc(Gear^.Damage, hwRound(Gear^.dX * _70))
  1601                 
  1601 
  1602         else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
  1602         else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
  1603                 inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
  1603                 inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
  1604                 
  1604 
  1605         else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
  1605         else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
  1606                 inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
  1606                 inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
  1607 
  1607 
  1608         doStepFallingGear(Gear);
  1608         doStepFallingGear(Gear);
  1609         CalcRotationDirAngle(Gear);
  1609         CalcRotationDirAngle(Gear);
  1648     // Hand off to doStepCase for the explosion
  1648     // Hand off to doStepCase for the explosion
  1649 
  1649 
  1650 end;
  1650 end;
  1651 
  1651 
  1652 procedure doStepCase(Gear: PGear);
  1652 procedure doStepCase(Gear: PGear);
  1653 var 
  1653 var
  1654     i, x, y: LongInt;
  1654     i, x, y: LongInt;
  1655     k: TGearType;
  1655     k: TGearType;
  1656     exBoom: boolean;
  1656     exBoom: boolean;
  1657     dX, dY: HWFloat;
  1657     dX, dY: HWFloat;
  1658     hog: PHedgehog;
  1658     hog: PHedgehog;
  1689         Gear^.Damage := 0;
  1689         Gear^.Damage := 0;
  1690         if Gear^.Health <= 0 then
  1690         if Gear^.Health <= 0 then
  1691             exBoom := true;
  1691             exBoom := true;
  1692         end
  1692         end
  1693     else
  1693     else
  1694         begin 
  1694         begin
  1695         if (Gear^.Pos <> posCaseHealth) and (GameTicks and $1FFF = 0) then // stir 'em up periodically
  1695         if (Gear^.Pos <> posCaseHealth) and (GameTicks and $1FFF = 0) then // stir 'em up periodically
  1696             begin
  1696             begin
  1697             gi := GearsList;
  1697             gi := GearsList;
  1698             while gi <> nil do
  1698             while gi <> nil do
  1699                 begin
  1699                 begin
  1726             if sparkles <> nil then
  1726             if sparkles <> nil then
  1727                 begin
  1727                 begin
  1728                 sparkles^.dX:= 0;
  1728                 sparkles^.dX:= 0;
  1729                 sparkles^.dY:= 0;
  1729                 sparkles^.dY:= 0;
  1730                 sparkles^.Angle:= 270;
  1730                 sparkles^.Angle:= 270;
  1731                 if Gear^.Tag = 1 then 
  1731                 if Gear^.Tag = 1 then
  1732                     sparkles^.Tint:= $3744D7FF
  1732                     sparkles^.Tint:= $3744D7FF
  1733                 else sparkles^.Tint:= $FAB22CFF
  1733                 else sparkles^.Tint:= $FAB22CFF
  1734                 end;
  1734                 end;
  1735             end;
  1735             end;
  1736         if Gear^.Timer < 1000 then 
  1736         if Gear^.Timer < 1000 then
  1737             begin
  1737             begin
  1738             AllInactive:= false;
  1738             AllInactive:= false;
  1739             exit
  1739             exit
  1740             end
  1740             end
  1741         end;
  1741         end;
  1790                 inc(Gear^.Damage, hwRound(Gear^.dY * _70));
  1790                 inc(Gear^.Damage, hwRound(Gear^.dY * _70));
  1791 
  1791 
  1792             if Gear^.dY > _0_2 then
  1792             if Gear^.dY > _0_2 then
  1793                 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do
  1793                 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do
  1794                     AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
  1794                     AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
  1795                     
  1795 
  1796             Gear^.dY := - Gear^.dY * Gear^.Elasticity;
  1796             Gear^.dY := - Gear^.dY * Gear^.Elasticity;
  1797             if Gear^.dY > - _0_001 then
  1797             if Gear^.dY > - _0_001 then
  1798                 Gear^.dY := _0
  1798                 Gear^.dY := _0
  1799             else if Gear^.dY < - _0_03 then
  1799             else if Gear^.dY < - _0_03 then
  1800                 PlaySound(Gear^.ImpactSound);
  1800                 PlaySound(Gear^.ImpactSound);
  1844         end
  1844         end
  1845 end;
  1845 end;
  1846 
  1846 
  1847 ////////////////////////////////////////////////////////////////////////////////
  1847 ////////////////////////////////////////////////////////////////////////////////
  1848 procedure doStepShover(Gear: PGear);
  1848 procedure doStepShover(Gear: PGear);
  1849 var 
  1849 var
  1850     HHGear: PGear;
  1850     HHGear: PGear;
  1851 begin
  1851 begin
  1852     HHGear := Gear^.Hedgehog^.Gear;
  1852     HHGear := Gear^.Hedgehog^.Gear;
  1853     HHGear^.State := HHGear^.State or gstNoDamage;
  1853     HHGear^.State := HHGear^.State or gstNoDamage;
  1854     DeleteCI(HHGear);
  1854     DeleteCI(HHGear);
  1860     Gear^.doStep := @doStepIdle
  1860     Gear^.doStep := @doStepIdle
  1861 end;
  1861 end;
  1862 
  1862 
  1863 ////////////////////////////////////////////////////////////////////////////////
  1863 ////////////////////////////////////////////////////////////////////////////////
  1864 procedure doStepWhip(Gear: PGear);
  1864 procedure doStepWhip(Gear: PGear);
  1865 var 
  1865 var
  1866     HHGear: PGear;
  1866     HHGear: PGear;
  1867     i: LongInt;
  1867     i: LongInt;
  1868 begin
  1868 begin
  1869     HHGear := Gear^.Hedgehog^.Gear;
  1869     HHGear := Gear^.Hedgehog^.Gear;
  1870     HHGear^.State := HHGear^.State or gstNoDamage;
  1870     HHGear^.State := HHGear^.State or gstNoDamage;
  1882     Gear^.doStep := @doStepIdle
  1882     Gear^.doStep := @doStepIdle
  1883 end;
  1883 end;
  1884 
  1884 
  1885 ////////////////////////////////////////////////////////////////////////////////
  1885 ////////////////////////////////////////////////////////////////////////////////
  1886 procedure doStepFlame(Gear: PGear);
  1886 procedure doStepFlame(Gear: PGear);
  1887 var 
  1887 var
  1888     gX,gY,i: LongInt;
  1888     gX,gY,i: LongInt;
  1889     sticky: Boolean;
  1889     sticky: Boolean;
  1890     vgt: PVisualGear;
  1890     vgt: PVisualGear;
  1891     tdX,tdY: HWFloat;
  1891     tdX,tdY: HWFloat;
  1892 begin
  1892 begin
  1909             end;
  1909             end;
  1910 
  1910 
  1911 
  1911 
  1912         if Gear^.dX.QWordValue > _0_01.QWordValue then
  1912         if Gear^.dX.QWordValue > _0_01.QWordValue then
  1913             Gear^.dX := Gear^.dX * _0_995;
  1913             Gear^.dX := Gear^.dX * _0_995;
  1914             
  1914 
  1915         Gear^.dY := Gear^.dY + cGravity;
  1915         Gear^.dY := Gear^.dY + cGravity;
  1916         // if sticky then Gear^.dY := Gear^.dY + cGravity;
  1916         // if sticky then Gear^.dY := Gear^.dY + cGravity;
  1917         
  1917 
  1918         if Gear^.dY.QWordValue > _0_2.QWordValue then
  1918         if Gear^.dY.QWordValue > _0_2.QWordValue then
  1919             Gear^.dY := Gear^.dY * _0_995;
  1919             Gear^.dY := Gear^.dY * _0_995;
  1920 
  1920 
  1921         //if sticky then Gear^.X := Gear^.X + Gear^.dX else
  1921         //if sticky then Gear^.X := Gear^.X + Gear^.dX else
  1922         Gear^.X := Gear^.X + Gear^.dX + cWindSpeed * 640;
  1922         Gear^.X := Gear^.X + Gear^.dX + cWindSpeed * 640;
  1973                     Gear^.dX:= tdX;
  1973                     Gear^.dX:= tdX;
  1974                     Gear^.dY:= tdY;
  1974                     Gear^.dY:= tdY;
  1975                     Gear^.Radius := 1;
  1975                     Gear^.Radius := 1;
  1976                     end
  1976                     end
  1977                 else if ((GameTicks and $3) = 3) then
  1977                 else if ((GameTicks and $3) = 3) then
  1978                     doMakeExplosion(gX, gY, 8, Gear^.Hedgehog, 0);//, EXPLNoDamage); 
  1978                     doMakeExplosion(gX, gY, 8, Gear^.Hedgehog, 0);//, EXPLNoDamage);
  1979                 //DrawExplosion(gX, gY, 4);
  1979                 //DrawExplosion(gX, gY, 4);
  1980                 
  1980 
  1981                 if ((GameTicks and $7) = 0) and (Random(2) = 0) then
  1981                 if ((GameTicks and $7) = 0) and (Random(2) = 0) then
  1982                     for i:= Random(2) downto 0 do
  1982                     for i:= Random(2) downto 0 do
  1983                         AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
  1983                         AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
  1984                         
  1984 
  1985                 if Gear^.Health > 0 then
  1985                 if Gear^.Health > 0 then
  1986                     dec(Gear^.Health);
  1986                     dec(Gear^.Health);
  1987                 Gear^.Timer := 450 - Gear^.Tag * 8
  1987                 Gear^.Timer := 450 - Gear^.Tag * 8
  1988                 end
  1988                 end
  1989             else
  1989             else
  2022         end;
  2022         end;
  2023 end;
  2023 end;
  2024 
  2024 
  2025 ////////////////////////////////////////////////////////////////////////////////
  2025 ////////////////////////////////////////////////////////////////////////////////
  2026 procedure doStepFirePunchWork(Gear: PGear);
  2026 procedure doStepFirePunchWork(Gear: PGear);
  2027 var 
  2027 var
  2028     HHGear: PGear;
  2028     HHGear: PGear;
  2029 begin
  2029 begin
  2030     AllInactive := false;
  2030     AllInactive := false;
  2031     if ((Gear^.Message and gmDestroy) <> 0) then
  2031     if ((Gear^.Message and gmDestroy) <> 0) then
  2032         begin
  2032         begin
  2059         lfIndestructible) then
  2059         lfIndestructible) then
  2060             HHGear^.Y := HHGear^.Y + HHGear^.dY
  2060             HHGear^.Y := HHGear^.Y + HHGear^.dY
  2061 end;
  2061 end;
  2062 
  2062 
  2063 procedure doStepFirePunch(Gear: PGear);
  2063 procedure doStepFirePunch(Gear: PGear);
  2064 var 
  2064 var
  2065     HHGear: PGear;
  2065     HHGear: PGear;
  2066 begin
  2066 begin
  2067     AllInactive := false;
  2067     AllInactive := false;
  2068     HHGear := Gear^.Hedgehog^.Gear;
  2068     HHGear := Gear^.Hedgehog^.Gear;
  2069     DeleteCI(HHGear);
  2069     DeleteCI(HHGear);
  2082 end;
  2082 end;
  2083 
  2083 
  2084 ////////////////////////////////////////////////////////////////////////////////
  2084 ////////////////////////////////////////////////////////////////////////////////
  2085 
  2085 
  2086 procedure doStepParachuteWork(Gear: PGear);
  2086 procedure doStepParachuteWork(Gear: PGear);
  2087 var 
  2087 var
  2088     HHGear: PGear;
  2088     HHGear: PGear;
  2089 begin
  2089 begin
  2090     HHGear := Gear^.Hedgehog^.Gear;
  2090     HHGear := Gear^.Hedgehog^.Gear;
  2091 
  2091 
  2092     inc(Gear^.Timer);
  2092     inc(Gear^.Timer);
  2111 
  2111 
  2112     HHGear^.X := HHGear^.X + cWindSpeed * 200;
  2112     HHGear^.X := HHGear^.X + cWindSpeed * 200;
  2113 
  2113 
  2114     if (Gear^.Message and gmLeft) <> 0 then
  2114     if (Gear^.Message and gmLeft) <> 0 then
  2115         HHGear^.X := HHGear^.X - cMaxWindSpeed * 80
  2115         HHGear^.X := HHGear^.X - cMaxWindSpeed * 80
  2116         
  2116 
  2117     else if (Gear^.Message and gmRight) <> 0 then
  2117     else if (Gear^.Message and gmRight) <> 0 then
  2118         HHGear^.X := HHGear^.X + cMaxWindSpeed * 80;
  2118         HHGear^.X := HHGear^.X + cMaxWindSpeed * 80;
  2119         
  2119 
  2120     if (Gear^.Message and gmUp) <> 0 then
  2120     if (Gear^.Message and gmUp) <> 0 then
  2121         HHGear^.Y := HHGear^.Y - cGravity * 40
  2121         HHGear^.Y := HHGear^.Y - cGravity * 40
  2122         
  2122 
  2123     else if (Gear^.Message and gmDown) <> 0 then
  2123     else if (Gear^.Message and gmDown) <> 0 then
  2124         HHGear^.Y := HHGear^.Y + cGravity * 40;
  2124         HHGear^.Y := HHGear^.Y + cGravity * 40;
  2125 
  2125 
  2126     // don't drift into obstacles
  2126     // don't drift into obstacles
  2127     if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
  2127     if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
  2130     Gear^.X := HHGear^.X;
  2130     Gear^.X := HHGear^.X;
  2131     Gear^.Y := HHGear^.Y
  2131     Gear^.Y := HHGear^.Y
  2132 end;
  2132 end;
  2133 
  2133 
  2134 procedure doStepParachute(Gear: PGear);
  2134 procedure doStepParachute(Gear: PGear);
  2135 var 
  2135 var
  2136     HHGear: PGear;
  2136     HHGear: PGear;
  2137 begin
  2137 begin
  2138     HHGear := Gear^.Hedgehog^.Gear;
  2138     HHGear := Gear^.Hedgehog^.Gear;
  2139 
  2139 
  2140     DeleteCI(HHGear);
  2140     DeleteCI(HHGear);
  2157     Gear^.X := Gear^.X + cAirPlaneSpeed * Gear^.Tag;
  2157     Gear^.X := Gear^.X + cAirPlaneSpeed * Gear^.Tag;
  2158 
  2158 
  2159     if (Gear^.Health > 0) and (not (Gear^.X < Gear^.dX)) and (Gear^.X < Gear^.dX + cAirPlaneSpeed) then
  2159     if (Gear^.Health > 0) and (not (Gear^.X < Gear^.dX)) and (Gear^.X < Gear^.dX + cAirPlaneSpeed) then
  2160         begin
  2160         begin
  2161         dec(Gear^.Health);
  2161         dec(Gear^.Health);
  2162             case Gear^.State of 
  2162             case Gear^.State of
  2163                 0: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
  2163                 0: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
  2164                 1: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine,    0, cBombsSpeed * Gear^.Tag, _0, 0);
  2164                 1: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine,    0, cBombsSpeed * Gear^.Tag, _0, 0);
  2165                 2: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtNapalmBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
  2165                 2: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtNapalmBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
  2166                 3: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtDrill, gsttmpFlag, cBombsSpeed * Gear^.Tag, _0, Gear^.Timer + 1);
  2166                 3: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtDrill, gsttmpFlag, cBombsSpeed * Gear^.Tag, _0, Gear^.Timer + 1);
  2167             //4: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtWaterMelon, 0, cBombsSpeed *
  2167             //4: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtWaterMelon, 0, cBombsSpeed *
  2200     Gear^.Y := int2hwFloat(topY-300);
  2200     Gear^.Y := int2hwFloat(topY-300);
  2201     Gear^.dX := int2hwFloat(Gear^.Target.X - 5 * Gear^.Tag * 15);
  2201     Gear^.dX := int2hwFloat(Gear^.Target.X - 5 * Gear^.Tag * 15);
  2202 
  2202 
  2203     // calcs for Napalm Strike, so that it will hit the target (without wind at least :P)
  2203     // calcs for Napalm Strike, so that it will hit the target (without wind at least :P)
  2204     if (Gear^.State = 2) then
  2204     if (Gear^.State = 2) then
  2205         Gear^.dX := Gear^.dX - cBombsSpeed * Gear^.Tag * 900 
  2205         Gear^.dX := Gear^.dX - cBombsSpeed * Gear^.Tag * 900
  2206     // calcs for regular falling gears
  2206     // calcs for regular falling gears
  2207     else if (int2hwFloat(Gear^.Target.Y) - Gear^.Y > _0) then
  2207     else if (int2hwFloat(Gear^.Target.Y) - Gear^.Y > _0) then
  2208             Gear^.dX := Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(Gear^.Target.Y) - Gear^.Y) * 2 /
  2208             Gear^.dX := Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(Gear^.Target.Y) - Gear^.Y) * 2 /
  2209                 cGravity) * Gear^.Tag;
  2209                 cGravity) * Gear^.Tag;
  2210 
  2210 
  2222     doStepFallingGear(Gear);
  2222     doStepFallingGear(Gear);
  2223     if (Gear^.State and gstCollision) <> 0 then
  2223     if (Gear^.State and gstCollision) <> 0 then
  2224         begin
  2224         begin
  2225         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
  2225         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
  2226         DeleteGear(Gear);
  2226         DeleteGear(Gear);
  2227         performRumble();
  2227         with mobileRecord do
       
  2228             if (performRumble <> nil) and (not fastUntilLag) then
       
  2229                 performRumble(kSystemSoundID_Vibrate);
  2228         exit
  2230         exit
  2229         end;
  2231         end;
  2230     if (GameTicks and $3F) = 0 then
  2232     if (GameTicks and $3F) = 0 then
  2231         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
  2233         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
  2232 end;
  2234 end;
  2233 
  2235 
  2234 ////////////////////////////////////////////////////////////////////////////////
  2236 ////////////////////////////////////////////////////////////////////////////////
  2235 
  2237 
  2236 procedure doStepGirder(Gear: PGear);
  2238 procedure doStepGirder(Gear: PGear);
  2237 var 
  2239 var
  2238     HHGear: PGear;
  2240     HHGear: PGear;
  2239     x, y, tx, ty: hwFloat;
  2241     x, y, tx, ty: hwFloat;
  2240 begin
  2242 begin
  2241     AllInactive := false;
  2243     AllInactive := false;
  2242 
  2244 
  2254         HHGear^.State := HHGear^.State and (not gstAttacking);
  2256         HHGear^.State := HHGear^.State and (not gstAttacking);
  2255         HHGear^.State := HHGear^.State or gstHHChooseTarget;
  2257         HHGear^.State := HHGear^.State or gstHHChooseTarget;
  2256         isCursorVisible := true;
  2258         isCursorVisible := true;
  2257         DeleteGear(Gear)
  2259         DeleteGear(Gear)
  2258         end
  2260         end
  2259     else 
  2261     else
  2260         begin
  2262         begin
  2261         PlaySound(sndPlaced);
  2263         PlaySound(sndPlaced);
  2262         DeleteGear(Gear);
  2264         DeleteGear(Gear);
  2263         AfterAttack;
  2265         AfterAttack;
  2264         end;
  2266         end;
  2267     HHGear^.Message := HHGear^.Message and (not gmAttack);
  2269     HHGear^.Message := HHGear^.Message and (not gmAttack);
  2268 end;
  2270 end;
  2269 
  2271 
  2270 ////////////////////////////////////////////////////////////////////////////////
  2272 ////////////////////////////////////////////////////////////////////////////////
  2271 procedure doStepTeleportAfter(Gear: PGear);
  2273 procedure doStepTeleportAfter(Gear: PGear);
  2272 var 
  2274 var
  2273     HHGear: PGear;
  2275     HHGear: PGear;
  2274 begin
  2276 begin
  2275     HHGear := Gear^.Hedgehog^.Gear;
  2277     HHGear := Gear^.Hedgehog^.Gear;
  2276     doStepHedgehogMoving(HHGear);
  2278     doStepHedgehogMoving(HHGear);
  2277     // if not infattack mode wait for hedgehog finish falling to collect cases
  2279     // if not infattack mode wait for hedgehog finish falling to collect cases
  2301             Gear^.doStep := @doStepTeleportAfter
  2303             Gear^.doStep := @doStepTeleportAfter
  2302         end;
  2304         end;
  2303 end;
  2305 end;
  2304 
  2306 
  2305 procedure doStepTeleport(Gear: PGear);
  2307 procedure doStepTeleport(Gear: PGear);
  2306 var 
  2308 var
  2307     HHGear: PGear;
  2309     HHGear: PGear;
  2308 begin
  2310 begin
  2309     AllInactive := false;
  2311     AllInactive := false;
  2310 
  2312 
  2311     HHGear := Gear^.Hedgehog^.Gear;
  2313     HHGear := Gear^.Hedgehog^.Gear;
  2342     Gear^.Target.X:= NoPointX
  2344     Gear^.Target.X:= NoPointX
  2343 end;
  2345 end;
  2344 
  2346 
  2345 ////////////////////////////////////////////////////////////////////////////////
  2347 ////////////////////////////////////////////////////////////////////////////////
  2346 procedure doStepSwitcherWork(Gear: PGear);
  2348 procedure doStepSwitcherWork(Gear: PGear);
  2347 var 
  2349 var
  2348     HHGear: PGear;
  2350     HHGear: PGear;
  2349     hedgehog: PHedgehog;
  2351     hedgehog: PHedgehog;
  2350     State: Longword;
  2352     State: Longword;
  2351 begin
  2353 begin
  2352     AllInactive := false;
  2354     AllInactive := false;
  2380         repeat
  2382         repeat
  2381             CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber);
  2383             CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber);
  2382         until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear^.Damage = 0);
  2384         until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear^.Damage = 0);
  2383 
  2385 
  2384         SwitchCurrentHedgehog(@CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]);
  2386         SwitchCurrentHedgehog(@CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]);
  2385         AmmoMenuInvalidated:= true; 
  2387         AmmoMenuInvalidated:= true;
  2386 
  2388 
  2387         HHGear := CurrentHedgehog^.Gear;
  2389         HHGear := CurrentHedgehog^.Gear;
  2388         HHGear^.State := State;
  2390         HHGear^.State := State;
  2389         HHGear^.Active := true;
  2391         HHGear^.Active := true;
  2390         FollowGear := HHGear;
  2392         FollowGear := HHGear;
  2394         Gear^.Y := HHGear^.Y
  2396         Gear^.Y := HHGear^.Y
  2395         end;
  2397         end;
  2396 end;
  2398 end;
  2397 
  2399 
  2398 procedure doStepSwitcher(Gear: PGear);
  2400 procedure doStepSwitcher(Gear: PGear);
  2399 var 
  2401 var
  2400     HHGear: PGear;
  2402     HHGear: PGear;
  2401 begin
  2403 begin
  2402     Gear^.doStep := @doStepSwitcherWork;
  2404     Gear^.doStep := @doStepSwitcherWork;
  2403 
  2405 
  2404     HHGear := Gear^.Hedgehog^.Gear;
  2406     HHGear := Gear^.Hedgehog^.Gear;
  2410         end
  2412         end
  2411 end;
  2413 end;
  2412 
  2414 
  2413 ////////////////////////////////////////////////////////////////////////////////
  2415 ////////////////////////////////////////////////////////////////////////////////
  2414 procedure doStepMortar(Gear: PGear);
  2416 procedure doStepMortar(Gear: PGear);
  2415 var 
  2417 var
  2416     dX, dY: hwFloat;
  2418     dX, dY: hwFloat;
  2417     i: LongInt;
  2419     i: LongInt;
  2418     dxn, dyn: boolean;
  2420     dxn, dyn: boolean;
  2419 begin
  2421 begin
  2420     AllInactive := false;
  2422     AllInactive := false;
  2443         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
  2445         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
  2444 end;
  2446 end;
  2445 
  2447 
  2446 ////////////////////////////////////////////////////////////////////////////////
  2448 ////////////////////////////////////////////////////////////////////////////////
  2447 procedure doStepKamikazeWork(Gear: PGear);
  2449 procedure doStepKamikazeWork(Gear: PGear);
  2448 var 
  2450 var
  2449     i: LongWord;
  2451     i: LongWord;
  2450     HHGear: PGear;
  2452     HHGear: PGear;
  2451     sparkles: PVisualGear;
  2453     sparkles: PVisualGear;
  2452     hasWishes: boolean;
  2454     hasWishes: boolean;
  2453 begin
  2455 begin
  2478             end
  2480             end
  2479         end;
  2481         end;
  2480 
  2482 
  2481     i := 2;
  2483     i := 2;
  2482     repeat
  2484     repeat
  2483         
  2485 
  2484         Gear^.X := Gear^.X + HHGear^.dX;
  2486         Gear^.X := Gear^.X + HHGear^.dX;
  2485         Gear^.Y := Gear^.Y + HHGear^.dY;
  2487         Gear^.Y := Gear^.Y + HHGear^.dY;
  2486         HHGear^.X := Gear^.X;
  2488         HHGear^.X := Gear^.X;
  2487         HHGear^.Y := Gear^.Y;
  2489         HHGear^.Y := Gear^.Y;
  2488 
  2490 
  2561         Gear^.doStep := @doStepKamikazeWork
  2563         Gear^.doStep := @doStepKamikazeWork
  2562         end
  2564         end
  2563 end;
  2565 end;
  2564 
  2566 
  2565 procedure doStepKamikaze(Gear: PGear);
  2567 procedure doStepKamikaze(Gear: PGear);
  2566 var 
  2568 var
  2567     HHGear: PGear;
  2569     HHGear: PGear;
  2568 begin
  2570 begin
  2569     AllInactive := false;
  2571     AllInactive := false;
  2570 
  2572 
  2571     HHGear := Gear^.Hedgehog^.Gear;
  2573     HHGear := Gear^.Hedgehog^.Gear;
  2582 end;
  2584 end;
  2583 
  2585 
  2584 ////////////////////////////////////////////////////////////////////////////////
  2586 ////////////////////////////////////////////////////////////////////////////////
  2585 
  2587 
  2586 const cakeh =   27;
  2588 const cakeh =   27;
  2587 var 
  2589 var
  2588     CakePoints: array[0..Pred(cakeh)] of record
  2590     CakePoints: array[0..Pred(cakeh)] of record
  2589         x, y: hwFloat;
  2591         x, y: hwFloat;
  2590     end;
  2592     end;
  2591     CakeI: Longword;
  2593     CakeI: Longword;
  2592 
  2594 
  2602     AfterAttack;
  2604     AfterAttack;
  2603     DeleteGear(Gear)
  2605     DeleteGear(Gear)
  2604 end;
  2606 end;
  2605 
  2607 
  2606 procedure doStepCakeDown(Gear: PGear);
  2608 procedure doStepCakeDown(Gear: PGear);
  2607 var 
  2609 var
  2608     gi: PGear;
  2610     gi: PGear;
  2609     dmg, dmgBase: LongInt;
  2611     dmg, dmgBase: LongInt;
  2610     fX, fY, tdX, tdY: hwFloat;
  2612     fX, fY, tdX, tdY: hwFloat;
  2611 begin
  2613 begin
  2612     AllInactive := false;
  2614     AllInactive := false;
  2688         Gear^.DirAngle := DxDy2Angle(tdx, tdy);
  2690         Gear^.DirAngle := DxDy2Angle(tdx, tdy);
  2689         end;
  2691         end;
  2690 end;
  2692 end;
  2691 
  2693 
  2692 procedure doStepCakeUp(Gear: PGear);
  2694 procedure doStepCakeUp(Gear: PGear);
  2693 var 
  2695 var
  2694     i: Longword;
  2696     i: Longword;
  2695 begin
  2697 begin
  2696     AllInactive := false;
  2698     AllInactive := false;
  2697 
  2699 
  2698     inc(Gear^.Tag);
  2700     inc(Gear^.Tag);
  2728             AfterAttack
  2730             AfterAttack
  2729         end
  2731         end
  2730 end;
  2732 end;
  2731 
  2733 
  2732 procedure doStepCake(Gear: PGear);
  2734 procedure doStepCake(Gear: PGear);
  2733 var 
  2735 var
  2734     HHGear: PGear;
  2736     HHGear: PGear;
  2735 begin
  2737 begin
  2736     AllInactive := false;
  2738     AllInactive := false;
  2737 
  2739 
  2738     HHGear := Gear^.Hedgehog^.Gear;
  2740     HHGear := Gear^.Hedgehog^.Gear;
  2833     Gear^.doStep := @doStepSeductionWear
  2835     Gear^.doStep := @doStepSeductionWear
  2834 end;
  2836 end;
  2835 
  2837 
  2836 ////////////////////////////////////////////////////////////////////////////////
  2838 ////////////////////////////////////////////////////////////////////////////////
  2837 procedure doStepWaterUp(Gear: PGear);
  2839 procedure doStepWaterUp(Gear: PGear);
  2838 var 
  2840 var
  2839     i: LongWord;
  2841     i: LongWord;
  2840 begin
  2842 begin
  2841     if (Gear^.Tag = 0)
  2843     if (Gear^.Tag = 0)
  2842     or (cWaterLine = 0) then
  2844     or (cWaterLine = 0) then
  2843         begin
  2845         begin
  2867 ////////////////////////////////////////////////////////////////////////////////
  2869 ////////////////////////////////////////////////////////////////////////////////
  2868 procedure doStepDrill(Gear: PGear);
  2870 procedure doStepDrill(Gear: PGear);
  2869 forward;
  2871 forward;
  2870 
  2872 
  2871 procedure doStepDrillDrilling(Gear: PGear);
  2873 procedure doStepDrillDrilling(Gear: PGear);
  2872 var 
  2874 var
  2873     t: PGearArray;
  2875     t: PGearArray;
  2874     ox, oy: hwFloat;
  2876     ox, oy: hwFloat;
  2875 begin
  2877 begin
  2876     AllInactive := false;
  2878     AllInactive := false;
  2877 
  2879 
  2891         end
  2893         end
  2892     end;
  2894     end;
  2893 
  2895 
  2894     if GameTicks > Gear^.FlightTime then
  2896     if GameTicks > Gear^.FlightTime then
  2895         t := CheckGearsCollision(Gear)
  2897         t := CheckGearsCollision(Gear)
  2896         
  2898 
  2897     else t := nil;
  2899     else t := nil;
  2898     //fixes drill not exploding when touching HH bug
  2900     //fixes drill not exploding when touching HH bug
  2899     
  2901 
  2900     if (Gear^.Timer = 0) or ((t <> nil) and (t^.Count <> 0))
  2902     if (Gear^.Timer = 0) or ((t <> nil) and (t^.Count <> 0))
  2901     or ( ((Gear^.State and gsttmpFlag) = 0) and (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))))
  2903     or ( ((Gear^.State and gsttmpFlag) = 0) and (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))))
  2902 // CheckLandValue returns true if the type isn't matched
  2904 // CheckLandValue returns true if the type isn't matched
  2903     or (not (CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible))) then
  2905     or (not (CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible))) then
  2904         begin
  2906         begin
  2909         else
  2911         else
  2910             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
  2912             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
  2911         DeleteGear(Gear);
  2913         DeleteGear(Gear);
  2912         exit
  2914         exit
  2913         end
  2915         end
  2914         
  2916 
  2915     else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not (TestCollisionXWithGear(Gear, hwSign(Gear^.dX)))) then
  2917     else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not (TestCollisionXWithGear(Gear, hwSign(Gear^.dX)))) then
  2916         begin
  2918         begin
  2917         StopSoundChan(Gear^.SoundChannel);
  2919         StopSoundChan(Gear^.SoundChannel);
  2918         Gear^.Tag := 1;
  2920         Gear^.Tag := 1;
  2919         Gear^.doStep := @doStepDrill
  2921         Gear^.doStep := @doStepDrill
  2921 
  2923 
  2922     dec(Gear^.Timer);
  2924     dec(Gear^.Timer);
  2923 end;
  2925 end;
  2924 
  2926 
  2925 procedure doStepDrill(Gear: PGear);
  2927 procedure doStepDrill(Gear: PGear);
  2926 var 
  2928 var
  2927     t: PGearArray;
  2929     t: PGearArray;
  2928     oldDx, oldDy: hwFloat;
  2930     oldDx, oldDy: hwFloat;
  2929     t2: hwFloat;
  2931     t2: hwFloat;
  2930 begin
  2932 begin
  2931     AllInactive := false;
  2933     AllInactive := false;
  2945         begin
  2947         begin
  2946         //hit
  2948         //hit
  2947         Gear^.dX := oldDx;
  2949         Gear^.dX := oldDx;
  2948         Gear^.dY := oldDy;
  2950         Gear^.dY := oldDy;
  2949 
  2951 
  2950         if GameTicks > Gear^.FlightTime then 
  2952         if GameTicks > Gear^.FlightTime then
  2951             t := CheckGearsCollision(Gear)
  2953             t := CheckGearsCollision(Gear)
  2952         else
  2954         else
  2953             t := nil;
  2955             t := nil;
  2954         if (t = nil) or (t^.Count = 0) then
  2956         if (t = nil) or (t^.Count = 0) then
  2955             begin
  2957             begin
  2956             //hit the ground not the HH
  2958             //hit the ground not the HH
  2957             t2 := _0_5 / Distance(Gear^.dX, Gear^.dY);
  2959             t2 := _0_5 / Distance(Gear^.dX, Gear^.dY);
  2958             Gear^.dX := Gear^.dX * t2;
  2960             Gear^.dX := Gear^.dX * t2;
  2959             Gear^.dY := Gear^.dY * t2;
  2961             Gear^.dY := Gear^.dY * t2;
  2960             end
  2962             end
  2961             
  2963 
  2962         else if (t <> nil) then
  2964         else if (t <> nil) then
  2963             begin
  2965             begin
  2964             //explode right on contact with HH
  2966             //explode right on contact with HH
  2965             if (Gear^.State and gsttmpFlag) <> 0 then
  2967             if (Gear^.State and gsttmpFlag) <> 0 then
  2966                 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound)
  2968                 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound)
  2970             exit;
  2972             exit;
  2971             end;
  2973             end;
  2972 
  2974 
  2973         Gear^.SoundChannel := LoopSound(sndDrillRocket);
  2975         Gear^.SoundChannel := LoopSound(sndDrillRocket);
  2974         Gear^.doStep := @doStepDrillDrilling;
  2976         Gear^.doStep := @doStepDrillDrilling;
  2975         
  2977 
  2976         if (Gear^.State and gsttmpFlag) <> 0 then
  2978         if (Gear^.State and gsttmpFlag) <> 0 then
  2977             gear^.RenderTimer:= true;
  2979             gear^.RenderTimer:= true;
  2978         if Gear^.Timer > 0 then dec(Gear^.Timer)
  2980         if Gear^.Timer > 0 then dec(Gear^.Timer)
  2979         end
  2981         end
  2980     else if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Tag <> 0) then
  2982     else if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Tag <> 0) then
  2981         begin
  2983         begin
  2982         if Gear^.Timer > 0 then 
  2984         if Gear^.Timer > 0 then
  2983             dec(Gear^.Timer)
  2985             dec(Gear^.Timer)
  2984         else
  2986         else
  2985             begin
  2987             begin
  2986             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
  2988             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
  2987             DeleteGear(Gear);
  2989             DeleteGear(Gear);
  2989         end;
  2991         end;
  2990 end;
  2992 end;
  2991 
  2993 
  2992 ////////////////////////////////////////////////////////////////////////////////
  2994 ////////////////////////////////////////////////////////////////////////////////
  2993 procedure doStepBallgunWork(Gear: PGear);
  2995 procedure doStepBallgunWork(Gear: PGear);
  2994 var 
  2996 var
  2995     HHGear, ball: PGear;
  2997     HHGear, ball: PGear;
  2996     rx, ry: hwFloat;
  2998     rx, ry: hwFloat;
  2997     gX, gY: LongInt;
  2999     gX, gY: LongInt;
  2998 begin
  3000 begin
  2999     AllInactive := false;
  3001     AllInactive := false;
  3019         AfterAttack
  3021         AfterAttack
  3020         end
  3022         end
  3021 end;
  3023 end;
  3022 
  3024 
  3023 procedure doStepBallgun(Gear: PGear);
  3025 procedure doStepBallgun(Gear: PGear);
  3024 var 
  3026 var
  3025     HHGear: PGear;
  3027     HHGear: PGear;
  3026 begin
  3028 begin
  3027     HHGear := Gear^.Hedgehog^.Gear;
  3029     HHGear := Gear^.Hedgehog^.Gear;
  3028     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown));
  3030     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown));
  3029     HHGear^.State := HHGear^.State or gstNotKickable;
  3031     HHGear^.State := HHGear^.State or gstNotKickable;
  3032 
  3034 
  3033 ////////////////////////////////////////////////////////////////////////////////
  3035 ////////////////////////////////////////////////////////////////////////////////
  3034 procedure doStepRCPlaneWork(Gear: PGear);
  3036 procedure doStepRCPlaneWork(Gear: PGear);
  3035 
  3037 
  3036 const cAngleSpeed =   3;
  3038 const cAngleSpeed =   3;
  3037 var 
  3039 var
  3038     HHGear: PGear;
  3040     HHGear: PGear;
  3039     i: LongInt;
  3041     i: LongInt;
  3040     dX, dY: hwFloat;
  3042     dX, dY: hwFloat;
  3041     fChanged: boolean;
  3043     fChanged: boolean;
  3042     trueAngle: Longword;
  3044     trueAngle: Longword;
  3141         CurAmmoGear := nil;
  3143         CurAmmoGear := nil;
  3142         if (GameFlags and gfInfAttack) = 0 then
  3144         if (GameFlags and gfInfAttack) = 0 then
  3143             begin
  3145             begin
  3144             if TagTurnTimeLeft = 0 then
  3146             if TagTurnTimeLeft = 0 then
  3145                 TagTurnTimeLeft:= TurnTimeLeft;
  3147                 TagTurnTimeLeft:= TurnTimeLeft;
  3146                 
  3148 
  3147             TurnTimeLeft:= 14 * 125;
  3149             TurnTimeLeft:= 14 * 125;
  3148             end;
  3150             end;
  3149 
  3151 
  3150         HHGear^.Message := 0;
  3152         HHGear^.Message := 0;
  3151         ParseCommand('/taunt ' + #1, true)
  3153         ParseCommand('/taunt ' + #1, true)
  3152         end
  3154         end
  3153 end;
  3155 end;
  3154 
  3156 
  3155 procedure doStepRCPlane(Gear: PGear);
  3157 procedure doStepRCPlane(Gear: PGear);
  3156 var 
  3158 var
  3157     HHGear: PGear;
  3159     HHGear: PGear;
  3158 begin
  3160 begin
  3159     HHGear := Gear^.Hedgehog^.Gear;
  3161     HHGear := Gear^.Hedgehog^.Gear;
  3160     HHGear^.Message := 0;
  3162     HHGear^.Message := 0;
  3161     HHGear^.State := HHGear^.State or gstNotKickable;
  3163     HHGear^.State := HHGear^.State or gstNotKickable;
  3162     Gear^.Angle := HHGear^.Angle;
  3164     Gear^.Angle := HHGear^.Angle;
  3163     Gear^.Tag := hwSign(HHGear^.dX);
  3165     Gear^.Tag := hwSign(HHGear^.dX);
  3164     
  3166 
  3165     if HHGear^.dX.isNegative then
  3167     if HHGear^.dX.isNegative then
  3166         Gear^.Angle := 4096 - Gear^.Angle;
  3168         Gear^.Angle := 4096 - Gear^.Angle;
  3167     Gear^.doStep := @doStepRCPlaneWork
  3169     Gear^.doStep := @doStepRCPlaneWork
  3168 end;
  3170 end;
  3169 
  3171 
  3170 ////////////////////////////////////////////////////////////////////////////////
  3172 ////////////////////////////////////////////////////////////////////////////////
  3171 procedure doStepJetpackWork(Gear: PGear);
  3173 procedure doStepJetpackWork(Gear: PGear);
  3172 var 
  3174 var
  3173     HHGear: PGear;
  3175     HHGear: PGear;
  3174     fuel, i: LongInt;
  3176     fuel, i: LongInt;
  3175     move: hwFloat;
  3177     move: hwFloat;
  3176     isUnderwater: Boolean;
  3178     isUnderwater: Boolean;
  3177     bubble: PVisualGear;
  3179     bubble: PVisualGear;
  3246         Gear^.MsgParam := 0
  3248         Gear^.MsgParam := 0
  3247         end;
  3249         end;
  3248 
  3250 
  3249     if Gear^.Health < 0 then
  3251     if Gear^.Health < 0 then
  3250         Gear^.Health := 0;
  3252         Gear^.Health := 0;
  3251         
  3253 
  3252     i:= Gear^.Health div 20;
  3254     i:= Gear^.Health div 20;
  3253     
  3255 
  3254     if (i <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
  3256     if (i <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
  3255         begin
  3257         begin
  3256         Gear^.Damage:= i;
  3258         Gear^.Damage:= i;
  3257         //AddCaption('Fuel: '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
  3259         //AddCaption('Fuel: '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
  3258         FreeTexture(Gear^.Tex);
  3260         FreeTexture(Gear^.Tex);
  3259         Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) + '%', cWhiteColor, fntSmall)
  3261         Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) + '%', cWhiteColor, fntSmall)
  3260         end;
  3262         end;
  3261 
  3263 
  3262     if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then 
  3264     if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then
  3263         Gear^.State := Gear^.State and (not gsttmpFlag);
  3265         Gear^.State := Gear^.State and (not gsttmpFlag);
  3264         
  3266 
  3265     HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
  3267     HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
  3266     HHGear^.State := HHGear^.State or gstMoving;
  3268     HHGear^.State := HHGear^.State or gstMoving;
  3267 
  3269 
  3268     Gear^.X := HHGear^.X;
  3270     Gear^.X := HHGear^.X;
  3269     Gear^.Y := HHGear^.Y;
  3271     Gear^.Y := HHGear^.Y;
  3270 
  3272 
  3271     if (not isUnderWater) and hasBorder and ((HHGear^.X < _0)
  3273     if (not isUnderWater) and hasBorder and ((HHGear^.X < _0)
  3272     or (hwRound(HHGear^.X) > LAND_WIDTH)) then
  3274     or (hwRound(HHGear^.X) > LAND_WIDTH)) then
  3273         HHGear^.dY.isNegative:= false;
  3275         HHGear^.dY.isNegative:= false;
  3274         
  3276 
  3275     if ((Gear^.State and gsttmpFlag) = 0)
  3277     if ((Gear^.State and gsttmpFlag) = 0)
  3276     or (HHGear^.dY < _0) then
  3278     or (HHGear^.dY < _0) then
  3277         doStepHedgehogMoving(HHGear);
  3279         doStepHedgehogMoving(HHGear);
  3278 
  3280 
  3279     if // (Gear^.Health = 0)
  3281     if // (Gear^.Health = 0)
  3301 //AddCaption(trmsg[sidFuel]+': '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
  3303 //AddCaption(trmsg[sidFuel]+': '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
  3302             end
  3304             end
  3303 end;
  3305 end;
  3304 
  3306 
  3305 procedure doStepJetpack(Gear: PGear);
  3307 procedure doStepJetpack(Gear: PGear);
  3306 var 
  3308 var
  3307     HHGear: PGear;
  3309     HHGear: PGear;
  3308 begin
  3310 begin
  3309     Gear^.Pos:= 0;
  3311     Gear^.Pos:= 0;
  3310     Gear^.doStep := @doStepJetpackWork;
  3312     Gear^.doStep := @doStepJetpackWork;
  3311 
  3313 
  3314     AfterAttack;
  3316     AfterAttack;
  3315     with HHGear^ do
  3317     with HHGear^ do
  3316         begin
  3318         begin
  3317         State := State and (not gstAttacking);
  3319         State := State and (not gstAttacking);
  3318         Message := Message and (not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight));
  3320         Message := Message and (not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight));
  3319         
  3321 
  3320         if (dY < _0_1) and (dY > -_0_1) then
  3322         if (dY < _0_1) and (dY > -_0_1) then
  3321             begin
  3323             begin
  3322             Gear^.State := Gear^.State or gsttmpFlag;
  3324             Gear^.State := Gear^.State or gsttmpFlag;
  3323             dY := dY - _0_2
  3325             dY := dY - _0_2
  3324             end
  3326             end
  3337         DeleteGear(Gear);
  3339         DeleteGear(Gear);
  3338         end;
  3340         end;
  3339 end;
  3341 end;
  3340 
  3342 
  3341 procedure doStepBirdyFly(Gear: PGear);
  3343 procedure doStepBirdyFly(Gear: PGear);
  3342 var 
  3344 var
  3343     HHGear: PGear;
  3345     HHGear: PGear;
  3344     fuel, i: LongInt;
  3346     fuel, i: LongInt;
  3345     move: hwFloat;
  3347     move: hwFloat;
  3346 begin
  3348 begin
  3347     HHGear := Gear^.Hedgehog^.Gear;
  3349     HHGear := Gear^.Hedgehog^.Gear;
  3348     if HHGear = nil then 
  3350     if HHGear = nil then
  3349         begin
  3351         begin
  3350         DeleteGear(Gear);
  3352         DeleteGear(Gear);
  3351         exit
  3353         exit
  3352         end;
  3354         end;
  3353 
  3355 
  3367     if (HHGear^.Message and gmUp) <> 0 then
  3369     if (HHGear^.Message and gmUp) <> 0 then
  3368         begin
  3370         begin
  3369         if (not HHGear^.dY.isNegative)
  3371         if (not HHGear^.dY.isNegative)
  3370         or (HHGear^.Y > -_256) then
  3372         or (HHGear^.Y > -_256) then
  3371             HHGear^.dY := HHGear^.dY - move;
  3373             HHGear^.dY := HHGear^.dY - move;
  3372             
  3374 
  3373         dec(Gear^.Health, fuel);
  3375         dec(Gear^.Health, fuel);
  3374         Gear^.MsgParam := Gear^.MsgParam or gmUp;
  3376         Gear^.MsgParam := Gear^.MsgParam or gmUp;
  3375         end;
  3377         end;
  3376         
  3378 
  3377     if (HHGear^.Message and gmLeft) <> 0 then move.isNegative := true;
  3379     if (HHGear^.Message and gmLeft) <> 0 then move.isNegative := true;
  3378     if (HHGear^.Message and (gmLeft or gmRight)) <> 0 then
  3380     if (HHGear^.Message and (gmLeft or gmRight)) <> 0 then
  3379         begin
  3381         begin
  3380         HHGear^.dX := HHGear^.dX + (move * _0_1);
  3382         HHGear^.dX := HHGear^.dX + (move * _0_1);
  3381         dec(Gear^.Health, fuel div 5);
  3383         dec(Gear^.Health, fuel div 5);
  3382         Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gmLeft or gmRight));
  3384         Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gmLeft or gmRight));
  3383         end;
  3385         end;
  3384 
  3386 
  3385     if Gear^.Health < 0 then
  3387     if Gear^.Health < 0 then
  3386         Gear^.Health := 0;
  3388         Gear^.Health := 0;
  3387         
  3389 
  3388     if ((GameTicks and $FF) = 0) and (Gear^.Health < 500) then
  3390     if ((GameTicks and $FF) = 0) and (Gear^.Health < 500) then
  3389         for i:= ((500-Gear^.Health) div 250) downto 0 do
  3391         for i:= ((500-Gear^.Health) div 250) downto 0 do
  3390             AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather);
  3392             AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather);
  3391 
  3393 
  3392     if (HHGear^.Message and gmAttack <> 0) then
  3394     if (HHGear^.Message and gmAttack <> 0) then
  3400             end;
  3402             end;
  3401         end;
  3403         end;
  3402 
  3404 
  3403     if HHGear^.Message and (gmUp or gmPrecise or gmLeft or gmRight) <> 0 then
  3405     if HHGear^.Message and (gmUp or gmPrecise or gmLeft or gmRight) <> 0 then
  3404         Gear^.State := Gear^.State and (not gsttmpFlag);
  3406         Gear^.State := Gear^.State and (not gsttmpFlag);
  3405         
  3407 
  3406     HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
  3408     HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
  3407     HHGear^.State := HHGear^.State or gstMoving;
  3409     HHGear^.State := HHGear^.State or gstMoving;
  3408 
  3410 
  3409     Gear^.X := HHGear^.X;
  3411     Gear^.X := HHGear^.X;
  3410     Gear^.Y := HHGear^.Y - int2hwFloat(32);
  3412     Gear^.Y := HHGear^.Y - int2hwFloat(32);
  3443             AfterAttack;
  3445             AfterAttack;
  3444             end
  3446             end
  3445 end;
  3447 end;
  3446 
  3448 
  3447 procedure doStepBirdyDescend(Gear: PGear);
  3449 procedure doStepBirdyDescend(Gear: PGear);
  3448 var 
  3450 var
  3449     HHGear: PGear;
  3451     HHGear: PGear;
  3450 begin
  3452 begin
  3451     if Gear^.Timer > 0 then
  3453     if Gear^.Timer > 0 then
  3452         dec(Gear^.Timer, 1)
  3454         dec(Gear^.Timer, 1)
  3453     else if Gear^.Hedgehog^.Gear = nil then
  3455     else if Gear^.Hedgehog^.Gear = nil then
  3484         Gear^.doStep := @doStepBirdyDescend;
  3486         Gear^.doStep := @doStepBirdyDescend;
  3485         end
  3487         end
  3486 end;
  3488 end;
  3487 
  3489 
  3488 procedure doStepBirdy(Gear: PGear);
  3490 procedure doStepBirdy(Gear: PGear);
  3489 var 
  3491 var
  3490     HHGear: PGear;
  3492     HHGear: PGear;
  3491 begin
  3493 begin
  3492     gear^.State :=  gear^.State or gstAnimation and (not gstTmpFlag);
  3494     gear^.State :=  gear^.State or gstAnimation and (not gstTmpFlag);
  3493     Gear^.doStep := @doStepBirdyAppear;
  3495     Gear^.doStep := @doStepBirdyAppear;
  3494     
  3496 
  3495     if CurrentHedgehog = nil then
  3497     if CurrentHedgehog = nil then
  3496         begin
  3498         begin
  3497         DeleteGear(Gear);
  3499         DeleteGear(Gear);
  3498         exit
  3500         exit
  3499         end;
  3501         end;
  3514         end
  3516         end
  3515 end;
  3517 end;
  3516 
  3518 
  3517 ////////////////////////////////////////////////////////////////////////////////
  3519 ////////////////////////////////////////////////////////////////////////////////
  3518 procedure doStepEggWork(Gear: PGear);
  3520 procedure doStepEggWork(Gear: PGear);
  3519 var 
  3521 var
  3520     vg: PVisualGear;
  3522     vg: PVisualGear;
  3521     i: LongInt;
  3523     i: LongInt;
  3522 begin
  3524 begin
  3523     AllInactive := false;
  3525     AllInactive := false;
  3524     {$IFNDEF PAS2C}
  3526     {$IFNDEF PAS2C}
  3557     if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and ((CurrentHedgehog^.Gear^.Message and gmSwitch) <> 0) then
  3559     if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and ((CurrentHedgehog^.Gear^.Message and gmSwitch) <> 0) then
  3558             with CurrentHedgehog^ do
  3560             with CurrentHedgehog^ do
  3559                 if (CurAmmoType = amPortalGun) then
  3561                 if (CurAmmoType = amPortalGun) then
  3560                     begin
  3562                     begin
  3561                     CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSwitch);
  3563                     CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSwitch);
  3562                 
  3564 
  3563                     CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^);
  3565                     CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^);
  3564                     if CurWeapon^.Pos <> 0 then
  3566                     if CurWeapon^.Pos <> 0 then
  3565                         CurWeapon^.Pos := 0
  3567                         CurWeapon^.Pos := 0
  3566                         
  3568 
  3567                     else
  3569                     else
  3568                     CurWeapon^.Pos := 1;
  3570                     CurWeapon^.Pos := 1;
  3569                     end;
  3571                     end;
  3570 end;
  3572 end;
  3571 
  3573 
  3572 procedure doStepPortal(Gear: PGear);
  3574 procedure doStepPortal(Gear: PGear);
  3573 var 
  3575 var
  3574     iterator, conPortal: PGear;
  3576     iterator, conPortal: PGear;
  3575     s, r, nx, ny, ox, oy, poffs, noffs, pspeed, nspeed,
  3577     s, r, nx, ny, ox, oy, poffs, noffs, pspeed, nspeed,
  3576     resetx, resety, resetdx, resetdy: hwFloat;
  3578     resetx, resety, resetdx, resetdy: hwFloat;
  3577     sx, sy, rh, resetr: LongInt;
  3579     sx, sy, rh, resetr: LongInt;
  3578     hasdxy, isbullet, iscake, isCollision: Boolean;
  3580     hasdxy, isbullet, iscake, isCollision: Boolean;
  3869             resety.QWordValue:= 4294967296 * 112;
  3871             resety.QWordValue:= 4294967296 * 112;
  3870             resetx.isNegative:= false;
  3872             resetx.isNegative:= false;
  3871             resetx.QWordValue:= 4294967296 * 35;
  3873             resetx.QWordValue:= 4294967296 * 35;
  3872             resetdx.isNegative:= false;
  3874             resetdx.isNegative:= false;
  3873             resetdx.QWordValue:= 4294967296 * 1152;
  3875             resetdx.QWordValue:= 4294967296 * 1152;
  3874     
  3876 
  3875             resetdy:=hwAbs(iterator^.dX*4);
  3877             resetdy:=hwAbs(iterator^.dX*4);
  3876             resetdy:= resetdy + hwPow(resetdy,3)/_6 + _3 * hwPow(resetdy,5) / _40 + _5 * hwPow(resetdy,7) / resety + resetx * hwPow(resetdy,9) / resetdx;
  3878             resetdy:= resetdy + hwPow(resetdy,3)/_6 + _3 * hwPow(resetdy,5) / _40 + _5 * hwPow(resetdy,7) / resety + resetx * hwPow(resetdy,9) / resetdx;
  3877             iterator^.Angle:= hwRound(resetdy*_2048 / _PI);
  3879             iterator^.Angle:= hwRound(resetdy*_2048 / _PI);
  3878             if (not iterator^.dY.isNegative) then iterator^.Angle:= 2048-iterator^.Angle;
  3880             if (not iterator^.dY.isNegative) then iterator^.Angle:= 2048-iterator^.Angle;
  3879             if iterator^.dX.isNegative then iterator^.Angle:= 4096-iterator^.Angle;
  3881             if iterator^.dX.isNegative then iterator^.Angle:= 4096-iterator^.Angle;
  3936     if destroyGear then
  3938     if destroyGear then
  3937         oldPortal^.Timer:= 0;
  3939         oldPortal^.Timer:= 0;
  3938 end;
  3940 end;
  3939 
  3941 
  3940 procedure doStepMovingPortal_real(Gear: PGear);
  3942 procedure doStepMovingPortal_real(Gear: PGear);
  3941 var 
  3943 var
  3942     x, y, tx, ty: LongInt;
  3944     x, y, tx, ty: LongInt;
  3943     s: hwFloat;
  3945     s: hwFloat;
  3944 begin
  3946 begin
  3945     x := hwRound(Gear^.X);
  3947     x := hwRound(Gear^.X);
  3946     y := hwRound(Gear^.Y);
  3948     y := hwRound(Gear^.Y);
  3950 
  3952 
  3951     if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then
  3953     if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then
  3952         begin
  3954         begin
  3953         Gear^.State := Gear^.State or gstCollision;
  3955         Gear^.State := Gear^.State or gstCollision;
  3954         Gear^.State := Gear^.State and (not gstMoving);
  3956         Gear^.State := Gear^.State and (not gstMoving);
  3955         
  3957 
  3956         if (Land[y, x] and lfBouncy <> 0)
  3958         if (Land[y, x] and lfBouncy <> 0)
  3957         or (not (CalcSlopeTangent(Gear, x, y, tx, ty, 255)))
  3959         or (not (CalcSlopeTangent(Gear, x, y, tx, ty, 255)))
  3958         or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
  3960         or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
  3959             begin
  3961             begin
  3960             loadNewPortalBall(Gear, true);
  3962             loadNewPortalBall(Gear, true);
  3978             Gear^.doStep := @doStepPortal;
  3980             Gear^.doStep := @doStepPortal;
  3979         end
  3981         end
  3980         else
  3982         else
  3981             loadNewPortalBall(Gear, true);
  3983             loadNewPortalBall(Gear, true);
  3982     end
  3984     end
  3983     
  3985 
  3984     else if (y > cWaterLine)
  3986     else if (y > cWaterLine)
  3985     or (y < -max(LAND_WIDTH,4096))
  3987     or (y < -max(LAND_WIDTH,4096))
  3986     or (x > 2*max(LAND_WIDTH,4096))
  3988     or (x > 2*max(LAND_WIDTH,4096))
  3987     or (x < -max(LAND_WIDTH,4096)) then
  3989     or (x < -max(LAND_WIDTH,4096)) then
  3988         loadNewPortalBall(Gear, true);
  3990         loadNewPortalBall(Gear, true);
  3990 
  3992 
  3991 procedure doStepMovingPortal(Gear: PGear);
  3993 procedure doStepMovingPortal(Gear: PGear);
  3992 begin
  3994 begin
  3993     doPortalColorSwitch();
  3995     doPortalColorSwitch();
  3994     doStepPerPixel(Gear, @doStepMovingPortal_real, true);
  3996     doStepPerPixel(Gear, @doStepMovingPortal_real, true);
  3995     if (Gear^.Timer < 1) 
  3997     if (Gear^.Timer < 1)
  3996     or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team) then
  3998     or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team) then
  3997         deleteGear(Gear);
  3999         deleteGear(Gear);
  3998 end;
  4000 end;
  3999 
  4001 
  4000 procedure doStepPortalShot(newPortal: PGear);
  4002 procedure doStepPortalShot(newPortal: PGear);
  4001 var 
  4003 var
  4002     iterator: PGear;
  4004     iterator: PGear;
  4003     s: hwFloat;
  4005     s: hwFloat;
  4004     CurWeapon: PAmmo;
  4006     CurWeapon: PAmmo;
  4005 begin
  4007 begin
  4006     s:= Distance (newPortal^.dX, newPortal^.dY);
  4008     s:= Distance (newPortal^.dX, newPortal^.dY);
  4076     newPortal^.doStep := @doStepMovingPortal;
  4078     newPortal^.doStep := @doStepMovingPortal;
  4077 end;
  4079 end;
  4078 
  4080 
  4079 ////////////////////////////////////////////////////////////////////////////////
  4081 ////////////////////////////////////////////////////////////////////////////////
  4080 procedure doStepPiano(Gear: PGear);
  4082 procedure doStepPiano(Gear: PGear);
  4081 var 
  4083 var
  4082     r0, r1: LongInt;
  4084     r0, r1: LongInt;
  4083     odY: hwFloat;
  4085     odY: hwFloat;
  4084 begin
  4086 begin
  4085     AllInactive := false;
  4087     AllInactive := false;
  4086     if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and 
  4088     if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and
  4087         ((CurrentHedgehog^.Gear^.Message and gmSlot) <> 0) then
  4089         ((CurrentHedgehog^.Gear^.Message and gmSlot) <> 0) then
  4088             begin
  4090             begin
  4089                 case CurrentHedgehog^.Gear^.MsgParam of 
  4091                 case CurrentHedgehog^.Gear^.MsgParam of
  4090                 0: PlaySound(sndPiano0);
  4092                 0: PlaySound(sndPiano0);
  4091                 1: PlaySound(sndPiano1);
  4093                 1: PlaySound(sndPiano1);
  4092                 2: PlaySound(sndPiano2);
  4094                 2: PlaySound(sndPiano2);
  4093                 3: PlaySound(sndPiano3);
  4095                 3: PlaySound(sndPiano3);
  4094                 4: PlaySound(sndPiano4);
  4096                 4: PlaySound(sndPiano4);
  4164 end;
  4166 end;
  4165 
  4167 
  4166 
  4168 
  4167 ////////////////////////////////////////////////////////////////////////////////
  4169 ////////////////////////////////////////////////////////////////////////////////
  4168 procedure doStepSineGunShotWork(Gear: PGear);
  4170 procedure doStepSineGunShotWork(Gear: PGear);
  4169 var 
  4171 var
  4170     x, y, rX, rY, t, tmp, initHealth: LongInt;
  4172     x, y, rX, rY, t, tmp, initHealth: LongInt;
  4171     oX, oY, ldX, ldY, sdX, sdY, sine, lx, ly, amp: hwFloat;
  4173     oX, oY, ldX, ldY, sdX, sdY, sine, lx, ly, amp: hwFloat;
  4172     justCollided: boolean;
  4174     justCollided: boolean;
  4173 begin
  4175 begin
  4174     AllInactive := false;
  4176     AllInactive := false;
  4259                         AddGear(x - Gear^.Radius + tmp, y - GetRandom(Gear^.Radius + 1), gtFlame, gsttmpFlag, _0, _0, 0)
  4261                         AddGear(x - Gear^.Radius + tmp, y - GetRandom(Gear^.Radius + 1), gtFlame, gsttmpFlag, _0, _0, 0)
  4260                         end
  4262                         end
  4261                     end;
  4263                     end;
  4262 
  4264 
  4263                 if random(100) = 0 then
  4265                 if random(100) = 0 then
  4264                     AddVisualGear(x, y, vgtSmokeTrace); 
  4266                     AddVisualGear(x, y, vgtSmokeTrace);
  4265                 end
  4267                 end
  4266                 else dec(Gear^.Health, 5); // if underwater get additional damage
  4268                 else dec(Gear^.Health, 5); // if underwater get additional damage
  4267             end;
  4269             end;
  4268 
  4270 
  4269         dec(Gear^.Health);
  4271         dec(Gear^.Health);
  4297 
  4299 
  4298 procedure doStepSineGunShot(Gear: PGear);
  4300 procedure doStepSineGunShot(Gear: PGear);
  4299 var
  4301 var
  4300     HHGear: PGear;
  4302     HHGear: PGear;
  4301 begin
  4303 begin
  4302     PlaySound(sndSineGun); 
  4304     PlaySound(sndSineGun);
  4303 
  4305 
  4304     // push the shooting Hedgehog back
  4306     // push the shooting Hedgehog back
  4305     HHGear := CurrentHedgehog^.Gear;
  4307     HHGear := CurrentHedgehog^.Gear;
  4306     Gear^.dX.isNegative := not Gear^.dX.isNegative;
  4308     Gear^.dX.isNegative := not Gear^.dX.isNegative;
  4307     Gear^.dY.isNegative := not Gear^.dY.isNegative;
  4309     Gear^.dY.isNegative := not Gear^.dY.isNegative;
  4310     AmmoShove(Gear, 0, 80);
  4312     AmmoShove(Gear, 0, 80);
  4311     Gear^.dX.isNegative := not Gear^.dX.isNegative;
  4313     Gear^.dX.isNegative := not Gear^.dX.isNegative;
  4312     Gear^.dY.isNegative := not Gear^.dY.isNegative;
  4314     Gear^.dY.isNegative := not Gear^.dY.isNegative;
  4313 
  4315 
  4314     Gear^.doStep := @doStepSineGunShotWork;
  4316     Gear^.doStep := @doStepSineGunShotWork;
  4315     performRumble();
  4317     with mobileRecord do
       
  4318         if (performRumble <> nil) and (not fastUntilLag) then
       
  4319             performRumble(kSystemSoundID_Vibrate);
  4316 end;
  4320 end;
  4317 
  4321 
  4318 ////////////////////////////////////////////////////////////////////////////////
  4322 ////////////////////////////////////////////////////////////////////////////////
  4319 procedure doStepFlamethrowerWork(Gear: PGear);
  4323 procedure doStepFlamethrowerWork(Gear: PGear);
  4320 var 
  4324 var
  4321     HHGear, flame: PGear;
  4325     HHGear, flame: PGear;
  4322     rx, ry, speed: hwFloat;
  4326     rx, ry, speed: hwFloat;
  4323     i, gX, gY: LongInt;
  4327     i, gX, gY: LongInt;
  4324 begin
  4328 begin
  4325     AllInactive := false;
  4329     AllInactive := false;
  4326     HHGear := Gear^.Hedgehog^.Gear;
  4330     HHGear := Gear^.Hedgehog^.Gear;
  4327     HedgehogChAngle(HHGear);
  4331     HedgehogChAngle(HHGear);
  4328     gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
  4332     gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
  4329     gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
  4333     gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
  4330     
  4334 
  4331     if (GameTicks and $FF) = 0 then
  4335     if (GameTicks and $FF) = 0 then
  4332         begin
  4336         begin
  4333         if (HHGear^.Message and gmRight) <> 0 then
  4337         if (HHGear^.Message and gmRight) <> 0 then
  4334             begin
  4338             begin
  4335             if HHGear^.dX.isNegative and (Gear^.Tag < 20) then
  4339             if HHGear^.dX.isNegative and (Gear^.Tag < 20) then
  4339             end
  4343             end
  4340         else if (HHGear^.Message and gmLeft) <> 0 then
  4344         else if (HHGear^.Message and gmLeft) <> 0 then
  4341             begin
  4345             begin
  4342             if HHGear^.dX.isNegative and (Gear^.Tag > 5) then
  4346             if HHGear^.dX.isNegative and (Gear^.Tag > 5) then
  4343                 dec(Gear^.Tag)
  4347                 dec(Gear^.Tag)
  4344             else if Gear^.Tag < 20 then 
  4348             else if Gear^.Tag < 20 then
  4345                 inc(Gear^.Tag);
  4349                 inc(Gear^.Tag);
  4346             end
  4350             end
  4347         end;
  4351         end;
  4348     
  4352 
  4349     dec(Gear^.Timer);
  4353     dec(Gear^.Timer);
  4350     if Gear^.Timer = 0 then
  4354     if Gear^.Timer = 0 then
  4351         begin
  4355         begin
  4352         dec(Gear^.Health);
  4356         dec(Gear^.Health);
  4353         if (Gear^.Health mod 5) = 0 then
  4357         if (Gear^.Health mod 5) = 0 then
  4354             begin
  4358             begin
  4355             rx := rndSign(getRandomf * _0_1);
  4359             rx := rndSign(getRandomf * _0_1);
  4356             ry := rndSign(getRandomf * _0_1);
  4360             ry := rndSign(getRandomf * _0_1);
  4357             speed := _0_5 * (_10 / Gear^.Tag);
  4361             speed := _0_5 * (_10 / Gear^.Tag);
  4358     
  4362 
  4359             flame:= AddGear(gx, gy, gtFlame, gstTmpFlag,
  4363             flame:= AddGear(gx, gy, gtFlame, gstTmpFlag,
  4360                     SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
  4364                     SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
  4361                     AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
  4365                     AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
  4362             flame^.CollisionMask:= $FF7F;
  4366             flame^.CollisionMask:= $FF7F;
  4363             
  4367 
  4364             if (Gear^.Health mod 30) = 0 then
  4368             if (Gear^.Health mod 30) = 0 then
  4365                 begin
  4369                 begin
  4366                 flame:= AddGear(gx, gy, gtFlame, 0,
  4370                 flame:= AddGear(gx, gy, gtFlame, 0,
  4367                         SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
  4371                         SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
  4368                         AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
  4372                         AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
  4389             end
  4393             end
  4390         end
  4394         end
  4391 end;
  4395 end;
  4392 
  4396 
  4393 procedure doStepFlamethrower(Gear: PGear);
  4397 procedure doStepFlamethrower(Gear: PGear);
  4394 var 
  4398 var
  4395     HHGear: PGear;
  4399     HHGear: PGear;
  4396 begin
  4400 begin
  4397     HHGear := Gear^.Hedgehog^.Gear;
  4401     HHGear := Gear^.Hedgehog^.Gear;
  4398     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight));
  4402     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight));
  4399     HHGear^.State := HHGear^.State or gstNotKickable;
  4403     HHGear^.State := HHGear^.State or gstNotKickable;
  4400     Gear^.doStep := @doStepFlamethrowerWork
  4404     Gear^.doStep := @doStepFlamethrowerWork
  4401 end;
  4405 end;
  4402 
  4406 
  4403 ////////////////////////////////////////////////////////////////////////////////
  4407 ////////////////////////////////////////////////////////////////////////////////
  4404 procedure doStepLandGunWork(Gear: PGear);
  4408 procedure doStepLandGunWork(Gear: PGear);
  4405 var 
  4409 var
  4406     HHGear, land: PGear;
  4410     HHGear, land: PGear;
  4407     rx, ry, speed: hwFloat;
  4411     rx, ry, speed: hwFloat;
  4408     i, gX, gY: LongInt;
  4412     i, gX, gY: LongInt;
  4409 begin
  4413 begin
  4410     AllInactive := false;
  4414     AllInactive := false;
  4411     HHGear := Gear^.Hedgehog^.Gear;
  4415     HHGear := Gear^.Hedgehog^.Gear;
  4412     HedgehogChAngle(HHGear);
  4416     HedgehogChAngle(HHGear);
  4413     gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
  4417     gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
  4414     gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
  4418     gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
  4415     
  4419 
  4416     if (GameTicks and $FF) = 0 then
  4420     if (GameTicks and $FF) = 0 then
  4417         begin
  4421         begin
  4418         if (HHGear^.Message and gmRight) <> 0 then
  4422         if (HHGear^.Message and gmRight) <> 0 then
  4419             begin
  4423             begin
  4420             if HHGear^.dX.isNegative and (Gear^.Tag < 20) then
  4424             if HHGear^.dX.isNegative and (Gear^.Tag < 20) then
  4428                 dec(Gear^.Tag)
  4432                 dec(Gear^.Tag)
  4429             else if Gear^.Tag < 20 then
  4433             else if Gear^.Tag < 20 then
  4430                 inc(Gear^.Tag);
  4434                 inc(Gear^.Tag);
  4431             end
  4435             end
  4432         end;
  4436         end;
  4433     
  4437 
  4434     dec(Gear^.Timer);
  4438     dec(Gear^.Timer);
  4435     if Gear^.Timer = 0 then
  4439     if Gear^.Timer = 0 then
  4436         begin
  4440         begin
  4437         dec(Gear^.Health);
  4441         dec(Gear^.Health);
  4438 
  4442 
  4439         rx := rndSign(getRandomf * _0_1);
  4443         rx := rndSign(getRandomf * _0_1);
  4440         ry := rndSign(getRandomf * _0_1);
  4444         ry := rndSign(getRandomf * _0_1);
  4441         speed := (_3 / Gear^.Tag);
  4445         speed := (_3 / Gear^.Tag);
  4442 
  4446 
  4443         land:= AddGear(gx, gy, gtFlake, gstTmpFlag, 
  4447         land:= AddGear(gx, gy, gtFlake, gstTmpFlag,
  4444                 SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx, 
  4448                 SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
  4445                 AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
  4449                 AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
  4446         land^.CollisionMask:= $FF7F;
  4450         land^.CollisionMask:= $FF7F;
  4447             
  4451 
  4448         Gear^.Timer:= Gear^.Tag
  4452         Gear^.Timer:= Gear^.Tag
  4449         end;
  4453         end;
  4450 
  4454 
  4451     if (Gear^.Health = 0) or ((HHGear^.State and gstHHDriven) = 0) or ((HHGear^.Message and gmAttack) <> 0) then
  4455     if (Gear^.Health = 0) or ((HHGear^.State and gstHHDriven) = 0) or ((HHGear^.Message and gmAttack) <> 0) then
  4452         begin
  4456         begin
  4466             end
  4470             end
  4467         end
  4471         end
  4468 end;
  4472 end;
  4469 
  4473 
  4470 procedure doStepLandGun(Gear: PGear);
  4474 procedure doStepLandGun(Gear: PGear);
  4471 var 
  4475 var
  4472     HHGear: PGear;
  4476     HHGear: PGear;
  4473 begin
  4477 begin
  4474     HHGear := Gear^.Hedgehog^.Gear;
  4478     HHGear := Gear^.Hedgehog^.Gear;
  4475     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight or gmAttack));
  4479     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight or gmAttack));
  4476     HHGear^.State := HHGear^.State or gstNotKickable;
  4480     HHGear^.State := HHGear^.State or gstNotKickable;
  4535 Gear^.Timer:= 250;
  4539 Gear^.Timer:= 250;
  4536 Gear^.doStep:= @doStepIdle
  4540 Gear^.doStep:= @doStepIdle
  4537 end;
  4541 end;
  4538 
  4542 
  4539 procedure doStepHammerHitWork(Gear: PGear);
  4543 procedure doStepHammerHitWork(Gear: PGear);
  4540 var 
  4544 var
  4541     i, j, ei: LongInt;
  4545     i, j, ei: LongInt;
  4542     HitGear: PGear;
  4546     HitGear: PGear;
  4543 begin
  4547 begin
  4544     AllInactive := false;
  4548     AllInactive := false;
  4545     HitGear := Gear^.LinkedGear;
  4549     HitGear := Gear^.LinkedGear;
  4590     SetLittle(HitGear^.dY);
  4594     SetLittle(HitGear^.dY);
  4591     HitGear^.Active:= true;
  4595     HitGear^.Active:= true;
  4592 end;
  4596 end;
  4593 
  4597 
  4594 procedure doStepHammerHit(Gear: PGear);
  4598 procedure doStepHammerHit(Gear: PGear);
  4595 var 
  4599 var
  4596     i, y: LongInt;
  4600     i, y: LongInt;
  4597     ar: TRangeArray;
  4601     ar: TRangeArray;
  4598     HHGear: PGear;
  4602     HHGear: PGear;
  4599 begin
  4603 begin
  4600     i := 0;
  4604     i := 0;
  4641 
  4645 
  4642     if ((Gear^.Message and gmUp) <> 0) then
  4646     if ((Gear^.Message and gmUp) <> 0) then
  4643         begin
  4647         begin
  4644         if (GameTicks and $F) <> 0 then
  4648         if (GameTicks and $F) <> 0 then
  4645         exit;
  4649         exit;
  4646         end 
  4650         end
  4647     else if (GameTicks and $1FF) <> 0 then
  4651     else if (GameTicks and $1FF) <> 0 then
  4648         exit;
  4652         exit;
  4649 
  4653 
  4650     if Gear^.Power < 45 then
  4654     if Gear^.Power < 45 then
  4651         begin
  4655         begin
  4678             if hh^.Gear^.Health > 0 then begin
  4682             if hh^.Gear^.Health > 0 then begin
  4679                 dec(hh^.Gear^.Health);
  4683                 dec(hh^.Gear^.Health);
  4680                 inc(graves[i]^.Health);
  4684                 inc(graves[i]^.Health);
  4681             end;
  4685             end;
  4682         end; -}
  4686         end; -}
  4683         end 
  4687         end
  4684     else 
  4688     else
  4685         begin
  4689         begin
  4686         // now really resurrect the hogs with the hp saved in the graves
  4690         // now really resurrect the hogs with the hp saved in the graves
  4687         for i:= 0 to graves.size - 1 do
  4691         for i:= 0 to graves.size - 1 do
  4688             if graves.ar^[i]^.Health > 0 then
  4692             if graves.ar^[i]^.Health > 0 then
  4689                 begin
  4693                 begin
  4727             begin
  4731             begin
  4728             PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := nil;
  4732             PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := nil;
  4729             graves.ar^[i]^.Health := 0;
  4733             graves.ar^[i]^.Health := 0;
  4730             end;
  4734             end;
  4731         Gear^.doStep := @doStepResurrectorWork;
  4735         Gear^.doStep := @doStepResurrectorWork;
  4732         end 
  4736         end
  4733     else 
  4737     else
  4734         begin
  4738         begin
  4735         StopSoundChan(Gear^.SoundChannel);
  4739         StopSoundChan(Gear^.SoundChannel);
  4736         Gear^.Timer := 250;
  4740         Gear^.Timer := 250;
  4737         Gear^.doStep := @doStepIdle;
  4741         Gear^.doStep := @doStepIdle;
  4738         end
  4742         end
  4748     doStepFallingGear(Gear);
  4752     doStepFallingGear(Gear);
  4749     if (Gear^.Timer > 0) and ((Gear^.State and gstCollision) <> 0) then
  4753     if (Gear^.Timer > 0) and ((Gear^.State and gstCollision) <> 0) then
  4750     begin
  4754     begin
  4751         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, Gear^.Hedgehog, EXPLAutoSound);
  4755         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, Gear^.Hedgehog, EXPLAutoSound);
  4752         gX := hwRound(Gear^.X);
  4756         gX := hwRound(Gear^.X);
  4753         gY := hwRound(Gear^.Y); 
  4757         gY := hwRound(Gear^.Y);
  4754         for i:= 0 to 10 do
  4758         for i:= 0 to 10 do
  4755         begin
  4759         begin
  4756             dX := AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandomf + _1);
  4760             dX := AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandomf + _1);
  4757             dY := AngleSin(i * 8) * _0_5 * (GetRandomf + _1);
  4761             dY := AngleSin(i * 8) * _0_5 * (GetRandomf + _1);
  4758             AddGear(gX, gY, gtFlame, 0, dX, dY, 0);
  4762             AddGear(gX, gY, gtFlame, 0, dX, dY, 0);
  4776     dec(Gear^.Timer)
  4780     dec(Gear^.Timer)
  4777 end;
  4781 end;
  4778 
  4782 
  4779 ////////////////////////////////////////////////////////////////////////////////
  4783 ////////////////////////////////////////////////////////////////////////////////
  4780 procedure doStepStructure(Gear: PGear);
  4784 procedure doStepStructure(Gear: PGear);
  4781 var 
  4785 var
  4782     x, y: LongInt;
  4786     x, y: LongInt;
  4783     HH: PHedgehog;
  4787     HH: PHedgehog;
  4784     t: PGear;
  4788     t: PGear;
  4785 begin
  4789 begin
  4786     HH:= Gear^.Hedgehog;
  4790     HH:= Gear^.Hedgehog;
  4793         Gear^.State:= Gear^.State and (not gstMoving);
  4797         Gear^.State:= Gear^.State and (not gstMoving);
  4794         end;
  4798         end;
  4795 
  4799 
  4796     dec(Gear^.Health, Gear^.Damage);
  4800     dec(Gear^.Health, Gear^.Damage);
  4797     Gear^.Damage:= 0;
  4801     Gear^.Damage:= 0;
  4798         
  4802 
  4799     if Gear^.Pos = 1 then
  4803     if Gear^.Pos = 1 then
  4800         begin
  4804         begin
  4801         AddGearCI(Gear);
  4805         AddGearCI(Gear);
  4802         AfterAttack;
  4806         AfterAttack;
  4803         if Gear = CurAmmoGear then
  4807         if Gear = CurAmmoGear then
  4804             CurAmmoGear:= nil;
  4808             CurAmmoGear:= nil;
  4805         if HH^.Gear <> nil then
  4809         if HH^.Gear <> nil then
  4806             HideHog(HH);
  4810             HideHog(HH);
  4807         Gear^.Pos:= 2
  4811         Gear^.Pos:= 2
  4808         end;
  4812         end;
  4809         
  4813 
  4810     if Gear^.Pos = 2 then
  4814     if Gear^.Pos = 2 then
  4811         begin
  4815         begin
  4812         if ((GameTicks mod 100) = 0) and (Gear^.Timer < 1000) then
  4816         if ((GameTicks mod 100) = 0) and (Gear^.Timer < 1000) then
  4813             begin
  4817             begin
  4814             if (Gear^.Timer mod 10) = 0 then
  4818             if (Gear^.Timer mod 10) = 0 then
  4820             inc(Gear^.Timer);
  4824             inc(Gear^.Timer);
  4821             end;
  4825             end;
  4822         if Gear^.Tag <= TotalRounds then
  4826         if Gear^.Tag <= TotalRounds then
  4823             Gear^.Pos:= 3;
  4827             Gear^.Pos:= 3;
  4824         end;
  4828         end;
  4825         
  4829 
  4826     if Gear^.Pos = 3 then
  4830     if Gear^.Pos = 3 then
  4827         if Gear^.Timer < 1000 then
  4831         if Gear^.Timer < 1000 then
  4828             begin
  4832             begin
  4829             if (Gear^.Timer mod 10) = 0 then
  4833             if (Gear^.Timer mod 10) = 0 then
  4830                 begin
  4834                 begin
  4838             begin
  4842             begin
  4839             if HH^.GearHidden <> nil then
  4843             if HH^.GearHidden <> nil then
  4840                 RestoreHog(HH);
  4844                 RestoreHog(HH);
  4841             Gear^.Pos:= 4;
  4845             Gear^.Pos:= 4;
  4842             end;
  4846             end;
  4843         
  4847 
  4844     if Gear^.Pos = 4 then
  4848     if Gear^.Pos = 4 then
  4845         if ((GameTicks mod 1000) = 0) and ((GameFlags and gfInvulnerable) = 0) then
  4849         if ((GameTicks mod 1000) = 0) and ((GameFlags and gfInvulnerable) = 0) then
  4846             begin
  4850             begin
  4847             t:= GearsList;
  4851             t:= GearsList;
  4848             while t <> nil do
  4852             while t <> nil do
  4850                 if (t^.Kind = gtHedgehog) and (t^.Hedgehog^.Team^.Clan = HH^.Team^.Clan) then
  4854                 if (t^.Kind = gtHedgehog) and (t^.Hedgehog^.Team^.Clan = HH^.Team^.Clan) then
  4851                     t^.Invulnerable:= true;
  4855                     t^.Invulnerable:= true;
  4852                 t:= t^.NextGear;
  4856                 t:= t^.NextGear;
  4853                 end;
  4857                 end;
  4854             end;
  4858             end;
  4855         
  4859 
  4856     if Gear^.Health <= 0 then
  4860     if Gear^.Health <= 0 then
  4857         begin
  4861         begin
  4858         if HH^.GearHidden <> nil then
  4862         if HH^.GearHidden <> nil then
  4859             RestoreHog(HH);
  4863             RestoreHog(HH);
  4860         
  4864 
  4861         x := hwRound(Gear^.X);
  4865         x := hwRound(Gear^.X);
  4862         y := hwRound(Gear^.Y);
  4866         y := hwRound(Gear^.Y);
  4863 
  4867 
  4864         DeleteCI(Gear);
  4868         DeleteCI(Gear);
  4865         DeleteGear(Gear);
  4869         DeleteGear(Gear);
  4868         end;
  4872         end;
  4869 end;
  4873 end;
  4870 
  4874 
  4871 ////////////////////////////////////////////////////////////////////////////////
  4875 ////////////////////////////////////////////////////////////////////////////////
  4872 (*
  4876 (*
  4873  TARDIS needs 
  4877  TARDIS needs
  4874  Warp in.  Pos = 1
  4878  Warp in.  Pos = 1
  4875  Pause.    Pos = 2
  4879  Pause.    Pos = 2
  4876  Hide gear  (TARDIS hedgehog was nil)
  4880  Hide gear  (TARDIS hedgehog was nil)
  4877  Warp out. Pos = 3
  4881  Warp out. Pos = 3
  4878  ... idle active for some time period ...  Pos = 4
  4882  ... idle active for some time period ...  Pos = 4
  4894         begin
  4898         begin
  4895         if (HH^.Gear <> nil) and (HH^.Gear^.State and gstInvisible = 0) then
  4899         if (HH^.Gear <> nil) and (HH^.Gear^.State and gstInvisible = 0) then
  4896             begin
  4900             begin
  4897             AfterAttack;
  4901             AfterAttack;
  4898             if Gear = CurAmmoGear then CurAmmoGear := nil;
  4902             if Gear = CurAmmoGear then CurAmmoGear := nil;
  4899             if (HH^.Gear^.Damage = 0) and  (HH^.Gear^.Health > 0) and 
  4903             if (HH^.Gear^.Damage = 0) and  (HH^.Gear^.Health > 0) and
  4900             ((Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
  4904             ((Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
  4901                 HideHog(HH)
  4905                 HideHog(HH)
  4902             end
  4906             end
  4903         //else if (HH^.Gear <> nil) and (HH^.Gear^.State and gstInvisible <> 0) then
  4907         //else if (HH^.Gear <> nil) and (HH^.Gear^.State and gstInvisible <> 0) then
  4904         else if (HH^.GearHidden <> nil) then// and (HH^.Gear^.State and gstInvisible <> 0) then
  4908         else if (HH^.GearHidden <> nil) then// and (HH^.Gear^.State and gstInvisible <> 0) then
  4914     end;
  4918     end;
  4915 
  4919 
  4916 if (Gear^.Pos = 1) and (GameTicks and $1F = 0) and (Gear^.Power < 255) then
  4920 if (Gear^.Pos = 1) and (GameTicks and $1F = 0) and (Gear^.Power < 255) then
  4917     begin
  4921     begin
  4918     inc(Gear^.Power);
  4922     inc(Gear^.Power);
  4919     if (Gear^.Power = 172) and (HH^.Gear <> nil) and 
  4923     if (Gear^.Power = 172) and (HH^.Gear <> nil) and
  4920         (HH^.Gear^.Damage = 0) and (HH^.Gear^.Health > 0) and
  4924         (HH^.Gear^.Damage = 0) and (HH^.Gear^.Health > 0) and
  4921         ((HH^.Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
  4925         ((HH^.Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
  4922             with HH^.Gear^ do
  4926             with HH^.Gear^ do
  4923                 begin
  4927                 begin
  4924                 State:= State or gstAnimation;
  4928                 State:= State or gstAnimation;
  4955                 inc(cnt);
  4959                 inc(cnt);
  4956     if (cnt = 0) or SuddenDeathDmg or (Gear^.Timer = 0) then
  4960     if (cnt = 0) or SuddenDeathDmg or (Gear^.Timer = 0) then
  4957         begin
  4961         begin
  4958         if HH^.GearHidden <> nil then
  4962         if HH^.GearHidden <> nil then
  4959             FindPlace(HH^.GearHidden, false, 0, LAND_WIDTH,true);
  4963             FindPlace(HH^.GearHidden, false, 0, LAND_WIDTH,true);
  4960             
  4964 
  4961         if HH^.GearHidden <> nil then
  4965         if HH^.GearHidden <> nil then
  4962             begin
  4966             begin
  4963             Gear^.X:= HH^.GearHidden^.X;
  4967             Gear^.X:= HH^.GearHidden^.X;
  4964             Gear^.Y:= HH^.GearHidden^.Y;
  4968             Gear^.Y:= HH^.GearHidden^.Y;
  4965             end;
  4969             end;
  5031 
  5035 
  5032 (*
  5036 (*
  5033 WIP. The ice gun will have the following effects.  It has been proposed by sheepluva that it take the appearance of a large freezer
  5037 WIP. The ice gun will have the following effects.  It has been proposed by sheepluva that it take the appearance of a large freezer
  5034 spewing ice cubes.  The cubes will be visual gears only.  The scatter from them and the impact snow dust should help hide imprecisions in things like the GearsNear effect.
  5038 spewing ice cubes.  The cubes will be visual gears only.  The scatter from them and the impact snow dust should help hide imprecisions in things like the GearsNear effect.
  5035 For now we assume a "ray" like a deagle projected out from the gun.
  5039 For now we assume a "ray" like a deagle projected out from the gun.
  5036 All these effects assume the ray's angle is not changed and that the target type was unchanged over a number of ticks.  This is a simplifying assumption for "gun was applying freezing effect to the same target".  
  5040 All these effects assume the ray's angle is not changed and that the target type was unchanged over a number of ticks.  This is a simplifying assumption for "gun was applying freezing effect to the same target".
  5037   * When fired at water a layer of ice textured land is added above the water.
  5041   * When fired at water a layer of ice textured land is added above the water.
  5038   * When fired at non-ice land (land and $FF00 and not lfIce) the land is overlaid with a thin layer of ice textured land around that point (say, 1 or 2px into land, 1px above). For attractiveness, a slope would probably be needed.
  5042   * When fired at non-ice land (land and $FF00 and not lfIce) the land is overlaid with a thin layer of ice textured land around that point (say, 1 or 2px into land, 1px above). For attractiveness, a slope would probably be needed.
  5039   * When fired at a hog (land and $00FF <> 0), while the hog is targetted, the hog's state is set to frozen.  As long as the gun is on the hog, a frozen hog sprite creeps up from the feet to the head.  If the effect is interrupted before reaching the top, the freezing state is cleared.
  5043   * When fired at a hog (land and $00FF <> 0), while the hog is targetted, the hog's state is set to frozen.  As long as the gun is on the hog, a frozen hog sprite creeps up from the feet to the head.  If the effect is interrupted before reaching the top, the freezing state is cleared.
  5040 A frozen hog will animate differently.  To be decided, but possibly in a similar fashion to a grave when it comes to explosions.  The hog might (possibly) not be damaged by explosions.  This might make freezing potentially useful for friendlies in a bad position.  It might be better to allow damage though.
  5044 A frozen hog will animate differently.  To be decided, but possibly in a similar fashion to a grave when it comes to explosions.  The hog might (possibly) not be damaged by explosions.  This might make freezing potentially useful for friendlies in a bad position.  It might be better to allow damage though.
  5041 A frozen hog stays frozen for a certain number of turns. Each turn the frozen overlay becomes fainter, until it fades and the hog animates normally again.
  5045 A frozen hog stays frozen for a certain number of turns. Each turn the frozen overlay becomes fainter, until it fades and the hog animates normally again.
  5071     with Gear^ do
  5075     with Gear^ do
  5072         begin
  5076         begin
  5073         HedgehogChAngle(HHGear);
  5077         HedgehogChAngle(HHGear);
  5074         ndX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _4;
  5078         ndX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _4;
  5075         ndY:= -AngleCos(HHGear^.Angle) * _4;
  5079         ndY:= -AngleCos(HHGear^.Angle) * _4;
  5076         if (ndX <> dX) or (ndY <> dY) or 
  5080         if (ndX <> dX) or (ndY <> dY) or
  5077            ((Target.X <> NoPointX) and (Target.X and LAND_WIDTH_MASK = 0) and 
  5081            ((Target.X <> NoPointX) and (Target.X and LAND_WIDTH_MASK = 0) and
  5078              (Target.Y and LAND_HEIGHT_MASK = 0) and ((Land[Target.Y, Target.X] = 0))) then
  5082              (Target.Y and LAND_HEIGHT_MASK = 0) and ((Land[Target.Y, Target.X] = 0))) then
  5079             begin
  5083             begin
  5080             dX:= ndX;
  5084             dX:= ndX;
  5081             dY:= ndY;
  5085             dY:= ndY;
  5082             Pos:= 0;
  5086             Pos:= 0;
  5086             Y:= HHGear^.Y;
  5090             Y:= HHGear^.Y;
  5087 (* unfreeze all semifrozen hogs - make this generic hog cleanup
  5091 (* unfreeze all semifrozen hogs - make this generic hog cleanup
  5088             iter := GearsList;
  5092             iter := GearsList;
  5089             while iter <> nil do
  5093             while iter <> nil do
  5090                 begin
  5094                 begin
  5091                 if (iter^.Kind = gtHedgehog) and 
  5095                 if (iter^.Kind = gtHedgehog) and
  5092                    (iter^.Hedgehog^.Effects[heFrozen] < 0) then 
  5096                    (iter^.Hedgehog^.Effects[heFrozen] < 0) then
  5093                     iter^.Hedgehog^.Effects[heFrozen]:= 0;
  5097                     iter^.Hedgehog^.Effects[heFrozen]:= 0;
  5094                 iter:= iter^.NextGear
  5098                 iter:= iter^.NextGear
  5095                 end *)
  5099                 end *)
  5096             end
  5100             end
  5097         else
  5101         else
  5209         begin
  5213         begin
  5210         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 300, CurrentHedgehog, EXPLAutoSound);
  5214         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 300, CurrentHedgehog, EXPLAutoSound);
  5211         DeleteGear(Gear)
  5215         DeleteGear(Gear)
  5212         end;
  5216         end;
  5213     // ssssss he essssscaped
  5217     // ssssss he essssscaped
  5214     if (Gear^.Timer > 250) and ((HHGear = nil) or 
  5218     if (Gear^.Timer > 250) and ((HHGear = nil) or
  5215             (((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) >  180) and
  5219             (((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) >  180) and
  5216             (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > _180))) then
  5220             (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > _180))) then
  5217         begin
  5221         begin
  5218         Gear^.State:= Gear^.State and (not gstTmpFlag);
  5222         Gear^.State:= Gear^.State and (not gstTmpFlag);
  5219         Gear^.Timer:= 0
  5223         Gear^.Timer:= 0
  5220         end;
  5224         end;
  5221     exit
  5225     exit
  5222     end;
  5226     end;
  5223 
  5227 
  5224 // Search out a new target, as target seek time has expired, target is dead, target is out of range, or we did not have a target
  5228 // Search out a new target, as target seek time has expired, target is dead, target is out of range, or we did not have a target
  5225 if (HHGear = nil) or (Gear^.Timer = 0) or 
  5229 if (HHGear = nil) or (Gear^.Timer = 0) or
  5226    (((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) >  Gear^.Angle) and
  5230    (((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) >  Gear^.Angle) and
  5227         (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > int2hwFloat(Gear^.Angle)))
  5231         (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > int2hwFloat(Gear^.Angle)))
  5228     then
  5232     then
  5229     begin
  5233     begin
  5230     hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Angle);
  5234     hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Angle);
  5337 end;
  5341 end;
  5338 (*
  5342 (*
  5339  This didn't end up getting used, but, who knows, might be reasonable for javellin or something
  5343  This didn't end up getting used, but, who knows, might be reasonable for javellin or something
  5340 // Make the knife initial angle based on the hog attack angle, or is that too hard?
  5344 // Make the knife initial angle based on the hog attack angle, or is that too hard?
  5341 procedure doStepKnife(Gear: PGear);
  5345 procedure doStepKnife(Gear: PGear);
  5342 var t, 
  5346 var t,
  5343     gx, gy, ga,  // gear x,y,angle
  5347     gx, gy, ga,  // gear x,y,angle
  5344     lx, ly, la, // land x,y,angle
  5348     lx, ly, la, // land x,y,angle
  5345     ox, oy, // x,y offset
  5349     ox, oy, // x,y offset
  5346     w, h,   // wXh of clip area
  5350     w, h,   // wXh of clip area
  5347     tx, ty  // tip position in sprite
  5351     tx, ty  // tip position in sprite
  5361     if Gear^.State and gstDrowning <> 0 then exit;
  5365     if Gear^.State and gstDrowning <> 0 then exit;
  5362     with Gear^ do
  5366     with Gear^ do
  5363         begin
  5367         begin
  5364         if CheckLandValue(gx, gy, $FF00) then
  5368         if CheckLandValue(gx, gy, $FF00) then
  5365             begin
  5369             begin
  5366             t:= Angle + hwRound((hwAbs(dX)+hwAbs(dY)) * _10); 
  5370             t:= Angle + hwRound((hwAbs(dX)+hwAbs(dY)) * _10);
  5367 
  5371 
  5368             if t < 0 then inc(t, 4096)
  5372             if t < 0 then inc(t, 4096)
  5369             else if 4095 < t then dec(t, 4096);
  5373             else if 4095 < t then dec(t, 4096);
  5370             Angle:= t;
  5374             Angle:= t;
  5371 
  5375 
  5398                     tx:=   0; ty:= 14
  5402                     tx:=   0; ty:= 14
  5399                     end;
  5403                     end;
  5400                 4:  begin
  5404                 4:  begin
  5401                     ox:= 29; oy:=  8;
  5405                     ox:= 29; oy:=  8;
  5402                      w:= 19;  h:= 19;
  5406                      w:= 19;  h:= 19;
  5403                     tx:=  0; ty:= 17 
  5407                     tx:=  0; ty:= 17
  5404                     end;
  5408                     end;
  5405                 5:  begin
  5409                 5:  begin
  5406                     ox:= 29; oy:=  32;
  5410                     ox:= 29; oy:=  32;
  5407                      w:= 15;  h:=  21;
  5411                      w:= 15;  h:=  21;
  5408                     tx:=  0; ty:=  20
  5412                     tx:=  0; ty:=  20
  5409                     end;
  5413                     end;
  5410                 6:  begin
  5414                 6:  begin
  5411                     ox:= 51; oy:=   3;
  5415                     ox:= 51; oy:=   3;
  5412                      w:= 11;  h:=  23;
  5416                      w:= 11;  h:=  23;
  5413                     tx:=  0; ty:=  22 
  5417                     tx:=  0; ty:=  22
  5414                     end;
  5418                     end;
  5415                 7:  begin
  5419                 7:  begin
  5416                     ox:= 51; oy:=  34;
  5420                     ox:= 51; oy:=  34;
  5417                      w:=  7;  h:=  24;
  5421                      w:=  7;  h:=  24;
  5418                     tx:=  0; ty:=  23
  5422                     tx:=  0; ty:=  23
  5419                     end
  5423                     end
  5420                 end;
  5424                 end;
  5421                 
  5425 
  5422             surf:= SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RMask, GMask, BMask, AMask);
  5426             surf:= SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RMask, GMask, BMask, AMask);
  5423             copyToXYFromRect(SpritesData[sprKnife].Surface, surf, ox, oy, w, h, 0, 0);
  5427             copyToXYFromRect(SpritesData[sprKnife].Surface, surf, ox, oy, w, h, 0, 0);
  5424             // try to make the knife hit point first
  5428             // try to make the knife hit point first
  5425             lx := 0;
  5429             lx := 0;
  5426             ly := 0;
  5430             ly := 0;
  5438                     else if Angle < 2048 then inc(Angle, 2048)
  5442                     else if Angle < 2048 then inc(Angle, 2048)
  5439                     end;
  5443                     end;
  5440                 AddFileLog('la: '+inttostr(la)+' ga: '+inttostr(ga)+' Angle: '+inttostr(Angle))
  5444                 AddFileLog('la: '+inttostr(la)+' ga: '+inttostr(ga)+' Angle: '+inttostr(Angle))
  5441                 end;
  5445                 end;
  5442             case Angle div 1024 of
  5446             case Angle div 1024 of
  5443                 0:  begin 
  5447                 0:  begin
  5444                     flipSurface(surf, true);
  5448                     flipSurface(surf, true);
  5445                     flipSurface(surf, true);
  5449                     flipSurface(surf, true);
  5446                     BlitImageAndGenerateCollisionInfo(gx-(w-tx), gy-(h-ty), w, surf)
  5450                     BlitImageAndGenerateCollisionInfo(gx-(w-tx), gy-(h-ty), w, surf)
  5447                     end;
  5451                     end;
  5448                 1:  begin
  5452                 1:  begin