hedgewars/GSHandlers.inc
changeset 8795 b5b79a8f9354
parent 8793 43e106417a05
parent 8774 39754516eee6
child 8812 fdac638c6f9a
equal deleted inserted replaced
8793:43e106417a05 8795:b5b79a8f9354
    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) and (gi^.Hedgehog^.Effects[heFrozen] = 0) then
    95                     if ((gi^.State and gstMoving) = 0) and (gi^.Hedgehog^.Effects[heFrozen] = 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, gdX: hwFloat;
   301     dX, dY, gdX: 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                 gdX:= Gear^.dX;
   341                 gdX:= Gear^.dX;
   342                 doMakeExplosion(x, y, 20, Gear^.Hedgehog, EXPLAutoSound);
   342                 doMakeExplosion(x, y, 20, Gear^.Hedgehog, EXPLAutoSound);
   345                     dX := rndSign(GetRandomf * _0_1) + gdX / 5;
   345                     dX := rndSign(GetRandomf * _0_1) + gdX / 5;
   346                     dY := (GetRandomf - _3) * _0_08;
   346                     dY := (GetRandomf - _3) * _0_08;
   347                     FollowGear := AddGear(x, y, gtCluster, 0, dX, dY, 25)
   347                     FollowGear := AddGear(x, y, gtCluster, 0, dX, dY, 25)
   348                     end
   348                     end
   349                 end;
   349                 end;
   350             gtWatermelon: 
   350             gtWatermelon:
   351                 begin
   351                 begin
   352                 x := hwRound(Gear^.X);
   352                 x := hwRound(Gear^.X);
   353                 y := hwRound(Gear^.Y);
   353                 y := hwRound(Gear^.Y);
   354                 gdX:= Gear^.dX;
   354                 gdX:= Gear^.dX;
   355                 doMakeExplosion(x, y, 75, Gear^.Hedgehog, EXPLAutoSound);
   355                 doMakeExplosion(x, y, 75, Gear^.Hedgehog, EXPLAutoSound);
   359                     dY := (GetRandomf - _1_5) * _0_3;
   359                     dY := (GetRandomf - _1_5) * _0_3;
   360                     FollowGear:= AddGear(x, y, gtMelonPiece, 0, dX, dY, 75);
   360                     FollowGear:= AddGear(x, y, gtMelonPiece, 0, dX, dY, 75);
   361                     FollowGear^.DirAngle := i * 60
   361                     FollowGear^.DirAngle := i * 60
   362                     end
   362                     end
   363                 end;
   363                 end;
   364             gtHellishBomb: 
   364             gtHellishBomb:
   365                 begin
   365                 begin
   366                 x := hwRound(Gear^.X);
   366                 x := hwRound(Gear^.X);
   367                 y := hwRound(Gear^.Y);
   367                 y := hwRound(Gear^.Y);
   368                 doMakeExplosion(x, y, 90, Gear^.Hedgehog, EXPLAutoSound);
   368                 doMakeExplosion(x, y, 90, Gear^.Hedgehog, EXPLAutoSound);
   369 
   369 
   375                         begin
   375                         begin
   376                         AddGear(x, y, gtFlame, gstTmpFlag, dX, dY, 0);
   376                         AddGear(x, y, gtFlame, gstTmpFlag, dX, dY, 0);
   377                         AddGear(x, y, gtFlame, 0, dX, -dY, 0)
   377                         AddGear(x, y, gtFlame, 0, dX, -dY, 0)
   378                         end
   378                         end
   379                     else
   379                     else
   380                         begin 
   380                         begin
   381                         AddGear(x, y, gtFlame, 0, dX, dY, 0);
   381                         AddGear(x, y, gtFlame, 0, dX, dY, 0);
   382                         AddGear(x, y, gtFlame, gstTmpFlag, dX, -dY, 0)
   382                         AddGear(x, y, gtFlame, gstTmpFlag, dX, -dY, 0)
   383                         end;
   383                         end;
   384                     end
   384                     end
   385                 end;
   385                 end;
   415         end;
   415         end;
   416 end;
   416 end;
   417 
   417 
   418 ////////////////////////////////////////////////////////////////////////////////
   418 ////////////////////////////////////////////////////////////////////////////////
   419 procedure doStepMolotov(Gear: PGear);
   419 procedure doStepMolotov(Gear: PGear);
   420 var 
   420 var
   421     s: Longword;
   421     s: Longword;
   422     i, gX, gY: LongInt;
   422     i, gX, gY: LongInt;
   423     dX, dY: hwFloat;
   423     dX, dY: hwFloat;
   424     smoke, glass: PVisualGear;
   424     smoke, glass: PVisualGear;
   425 begin
   425 begin
   435         // adjust angle to match the texture
   435         // adjust angle to match the texture
   436         if Gear^.dX.isNegative then
   436         if Gear^.dX.isNegative then
   437             i:= 130
   437             i:= 130
   438         else
   438         else
   439             i:= 50;
   439             i:= 50;
   440             
   440 
   441         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);
   441         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);
   442         if smoke <> nil then
   442         if smoke <> nil then
   443             smoke^.Scale:= 0.75;
   443             smoke^.Scale:= 0.75;
   444         end;
   444         end;
   445 
   445 
   695                         end
   695                         end
   696                     else allpx:= false
   696                     else allpx:= false
   697                     end;
   697                     end;
   698                 p:= @(p^[s^.pitch shr 2])
   698                 p:= @(p^[s^.pitch shr 2])
   699                 end;
   699                 end;
   700             
   700 
   701             // Why is this here.  For one thing, there's no test on +1 being safe. 
   701             // Why is this here.  For one thing, there's no test on +1 being safe.
   702             //Land[py, px+1]:= lfBasic;
   702             //Land[py, px+1]:= lfBasic;
   703             
   703 
   704             if allpx then
   704             if allpx then
   705                 UpdateLandTexture(xx, Pred(s^.h), yy, Pred(s^.w), true)
   705                 UpdateLandTexture(xx, Pred(s^.h), yy, Pred(s^.w), true)
   706             else
   706             else
   707                 begin
   707                 begin
   708                 UpdateLandTexture(
   708                 UpdateLandTexture(
   763     Gear^.dY := Gear^.dY + cGravity
   763     Gear^.dY := Gear^.dY + cGravity
   764 end;
   764 end;
   765 
   765 
   766 ////////////////////////////////////////////////////////////////////////////////
   766 ////////////////////////////////////////////////////////////////////////////////
   767 procedure doStepBeeWork(Gear: PGear);
   767 procedure doStepBeeWork(Gear: PGear);
   768 var 
   768 var
   769     t: hwFloat;
   769     t: hwFloat;
   770     gX,gY,i: LongInt;
   770     gX,gY,i: LongInt;
   771     uw, nuw: boolean;
   771     uw, nuw: boolean;
   772     flower: PVisualGear;
   772     flower: PVisualGear;
   773 
   773 
   878     if Gear^.Timer = 0 then
   878     if Gear^.Timer = 0 then
   879         begin
   879         begin
   880         Gear^.Hedgehog^.Gear^.Message:= Gear^.Hedgehog^.Gear^.Message and (not gmAttack);
   880         Gear^.Hedgehog^.Gear^.Message:= Gear^.Hedgehog^.Gear^.Message and (not gmAttack);
   881         Gear^.Hedgehog^.Gear^.State:= Gear^.Hedgehog^.Gear^.State and (not gstAttacking);
   881         Gear^.Hedgehog^.Gear^.State:= Gear^.Hedgehog^.Gear^.State and (not gstAttacking);
   882         AttackBar:= 0;
   882         AttackBar:= 0;
   883         
   883 
   884         Gear^.SoundChannel := LoopSound(sndBee);
   884         Gear^.SoundChannel := LoopSound(sndBee);
   885         Gear^.Timer := 5000;
   885         Gear^.Timer := 5000;
   886         // save initial speed in otherwise unused Friction variable
   886         // save initial speed in otherwise unused Friction variable
   887         Gear^.Friction := Distance(Gear^.dX, Gear^.dY);
   887         Gear^.Friction := Distance(Gear^.dX, Gear^.dY);
   888         Gear^.doStep := @doStepBeeWork
   888         Gear^.doStep := @doStepBeeWork
   900         AfterAttack
   900         AfterAttack
   901         end
   901         end
   902 end;
   902 end;
   903 
   903 
   904 procedure doStepShotgunShot(Gear: PGear);
   904 procedure doStepShotgunShot(Gear: PGear);
   905 var 
   905 var
   906     i: LongWord;
   906     i: LongWord;
   907     shell: PVisualGear;
   907     shell: PVisualGear;
   908 begin
   908 begin
   909     AllInactive := false;
   909     AllInactive := false;
   910 
   910 
   976         oy:= Bullet^.Friction;
   976         oy:= Bullet^.Friction;
   977         end;
   977         end;
   978 
   978 
   979         // Bullet trail
   979         // Bullet trail
   980         VGear := AddVisualGear(hwRound(ox), hwRound(oy), vgtLineTrail);
   980         VGear := AddVisualGear(hwRound(ox), hwRound(oy), vgtLineTrail);
   981         
   981 
   982         if VGear <> nil then
   982         if VGear <> nil then
   983             begin
   983             begin
   984             VGear^.X:= hwFloat2Float(ox);
   984             VGear^.X:= hwFloat2Float(ox);
   985             VGear^.Y:= hwFloat2Float(oy);
   985             VGear^.Y:= hwFloat2Float(oy);
   986             VGear^.dX:= hwFloat2Float(Bullet^.X);
   986             VGear^.dX:= hwFloat2Float(Bullet^.X);
   999             VGear^.Timer := 200;
   999             VGear^.Timer := 200;
  1000             end;
  1000             end;
  1001 end;
  1001 end;
  1002 
  1002 
  1003 procedure doStepBulletWork(Gear: PGear);
  1003 procedure doStepBulletWork(Gear: PGear);
  1004 var 
  1004 var
  1005     i, x, y: LongWord;
  1005     i, x, y: LongWord;
  1006     oX, oY: hwFloat;
  1006     oX, oY: hwFloat;
  1007     VGear: PVisualGear;
  1007     VGear: PVisualGear;
  1008 begin
  1008 begin
  1009     AllInactive := false;
  1009     AllInactive := false;
  1014     repeat
  1014     repeat
  1015         Gear^.X := Gear^.X + Gear^.dX;
  1015         Gear^.X := Gear^.X + Gear^.dX;
  1016         Gear^.Y := Gear^.Y + Gear^.dY;
  1016         Gear^.Y := Gear^.Y + Gear^.dY;
  1017         x := hwRound(Gear^.X);
  1017         x := hwRound(Gear^.X);
  1018         y := hwRound(Gear^.Y);
  1018         y := hwRound(Gear^.Y);
  1019         
  1019 
  1020         if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] <> 0) then
  1020         if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] <> 0) then
  1021             inc(Gear^.Damage);
  1021             inc(Gear^.Damage);
  1022         // let's interrupt before a collision to give portals a chance to catch the bullet
  1022         // let's interrupt before a collision to give portals a chance to catch the bullet
  1023         if (Gear^.Damage = 1) and (Gear^.Tag = 0) and not(CheckLandValue(x, y, lfLandMask)) then
  1023         if (Gear^.Damage = 1) and (Gear^.Tag = 0) and not(CheckLandValue(x, y, lfLandMask)) then
  1024             begin
  1024             begin
  1036             if Gear^.AmmoType = amDEagle then
  1036             if Gear^.AmmoType = amDEagle then
  1037                 AmmoShove(Gear, 7, 20)
  1037                 AmmoShove(Gear, 7, 20)
  1038         else
  1038         else
  1039             AmmoShove(Gear, Gear^.Timer, 20);
  1039             AmmoShove(Gear, Gear^.Timer, 20);
  1040         CheckGearDrowning(Gear);
  1040         CheckGearDrowning(Gear);
  1041         dec(i) 
  1041         dec(i)
  1042     until (i = 0) or (Gear^.Damage > Gear^.Health) or ((Gear^.State and gstDrowning) <> 0);
  1042     until (i = 0) or (Gear^.Damage > Gear^.Health) or ((Gear^.State and gstDrowning) <> 0);
  1043 
  1043 
  1044     if Gear^.Damage > 0 then
  1044     if Gear^.Damage > 0 then
  1045         begin
  1045         begin
  1046         DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 82 - i, 1);
  1046         DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 82 - i, 1);
  1064             begin
  1064             begin
  1065             if (Gear^.Kind = gtSniperRifleShot) and ((GameFlags and gfLaserSight) = 0) then
  1065             if (Gear^.Kind = gtSniperRifleShot) and ((GameFlags and gfLaserSight) = 0) then
  1066                 cLaserSighting := false;
  1066                 cLaserSighting := false;
  1067             if (Ammoz[Gear^.AmmoType].Ammo.NumPerTurn <= CurrentHedgehog^.MultiShootAttacks) and ((GameFlags and gfArtillery) = 0) then
  1067             if (Ammoz[Gear^.AmmoType].Ammo.NumPerTurn <= CurrentHedgehog^.MultiShootAttacks) and ((GameFlags and gfArtillery) = 0) then
  1068                 cArtillery := false;
  1068                 cArtillery := false;
  1069         
  1069 
  1070         // Bullet Hit
  1070         // Bullet Hit
  1071             if (hwRound(Gear^.X) and LAND_WIDTH_MASK = 0) and (hwRound(Gear^.Y) and LAND_HEIGHT_MASK = 0) then
  1071             if (hwRound(Gear^.X) and LAND_WIDTH_MASK = 0) and (hwRound(Gear^.Y) and LAND_HEIGHT_MASK = 0) then
  1072                 begin
  1072                 begin
  1073                 VGear := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBulletHit);
  1073                 VGear := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBulletHit);
  1074                 if VGear <> nil then
  1074                 if VGear <> nil then
  1075                     begin
  1075                     begin
  1076                     VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY);
  1076                     VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY);
  1077                     end;
  1077                     end;
  1078                 end;
  1078                 end;
  1079        
  1079 
  1080             spawnBulletTrail(Gear);
  1080             spawnBulletTrail(Gear);
  1081             Gear^.doStep := @doStepShotIdle
  1081             Gear^.doStep := @doStepShotIdle
  1082             end;
  1082             end;
  1083 end;
  1083 end;
  1084 
  1084 
  1090     Gear^.Y := Gear^.Y + Gear^.dY * 3;
  1090     Gear^.Y := Gear^.Y + Gear^.dY * 3;
  1091     Gear^.doStep := @doStepBulletWork
  1091     Gear^.doStep := @doStepBulletWork
  1092 end;
  1092 end;
  1093 
  1093 
  1094 procedure doStepSniperRifleShot(Gear: PGear);
  1094 procedure doStepSniperRifleShot(Gear: PGear);
  1095 var 
  1095 var
  1096     HHGear: PGear;
  1096     HHGear: PGear;
  1097     shell: PVisualGear;
  1097     shell: PVisualGear;
  1098 begin
  1098 begin
  1099     cArtillery := true;
  1099     cArtillery := true;
  1100     HHGear := Gear^.Hedgehog^.Gear;
  1100     HHGear := Gear^.Hedgehog^.Gear;
  1121         Gear^.State := Gear^.State or gstAnimation;
  1121         Gear^.State := Gear^.State or gstAnimation;
  1122         Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _0_5;
  1122         Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _0_5;
  1123         Gear^.dY := -AngleCos(HHGear^.Angle) * _0_5;
  1123         Gear^.dY := -AngleCos(HHGear^.Angle) * _0_5;
  1124         PlaySound(sndGun);
  1124         PlaySound(sndGun);
  1125         // add 3 initial steps to avoid problem with ammoshove related to calculation of radius + 1 radius as gear widths, and also just weird angles
  1125         // add 3 initial steps to avoid problem with ammoshove related to calculation of radius + 1 radius as gear widths, and also just weird angles
  1126         Gear^.X := Gear^.X + Gear^.dX * 3;  
  1126         Gear^.X := Gear^.X + Gear^.dX * 3;
  1127         Gear^.Y := Gear^.Y + Gear^.dY * 3;
  1127         Gear^.Y := Gear^.Y + Gear^.dY * 3;
  1128         Gear^.doStep := @doStepBulletWork;
  1128         Gear^.doStep := @doStepBulletWork;
  1129         end
  1129         end
  1130     else
  1130     else
  1131         if (GameTicks mod 32) = 0 then
  1131         if (GameTicks mod 32) = 0 then
  1150 ////////////////////////////////////////////////////////////////////////////////
  1150 ////////////////////////////////////////////////////////////////////////////////
  1151 procedure doStepActionTimer(Gear: PGear);
  1151 procedure doStepActionTimer(Gear: PGear);
  1152 begin
  1152 begin
  1153 dec(Gear^.Timer);
  1153 dec(Gear^.Timer);
  1154 case Gear^.Kind of
  1154 case Gear^.Kind of
  1155     gtATStartGame: 
  1155     gtATStartGame:
  1156         begin
  1156         begin
  1157         AllInactive := false;
  1157         AllInactive := false;
  1158         if Gear^.Timer = 0 then
  1158         if Gear^.Timer = 0 then
  1159             begin
  1159             begin
  1160             AddCaption(trmsg[sidStartFight], cWhiteColor, capgrpGameState);
  1160             AddCaption(trmsg[sidStartFight], cWhiteColor, capgrpGameState);
  1161             end
  1161             end
  1162         end;
  1162         end;
  1163     gtATFinishGame: 
  1163     gtATFinishGame:
  1164         begin
  1164         begin
  1165         AllInactive := false;
  1165         AllInactive := false;
  1166         if Gear^.Timer = 1000 then
  1166         if Gear^.Timer = 1000 then
  1167             begin
  1167             begin
  1168             ScreenFade := sfToBlack;
  1168             ScreenFade := sfToBlack;
  1181     DeleteGear(Gear)
  1181     DeleteGear(Gear)
  1182 end;
  1182 end;
  1183 
  1183 
  1184 ////////////////////////////////////////////////////////////////////////////////
  1184 ////////////////////////////////////////////////////////////////////////////////
  1185 procedure doStepPickHammerWork(Gear: PGear);
  1185 procedure doStepPickHammerWork(Gear: PGear);
  1186 var 
  1186 var
  1187     i, ei, x, y: LongInt;
  1187     i, ei, x, y: LongInt;
  1188     HHGear: PGear;
  1188     HHGear: PGear;
  1189 begin
  1189 begin
  1190     AllInactive := false;
  1190     AllInactive := false;
  1191     HHGear := Gear^.Hedgehog^.Gear;
  1191     HHGear := Gear^.Hedgehog^.Gear;
  1272             Gear^.dX := _0_3
  1272             Gear^.dX := _0_3
  1273     else Gear^.dX := _0;
  1273     else Gear^.dX := _0;
  1274 end;
  1274 end;
  1275 
  1275 
  1276 procedure doStepPickHammer(Gear: PGear);
  1276 procedure doStepPickHammer(Gear: PGear);
  1277 var 
  1277 var
  1278     i, y: LongInt;
  1278     i, y: LongInt;
  1279     ar: TRangeArray;
  1279     ar: TRangeArray;
  1280     HHGear: PGear;
  1280     HHGear: PGear;
  1281 begin
  1281 begin
  1282     i := 0;
  1282     i := 0;
  1299     doStepPickHammerWork(Gear);
  1299     doStepPickHammerWork(Gear);
  1300     Gear^.doStep := @doStepPickHammerWork
  1300     Gear^.doStep := @doStepPickHammerWork
  1301 end;
  1301 end;
  1302 
  1302 
  1303 ////////////////////////////////////////////////////////////////////////////////
  1303 ////////////////////////////////////////////////////////////////////////////////
  1304 var 
  1304 var
  1305     BTPrevAngle, BTSteps: LongInt;
  1305     BTPrevAngle, BTSteps: LongInt;
  1306 
  1306 
  1307 procedure doStepBlowTorchWork(Gear: PGear);
  1307 procedure doStepBlowTorchWork(Gear: PGear);
  1308 var 
  1308 var
  1309     HHGear: PGear;
  1309     HHGear: PGear;
  1310     b: boolean;
  1310     b: boolean;
  1311     prevX: LongInt;
  1311     prevX: LongInt;
  1312 begin
  1312 begin
  1313     AllInactive := false;
  1313     AllInactive := false;
  1314     dec(Gear^.Timer);
  1314     dec(Gear^.Timer);
  1315     if ((GameFlags and gfInfAttack) <> 0) and (TurnTimeLeft > 0) then
  1315     if ((GameFlags and gfInfAttack) <> 0) and (TurnTimeLeft > 0) then
  1316         dec(TurnTimeLeft);
  1316         dec(TurnTimeLeft);
  1317     
  1317 
  1318     HHGear := Gear^.Hedgehog^.Gear;
  1318     HHGear := Gear^.Hedgehog^.Gear;
  1319 
  1319 
  1320     HedgehogChAngle(HHGear);
  1320     HedgehogChAngle(HHGear);
  1321 
  1321 
  1322     b := false;
  1322     b := false;
  1393         AfterAttack
  1393         AfterAttack
  1394         end
  1394         end
  1395 end;
  1395 end;
  1396 
  1396 
  1397 procedure doStepBlowTorch(Gear: PGear);
  1397 procedure doStepBlowTorch(Gear: PGear);
  1398 var 
  1398 var
  1399     HHGear: PGear;
  1399     HHGear: PGear;
  1400 begin
  1400 begin
  1401     BTPrevAngle := High(LongInt);
  1401     BTPrevAngle := High(LongInt);
  1402     BTSteps := 0;
  1402     BTSteps := 0;
  1403     HHGear := Gear^.Hedgehog^.Gear;
  1403     HHGear := Gear^.Hedgehog^.Gear;
  1441             inc(Gear^.Damage, hwRound(Gear^.dX * _70))
  1441             inc(Gear^.Damage, hwRound(Gear^.dX * _70))
  1442         else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
  1442         else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
  1443             inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
  1443             inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
  1444         else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
  1444         else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
  1445             inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
  1445             inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
  1446         
  1446 
  1447         if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then
  1447         if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then
  1448             begin
  1448             begin
  1449             vg:= AddVisualGear(hwRound(Gear^.X) - 4  + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
  1449             vg:= AddVisualGear(hwRound(Gear^.X) - 4  + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
  1450             if vg <> nil then
  1450             if vg <> nil then
  1451                 vg^.Scale:= 0.5
  1451                 vg^.Scale:= 0.5
  1503 
  1503 
  1504 ////////////////////////////////////////////////////////////////////////////////
  1504 ////////////////////////////////////////////////////////////////////////////////
  1505 procedure doStepSMine(Gear: PGear);
  1505 procedure doStepSMine(Gear: PGear);
  1506 begin
  1506 begin
  1507     // TODO: do real calculation?
  1507     // TODO: do real calculation?
  1508     if TestCollisionXwithGear(Gear, 2) 
  1508     if TestCollisionXwithGear(Gear, 2)
  1509     or (TestCollisionYwithGear(Gear, -2) <> 0) 
  1509     or (TestCollisionYwithGear(Gear, -2) <> 0)
  1510     or TestCollisionXwithGear(Gear, -2) 
  1510     or TestCollisionXwithGear(Gear, -2)
  1511     or (TestCollisionYwithGear(Gear, 2) <> 0) then
  1511     or (TestCollisionYwithGear(Gear, 2) <> 0) then
  1512         begin
  1512         begin
  1513         if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
  1513         if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
  1514             begin
  1514             begin
  1515             PlaySound(sndRopeAttach);
  1515             PlaySound(sndRopeAttach);
  1580 TODO
  1580 TODO
  1581 Increase damage as barrel smokes?
  1581 Increase damage as barrel smokes?
  1582 Try tweaking friction some more
  1582 Try tweaking friction some more
  1583 *)
  1583 *)
  1584 procedure doStepRollingBarrel(Gear: PGear);
  1584 procedure doStepRollingBarrel(Gear: PGear);
  1585 var 
  1585 var
  1586     i: LongInt;
  1586     i: LongInt;
  1587     particle: PVisualGear;
  1587     particle: PVisualGear;
  1588 begin
  1588 begin
  1589     if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then
  1589     if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then
  1590         SetLittle(Gear^.dY);
  1590         SetLittle(Gear^.dY);
  1591     Gear^.State := Gear^.State or gstAnimation;
  1591     Gear^.State := Gear^.State or gstAnimation;
  1592     
  1592 
  1593     if ((Gear^.dX.QWordValue <> 0)
  1593     if ((Gear^.dX.QWordValue <> 0)
  1594     or (Gear^.dY.QWordValue <> 0))  then
  1594     or (Gear^.dY.QWordValue <> 0))  then
  1595         begin
  1595         begin
  1596         DeleteCI(Gear);
  1596         DeleteCI(Gear);
  1597         AllInactive := false;
  1597         AllInactive := false;
  1606                     particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
  1606                     particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
  1607                 end
  1607                 end
  1608             end
  1608             end
  1609         else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then
  1609         else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then
  1610                 inc(Gear^.Damage, hwRound(Gear^.dX * _70))
  1610                 inc(Gear^.Damage, hwRound(Gear^.dX * _70))
  1611                 
  1611 
  1612         else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
  1612         else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
  1613                 inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
  1613                 inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
  1614                 
  1614 
  1615         else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
  1615         else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
  1616                 inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
  1616                 inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
  1617 
  1617 
  1618         doStepFallingGear(Gear);
  1618         doStepFallingGear(Gear);
  1619         CalcRotationDirAngle(Gear);
  1619         CalcRotationDirAngle(Gear);
  1658     // Hand off to doStepCase for the explosion
  1658     // Hand off to doStepCase for the explosion
  1659 
  1659 
  1660 end;
  1660 end;
  1661 
  1661 
  1662 procedure doStepCase(Gear: PGear);
  1662 procedure doStepCase(Gear: PGear);
  1663 var 
  1663 var
  1664     i, x, y: LongInt;
  1664     i, x, y: LongInt;
  1665     k: TGearType;
  1665     k: TGearType;
  1666     exBoom: boolean;
  1666     exBoom: boolean;
  1667     dX, dY: HWFloat;
  1667     dX, dY: HWFloat;
  1668     hog: PHedgehog;
  1668     hog: PHedgehog;
  1699         Gear^.Damage := 0;
  1699         Gear^.Damage := 0;
  1700         if Gear^.Health <= 0 then
  1700         if Gear^.Health <= 0 then
  1701             exBoom := true;
  1701             exBoom := true;
  1702         end
  1702         end
  1703     else
  1703     else
  1704         begin 
  1704         begin
  1705         if (Gear^.Pos <> posCaseHealth) and (GameTicks and $1FFF = 0) then // stir 'em up periodically
  1705         if (Gear^.Pos <> posCaseHealth) and (GameTicks and $1FFF = 0) then // stir 'em up periodically
  1706             begin
  1706             begin
  1707             gi := GearsList;
  1707             gi := GearsList;
  1708             while gi <> nil do
  1708             while gi <> nil do
  1709                 begin
  1709                 begin
  1736             if sparkles <> nil then
  1736             if sparkles <> nil then
  1737                 begin
  1737                 begin
  1738                 sparkles^.dX:= 0;
  1738                 sparkles^.dX:= 0;
  1739                 sparkles^.dY:= 0;
  1739                 sparkles^.dY:= 0;
  1740                 sparkles^.Angle:= 270;
  1740                 sparkles^.Angle:= 270;
  1741                 if Gear^.Tag = 1 then 
  1741                 if Gear^.Tag = 1 then
  1742                     sparkles^.Tint:= $3744D7FF
  1742                     sparkles^.Tint:= $3744D7FF
  1743                 else sparkles^.Tint:= $FAB22CFF
  1743                 else sparkles^.Tint:= $FAB22CFF
  1744                 end;
  1744                 end;
  1745             end;
  1745             end;
  1746         if Gear^.Timer < 1000 then 
  1746         if Gear^.Timer < 1000 then
  1747             begin
  1747             begin
  1748             AllInactive:= false;
  1748             AllInactive:= false;
  1749             exit
  1749             exit
  1750             end
  1750             end
  1751         end;
  1751         end;
  1800                 inc(Gear^.Damage, hwRound(Gear^.dY * _70));
  1800                 inc(Gear^.Damage, hwRound(Gear^.dY * _70));
  1801 
  1801 
  1802             if Gear^.dY > _0_2 then
  1802             if Gear^.dY > _0_2 then
  1803                 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do
  1803                 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do
  1804                     AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
  1804                     AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
  1805                     
  1805 
  1806             Gear^.dY := - Gear^.dY * Gear^.Elasticity;
  1806             Gear^.dY := - Gear^.dY * Gear^.Elasticity;
  1807             if Gear^.dY > - _0_001 then
  1807             if Gear^.dY > - _0_001 then
  1808                 Gear^.dY := _0
  1808                 Gear^.dY := _0
  1809             else if Gear^.dY < - _0_03 then
  1809             else if Gear^.dY < - _0_03 then
  1810                 PlaySound(Gear^.ImpactSound);
  1810                 PlaySound(Gear^.ImpactSound);
  1854         end
  1854         end
  1855 end;
  1855 end;
  1856 
  1856 
  1857 ////////////////////////////////////////////////////////////////////////////////
  1857 ////////////////////////////////////////////////////////////////////////////////
  1858 procedure doStepShover(Gear: PGear);
  1858 procedure doStepShover(Gear: PGear);
  1859 var 
  1859 var
  1860     HHGear: PGear;
  1860     HHGear: PGear;
  1861 begin
  1861 begin
  1862     HHGear := Gear^.Hedgehog^.Gear;
  1862     HHGear := Gear^.Hedgehog^.Gear;
  1863     HHGear^.State := HHGear^.State or gstNoDamage;
  1863     HHGear^.State := HHGear^.State or gstNoDamage;
  1864     DeleteCI(HHGear);
  1864     DeleteCI(HHGear);
  1870     Gear^.doStep := @doStepIdle
  1870     Gear^.doStep := @doStepIdle
  1871 end;
  1871 end;
  1872 
  1872 
  1873 ////////////////////////////////////////////////////////////////////////////////
  1873 ////////////////////////////////////////////////////////////////////////////////
  1874 procedure doStepWhip(Gear: PGear);
  1874 procedure doStepWhip(Gear: PGear);
  1875 var 
  1875 var
  1876     HHGear: PGear;
  1876     HHGear: PGear;
  1877     i: LongInt;
  1877     i: LongInt;
  1878 begin
  1878 begin
  1879     HHGear := Gear^.Hedgehog^.Gear;
  1879     HHGear := Gear^.Hedgehog^.Gear;
  1880     HHGear^.State := HHGear^.State or gstNoDamage;
  1880     HHGear^.State := HHGear^.State or gstNoDamage;
  1892     Gear^.doStep := @doStepIdle
  1892     Gear^.doStep := @doStepIdle
  1893 end;
  1893 end;
  1894 
  1894 
  1895 ////////////////////////////////////////////////////////////////////////////////
  1895 ////////////////////////////////////////////////////////////////////////////////
  1896 procedure doStepFlame(Gear: PGear);
  1896 procedure doStepFlame(Gear: PGear);
  1897 var 
  1897 var
  1898     gX,gY,i: LongInt;
  1898     gX,gY,i: LongInt;
  1899     sticky: Boolean;
  1899     sticky: Boolean;
  1900     vgt: PVisualGear;
  1900     vgt: PVisualGear;
  1901     tdX,tdY: HWFloat;
  1901     tdX,tdY: HWFloat;
  1902 begin
  1902 begin
  1919             end;
  1919             end;
  1920 
  1920 
  1921 
  1921 
  1922         if Gear^.dX.QWordValue > _0_01.QWordValue then
  1922         if Gear^.dX.QWordValue > _0_01.QWordValue then
  1923             Gear^.dX := Gear^.dX * _0_995;
  1923             Gear^.dX := Gear^.dX * _0_995;
  1924             
  1924 
  1925         Gear^.dY := Gear^.dY + cGravity;
  1925         Gear^.dY := Gear^.dY + cGravity;
  1926         // if sticky then Gear^.dY := Gear^.dY + cGravity;
  1926         // if sticky then Gear^.dY := Gear^.dY + cGravity;
  1927         
  1927 
  1928         if Gear^.dY.QWordValue > _0_2.QWordValue then
  1928         if Gear^.dY.QWordValue > _0_2.QWordValue then
  1929             Gear^.dY := Gear^.dY * _0_995;
  1929             Gear^.dY := Gear^.dY * _0_995;
  1930 
  1930 
  1931         //if sticky then Gear^.X := Gear^.X + Gear^.dX else
  1931         //if sticky then Gear^.X := Gear^.X + Gear^.dX else
  1932         Gear^.X := Gear^.X + Gear^.dX + cWindSpeed * 640;
  1932         Gear^.X := Gear^.X + Gear^.dX + cWindSpeed * 640;
  1983                     Gear^.dX:= tdX;
  1983                     Gear^.dX:= tdX;
  1984                     Gear^.dY:= tdY;
  1984                     Gear^.dY:= tdY;
  1985                     Gear^.Radius := 1;
  1985                     Gear^.Radius := 1;
  1986                     end
  1986                     end
  1987                 else if ((GameTicks and $3) = 3) then
  1987                 else if ((GameTicks and $3) = 3) then
  1988                     doMakeExplosion(gX, gY, 8, Gear^.Hedgehog, 0);//, EXPLNoDamage); 
  1988                     doMakeExplosion(gX, gY, 8, Gear^.Hedgehog, 0);//, EXPLNoDamage);
  1989                 //DrawExplosion(gX, gY, 4);
  1989                 //DrawExplosion(gX, gY, 4);
  1990                 
  1990 
  1991                 if ((GameTicks and $7) = 0) and (Random(2) = 0) then
  1991                 if ((GameTicks and $7) = 0) and (Random(2) = 0) then
  1992                     for i:= Random(2) downto 0 do
  1992                     for i:= Random(2) downto 0 do
  1993                         AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
  1993                         AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
  1994                         
  1994 
  1995                 if Gear^.Health > 0 then
  1995                 if Gear^.Health > 0 then
  1996                     dec(Gear^.Health);
  1996                     dec(Gear^.Health);
  1997                 Gear^.Timer := 450 - Gear^.Tag * 8
  1997                 Gear^.Timer := 450 - Gear^.Tag * 8
  1998                 end
  1998                 end
  1999             else
  1999             else
  2032         end;
  2032         end;
  2033 end;
  2033 end;
  2034 
  2034 
  2035 ////////////////////////////////////////////////////////////////////////////////
  2035 ////////////////////////////////////////////////////////////////////////////////
  2036 procedure doStepFirePunchWork(Gear: PGear);
  2036 procedure doStepFirePunchWork(Gear: PGear);
  2037 var 
  2037 var
  2038     HHGear: PGear;
  2038     HHGear: PGear;
  2039 begin
  2039 begin
  2040     AllInactive := false;
  2040     AllInactive := false;
  2041     if ((Gear^.Message and gmDestroy) <> 0) then
  2041     if ((Gear^.Message and gmDestroy) <> 0) then
  2042         begin
  2042         begin
  2069         lfIndestructible) then
  2069         lfIndestructible) then
  2070             HHGear^.Y := HHGear^.Y + HHGear^.dY
  2070             HHGear^.Y := HHGear^.Y + HHGear^.dY
  2071 end;
  2071 end;
  2072 
  2072 
  2073 procedure doStepFirePunch(Gear: PGear);
  2073 procedure doStepFirePunch(Gear: PGear);
  2074 var 
  2074 var
  2075     HHGear: PGear;
  2075     HHGear: PGear;
  2076 begin
  2076 begin
  2077     AllInactive := false;
  2077     AllInactive := false;
  2078     HHGear := Gear^.Hedgehog^.Gear;
  2078     HHGear := Gear^.Hedgehog^.Gear;
  2079     DeleteCI(HHGear);
  2079     DeleteCI(HHGear);
  2092 end;
  2092 end;
  2093 
  2093 
  2094 ////////////////////////////////////////////////////////////////////////////////
  2094 ////////////////////////////////////////////////////////////////////////////////
  2095 
  2095 
  2096 procedure doStepParachuteWork(Gear: PGear);
  2096 procedure doStepParachuteWork(Gear: PGear);
  2097 var 
  2097 var
  2098     HHGear: PGear;
  2098     HHGear: PGear;
  2099 begin
  2099 begin
  2100     HHGear := Gear^.Hedgehog^.Gear;
  2100     HHGear := Gear^.Hedgehog^.Gear;
  2101 
  2101 
  2102     inc(Gear^.Timer);
  2102     inc(Gear^.Timer);
  2121 
  2121 
  2122     HHGear^.X := HHGear^.X + cWindSpeed * 200;
  2122     HHGear^.X := HHGear^.X + cWindSpeed * 200;
  2123 
  2123 
  2124     if (Gear^.Message and gmLeft) <> 0 then
  2124     if (Gear^.Message and gmLeft) <> 0 then
  2125         HHGear^.X := HHGear^.X - cMaxWindSpeed * 80
  2125         HHGear^.X := HHGear^.X - cMaxWindSpeed * 80
  2126         
  2126 
  2127     else if (Gear^.Message and gmRight) <> 0 then
  2127     else if (Gear^.Message and gmRight) <> 0 then
  2128         HHGear^.X := HHGear^.X + cMaxWindSpeed * 80;
  2128         HHGear^.X := HHGear^.X + cMaxWindSpeed * 80;
  2129         
  2129 
  2130     if (Gear^.Message and gmUp) <> 0 then
  2130     if (Gear^.Message and gmUp) <> 0 then
  2131         HHGear^.Y := HHGear^.Y - cGravity * 40
  2131         HHGear^.Y := HHGear^.Y - cGravity * 40
  2132         
  2132 
  2133     else if (Gear^.Message and gmDown) <> 0 then
  2133     else if (Gear^.Message and gmDown) <> 0 then
  2134         HHGear^.Y := HHGear^.Y + cGravity * 40;
  2134         HHGear^.Y := HHGear^.Y + cGravity * 40;
  2135 
  2135 
  2136     // don't drift into obstacles
  2136     // don't drift into obstacles
  2137     if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
  2137     if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
  2140     Gear^.X := HHGear^.X;
  2140     Gear^.X := HHGear^.X;
  2141     Gear^.Y := HHGear^.Y
  2141     Gear^.Y := HHGear^.Y
  2142 end;
  2142 end;
  2143 
  2143 
  2144 procedure doStepParachute(Gear: PGear);
  2144 procedure doStepParachute(Gear: PGear);
  2145 var 
  2145 var
  2146     HHGear: PGear;
  2146     HHGear: PGear;
  2147 begin
  2147 begin
  2148     HHGear := Gear^.Hedgehog^.Gear;
  2148     HHGear := Gear^.Hedgehog^.Gear;
  2149 
  2149 
  2150     DeleteCI(HHGear);
  2150     DeleteCI(HHGear);
  2167     Gear^.X := Gear^.X + cAirPlaneSpeed * Gear^.Tag;
  2167     Gear^.X := Gear^.X + cAirPlaneSpeed * Gear^.Tag;
  2168 
  2168 
  2169     if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then
  2169     if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then
  2170         begin
  2170         begin
  2171         dec(Gear^.Health);
  2171         dec(Gear^.Health);
  2172             case Gear^.State of 
  2172             case Gear^.State of
  2173                 0: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
  2173                 0: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
  2174                 1: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine,    0, cBombsSpeed * Gear^.Tag, _0, 0);
  2174                 1: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine,    0, cBombsSpeed * Gear^.Tag, _0, 0);
  2175                 2: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtNapalmBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
  2175                 2: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtNapalmBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
  2176                 3: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtDrill, gsttmpFlag, cBombsSpeed * Gear^.Tag, _0, Gear^.Timer + 1);
  2176                 3: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtDrill, gsttmpFlag, cBombsSpeed * Gear^.Tag, _0, Gear^.Timer + 1);
  2177             //4: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtWaterMelon, 0, cBombsSpeed *
  2177             //4: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtWaterMelon, 0, cBombsSpeed *
  2210     Gear^.Y := int2hwFloat(topY-300);
  2210     Gear^.Y := int2hwFloat(topY-300);
  2211     Gear^.dX := int2hwFloat(Gear^.Target.X - 5 * Gear^.Tag * 15);
  2211     Gear^.dX := int2hwFloat(Gear^.Target.X - 5 * Gear^.Tag * 15);
  2212 
  2212 
  2213     // calcs for Napalm Strike, so that it will hit the target (without wind at least :P)
  2213     // calcs for Napalm Strike, so that it will hit the target (without wind at least :P)
  2214     if (Gear^.State = 2) then
  2214     if (Gear^.State = 2) then
  2215         Gear^.dX := Gear^.dX - cBombsSpeed * Gear^.Tag * 900 
  2215         Gear^.dX := Gear^.dX - cBombsSpeed * Gear^.Tag * 900
  2216     // calcs for regular falling gears
  2216     // calcs for regular falling gears
  2217     else if (int2hwFloat(Gear^.Target.Y) - Gear^.Y > _0) then
  2217     else if (int2hwFloat(Gear^.Target.Y) - Gear^.Y > _0) then
  2218             Gear^.dX := Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(Gear^.Target.Y) - Gear^.Y) * 2 /
  2218             Gear^.dX := Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(Gear^.Target.Y) - Gear^.Y) * 2 /
  2219                 cGravity) * Gear^.Tag;
  2219                 cGravity) * Gear^.Tag;
  2220 
  2220 
  2244 end;
  2244 end;
  2245 
  2245 
  2246 ////////////////////////////////////////////////////////////////////////////////
  2246 ////////////////////////////////////////////////////////////////////////////////
  2247 
  2247 
  2248 procedure doStepGirder(Gear: PGear);
  2248 procedure doStepGirder(Gear: PGear);
  2249 var 
  2249 var
  2250     HHGear: PGear;
  2250     HHGear: PGear;
  2251     x, y, tx, ty: hwFloat;
  2251     x, y, tx, ty: hwFloat;
  2252 begin
  2252 begin
  2253     AllInactive := false;
  2253     AllInactive := false;
  2254 
  2254 
  2266         HHGear^.State := HHGear^.State and (not gstAttacking);
  2266         HHGear^.State := HHGear^.State and (not gstAttacking);
  2267         HHGear^.State := HHGear^.State or gstHHChooseTarget;
  2267         HHGear^.State := HHGear^.State or gstHHChooseTarget;
  2268         isCursorVisible := true;
  2268         isCursorVisible := true;
  2269         DeleteGear(Gear)
  2269         DeleteGear(Gear)
  2270         end
  2270         end
  2271     else 
  2271     else
  2272         begin
  2272         begin
  2273         PlaySound(sndPlaced);
  2273         PlaySound(sndPlaced);
  2274         DeleteGear(Gear);
  2274         DeleteGear(Gear);
  2275         AfterAttack;
  2275         AfterAttack;
  2276         end;
  2276         end;
  2279     HHGear^.Message := HHGear^.Message and (not gmAttack);
  2279     HHGear^.Message := HHGear^.Message and (not gmAttack);
  2280 end;
  2280 end;
  2281 
  2281 
  2282 ////////////////////////////////////////////////////////////////////////////////
  2282 ////////////////////////////////////////////////////////////////////////////////
  2283 procedure doStepTeleportAfter(Gear: PGear);
  2283 procedure doStepTeleportAfter(Gear: PGear);
  2284 var 
  2284 var
  2285     HHGear: PGear;
  2285     HHGear: PGear;
  2286 begin
  2286 begin
  2287     HHGear := Gear^.Hedgehog^.Gear;
  2287     HHGear := Gear^.Hedgehog^.Gear;
  2288     doStepHedgehogMoving(HHGear);
  2288     doStepHedgehogMoving(HHGear);
  2289     // if not infattack mode wait for hedgehog finish falling to collect cases
  2289     // if not infattack mode wait for hedgehog finish falling to collect cases
  2313             Gear^.doStep := @doStepTeleportAfter
  2313             Gear^.doStep := @doStepTeleportAfter
  2314         end;
  2314         end;
  2315 end;
  2315 end;
  2316 
  2316 
  2317 procedure doStepTeleport(Gear: PGear);
  2317 procedure doStepTeleport(Gear: PGear);
  2318 var 
  2318 var
  2319     HHGear: PGear;
  2319     HHGear: PGear;
  2320 begin
  2320 begin
  2321     AllInactive := false;
  2321     AllInactive := false;
  2322 
  2322 
  2323     HHGear := Gear^.Hedgehog^.Gear;
  2323     HHGear := Gear^.Hedgehog^.Gear;
  2354     Gear^.Target.X:= NoPointX
  2354     Gear^.Target.X:= NoPointX
  2355 end;
  2355 end;
  2356 
  2356 
  2357 ////////////////////////////////////////////////////////////////////////////////
  2357 ////////////////////////////////////////////////////////////////////////////////
  2358 procedure doStepSwitcherWork(Gear: PGear);
  2358 procedure doStepSwitcherWork(Gear: PGear);
  2359 var 
  2359 var
  2360     HHGear: PGear;
  2360     HHGear: PGear;
  2361     hedgehog: PHedgehog;
  2361     hedgehog: PHedgehog;
  2362     State: Longword;
  2362     State: Longword;
  2363 begin
  2363 begin
  2364     AllInactive := false;
  2364     AllInactive := false;
  2389 
  2389 
  2390         PlaySound(sndSwitchHog);
  2390         PlaySound(sndSwitchHog);
  2391 
  2391 
  2392         repeat
  2392         repeat
  2393             CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber);
  2393             CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber);
  2394         until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and 
  2394         until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and
  2395               (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear^.Damage = 0) and 
  2395               (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear^.Damage = 0) and
  2396               (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen]=0);
  2396               (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen]=0);
  2397 
  2397 
  2398         SwitchCurrentHedgehog(@CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]);
  2398         SwitchCurrentHedgehog(@CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]);
  2399         AmmoMenuInvalidated:= true; 
  2399         AmmoMenuInvalidated:= true;
  2400 
  2400 
  2401         HHGear := CurrentHedgehog^.Gear;
  2401         HHGear := CurrentHedgehog^.Gear;
  2402         HHGear^.State := State;
  2402         HHGear^.State := State;
  2403         HHGear^.Active := true;
  2403         HHGear^.Active := true;
  2404         FollowGear := HHGear;
  2404         FollowGear := HHGear;
  2408         Gear^.Y := HHGear^.Y
  2408         Gear^.Y := HHGear^.Y
  2409         end;
  2409         end;
  2410 end;
  2410 end;
  2411 
  2411 
  2412 procedure doStepSwitcher(Gear: PGear);
  2412 procedure doStepSwitcher(Gear: PGear);
  2413 var 
  2413 var
  2414     HHGear: PGear;
  2414     HHGear: PGear;
  2415 begin
  2415 begin
  2416     Gear^.doStep := @doStepSwitcherWork;
  2416     Gear^.doStep := @doStepSwitcherWork;
  2417 
  2417 
  2418     HHGear := Gear^.Hedgehog^.Gear;
  2418     HHGear := Gear^.Hedgehog^.Gear;
  2424         end
  2424         end
  2425 end;
  2425 end;
  2426 
  2426 
  2427 ////////////////////////////////////////////////////////////////////////////////
  2427 ////////////////////////////////////////////////////////////////////////////////
  2428 procedure doStepMortar(Gear: PGear);
  2428 procedure doStepMortar(Gear: PGear);
  2429 var 
  2429 var
  2430     dX, dY, gdX, gdY: hwFloat;
  2430     dX, dY, gdX, gdY: hwFloat;
  2431     i: LongInt;
  2431     i: LongInt;
  2432     dxn, dyn: boolean;
  2432     dxn, dyn: boolean;
  2433 begin
  2433 begin
  2434     AllInactive := false;
  2434     AllInactive := false;
  2459         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
  2459         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
  2460 end;
  2460 end;
  2461 
  2461 
  2462 ////////////////////////////////////////////////////////////////////////////////
  2462 ////////////////////////////////////////////////////////////////////////////////
  2463 procedure doStepKamikazeWork(Gear: PGear);
  2463 procedure doStepKamikazeWork(Gear: PGear);
  2464 var 
  2464 var
  2465     i: LongWord;
  2465     i: LongWord;
  2466     HHGear: PGear;
  2466     HHGear: PGear;
  2467     sparkles: PVisualGear;
  2467     sparkles: PVisualGear;
  2468     hasWishes: boolean;
  2468     hasWishes: boolean;
  2469 begin
  2469 begin
  2494             end
  2494             end
  2495         end;
  2495         end;
  2496 
  2496 
  2497     i := 2;
  2497     i := 2;
  2498     repeat
  2498     repeat
  2499         
  2499 
  2500         Gear^.X := Gear^.X + HHGear^.dX;
  2500         Gear^.X := Gear^.X + HHGear^.dX;
  2501         Gear^.Y := Gear^.Y + HHGear^.dY;
  2501         Gear^.Y := Gear^.Y + HHGear^.dY;
  2502         HHGear^.X := Gear^.X;
  2502         HHGear^.X := Gear^.X;
  2503         HHGear^.Y := Gear^.Y;
  2503         HHGear^.Y := Gear^.Y;
  2504 
  2504 
  2577         Gear^.doStep := @doStepKamikazeWork
  2577         Gear^.doStep := @doStepKamikazeWork
  2578         end
  2578         end
  2579 end;
  2579 end;
  2580 
  2580 
  2581 procedure doStepKamikaze(Gear: PGear);
  2581 procedure doStepKamikaze(Gear: PGear);
  2582 var 
  2582 var
  2583     HHGear: PGear;
  2583     HHGear: PGear;
  2584 begin
  2584 begin
  2585     AllInactive := false;
  2585     AllInactive := false;
  2586 
  2586 
  2587     HHGear := Gear^.Hedgehog^.Gear;
  2587     HHGear := Gear^.Hedgehog^.Gear;
  2598 end;
  2598 end;
  2599 
  2599 
  2600 ////////////////////////////////////////////////////////////////////////////////
  2600 ////////////////////////////////////////////////////////////////////////////////
  2601 
  2601 
  2602 const cakeh =   27;
  2602 const cakeh =   27;
  2603 var 
  2603 var
  2604     CakePoints: array[0..Pred(cakeh)] of record
  2604     CakePoints: array[0..Pred(cakeh)] of record
  2605         x, y: hwFloat;
  2605         x, y: hwFloat;
  2606     end;
  2606     end;
  2607     CakeI: Longword;
  2607     CakeI: Longword;
  2608 
  2608 
  2618     AfterAttack;
  2618     AfterAttack;
  2619     DeleteGear(Gear)
  2619     DeleteGear(Gear)
  2620 end;
  2620 end;
  2621 
  2621 
  2622 procedure doStepCakeDown(Gear: PGear);
  2622 procedure doStepCakeDown(Gear: PGear);
  2623 var 
  2623 var
  2624     gi: PGear;
  2624     gi: PGear;
  2625     dmg, dmgBase: LongInt;
  2625     dmg, dmgBase: LongInt;
  2626     fX, fY, tdX, tdY: hwFloat;
  2626     fX, fY, tdX, tdY: hwFloat;
  2627 begin
  2627 begin
  2628     AllInactive := false;
  2628     AllInactive := false;
  2704         Gear^.DirAngle := DxDy2Angle(tdx, tdy);
  2704         Gear^.DirAngle := DxDy2Angle(tdx, tdy);
  2705         end;
  2705         end;
  2706 end;
  2706 end;
  2707 
  2707 
  2708 procedure doStepCakeUp(Gear: PGear);
  2708 procedure doStepCakeUp(Gear: PGear);
  2709 var 
  2709 var
  2710     i: Longword;
  2710     i: Longword;
  2711 begin
  2711 begin
  2712     AllInactive := false;
  2712     AllInactive := false;
  2713 
  2713 
  2714     inc(Gear^.Tag);
  2714     inc(Gear^.Tag);
  2744             AfterAttack
  2744             AfterAttack
  2745         end
  2745         end
  2746 end;
  2746 end;
  2747 
  2747 
  2748 procedure doStepCake(Gear: PGear);
  2748 procedure doStepCake(Gear: PGear);
  2749 var 
  2749 var
  2750     HHGear: PGear;
  2750     HHGear: PGear;
  2751 begin
  2751 begin
  2752     AllInactive := false;
  2752     AllInactive := false;
  2753 
  2753 
  2754     HHGear := Gear^.Hedgehog^.Gear;
  2754     HHGear := Gear^.Hedgehog^.Gear;
  2848     Gear^.doStep := @doStepSeductionWear
  2848     Gear^.doStep := @doStepSeductionWear
  2849 end;
  2849 end;
  2850 
  2850 
  2851 ////////////////////////////////////////////////////////////////////////////////
  2851 ////////////////////////////////////////////////////////////////////////////////
  2852 procedure doStepWaterUp(Gear: PGear);
  2852 procedure doStepWaterUp(Gear: PGear);
  2853 var 
  2853 var
  2854     i: LongWord;
  2854     i: LongWord;
  2855 begin
  2855 begin
  2856     if (Gear^.Tag = 0)
  2856     if (Gear^.Tag = 0)
  2857     or (cWaterLine = 0) then
  2857     or (cWaterLine = 0) then
  2858         begin
  2858         begin
  2882 ////////////////////////////////////////////////////////////////////////////////
  2882 ////////////////////////////////////////////////////////////////////////////////
  2883 procedure doStepDrill(Gear: PGear);
  2883 procedure doStepDrill(Gear: PGear);
  2884 forward;
  2884 forward;
  2885 
  2885 
  2886 procedure doStepDrillDrilling(Gear: PGear);
  2886 procedure doStepDrillDrilling(Gear: PGear);
  2887 var 
  2887 var
  2888     t: PGearArray;
  2888     t: PGearArray;
  2889     tempColl: Word; 
  2889     tempColl: Word;
  2890 begin
  2890 begin
  2891     AllInactive := false;
  2891     AllInactive := false;
  2892 
  2892 
  2893 
  2893 
  2894     if (Gear^.Timer > 0) and ((Gear^.Timer mod 10) = 0) then
  2894     if (Gear^.Timer > 0) and ((Gear^.Timer mod 10) = 0) then
  2909     if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) <> 0) or TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) or (GameTicks > Gear^.FlightTime) then
  2909     if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) <> 0) or TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) or (GameTicks > Gear^.FlightTime) then
  2910         t := CheckGearsCollision(Gear)
  2910         t := CheckGearsCollision(Gear)
  2911     else t := nil;
  2911     else t := nil;
  2912     Gear^.CollisionMask:= tempColl;
  2912     Gear^.CollisionMask:= tempColl;
  2913     //fixes drill not exploding when touching HH bug
  2913     //fixes drill not exploding when touching HH bug
  2914     
  2914 
  2915     if (Gear^.Timer = 0) or ((t <> nil) and (t^.Count <> 0))
  2915     if (Gear^.Timer = 0) or ((t <> nil) and (t^.Count <> 0))
  2916     or ( ((Gear^.State and gsttmpFlag) = 0) and (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))))
  2916     or ( ((Gear^.State and gsttmpFlag) = 0) and (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))))
  2917 // CheckLandValue returns true if the type isn't matched
  2917 // CheckLandValue returns true if the type isn't matched
  2918     or (not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible)) then
  2918     or (not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible)) then
  2919         begin
  2919         begin
  2924         else
  2924         else
  2925             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
  2925             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
  2926         DeleteGear(Gear);
  2926         DeleteGear(Gear);
  2927         exit
  2927         exit
  2928         end
  2928         end
  2929         
  2929 
  2930     else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) then
  2930     else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) then
  2931         begin
  2931         begin
  2932         StopSoundChan(Gear^.SoundChannel);
  2932         StopSoundChan(Gear^.SoundChannel);
  2933         Gear^.Tag := 1;
  2933         Gear^.Tag := 1;
  2934         Gear^.doStep := @doStepDrill
  2934         Gear^.doStep := @doStepDrill
  2936 
  2936 
  2937     dec(Gear^.Timer);
  2937     dec(Gear^.Timer);
  2938 end;
  2938 end;
  2939 
  2939 
  2940 procedure doStepDrill(Gear: PGear);
  2940 procedure doStepDrill(Gear: PGear);
  2941 var 
  2941 var
  2942     t: PGearArray;
  2942     t: PGearArray;
  2943     oldDx, oldDy: hwFloat;
  2943     oldDx, oldDy: hwFloat;
  2944     t2: hwFloat;
  2944     t2: hwFloat;
  2945 begin
  2945 begin
  2946     AllInactive := false;
  2946     AllInactive := false;
  2960         begin
  2960         begin
  2961         //hit
  2961         //hit
  2962         Gear^.dX := oldDx;
  2962         Gear^.dX := oldDx;
  2963         Gear^.dY := oldDy;
  2963         Gear^.dY := oldDy;
  2964 
  2964 
  2965         if GameTicks > Gear^.FlightTime then 
  2965         if GameTicks > Gear^.FlightTime then
  2966             t := CheckGearsCollision(Gear)
  2966             t := CheckGearsCollision(Gear)
  2967         else
  2967         else
  2968             t := nil;
  2968             t := nil;
  2969         if (t = nil) or (t^.Count = 0) then
  2969         if (t = nil) or (t^.Count = 0) then
  2970             begin
  2970             begin
  2971             //hit the ground not the HH
  2971             //hit the ground not the HH
  2972             t2 := _0_5 / Distance(Gear^.dX, Gear^.dY);
  2972             t2 := _0_5 / Distance(Gear^.dX, Gear^.dY);
  2973             Gear^.dX := Gear^.dX * t2;
  2973             Gear^.dX := Gear^.dX * t2;
  2974             Gear^.dY := Gear^.dY * t2;
  2974             Gear^.dY := Gear^.dY * t2;
  2975             end
  2975             end
  2976             
  2976 
  2977         else if (t <> nil) then
  2977         else if (t <> nil) then
  2978             begin
  2978             begin
  2979             //explode right on contact with HH
  2979             //explode right on contact with HH
  2980             if (Gear^.State and gsttmpFlag) <> 0 then
  2980             if (Gear^.State and gsttmpFlag) <> 0 then
  2981                 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound)
  2981                 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound)
  2985             exit;
  2985             exit;
  2986             end;
  2986             end;
  2987 
  2987 
  2988         Gear^.SoundChannel := LoopSound(sndDrillRocket);
  2988         Gear^.SoundChannel := LoopSound(sndDrillRocket);
  2989         Gear^.doStep := @doStepDrillDrilling;
  2989         Gear^.doStep := @doStepDrillDrilling;
  2990         
  2990 
  2991         if (Gear^.State and gsttmpFlag) <> 0 then
  2991         if (Gear^.State and gsttmpFlag) <> 0 then
  2992             gear^.RenderTimer:= true;
  2992             gear^.RenderTimer:= true;
  2993         if Gear^.Timer > 0 then dec(Gear^.Timer)
  2993         if Gear^.Timer > 0 then dec(Gear^.Timer)
  2994         end
  2994         end
  2995     else if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Tag <> 0) then
  2995     else if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Tag <> 0) then
  2996         begin
  2996         begin
  2997         if Gear^.Timer > 0 then 
  2997         if Gear^.Timer > 0 then
  2998             dec(Gear^.Timer)
  2998             dec(Gear^.Timer)
  2999         else
  2999         else
  3000             begin
  3000             begin
  3001             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
  3001             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
  3002             DeleteGear(Gear);
  3002             DeleteGear(Gear);
  3004         end;
  3004         end;
  3005 end;
  3005 end;
  3006 
  3006 
  3007 ////////////////////////////////////////////////////////////////////////////////
  3007 ////////////////////////////////////////////////////////////////////////////////
  3008 procedure doStepBallgunWork(Gear: PGear);
  3008 procedure doStepBallgunWork(Gear: PGear);
  3009 var 
  3009 var
  3010     HHGear, ball: PGear;
  3010     HHGear, ball: PGear;
  3011     rx, ry: hwFloat;
  3011     rx, ry: hwFloat;
  3012     gX, gY: LongInt;
  3012     gX, gY: LongInt;
  3013 begin
  3013 begin
  3014     AllInactive := false;
  3014     AllInactive := false;
  3034         AfterAttack
  3034         AfterAttack
  3035         end
  3035         end
  3036 end;
  3036 end;
  3037 
  3037 
  3038 procedure doStepBallgun(Gear: PGear);
  3038 procedure doStepBallgun(Gear: PGear);
  3039 var 
  3039 var
  3040     HHGear: PGear;
  3040     HHGear: PGear;
  3041 begin
  3041 begin
  3042     HHGear := Gear^.Hedgehog^.Gear;
  3042     HHGear := Gear^.Hedgehog^.Gear;
  3043     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown));
  3043     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown));
  3044     HHGear^.State := HHGear^.State or gstNotKickable;
  3044     HHGear^.State := HHGear^.State or gstNotKickable;
  3047 
  3047 
  3048 ////////////////////////////////////////////////////////////////////////////////
  3048 ////////////////////////////////////////////////////////////////////////////////
  3049 procedure doStepRCPlaneWork(Gear: PGear);
  3049 procedure doStepRCPlaneWork(Gear: PGear);
  3050 
  3050 
  3051 const cAngleSpeed =   3;
  3051 const cAngleSpeed =   3;
  3052 var 
  3052 var
  3053     HHGear: PGear;
  3053     HHGear: PGear;
  3054     i: LongInt;
  3054     i: LongInt;
  3055     dX, dY: hwFloat;
  3055     dX, dY: hwFloat;
  3056     fChanged: boolean;
  3056     fChanged: boolean;
  3057     trueAngle: Longword;
  3057     trueAngle: Longword;
  3156         CurAmmoGear := nil;
  3156         CurAmmoGear := nil;
  3157         if (GameFlags and gfInfAttack) = 0 then
  3157         if (GameFlags and gfInfAttack) = 0 then
  3158             begin
  3158             begin
  3159             if TagTurnTimeLeft = 0 then
  3159             if TagTurnTimeLeft = 0 then
  3160                 TagTurnTimeLeft:= TurnTimeLeft;
  3160                 TagTurnTimeLeft:= TurnTimeLeft;
  3161                 
  3161 
  3162             TurnTimeLeft:= 14 * 125;
  3162             TurnTimeLeft:= 14 * 125;
  3163             end;
  3163             end;
  3164 
  3164 
  3165         HHGear^.Message := 0;
  3165         HHGear^.Message := 0;
  3166         ParseCommand('/taunt ' + #1, true)
  3166         ParseCommand('/taunt ' + #1, true)
  3167         end
  3167         end
  3168 end;
  3168 end;
  3169 
  3169 
  3170 procedure doStepRCPlane(Gear: PGear);
  3170 procedure doStepRCPlane(Gear: PGear);
  3171 var 
  3171 var
  3172     HHGear: PGear;
  3172     HHGear: PGear;
  3173 begin
  3173 begin
  3174     HHGear := Gear^.Hedgehog^.Gear;
  3174     HHGear := Gear^.Hedgehog^.Gear;
  3175     HHGear^.Message := 0;
  3175     HHGear^.Message := 0;
  3176     HHGear^.State := HHGear^.State or gstNotKickable;
  3176     HHGear^.State := HHGear^.State or gstNotKickable;
  3177     Gear^.Angle := HHGear^.Angle;
  3177     Gear^.Angle := HHGear^.Angle;
  3178     Gear^.Tag := hwSign(HHGear^.dX);
  3178     Gear^.Tag := hwSign(HHGear^.dX);
  3179     
  3179 
  3180     if HHGear^.dX.isNegative then
  3180     if HHGear^.dX.isNegative then
  3181         Gear^.Angle := 4096 - Gear^.Angle;
  3181         Gear^.Angle := 4096 - Gear^.Angle;
  3182     Gear^.doStep := @doStepRCPlaneWork
  3182     Gear^.doStep := @doStepRCPlaneWork
  3183 end;
  3183 end;
  3184 
  3184 
  3185 ////////////////////////////////////////////////////////////////////////////////
  3185 ////////////////////////////////////////////////////////////////////////////////
  3186 procedure doStepJetpackWork(Gear: PGear);
  3186 procedure doStepJetpackWork(Gear: PGear);
  3187 var 
  3187 var
  3188     HHGear: PGear;
  3188     HHGear: PGear;
  3189     fuel, i: LongInt;
  3189     fuel, i: LongInt;
  3190     move: hwFloat;
  3190     move: hwFloat;
  3191     isUnderwater: Boolean;
  3191     isUnderwater: Boolean;
  3192     bubble: PVisualGear;
  3192     bubble: PVisualGear;
  3261         Gear^.MsgParam := 0
  3261         Gear^.MsgParam := 0
  3262         end;
  3262         end;
  3263 
  3263 
  3264     if Gear^.Health < 0 then
  3264     if Gear^.Health < 0 then
  3265         Gear^.Health := 0;
  3265         Gear^.Health := 0;
  3266         
  3266 
  3267     i:= Gear^.Health div 20;
  3267     i:= Gear^.Health div 20;
  3268     
  3268 
  3269     if (i <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
  3269     if (i <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
  3270         begin
  3270         begin
  3271         Gear^.Damage:= i;
  3271         Gear^.Damage:= i;
  3272         //AddCaption('Fuel: '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
  3272         //AddCaption('Fuel: '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
  3273         FreeTexture(Gear^.Tex);
  3273         FreeTexture(Gear^.Tex);
  3274         Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) + '%', cWhiteColor, fntSmall)
  3274         Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) + '%', cWhiteColor, fntSmall)
  3275         end;
  3275         end;
  3276 
  3276 
  3277     if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then 
  3277     if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then
  3278         Gear^.State := Gear^.State and (not gsttmpFlag);
  3278         Gear^.State := Gear^.State and (not gsttmpFlag);
  3279         
  3279 
  3280     HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
  3280     HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
  3281     HHGear^.State := HHGear^.State or gstMoving;
  3281     HHGear^.State := HHGear^.State or gstMoving;
  3282 
  3282 
  3283     Gear^.X := HHGear^.X;
  3283     Gear^.X := HHGear^.X;
  3284     Gear^.Y := HHGear^.Y;
  3284     Gear^.Y := HHGear^.Y;
  3285 
  3285 
  3286     if not isUnderWater and hasBorder and ((HHGear^.X < _0)
  3286     if not isUnderWater and hasBorder and ((HHGear^.X < _0)
  3287     or (hwRound(HHGear^.X) > LAND_WIDTH)) then
  3287     or (hwRound(HHGear^.X) > LAND_WIDTH)) then
  3288         HHGear^.dY.isNegative:= false;
  3288         HHGear^.dY.isNegative:= false;
  3289         
  3289 
  3290     if ((Gear^.State and gsttmpFlag) = 0)
  3290     if ((Gear^.State and gsttmpFlag) = 0)
  3291     or (HHGear^.dY < _0) then
  3291     or (HHGear^.dY < _0) then
  3292         doStepHedgehogMoving(HHGear);
  3292         doStepHedgehogMoving(HHGear);
  3293 
  3293 
  3294     if // (Gear^.Health = 0)
  3294     if // (Gear^.Health = 0)
  3316 //AddCaption(trmsg[sidFuel]+': '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
  3316 //AddCaption(trmsg[sidFuel]+': '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
  3317             end
  3317             end
  3318 end;
  3318 end;
  3319 
  3319 
  3320 procedure doStepJetpack(Gear: PGear);
  3320 procedure doStepJetpack(Gear: PGear);
  3321 var 
  3321 var
  3322     HHGear: PGear;
  3322     HHGear: PGear;
  3323 begin
  3323 begin
  3324     Gear^.Pos:= 0;
  3324     Gear^.Pos:= 0;
  3325     Gear^.doStep := @doStepJetpackWork;
  3325     Gear^.doStep := @doStepJetpackWork;
  3326 
  3326 
  3329     AfterAttack;
  3329     AfterAttack;
  3330     with HHGear^ do
  3330     with HHGear^ do
  3331         begin
  3331         begin
  3332         State := State and (not gstAttacking);
  3332         State := State and (not gstAttacking);
  3333         Message := Message and (not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight));
  3333         Message := Message and (not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight));
  3334         
  3334 
  3335         if (dY < _0_1) and (dY > -_0_1) then
  3335         if (dY < _0_1) and (dY > -_0_1) then
  3336             begin
  3336             begin
  3337             Gear^.State := Gear^.State or gsttmpFlag;
  3337             Gear^.State := Gear^.State or gsttmpFlag;
  3338             dY := dY - _0_2
  3338             dY := dY - _0_2
  3339             end
  3339             end
  3352         DeleteGear(Gear);
  3352         DeleteGear(Gear);
  3353         end;
  3353         end;
  3354 end;
  3354 end;
  3355 
  3355 
  3356 procedure doStepBirdyFly(Gear: PGear);
  3356 procedure doStepBirdyFly(Gear: PGear);
  3357 var 
  3357 var
  3358     HHGear: PGear;
  3358     HHGear: PGear;
  3359     fuel, i: LongInt;
  3359     fuel, i: LongInt;
  3360     move: hwFloat;
  3360     move: hwFloat;
  3361 begin
  3361 begin
  3362     HHGear := Gear^.Hedgehog^.Gear;
  3362     HHGear := Gear^.Hedgehog^.Gear;
  3363     if HHGear = nil then 
  3363     if HHGear = nil then
  3364         begin
  3364         begin
  3365         DeleteGear(Gear);
  3365         DeleteGear(Gear);
  3366         exit
  3366         exit
  3367         end;
  3367         end;
  3368 
  3368 
  3382     if (HHGear^.Message and gmUp) <> 0 then
  3382     if (HHGear^.Message and gmUp) <> 0 then
  3383         begin
  3383         begin
  3384         if (not HHGear^.dY.isNegative)
  3384         if (not HHGear^.dY.isNegative)
  3385         or (HHGear^.Y > -_256) then
  3385         or (HHGear^.Y > -_256) then
  3386             HHGear^.dY := HHGear^.dY - move;
  3386             HHGear^.dY := HHGear^.dY - move;
  3387             
  3387 
  3388         dec(Gear^.Health, fuel);
  3388         dec(Gear^.Health, fuel);
  3389         Gear^.MsgParam := Gear^.MsgParam or gmUp;
  3389         Gear^.MsgParam := Gear^.MsgParam or gmUp;
  3390         end;
  3390         end;
  3391         
  3391 
  3392     if (HHGear^.Message and gmLeft) <> 0 then move.isNegative := true;
  3392     if (HHGear^.Message and gmLeft) <> 0 then move.isNegative := true;
  3393     if (HHGear^.Message and (gmLeft or gmRight)) <> 0 then
  3393     if (HHGear^.Message and (gmLeft or gmRight)) <> 0 then
  3394         begin
  3394         begin
  3395         HHGear^.dX := HHGear^.dX + (move * _0_1);
  3395         HHGear^.dX := HHGear^.dX + (move * _0_1);
  3396         dec(Gear^.Health, fuel div 5);
  3396         dec(Gear^.Health, fuel div 5);
  3397         Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gmLeft or gmRight));
  3397         Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gmLeft or gmRight));
  3398         end;
  3398         end;
  3399 
  3399 
  3400     if Gear^.Health < 0 then
  3400     if Gear^.Health < 0 then
  3401         Gear^.Health := 0;
  3401         Gear^.Health := 0;
  3402         
  3402 
  3403     if ((GameTicks and $FF) = 0) and (Gear^.Health < 500) then
  3403     if ((GameTicks and $FF) = 0) and (Gear^.Health < 500) then
  3404         for i:= ((500-Gear^.Health) div 250) downto 0 do
  3404         for i:= ((500-Gear^.Health) div 250) downto 0 do
  3405             AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather);
  3405             AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather);
  3406 
  3406 
  3407     if (HHGear^.Message and gmAttack <> 0) then
  3407     if (HHGear^.Message and gmAttack <> 0) then
  3415             end;
  3415             end;
  3416         end;
  3416         end;
  3417 
  3417 
  3418     if HHGear^.Message and (gmUp or gmPrecise or gmLeft or gmRight) <> 0 then
  3418     if HHGear^.Message and (gmUp or gmPrecise or gmLeft or gmRight) <> 0 then
  3419         Gear^.State := Gear^.State and (not gsttmpFlag);
  3419         Gear^.State := Gear^.State and (not gsttmpFlag);
  3420         
  3420 
  3421     HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
  3421     HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
  3422     HHGear^.State := HHGear^.State or gstMoving;
  3422     HHGear^.State := HHGear^.State or gstMoving;
  3423 
  3423 
  3424     Gear^.X := HHGear^.X;
  3424     Gear^.X := HHGear^.X;
  3425     Gear^.Y := HHGear^.Y - int2hwFloat(32);
  3425     Gear^.Y := HHGear^.Y - int2hwFloat(32);
  3458             AfterAttack;
  3458             AfterAttack;
  3459             end
  3459             end
  3460 end;
  3460 end;
  3461 
  3461 
  3462 procedure doStepBirdyDescend(Gear: PGear);
  3462 procedure doStepBirdyDescend(Gear: PGear);
  3463 var 
  3463 var
  3464     HHGear: PGear;
  3464     HHGear: PGear;
  3465 begin
  3465 begin
  3466     if Gear^.Timer > 0 then
  3466     if Gear^.Timer > 0 then
  3467         dec(Gear^.Timer, 1)
  3467         dec(Gear^.Timer, 1)
  3468     else if Gear^.Hedgehog^.Gear = nil then
  3468     else if Gear^.Hedgehog^.Gear = nil then
  3499         Gear^.doStep := @doStepBirdyDescend;
  3499         Gear^.doStep := @doStepBirdyDescend;
  3500         end
  3500         end
  3501 end;
  3501 end;
  3502 
  3502 
  3503 procedure doStepBirdy(Gear: PGear);
  3503 procedure doStepBirdy(Gear: PGear);
  3504 var 
  3504 var
  3505     HHGear: PGear;
  3505     HHGear: PGear;
  3506 begin
  3506 begin
  3507     gear^.State :=  gear^.State or gstAnimation and (not gstTmpFlag);
  3507     gear^.State :=  gear^.State or gstAnimation and (not gstTmpFlag);
  3508     Gear^.doStep := @doStepBirdyAppear;
  3508     Gear^.doStep := @doStepBirdyAppear;
  3509     
  3509 
  3510     if CurrentHedgehog = nil then
  3510     if CurrentHedgehog = nil then
  3511         begin
  3511         begin
  3512         DeleteGear(Gear);
  3512         DeleteGear(Gear);
  3513         exit
  3513         exit
  3514         end;
  3514         end;
  3529         end
  3529         end
  3530 end;
  3530 end;
  3531 
  3531 
  3532 ////////////////////////////////////////////////////////////////////////////////
  3532 ////////////////////////////////////////////////////////////////////////////////
  3533 procedure doStepEggWork(Gear: PGear);
  3533 procedure doStepEggWork(Gear: PGear);
  3534 var 
  3534 var
  3535     vg: PVisualGear;
  3535     vg: PVisualGear;
  3536     i: LongInt;
  3536     i: LongInt;
  3537 begin
  3537 begin
  3538     AllInactive := false;
  3538     AllInactive := false;
  3539     Gear^.dX := Gear^.dX;
  3539     Gear^.dX := Gear^.dX;
  3570     if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and ((CurrentHedgehog^.Gear^.Message and gmSwitch) <> 0) then
  3570     if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and ((CurrentHedgehog^.Gear^.Message and gmSwitch) <> 0) then
  3571             with CurrentHedgehog^ do
  3571             with CurrentHedgehog^ do
  3572                 if (CurAmmoType = amPortalGun) then
  3572                 if (CurAmmoType = amPortalGun) then
  3573                     begin
  3573                     begin
  3574                     CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSwitch);
  3574                     CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSwitch);
  3575                 
  3575 
  3576                     CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^);
  3576                     CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^);
  3577                     if CurWeapon^.Pos <> 0 then
  3577                     if CurWeapon^.Pos <> 0 then
  3578                         CurWeapon^.Pos := 0
  3578                         CurWeapon^.Pos := 0
  3579                         
  3579 
  3580                     else
  3580                     else
  3581                     CurWeapon^.Pos := 1;
  3581                     CurWeapon^.Pos := 1;
  3582                     end;
  3582                     end;
  3583 end;
  3583 end;
  3584 
  3584 
  3585 procedure doStepPortal(Gear: PGear);
  3585 procedure doStepPortal(Gear: PGear);
  3586 var 
  3586 var
  3587     iterator, conPortal: PGear;
  3587     iterator, conPortal: PGear;
  3588     s, r, nx, ny, ox, oy, poffs, noffs, pspeed, nspeed,
  3588     s, r, nx, ny, ox, oy, poffs, noffs, pspeed, nspeed,
  3589     resetx, resety, resetdx, resetdy: hwFloat;
  3589     resetx, resety, resetdx, resetdy: hwFloat;
  3590     sx, sy, rh, resetr: LongInt;
  3590     sx, sy, rh, resetr: LongInt;
  3591     hasdxy, isbullet, iscake, isCollision: Boolean;
  3591     hasdxy, isbullet, iscake, isCollision: Boolean;
  3882             resety.QWordValue:= 4294967296 * 112;
  3882             resety.QWordValue:= 4294967296 * 112;
  3883             resetx.isNegative:= false;
  3883             resetx.isNegative:= false;
  3884             resetx.QWordValue:= 4294967296 * 35;
  3884             resetx.QWordValue:= 4294967296 * 35;
  3885             resetdx.isNegative:= false;
  3885             resetdx.isNegative:= false;
  3886             resetdx.QWordValue:= 4294967296 * 1152;
  3886             resetdx.QWordValue:= 4294967296 * 1152;
  3887     
  3887 
  3888             resetdy:=hwAbs(iterator^.dX*4);
  3888             resetdy:=hwAbs(iterator^.dX*4);
  3889             resetdy:= resetdy + hwPow(resetdy,3)/_6 + _3 * hwPow(resetdy,5) / _40 + _5 * hwPow(resetdy,7) / resety + resetx * hwPow(resetdy,9) / resetdx;
  3889             resetdy:= resetdy + hwPow(resetdy,3)/_6 + _3 * hwPow(resetdy,5) / _40 + _5 * hwPow(resetdy,7) / resety + resetx * hwPow(resetdy,9) / resetdx;
  3890             iterator^.Angle:= hwRound(resetdy*_2048 / _PI);
  3890             iterator^.Angle:= hwRound(resetdy*_2048 / _PI);
  3891             if not iterator^.dY.isNegative then iterator^.Angle:= 2048-iterator^.Angle;
  3891             if not iterator^.dY.isNegative then iterator^.Angle:= 2048-iterator^.Angle;
  3892             if iterator^.dX.isNegative then iterator^.Angle:= 4096-iterator^.Angle;
  3892             if iterator^.dX.isNegative then iterator^.Angle:= 4096-iterator^.Angle;
  3903         and (iterator = CurrentHedgehog^.Gear)
  3903         and (iterator = CurrentHedgehog^.Gear)
  3904         and (CurAmmoGear <> nil)
  3904         and (CurAmmoGear <> nil)
  3905         and (CurAmmoGear^.Kind =gtRope) then
  3905         and (CurAmmoGear^.Kind =gtRope) then
  3906                CurAmmoGear^.PortalCounter:= 1;
  3906                CurAmmoGear^.PortalCounter:= 1;
  3907 
  3907 
  3908         if not isbullet and (iterator^.State and gstInvisible = 0) 
  3908         if not isbullet and (iterator^.State and gstInvisible = 0)
  3909         and (iterator^.Kind <> gtFlake) then
  3909         and (iterator^.Kind <> gtFlake) then
  3910             FollowGear := iterator;
  3910             FollowGear := iterator;
  3911 
  3911 
  3912         // store X/Y values of exit for net bullet trail
  3912         // store X/Y values of exit for net bullet trail
  3913         if isbullet then
  3913         if isbullet then
  3949     if destroyGear then
  3949     if destroyGear then
  3950         oldPortal^.Timer:= 0;
  3950         oldPortal^.Timer:= 0;
  3951 end;
  3951 end;
  3952 
  3952 
  3953 procedure doStepMovingPortal_real(Gear: PGear);
  3953 procedure doStepMovingPortal_real(Gear: PGear);
  3954 var 
  3954 var
  3955     x, y, tx, ty: LongInt;
  3955     x, y, tx, ty: LongInt;
  3956     s: hwFloat;
  3956     s: hwFloat;
  3957 begin
  3957 begin
  3958     x := hwRound(Gear^.X);
  3958     x := hwRound(Gear^.X);
  3959     y := hwRound(Gear^.Y);
  3959     y := hwRound(Gear^.Y);
  3963 
  3963 
  3964     if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then
  3964     if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then
  3965         begin
  3965         begin
  3966         Gear^.State := Gear^.State or gstCollision;
  3966         Gear^.State := Gear^.State or gstCollision;
  3967         Gear^.State := Gear^.State and (not gstMoving);
  3967         Gear^.State := Gear^.State and (not gstMoving);
  3968         
  3968 
  3969         if (Land[y, x] and lfBouncy <> 0)
  3969         if (Land[y, x] and lfBouncy <> 0)
  3970         or (not CalcSlopeTangent(Gear, x, y, tx, ty, 255))
  3970         or (not CalcSlopeTangent(Gear, x, y, tx, ty, 255))
  3971         or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
  3971         or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
  3972             begin
  3972             begin
  3973             loadNewPortalBall(Gear, true);
  3973             loadNewPortalBall(Gear, true);
  3991             Gear^.doStep := @doStepPortal;
  3991             Gear^.doStep := @doStepPortal;
  3992         end
  3992         end
  3993         else
  3993         else
  3994             loadNewPortalBall(Gear, true);
  3994             loadNewPortalBall(Gear, true);
  3995     end
  3995     end
  3996     
  3996 
  3997     else if (y > cWaterLine)
  3997     else if (y > cWaterLine)
  3998     or (y < -max(LAND_WIDTH,4096))
  3998     or (y < -max(LAND_WIDTH,4096))
  3999     or (x > 2*max(LAND_WIDTH,4096))
  3999     or (x > 2*max(LAND_WIDTH,4096))
  4000     or (x < -max(LAND_WIDTH,4096)) then
  4000     or (x < -max(LAND_WIDTH,4096)) then
  4001         loadNewPortalBall(Gear, true);
  4001         loadNewPortalBall(Gear, true);
  4003 
  4003 
  4004 procedure doStepMovingPortal(Gear: PGear);
  4004 procedure doStepMovingPortal(Gear: PGear);
  4005 begin
  4005 begin
  4006     doPortalColorSwitch();
  4006     doPortalColorSwitch();
  4007     doStepPerPixel(Gear, @doStepMovingPortal_real, true);
  4007     doStepPerPixel(Gear, @doStepMovingPortal_real, true);
  4008     if (Gear^.Timer < 1) 
  4008     if (Gear^.Timer < 1)
  4009     or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team) then
  4009     or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team) then
  4010         deleteGear(Gear);
  4010         deleteGear(Gear);
  4011 end;
  4011 end;
  4012 
  4012 
  4013 procedure doStepPortalShot(newPortal: PGear);
  4013 procedure doStepPortalShot(newPortal: PGear);
  4014 var 
  4014 var
  4015     iterator: PGear;
  4015     iterator: PGear;
  4016     s: hwFloat;
  4016     s: hwFloat;
  4017     CurWeapon: PAmmo;
  4017     CurWeapon: PAmmo;
  4018 begin
  4018 begin
  4019     s:= Distance (newPortal^.dX, newPortal^.dY);
  4019     s:= Distance (newPortal^.dX, newPortal^.dY);
  4089     newPortal^.doStep := @doStepMovingPortal;
  4089     newPortal^.doStep := @doStepMovingPortal;
  4090 end;
  4090 end;
  4091 
  4091 
  4092 ////////////////////////////////////////////////////////////////////////////////
  4092 ////////////////////////////////////////////////////////////////////////////////
  4093 procedure doStepPiano(Gear: PGear);
  4093 procedure doStepPiano(Gear: PGear);
  4094 var 
  4094 var
  4095     r0, r1: LongInt;
  4095     r0, r1: LongInt;
  4096     odY: hwFloat;
  4096     odY: hwFloat;
  4097 begin
  4097 begin
  4098     AllInactive := false;
  4098     AllInactive := false;
  4099     if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and 
  4099     if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and
  4100         ((CurrentHedgehog^.Gear^.Message and gmSlot) <> 0) then
  4100         ((CurrentHedgehog^.Gear^.Message and gmSlot) <> 0) then
  4101             begin
  4101             begin
  4102                 case CurrentHedgehog^.Gear^.MsgParam of 
  4102                 case CurrentHedgehog^.Gear^.MsgParam of
  4103                 0: PlaySound(sndPiano0);
  4103                 0: PlaySound(sndPiano0);
  4104                 1: PlaySound(sndPiano1);
  4104                 1: PlaySound(sndPiano1);
  4105                 2: PlaySound(sndPiano2);
  4105                 2: PlaySound(sndPiano2);
  4106                 3: PlaySound(sndPiano3);
  4106                 3: PlaySound(sndPiano3);
  4107                 4: PlaySound(sndPiano4);
  4107                 4: PlaySound(sndPiano4);
  4177 end;
  4177 end;
  4178 
  4178 
  4179 
  4179 
  4180 ////////////////////////////////////////////////////////////////////////////////
  4180 ////////////////////////////////////////////////////////////////////////////////
  4181 procedure doStepSineGunShotWork(Gear: PGear);
  4181 procedure doStepSineGunShotWork(Gear: PGear);
  4182 var 
  4182 var
  4183     x, y, rX, rY, t, tmp, initHealth: LongInt;
  4183     x, y, rX, rY, t, tmp, initHealth: LongInt;
  4184     oX, oY, ldX, ldY, sdX, sdY, sine, lx, ly, amp: hwFloat;
  4184     oX, oY, ldX, ldY, sdX, sdY, sine, lx, ly, amp: hwFloat;
  4185     justCollided: boolean;
  4185     justCollided: boolean;
  4186 begin
  4186 begin
  4187     AllInactive := false;
  4187     AllInactive := false;
  4272                         AddGear(x - Gear^.Radius + tmp, y - GetRandom(Gear^.Radius + 1), gtFlame, gsttmpFlag, _0, _0, 0)
  4272                         AddGear(x - Gear^.Radius + tmp, y - GetRandom(Gear^.Radius + 1), gtFlame, gsttmpFlag, _0, _0, 0)
  4273                         end
  4273                         end
  4274                     end;
  4274                     end;
  4275 
  4275 
  4276                 if random(100) = 0 then
  4276                 if random(100) = 0 then
  4277                     AddVisualGear(x, y, vgtSmokeTrace); 
  4277                     AddVisualGear(x, y, vgtSmokeTrace);
  4278                 end
  4278                 end
  4279                 else dec(Gear^.Health, 5); // if underwater get additional damage
  4279                 else dec(Gear^.Health, 5); // if underwater get additional damage
  4280             end;
  4280             end;
  4281 
  4281 
  4282         dec(Gear^.Health);
  4282         dec(Gear^.Health);
  4310 
  4310 
  4311 procedure doStepSineGunShot(Gear: PGear);
  4311 procedure doStepSineGunShot(Gear: PGear);
  4312 var
  4312 var
  4313     HHGear: PGear;
  4313     HHGear: PGear;
  4314 begin
  4314 begin
  4315     PlaySound(sndSineGun); 
  4315     PlaySound(sndSineGun);
  4316 
  4316 
  4317     // push the shooting Hedgehog back
  4317     // push the shooting Hedgehog back
  4318     HHGear := CurrentHedgehog^.Gear;
  4318     HHGear := CurrentHedgehog^.Gear;
  4319     Gear^.dX.isNegative := not Gear^.dX.isNegative;
  4319     Gear^.dX.isNegative := not Gear^.dX.isNegative;
  4320     Gear^.dY.isNegative := not Gear^.dY.isNegative;
  4320     Gear^.dY.isNegative := not Gear^.dY.isNegative;
  4330             performRumble(kSystemSoundID_Vibrate);
  4330             performRumble(kSystemSoundID_Vibrate);
  4331 end;
  4331 end;
  4332 
  4332 
  4333 ////////////////////////////////////////////////////////////////////////////////
  4333 ////////////////////////////////////////////////////////////////////////////////
  4334 procedure doStepFlamethrowerWork(Gear: PGear);
  4334 procedure doStepFlamethrowerWork(Gear: PGear);
  4335 var 
  4335 var
  4336     HHGear, flame: PGear;
  4336     HHGear, flame: PGear;
  4337     rx, ry, speed: hwFloat;
  4337     rx, ry, speed: hwFloat;
  4338     i, gX, gY: LongInt;
  4338     i, gX, gY: LongInt;
  4339 begin
  4339 begin
  4340     AllInactive := false;
  4340     AllInactive := false;
  4341     HHGear := Gear^.Hedgehog^.Gear;
  4341     HHGear := Gear^.Hedgehog^.Gear;
  4342     HedgehogChAngle(HHGear);
  4342     HedgehogChAngle(HHGear);
  4343     gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
  4343     gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
  4344     gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
  4344     gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
  4345     
  4345 
  4346     if (GameTicks and $FF) = 0 then
  4346     if (GameTicks and $FF) = 0 then
  4347         begin
  4347         begin
  4348         if (HHGear^.Message and gmRight) <> 0 then
  4348         if (HHGear^.Message and gmRight) <> 0 then
  4349             begin
  4349             begin
  4350             if HHGear^.dX.isNegative and (Gear^.Tag < 20) then
  4350             if HHGear^.dX.isNegative and (Gear^.Tag < 20) then
  4354             end
  4354             end
  4355         else if (HHGear^.Message and gmLeft) <> 0 then
  4355         else if (HHGear^.Message and gmLeft) <> 0 then
  4356             begin
  4356             begin
  4357             if HHGear^.dX.isNegative and (Gear^.Tag > 5) then
  4357             if HHGear^.dX.isNegative and (Gear^.Tag > 5) then
  4358                 dec(Gear^.Tag)
  4358                 dec(Gear^.Tag)
  4359             else if Gear^.Tag < 20 then 
  4359             else if Gear^.Tag < 20 then
  4360                 inc(Gear^.Tag);
  4360                 inc(Gear^.Tag);
  4361             end
  4361             end
  4362         end;
  4362         end;
  4363     
  4363 
  4364     dec(Gear^.Timer);
  4364     dec(Gear^.Timer);
  4365     if Gear^.Timer = 0 then
  4365     if Gear^.Timer = 0 then
  4366         begin
  4366         begin
  4367         dec(Gear^.Health);
  4367         dec(Gear^.Health);
  4368         if (Gear^.Health mod 5) = 0 then
  4368         if (Gear^.Health mod 5) = 0 then
  4369             begin
  4369             begin
  4370             rx := rndSign(getRandomf * _0_1);
  4370             rx := rndSign(getRandomf * _0_1);
  4371             ry := rndSign(getRandomf * _0_1);
  4371             ry := rndSign(getRandomf * _0_1);
  4372             speed := _0_5 * (_10 / Gear^.Tag);
  4372             speed := _0_5 * (_10 / Gear^.Tag);
  4373     
  4373 
  4374             flame:= AddGear(gx, gy, gtFlame, gstTmpFlag,
  4374             flame:= AddGear(gx, gy, gtFlame, gstTmpFlag,
  4375                     SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
  4375                     SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
  4376                     AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
  4376                     AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
  4377             flame^.CollisionMask:= lfNotCurrentMask;
  4377             flame^.CollisionMask:= lfNotCurrentMask;
  4378             
  4378 
  4379             if (Gear^.Health mod 30) = 0 then
  4379             if (Gear^.Health mod 30) = 0 then
  4380                 begin
  4380                 begin
  4381                 flame:= AddGear(gx, gy, gtFlame, 0,
  4381                 flame:= AddGear(gx, gy, gtFlame, 0,
  4382                         SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
  4382                         SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
  4383                         AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
  4383                         AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
  4404             end
  4404             end
  4405         end
  4405         end
  4406 end;
  4406 end;
  4407 
  4407 
  4408 procedure doStepFlamethrower(Gear: PGear);
  4408 procedure doStepFlamethrower(Gear: PGear);
  4409 var 
  4409 var
  4410     HHGear: PGear;
  4410     HHGear: PGear;
  4411 begin
  4411 begin
  4412     HHGear := Gear^.Hedgehog^.Gear;
  4412     HHGear := Gear^.Hedgehog^.Gear;
  4413     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight));
  4413     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight));
  4414     HHGear^.State := HHGear^.State or gstNotKickable;
  4414     HHGear^.State := HHGear^.State or gstNotKickable;
  4415     Gear^.doStep := @doStepFlamethrowerWork
  4415     Gear^.doStep := @doStepFlamethrowerWork
  4416 end;
  4416 end;
  4417 
  4417 
  4418 ////////////////////////////////////////////////////////////////////////////////
  4418 ////////////////////////////////////////////////////////////////////////////////
  4419 procedure doStepLandGunWork(Gear: PGear);
  4419 procedure doStepLandGunWork(Gear: PGear);
  4420 var 
  4420 var
  4421     HHGear, land: PGear;
  4421     HHGear, land: PGear;
  4422     rx, ry, speed: hwFloat;
  4422     rx, ry, speed: hwFloat;
  4423     i, gX, gY: LongInt;
  4423     i, gX, gY: LongInt;
  4424 begin
  4424 begin
  4425     AllInactive := false;
  4425     AllInactive := false;
  4426     HHGear := Gear^.Hedgehog^.Gear;
  4426     HHGear := Gear^.Hedgehog^.Gear;
  4427     HedgehogChAngle(HHGear);
  4427     HedgehogChAngle(HHGear);
  4428     gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
  4428     gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
  4429     gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
  4429     gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
  4430     
  4430 
  4431     if (GameTicks and $FF) = 0 then
  4431     if (GameTicks and $FF) = 0 then
  4432         begin
  4432         begin
  4433         if (HHGear^.Message and gmRight) <> 0 then
  4433         if (HHGear^.Message and gmRight) <> 0 then
  4434             begin
  4434             begin
  4435             if HHGear^.dX.isNegative and (Gear^.Tag < 20) then
  4435             if HHGear^.dX.isNegative and (Gear^.Tag < 20) then
  4443                 dec(Gear^.Tag)
  4443                 dec(Gear^.Tag)
  4444             else if Gear^.Tag < 20 then
  4444             else if Gear^.Tag < 20 then
  4445                 inc(Gear^.Tag);
  4445                 inc(Gear^.Tag);
  4446             end
  4446             end
  4447         end;
  4447         end;
  4448     
  4448 
  4449     dec(Gear^.Timer);
  4449     dec(Gear^.Timer);
  4450     if Gear^.Timer = 0 then
  4450     if Gear^.Timer = 0 then
  4451         begin
  4451         begin
  4452         dec(Gear^.Health);
  4452         dec(Gear^.Health);
  4453 
  4453 
  4454         rx := rndSign(getRandomf * _0_1);
  4454         rx := rndSign(getRandomf * _0_1);
  4455         ry := rndSign(getRandomf * _0_1);
  4455         ry := rndSign(getRandomf * _0_1);
  4456         speed := (_3 / Gear^.Tag);
  4456         speed := (_3 / Gear^.Tag);
  4457 
  4457 
  4458         land:= AddGear(gx, gy, gtFlake, gstTmpFlag, 
  4458         land:= AddGear(gx, gy, gtFlake, gstTmpFlag,
  4459                 SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx, 
  4459                 SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
  4460                 AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
  4460                 AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
  4461         land^.CollisionMask:= lfNotCurrentMask;
  4461         land^.CollisionMask:= lfNotCurrentMask;
  4462             
  4462 
  4463         Gear^.Timer:= Gear^.Tag
  4463         Gear^.Timer:= Gear^.Tag
  4464         end;
  4464         end;
  4465 
  4465 
  4466     if (Gear^.Health = 0) or ((HHGear^.State and gstHHDriven) = 0) or ((HHGear^.Message and gmAttack) <> 0) then
  4466     if (Gear^.Health = 0) or ((HHGear^.State and gstHHDriven) = 0) or ((HHGear^.Message and gmAttack) <> 0) then
  4467         begin
  4467         begin
  4481             end
  4481             end
  4482         end
  4482         end
  4483 end;
  4483 end;
  4484 
  4484 
  4485 procedure doStepLandGun(Gear: PGear);
  4485 procedure doStepLandGun(Gear: PGear);
  4486 var 
  4486 var
  4487     HHGear: PGear;
  4487     HHGear: PGear;
  4488 begin
  4488 begin
  4489     HHGear := Gear^.Hedgehog^.Gear;
  4489     HHGear := Gear^.Hedgehog^.Gear;
  4490     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight or gmAttack));
  4490     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight or gmAttack));
  4491     HHGear^.State := HHGear^.State or gstNotKickable;
  4491     HHGear^.State := HHGear^.State or gstNotKickable;
  4550 Gear^.Timer:= 250;
  4550 Gear^.Timer:= 250;
  4551 Gear^.doStep:= @doStepIdle
  4551 Gear^.doStep:= @doStepIdle
  4552 end;
  4552 end;
  4553 
  4553 
  4554 procedure doStepHammerHitWork(Gear: PGear);
  4554 procedure doStepHammerHitWork(Gear: PGear);
  4555 var 
  4555 var
  4556     i, j, ei: LongInt;
  4556     i, j, ei: LongInt;
  4557     HitGear: PGear;
  4557     HitGear: PGear;
  4558 begin
  4558 begin
  4559     AllInactive := false;
  4559     AllInactive := false;
  4560     HitGear := Gear^.LinkedGear;
  4560     HitGear := Gear^.LinkedGear;
  4606     SetLittle(HitGear^.dY);
  4606     SetLittle(HitGear^.dY);
  4607     HitGear^.Active:= true;
  4607     HitGear^.Active:= true;
  4608 end;
  4608 end;
  4609 
  4609 
  4610 procedure doStepHammerHit(Gear: PGear);
  4610 procedure doStepHammerHit(Gear: PGear);
  4611 var 
  4611 var
  4612     i, y: LongInt;
  4612     i, y: LongInt;
  4613     ar: TRangeArray;
  4613     ar: TRangeArray;
  4614     HHGear: PGear;
  4614     HHGear: PGear;
  4615 begin
  4615 begin
  4616     i := 0;
  4616     i := 0;
  4656 
  4656 
  4657     if ((Gear^.Message and gmUp) <> 0) then
  4657     if ((Gear^.Message and gmUp) <> 0) then
  4658         begin
  4658         begin
  4659         if (GameTicks and $F) <> 0 then
  4659         if (GameTicks and $F) <> 0 then
  4660         exit;
  4660         exit;
  4661         end 
  4661         end
  4662     else if (GameTicks and $1FF) <> 0 then
  4662     else if (GameTicks and $1FF) <> 0 then
  4663         exit;
  4663         exit;
  4664 
  4664 
  4665     if Gear^.Power < 45 then
  4665     if Gear^.Power < 45 then
  4666         begin
  4666         begin
  4693             if hh^.Gear^.Health > 0 then begin
  4693             if hh^.Gear^.Health > 0 then begin
  4694                 dec(hh^.Gear^.Health);
  4694                 dec(hh^.Gear^.Health);
  4695                 inc(graves[i]^.Health);
  4695                 inc(graves[i]^.Health);
  4696             end;
  4696             end;
  4697         end; -}
  4697         end; -}
  4698         end 
  4698         end
  4699     else 
  4699     else
  4700         begin
  4700         begin
  4701         // now really resurrect the hogs with the hp saved in the graves
  4701         // now really resurrect the hogs with the hp saved in the graves
  4702         for i:= 0 to graves.size - 1 do
  4702         for i:= 0 to graves.size - 1 do
  4703             if graves.ar^[i]^.Health > 0 then
  4703             if graves.ar^[i]^.Health > 0 then
  4704                 begin
  4704                 begin
  4753                 hh^.Gear^.Damage:= 1;
  4753                 hh^.Gear^.Damage:= 1;
  4754             RenderHealth(hh^);
  4754             RenderHealth(hh^);
  4755             RecountTeamHealth(hh^.Team);
  4755             RecountTeamHealth(hh^.Team);
  4756             inc(graves.ar^[Gear^.Tag]^.Health);
  4756             inc(graves.ar^[Gear^.Tag]^.Health);
  4757             inc(Gear^.Tag)
  4757             inc(Gear^.Tag)
  4758             end 
  4758             end
  4759         end 
  4759         end
  4760     else 
  4760     else
  4761         begin
  4761         begin
  4762         StopSoundChan(Gear^.SoundChannel);
  4762         StopSoundChan(Gear^.SoundChannel);
  4763         Gear^.Timer := 250;
  4763         Gear^.Timer := 250;
  4764         Gear^.doStep := @doStepIdle;
  4764         Gear^.doStep := @doStepIdle;
  4765         end
  4765         end
  4775     doStepFallingGear(Gear);
  4775     doStepFallingGear(Gear);
  4776     if (Gear^.Timer > 0) and ((Gear^.State and gstCollision) <> 0) then
  4776     if (Gear^.Timer > 0) and ((Gear^.State and gstCollision) <> 0) then
  4777     begin
  4777     begin
  4778         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, Gear^.Hedgehog, EXPLAutoSound);
  4778         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, Gear^.Hedgehog, EXPLAutoSound);
  4779         gX := hwRound(Gear^.X);
  4779         gX := hwRound(Gear^.X);
  4780         gY := hwRound(Gear^.Y); 
  4780         gY := hwRound(Gear^.Y);
  4781         for i:= 0 to 10 do
  4781         for i:= 0 to 10 do
  4782         begin
  4782         begin
  4783             dX := AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandomf + _1);
  4783             dX := AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandomf + _1);
  4784             dY := AngleSin(i * 8) * _0_5 * (GetRandomf + _1);
  4784             dY := AngleSin(i * 8) * _0_5 * (GetRandomf + _1);
  4785             AddGear(gX, gY, gtFlame, 0, dX, dY, 0);
  4785             AddGear(gX, gY, gtFlame, 0, dX, dY, 0);
  4803     dec(Gear^.Timer)
  4803     dec(Gear^.Timer)
  4804 end;
  4804 end;
  4805 
  4805 
  4806 ////////////////////////////////////////////////////////////////////////////////
  4806 ////////////////////////////////////////////////////////////////////////////////
  4807 procedure doStepStructure(Gear: PGear);
  4807 procedure doStepStructure(Gear: PGear);
  4808 var 
  4808 var
  4809     x, y: LongInt;
  4809     x, y: LongInt;
  4810     HH: PHedgehog;
  4810     HH: PHedgehog;
  4811     t: PGear;
  4811     t: PGear;
  4812 begin
  4812 begin
  4813     HH:= Gear^.Hedgehog;
  4813     HH:= Gear^.Hedgehog;
  4820         Gear^.State:= Gear^.State and (not gstMoving);
  4820         Gear^.State:= Gear^.State and (not gstMoving);
  4821         end;
  4821         end;
  4822 
  4822 
  4823     dec(Gear^.Health, Gear^.Damage);
  4823     dec(Gear^.Health, Gear^.Damage);
  4824     Gear^.Damage:= 0;
  4824     Gear^.Damage:= 0;
  4825         
  4825 
  4826     if Gear^.Pos = 1 then
  4826     if Gear^.Pos = 1 then
  4827         begin
  4827         begin
  4828         AddGearCI(Gear);
  4828         AddGearCI(Gear);
  4829         AfterAttack;
  4829         AfterAttack;
  4830         if Gear = CurAmmoGear then
  4830         if Gear = CurAmmoGear then
  4831             CurAmmoGear:= nil;
  4831             CurAmmoGear:= nil;
  4832         if HH^.Gear <> nil then
  4832         if HH^.Gear <> nil then
  4833             HideHog(HH);
  4833             HideHog(HH);
  4834         Gear^.Pos:= 2
  4834         Gear^.Pos:= 2
  4835         end;
  4835         end;
  4836         
  4836 
  4837     if Gear^.Pos = 2 then
  4837     if Gear^.Pos = 2 then
  4838         begin
  4838         begin
  4839         if ((GameTicks mod 100) = 0) and (Gear^.Timer < 1000) then
  4839         if ((GameTicks mod 100) = 0) and (Gear^.Timer < 1000) then
  4840             begin
  4840             begin
  4841             if (Gear^.Timer mod 10) = 0 then
  4841             if (Gear^.Timer mod 10) = 0 then
  4847             inc(Gear^.Timer);
  4847             inc(Gear^.Timer);
  4848             end;
  4848             end;
  4849         if Gear^.Tag <= TotalRounds then
  4849         if Gear^.Tag <= TotalRounds then
  4850             Gear^.Pos:= 3;
  4850             Gear^.Pos:= 3;
  4851         end;
  4851         end;
  4852         
  4852 
  4853     if Gear^.Pos = 3 then
  4853     if Gear^.Pos = 3 then
  4854         if Gear^.Timer < 1000 then
  4854         if Gear^.Timer < 1000 then
  4855             begin
  4855             begin
  4856             if (Gear^.Timer mod 10) = 0 then
  4856             if (Gear^.Timer mod 10) = 0 then
  4857                 begin
  4857                 begin
  4865             begin
  4865             begin
  4866             if HH^.GearHidden <> nil then
  4866             if HH^.GearHidden <> nil then
  4867                 RestoreHog(HH);
  4867                 RestoreHog(HH);
  4868             Gear^.Pos:= 4;
  4868             Gear^.Pos:= 4;
  4869             end;
  4869             end;
  4870         
  4870 
  4871     if Gear^.Pos = 4 then
  4871     if Gear^.Pos = 4 then
  4872         if ((GameTicks mod 1000) = 0) and ((GameFlags and gfInvulnerable) = 0) then
  4872         if ((GameTicks mod 1000) = 0) and ((GameFlags and gfInvulnerable) = 0) then
  4873             begin
  4873             begin
  4874             t:= GearsList;
  4874             t:= GearsList;
  4875             while t <> nil do
  4875             while t <> nil do
  4877                 if (t^.Kind = gtHedgehog) and (t^.Hedgehog^.Team^.Clan = HH^.Team^.Clan) then
  4877                 if (t^.Kind = gtHedgehog) and (t^.Hedgehog^.Team^.Clan = HH^.Team^.Clan) then
  4878                     t^.Invulnerable:= true;
  4878                     t^.Invulnerable:= true;
  4879                 t:= t^.NextGear;
  4879                 t:= t^.NextGear;
  4880                 end;
  4880                 end;
  4881             end;
  4881             end;
  4882         
  4882 
  4883     if Gear^.Health <= 0 then
  4883     if Gear^.Health <= 0 then
  4884         begin
  4884         begin
  4885         if HH^.GearHidden <> nil then
  4885         if HH^.GearHidden <> nil then
  4886             RestoreHog(HH);
  4886             RestoreHog(HH);
  4887         
  4887 
  4888         x := hwRound(Gear^.X);
  4888         x := hwRound(Gear^.X);
  4889         y := hwRound(Gear^.Y);
  4889         y := hwRound(Gear^.Y);
  4890 
  4890 
  4891         DeleteCI(Gear);
  4891         DeleteCI(Gear);
  4892         DeleteGear(Gear);
  4892         DeleteGear(Gear);
  4895         end;
  4895         end;
  4896 end;
  4896 end;
  4897 
  4897 
  4898 ////////////////////////////////////////////////////////////////////////////////
  4898 ////////////////////////////////////////////////////////////////////////////////
  4899 (*
  4899 (*
  4900  TARDIS needs 
  4900  TARDIS needs
  4901  Warp in.  Pos = 1
  4901  Warp in.  Pos = 1
  4902  Pause.    Pos = 2
  4902  Pause.    Pos = 2
  4903  Hide gear  (TARDIS hedgehog was nil)
  4903  Hide gear  (TARDIS hedgehog was nil)
  4904  Warp out. Pos = 3
  4904  Warp out. Pos = 3
  4905  ... idle active for some time period ...  Pos = 4
  4905  ... idle active for some time period ...  Pos = 4
  4921         begin
  4921         begin
  4922         if (HH^.Gear <> nil) and (HH^.Gear^.State and gstInvisible = 0) then
  4922         if (HH^.Gear <> nil) and (HH^.Gear^.State and gstInvisible = 0) then
  4923             begin
  4923             begin
  4924             AfterAttack;
  4924             AfterAttack;
  4925             if Gear = CurAmmoGear then CurAmmoGear := nil;
  4925             if Gear = CurAmmoGear then CurAmmoGear := nil;
  4926             if (HH^.Gear^.Damage = 0) and  (HH^.Gear^.Health > 0) and 
  4926             if (HH^.Gear^.Damage = 0) and  (HH^.Gear^.Health > 0) and
  4927             ((Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
  4927             ((Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
  4928                 HideHog(HH)
  4928                 HideHog(HH)
  4929             end
  4929             end
  4930         //else if (HH^.Gear <> nil) and (HH^.Gear^.State and gstInvisible <> 0) then
  4930         //else if (HH^.Gear <> nil) and (HH^.Gear^.State and gstInvisible <> 0) then
  4931         else if (HH^.GearHidden <> nil) then// and (HH^.Gear^.State and gstInvisible <> 0) then
  4931         else if (HH^.GearHidden <> nil) then// and (HH^.Gear^.State and gstInvisible <> 0) then
  4941     end;
  4941     end;
  4942 
  4942 
  4943 if (Gear^.Pos = 1) and (GameTicks and $1F = 0) and (Gear^.Power < 255) then
  4943 if (Gear^.Pos = 1) and (GameTicks and $1F = 0) and (Gear^.Power < 255) then
  4944     begin
  4944     begin
  4945     inc(Gear^.Power);
  4945     inc(Gear^.Power);
  4946     if (Gear^.Power = 172) and (HH^.Gear <> nil) and 
  4946     if (Gear^.Power = 172) and (HH^.Gear <> nil) and
  4947         (HH^.Gear^.Damage = 0) and (HH^.Gear^.Health > 0) and
  4947         (HH^.Gear^.Damage = 0) and (HH^.Gear^.Health > 0) and
  4948         ((HH^.Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
  4948         ((HH^.Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
  4949             with HH^.Gear^ do
  4949             with HH^.Gear^ do
  4950                 begin
  4950                 begin
  4951                 State:= State or gstAnimation;
  4951                 State:= State or gstAnimation;
  4982                 inc(cnt);
  4982                 inc(cnt);
  4983     if (cnt = 0) or SuddenDeathDmg or (Gear^.Timer = 0) then
  4983     if (cnt = 0) or SuddenDeathDmg or (Gear^.Timer = 0) then
  4984         begin
  4984         begin
  4985         if HH^.GearHidden <> nil then
  4985         if HH^.GearHidden <> nil then
  4986             FindPlace(HH^.GearHidden, false, 0, LAND_WIDTH,true);
  4986             FindPlace(HH^.GearHidden, false, 0, LAND_WIDTH,true);
  4987             
  4987 
  4988         if HH^.GearHidden <> nil then
  4988         if HH^.GearHidden <> nil then
  4989             begin
  4989             begin
  4990             Gear^.X:= HH^.GearHidden^.X;
  4990             Gear^.X:= HH^.GearHidden^.X;
  4991             Gear^.Y:= HH^.GearHidden^.Y;
  4991             Gear^.Y:= HH^.GearHidden^.Y;
  4992             end;
  4992             end;
  5058 
  5058 
  5059 (*
  5059 (*
  5060 WIP. The ice gun will have the following effects.  It has been proposed by sheepluva that it take the appearance of a large freezer
  5060 WIP. The ice gun will have the following effects.  It has been proposed by sheepluva that it take the appearance of a large freezer
  5061 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.
  5061 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.
  5062 For now we assume a "ray" like a deagle projected out from the gun.
  5062 For now we assume a "ray" like a deagle projected out from the gun.
  5063 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".  
  5063 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".
  5064   * When fired at water a layer of ice textured land is added above the water.
  5064   * When fired at water a layer of ice textured land is added above the water.
  5065   * When fired at non-ice land (land and lfLandMask 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.
  5065   * When fired at non-ice land (land and lfLandMask 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.
  5066   * 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.
  5066   * 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.
  5067 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.
  5067 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.
  5068 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.
  5068 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.
  5069 *)
  5069 *)
  5070 
  5070 
  5071 
  5071 
  5072 procedure updateFuel(Gear: PGear);
  5072 procedure updateFuel(Gear: PGear);
  5073 var 
  5073 var
  5074   t:LongInt;
  5074   t:LongInt;
  5075 begin
  5075 begin
  5076     t:= Gear^.Health div 10;
  5076     t:= Gear^.Health div 10;
  5077     if (t <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
  5077     if (t <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
  5078     begin
  5078     begin
  5101     //unfreeze all semifrozen hogs - make this generic hog cleanup
  5101     //unfreeze all semifrozen hogs - make this generic hog cleanup
  5102 (*
  5102 (*
  5103     iter := GearsList;
  5103     iter := GearsList;
  5104     while iter <> nil do
  5104     while iter <> nil do
  5105         begin
  5105         begin
  5106         if (iter^.Kind = gtHedgehog) and 
  5106         if (iter^.Kind = gtHedgehog) and
  5107         (iter^.Hedgehog^.Effects[heFrozen] and $FF = 0) then 
  5107         (iter^.Hedgehog^.Effects[heFrozen] and $FF = 0) then
  5108         iter^.Hedgehog^.Effects[heFrozen]:= 0;
  5108         iter^.Hedgehog^.Effects[heFrozen]:= 0;
  5109         iter:= iter^.NextGear
  5109         iter:= iter^.NextGear
  5110         end 
  5110         end
  5111 *)
  5111 *)
  5112   end;
  5112   end;
  5113 end;
  5113 end;
  5114 
       
  5115 
  5114 
  5116 procedure doStepIceGun(Gear: PGear);
  5115 procedure doStepIceGun(Gear: PGear);
  5117 const iceWaitCollision:Longint = 0;
  5116 const iceWaitCollision:Longint = 0;
  5118 const iceCollideWithGround:Longint = 1;
  5117 const iceCollideWithGround:Longint = 1;
  5119 //const iceWaitNextTarget:Longint = 2;
  5118 //const iceWaitNextTarget:Longint = 2;
  5129     ndX, ndY: hwFloat;
  5128     ndX, ndY: hwFloat;
  5130     i, t, gX, gY: LongInt;
  5129     i, t, gX, gY: LongInt;
  5131     hogs: PGearArrayS;
  5130     hogs: PGearArrayS;
  5132 begin
  5131 begin
  5133     HHGear := Gear^.Hedgehog^.Gear;
  5132     HHGear := Gear^.Hedgehog^.Gear;
  5134     if (Gear^.Message and gmAttack <> 0) or (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) then
  5133     if (Gear^.Message and gmAttack <> 0) or (HHGear = nil) or (HHGear^.Damage <> 0) then
  5135         begin
  5134         begin
  5136         DeleteGear(Gear);
  5135         DeleteGear(Gear);
  5137         AfterAttack;
  5136         AfterAttack;
  5138         exit
  5137         exit
  5139         end
  5138         end
  5142     with Gear^ do
  5141     with Gear^ do
  5143         begin
  5142         begin
  5144         HedgehogChAngle(HHGear);
  5143         HedgehogChAngle(HHGear);
  5145         ndX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _4;
  5144         ndX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _4;
  5146         ndY:= -AngleCos(HHGear^.Angle) * _4;
  5145         ndY:= -AngleCos(HHGear^.Angle) * _4;
  5147         if (ndX <> dX) or (ndY <> dY) or 
  5146         if (ndX <> dX) or (ndY <> dY) or
  5148            ((Target.X <> NoPointX) and (Target.X and LAND_WIDTH_MASK = 0) and 
  5147            ((Target.X <> NoPointX) and (Target.X and LAND_WIDTH_MASK = 0) and
  5149              (Target.Y and LAND_HEIGHT_MASK = 0) and ((Land[Target.Y, Target.X] = 0))) then
  5148              (Target.Y and LAND_HEIGHT_MASK = 0) and ((Land[Target.Y, Target.X] = 0))) then
  5150             begin
  5149             begin
  5151                 updateTarget(Gear, ndX, ndY);
  5150                 updateTarget(Gear, ndX, ndY);
  5152                 IceState := iceWaitCollision;
  5151                 Health := iceWaitCollision;
  5153             end
  5152             end
  5154         else
  5153         else
  5155             begin
  5154             begin
  5156             X:= X + dX;
  5155             X:= X + dX;
  5157             Y:= Y + dY;
  5156             Y:= Y + dY;
  5158             gX:= hwRound(X);
  5157             gX:= hwRound(X);
  5159             gY:= hwRound(Y);    
  5158             gY:= hwRound(Y);
  5160             if Target.X = NoPointX then 
  5159             if Target.X = NoPointX then
  5161             begin
  5160             begin
  5162                 t:= hwRound(hwSqr(X-HHGear^.X)+hwSqr(Y-HHGear^.Y));
  5161                 t:= hwRound(hwSqr(X-HHGear^.X)+hwSqr(Y-HHGear^.Y));
  5163             end;
  5162             end;
  5164 
  5163 
  5165             if Target.X <> NoPointX then
  5164             if Target.X <> NoPointX then
  5166             begin
  5165             begin
  5167                 CheckCollisionWithLand(Gear);
  5166                 CheckCollisionWithLand(Gear);
  5168                 if (State and gstCollision) <> 0 then
  5167                 if (State and gstCollision) <> 0 then
  5169                 begin        
  5168                 begin
  5170                 if IceState = iceWaitCollision then
  5169                 if Health = iceWaitCollision then
  5171                     begin
  5170                     begin
  5172                     IceState := iceCollideWithGround;
  5171                     Health := iceCollideWithGround;
  5173                     IceTime := GameTicks;                    
  5172                     Power := GameTicks;
  5174                     end                    
  5173                     end
  5175                 end
  5174                 end
  5176                 else if (target.y >= cWaterLine) then
  5175                 else if (target.y >= cWaterLine) then
  5177                     begin
  5176                     begin
  5178                     if IceState = iceWaitCollision then
  5177                     if Health = iceWaitCollision then
  5179                         begin
  5178                         begin
  5180                         IceState := iceCollideWithWater;
  5179                         Health := iceCollideWithWater;
  5181                         IceTime := GameTicks;  
  5180                         Power := GameTicks;
  5182                         end;
  5181                         end;
  5183                     end;
  5182                     end;
  5184 
  5183 
  5185                 if (abs(gX-Target.X) < 2) and (abs(gY-Target.Y) < 2) then
  5184                 if (abs(gX-Target.X) < 2) and (abs(gY-Target.Y) < 2) then
  5186                     begin
  5185                     begin
  5187                     X:= HHGear^.X;
  5186                     X:= HHGear^.X;
  5188                     Y:= HHGear^.Y
  5187                     Y:= HHGear^.Y
  5189                     end;
  5188                     end;
  5190 
  5189 
  5191                 if (IceState = iceCollideWithGround) and ((GameTicks - IceTime) > groundFreezingTime) then
  5190                 if (Health = iceCollideWithGround) and ((GameTicks - Power) > groundFreezingTime) then
  5192                     begin 
  5191                     begin
  5193                     FillRoundInLand(target.x, target.y, iceRadius, icePixel);
  5192                     FillRoundInLand(target.x, target.y, iceRadius, icePixel);
  5194                     landRect.x := min(max(target.x - iceRadius, 0), LAND_WIDTH - 1);
  5193                     landRect.x := min(max(target.x - iceRadius, 0), LAND_WIDTH - 1);
  5195                     landRect.y := min(max(target.y - iceRadius, 0), LAND_HEIGHT - 1);
  5194                     landRect.y := min(max(target.y - iceRadius, 0), LAND_HEIGHT - 1);
  5196                     landRect.w := min(2*iceRadius, LAND_WIDTH - landRect.x - 1);
  5195                     landRect.w := min(2*iceRadius, LAND_WIDTH - landRect.x - 1);
  5197                     landRect.h := min(2*iceRadius, LAND_HEIGHT - landRect.y - 1);
  5196                     landRect.h := min(2*iceRadius, LAND_HEIGHT - landRect.y - 1);
  5198                     UpdateLandTexture(landRect.x, landRect.w, landRect.y, landRect.h, true);
  5197                     UpdateLandTexture(landRect.x, landRect.w, landRect.y, landRect.h, true);
  5199                             
  5198 
  5200                     // FillRoundInLandWithIce(Target.X, Target.Y, iceRadius);
  5199                     // FillRoundInLandWithIce(Target.X, Target.Y, iceRadius);
  5201                     SetAllHHToActive;
  5200                     SetAllHHToActive;
  5202                     IceState := iceWaitCollision;
  5201                     Health := iceWaitCollision;
  5203                     end;
  5202                     end;
  5204 
  5203 
  5205                 if (IceState = iceCollideWithWater) and ((GameTicks - IceTime) > groundFreezingTime) then
  5204                 if (Health = iceCollideWithWater) and ((GameTicks - Power) > groundFreezingTime) then
  5206                     begin                    
  5205                     begin
  5207                     DrawIceBreak(Target.X, cWaterLine - iceHeight, iceRadius, iceHeight);
  5206                     DrawIceBreak(Target.X, cWaterLine - iceHeight, iceRadius, iceHeight);
  5208                     SetAllHHToActive; 
  5207                     SetAllHHToActive;
  5209                     IceState := iceWaitCollision;
  5208                     Health := iceWaitCollision;
  5210                     end;
  5209                     end;
  5211 
  5210 
  5212 // freeze nearby hogs
  5211 // freeze nearby hogs
  5213                 hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2);
  5212                 hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2);
  5214                 if hogs.size > 0 then
  5213                 if hogs.size > 0 then
  5215                     for i:= 0 to hogs.size - 1 do
  5214                     for i:= 0 to hogs.size - 1 do
  5216                         if hogs.ar^[i] <> HHGear then
  5215                         if hogs.ar^[i] <> HHGear then
  5217                             if GameTicks mod 5 = 0 then 
  5216                             if GameTicks mod 5 = 0 then
  5218                                 begin
  5217                                 begin
  5219                                 hogs.ar^[i]^.Active:= true;
  5218                                 hogs.ar^[i]^.Active:= true;
  5220                                 if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] < 256 then
  5219                                 if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] < 256 then
  5221                                     hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] := hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] + 1
  5220                                     hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] := hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] + 1
  5222                                 else if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] = 256 then
  5221                                 else if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] = 256 then
  5314         begin
  5313         begin
  5315         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 300, CurrentHedgehog, EXPLAutoSound);
  5314         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 300, CurrentHedgehog, EXPLAutoSound);
  5316         DeleteGear(Gear)
  5315         DeleteGear(Gear)
  5317         end;
  5316         end;
  5318     // ssssss he essssscaped
  5317     // ssssss he essssscaped
  5319     if (Gear^.Timer > 250) and ((HHGear = nil) or 
  5318     if (Gear^.Timer > 250) and ((HHGear = nil) or
  5320             (((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) >  180) and
  5319             (((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) >  180) and
  5321             (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > _180))) then
  5320             (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > _180))) then
  5322         begin
  5321         begin
  5323         Gear^.State:= Gear^.State and (not gstTmpFlag);
  5322         Gear^.State:= Gear^.State and (not gstTmpFlag);
  5324         Gear^.Timer:= 0
  5323         Gear^.Timer:= 0
  5325         end;
  5324         end;
  5326     exit
  5325     exit
  5327     end;
  5326     end;
  5328 
  5327 
  5329 // 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
  5328 // 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
  5330 if (HHGear = nil) or (Gear^.Timer = 0) or 
  5329 if (HHGear = nil) or (Gear^.Timer = 0) or
  5331    (((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) >  Gear^.Angle) and
  5330    (((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) >  Gear^.Angle) and
  5332         (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > int2hwFloat(Gear^.Angle)))
  5331         (Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > int2hwFloat(Gear^.Angle)))
  5333     then
  5332     then
  5334     begin
  5333     begin
  5335     hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Angle);
  5334     hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Angle);
  5442 end;
  5441 end;
  5443 (*
  5442 (*
  5444  This didn't end up getting used, but, who knows, might be reasonable for javellin or something
  5443  This didn't end up getting used, but, who knows, might be reasonable for javellin or something
  5445 // Make the knife initial angle based on the hog attack angle, or is that too hard?
  5444 // Make the knife initial angle based on the hog attack angle, or is that too hard?
  5446 procedure doStepKnife(Gear: PGear);
  5445 procedure doStepKnife(Gear: PGear);
  5447 var t, 
  5446 var t,
  5448     gx, gy, ga,  // gear x,y,angle
  5447     gx, gy, ga,  // gear x,y,angle
  5449     lx, ly, la, // land x,y,angle
  5448     lx, ly, la, // land x,y,angle
  5450     ox, oy, // x,y offset
  5449     ox, oy, // x,y offset
  5451     w, h,   // wXh of clip area
  5450     w, h,   // wXh of clip area
  5452     tx, ty  // tip position in sprite
  5451     tx, ty  // tip position in sprite
  5466     if Gear^.State and gstDrowning <> 0 then exit;
  5465     if Gear^.State and gstDrowning <> 0 then exit;
  5467     with Gear^ do
  5466     with Gear^ do
  5468         begin
  5467         begin
  5469         if CheckLandValue(gx, gy, lfLandMask) then
  5468         if CheckLandValue(gx, gy, lfLandMask) then
  5470             begin
  5469             begin
  5471             t:= Angle + hwRound((hwAbs(dX)+hwAbs(dY)) * _10); 
  5470             t:= Angle + hwRound((hwAbs(dX)+hwAbs(dY)) * _10);
  5472 
  5471 
  5473             if t < 0 then inc(t, 4096)
  5472             if t < 0 then inc(t, 4096)
  5474             else if 4095 < t then dec(t, 4096);
  5473             else if 4095 < t then dec(t, 4096);
  5475             Angle:= t;
  5474             Angle:= t;
  5476 
  5475 
  5503                     tx:=   0; ty:= 14
  5502                     tx:=   0; ty:= 14
  5504                     end;
  5503                     end;
  5505                 4:  begin
  5504                 4:  begin
  5506                     ox:= 29; oy:=  8;
  5505                     ox:= 29; oy:=  8;
  5507                      w:= 19;  h:= 19;
  5506                      w:= 19;  h:= 19;
  5508                     tx:=  0; ty:= 17 
  5507                     tx:=  0; ty:= 17
  5509                     end;
  5508                     end;
  5510                 5:  begin
  5509                 5:  begin
  5511                     ox:= 29; oy:=  32;
  5510                     ox:= 29; oy:=  32;
  5512                      w:= 15;  h:=  21;
  5511                      w:= 15;  h:=  21;
  5513                     tx:=  0; ty:=  20
  5512                     tx:=  0; ty:=  20
  5514                     end;
  5513                     end;
  5515                 6:  begin
  5514                 6:  begin
  5516                     ox:= 51; oy:=   3;
  5515                     ox:= 51; oy:=   3;
  5517                      w:= 11;  h:=  23;
  5516                      w:= 11;  h:=  23;
  5518                     tx:=  0; ty:=  22 
  5517                     tx:=  0; ty:=  22
  5519                     end;
  5518                     end;
  5520                 7:  begin
  5519                 7:  begin
  5521                     ox:= 51; oy:=  34;
  5520                     ox:= 51; oy:=  34;
  5522                      w:=  7;  h:=  24;
  5521                      w:=  7;  h:=  24;
  5523                     tx:=  0; ty:=  23
  5522                     tx:=  0; ty:=  23
  5524                     end
  5523                     end
  5525                 end;
  5524                 end;
  5526                 
  5525 
  5527             surf:= SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RMask, GMask, BMask, AMask);
  5526             surf:= SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RMask, GMask, BMask, AMask);
  5528             copyToXYFromRect(SpritesData[sprKnife].Surface, surf, ox, oy, w, h, 0, 0);
  5527             copyToXYFromRect(SpritesData[sprKnife].Surface, surf, ox, oy, w, h, 0, 0);
  5529             // try to make the knife hit point first
  5528             // try to make the knife hit point first
  5530             lx := 0;
  5529             lx := 0;
  5531             ly := 0;
  5530             ly := 0;
  5543                     else if Angle < 2048 then inc(Angle, 2048)
  5542                     else if Angle < 2048 then inc(Angle, 2048)
  5544                     end;
  5543                     end;
  5545                 AddFileLog('la: '+inttostr(la)+' ga: '+inttostr(ga)+' Angle: '+inttostr(Angle))
  5544                 AddFileLog('la: '+inttostr(la)+' ga: '+inttostr(ga)+' Angle: '+inttostr(Angle))
  5546                 end;
  5545                 end;
  5547             case Angle div 1024 of
  5546             case Angle div 1024 of
  5548                 0:  begin 
  5547                 0:  begin
  5549                     flipSurface(surf, true);
  5548                     flipSurface(surf, true);
  5550                     flipSurface(surf, true);
  5549                     flipSurface(surf, true);
  5551                     BlitImageAndGenerateCollisionInfo(gx-(w-tx), gy-(h-ty), w, surf)
  5550                     BlitImageAndGenerateCollisionInfo(gx-(w-tx), gy-(h-ty), w, surf)
  5552                     end;
  5551                     end;
  5553                 1:  begin
  5552                 1:  begin