hedgewars/GSHandlers.inc
changeset 2948 3f21a9dc93d0
parent 2944 e8a891bf6660
child 2955 fb361d137524
equal deleted inserted replaced
2947:803b277e4894 2948:3f21a9dc93d0
    18 
    18 
    19 procedure makeHogsWorry(x, y: hwFloat; r: LongInt);
    19 procedure makeHogsWorry(x, y: hwFloat; r: LongInt);
    20 var gi: PGear;
    20 var gi: PGear;
    21      d: LongInt;
    21      d: LongInt;
    22 begin
    22 begin
    23 	gi:= GearsList;
    23     gi:= GearsList;
    24 	while gi <> nil do
    24     while gi <> nil do
    25 		begin
    25         begin
    26 		d:= r - hwRound(Distance(gi^.X - x, gi^.Y - y));
    26         d:= r - hwRound(Distance(gi^.X - x, gi^.Y - y));
    27 		if (d > 1) and (gi^.Kind = gtHedgehog) and not gi^.Invulnerable and (GetRandom(2) = 0) then
    27         if (d > 1) and (gi^.Kind = gtHedgehog) and not gi^.Invulnerable and (GetRandom(2) = 0) then
    28 			begin
    28             begin
    29 			if (CurrentHedgehog^.Gear = gi) then
    29             if (CurrentHedgehog^.Gear = gi) then
    30 				PlaySound(sndOops, PHedgehog(gi^.Hedgehog)^.Team^.voicepack)
    30                 PlaySound(sndOops, PHedgehog(gi^.Hedgehog)^.Team^.voicepack)
    31 			else
    31             else
    32 				begin
    32                 begin
    33 				if (gi^.State and gstMoving) = 0 then
    33                 if (gi^.State and gstMoving) = 0 then
    34 					gi^.State:= gi^.State or gstLoser;
    34                     gi^.State:= gi^.State or gstLoser;
    35 				if d > r div 2 then
    35                 if d > r div 2 then
    36 					PlaySound(sndNooo, PHedgehog(gi^.Hedgehog)^.Team^.voicepack)
    36                     PlaySound(sndNooo, PHedgehog(gi^.Hedgehog)^.Team^.voicepack)
    37 				else
    37                 else
    38 					PlaySound(sndUhOh, PHedgehog(gi^.Hedgehog)^.Team^.voicepack);
    38                     PlaySound(sndUhOh, PHedgehog(gi^.Hedgehog)^.Team^.voicepack);
    39 				end;
    39                 end;
    40 			end;
    40             end;
    41 		gi:= gi^.NextGear
    41         gi:= gi^.NextGear
    42 		end;
    42         end;
    43 end;
    43 end;
    44 ////////////////////////////////////////////////////////////////////////////////
    44 ////////////////////////////////////////////////////////////////////////////////
    45 procedure doStepDrowningGear(Gear: PGear); forward;
    45 procedure doStepDrowningGear(Gear: PGear); forward;
    46 
    46 
    47 function CheckGearDrowning(Gear: PGear): boolean;
    47 function CheckGearDrowning(Gear: PGear): boolean;
    66         begin
    66         begin
    67         CheckGearDrowning:= true;
    67         CheckGearDrowning:= true;
    68         Gear^.State:= gstDrowning;
    68         Gear^.State:= gstDrowning;
    69         Gear^.RenderTimer:= false;
    69         Gear^.RenderTimer:= false;
    70         Gear^.doStep:= @doStepDrowningGear;
    70         Gear^.doStep:= @doStepDrowningGear;
    71 		if Gear^.Kind = gtHedgehog then
    71         if Gear^.Kind = gtHedgehog then
    72 			begin
    72             begin
    73 			Gear^.State:= Gear^.State and (not gstHHDriven);
    73             Gear^.State:= Gear^.State and (not gstHHDriven);
    74 			AddCaption(Format(GetEventString(eidDrowned), PHedgehog(Gear^.Hedgehog)^.Name), cWhiteColor, capgrpMessage);
    74             AddCaption(Format(GetEventString(eidDrowned), PHedgehog(Gear^.Hedgehog)^.Name), cWhiteColor, capgrpMessage);
    75 			end
    75             end
    76         end;
    76         end;
    77     PlaySound(sndSplash)
    77     PlaySound(sndSplash)
    78     end
    78     end
    79     else
    79     else
    80 	CheckGearDrowning:= false
    80     CheckGearDrowning:= false
    81 end;
    81 end;
    82 
    82 
    83 procedure CheckCollision(Gear: PGear);
    83 procedure CheckCollision(Gear: PGear);
    84 begin
    84 begin
    85 if TestCollisionXwithGear(Gear, hwSign(Gear^.X)) or TestCollisionYwithGear(Gear, hwSign(Gear^.Y))
    85 if TestCollisionXwithGear(Gear, hwSign(Gear^.X)) or TestCollisionYwithGear(Gear, hwSign(Gear^.Y))
    86 	then Gear^.State:= Gear^.State or      gstCollision
    86     then Gear^.State:= Gear^.State or      gstCollision
    87 	else Gear^.State:= Gear^.State and not gstCollision
    87     else Gear^.State:= Gear^.State and not gstCollision
    88 end;
    88 end;
    89 
    89 
    90 procedure CheckHHDamage(Gear: PGear);
    90 procedure CheckHHDamage(Gear: PGear);
    91 var 
    91 var 
    92 	dmg: Longword;
    92     dmg: Longword;
    93 	i: LongInt;
    93     i: LongInt;
    94 	particle: PVisualGear;
    94     particle: PVisualGear;
    95 begin
    95 begin
    96 if _0_4 < Gear^.dY then
    96 if _0_4 < Gear^.dY then
    97 	begin
    97     begin
    98 	dmg:= ModifyDamage(1 + hwRound((hwAbs(Gear^.dY) - _0_4) * 70), Gear);
    98     dmg:= ModifyDamage(1 + hwRound((hwAbs(Gear^.dY) - _0_4) * 70), Gear);
    99     if dmg < 1 then exit;
    99     if dmg < 1 then exit;
   100 
   100 
   101 	for i:= min(12, (3 + dmg div 10)) downto 0 do begin
   101     for i:= min(12, (3 + dmg div 10)) downto 0 do begin
   102 		particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
   102         particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
   103         if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX / 5);
   103         if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX / 5);
   104 		end;
   104         end;
   105 
   105 
   106     if(Gear^.Invulnerable) then exit;
   106     if(Gear^.Invulnerable) then exit;
   107 
   107 
   108 	if _0_6 < Gear^.dY then
   108     if _0_6 < Gear^.dY then
   109 		PlaySound(sndOw4, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack)
   109         PlaySound(sndOw4, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack)
   110 	else
   110     else
   111 		PlaySound(sndOw1, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack);
   111         PlaySound(sndOw1, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack);
   112 
   112 
   113     ApplyDamage(Gear, dmg);
   113     ApplyDamage(Gear, dmg);
   114 	end
   114     end
   115 end;
   115 end;
   116 
   116 
   117 ////////////////////////////////////////////////////////////////////////////////
   117 ////////////////////////////////////////////////////////////////////////////////
   118 ////////////////////////////////////////////////////////////////////////////////
   118 ////////////////////////////////////////////////////////////////////////////////
   119 procedure CalcRotationDirAngle(Gear: PGear);
   119 procedure CalcRotationDirAngle(Gear: PGear);
   120 var dAngle: real;
   120 var dAngle: real;
   121 begin
   121 begin
   122 dAngle:= (hwAbs(Gear^.dX) + hwAbs(Gear^.dY)).QWordValue / $80000000;
   122 dAngle:= (hwAbs(Gear^.dX) + hwAbs(Gear^.dY)).QWordValue / $80000000;
   123 if not Gear^.dX.isNegative then
   123 if not Gear^.dX.isNegative then
   124 	Gear^.DirAngle:= Gear^.DirAngle + dAngle
   124     Gear^.DirAngle:= Gear^.DirAngle + dAngle
   125 else
   125 else
   126 	Gear^.DirAngle:= Gear^.DirAngle - dAngle;
   126     Gear^.DirAngle:= Gear^.DirAngle - dAngle;
   127 
   127 
   128 if Gear^.DirAngle < 0 then Gear^.DirAngle:= Gear^.DirAngle + 360
   128 if Gear^.DirAngle < 0 then Gear^.DirAngle:= Gear^.DirAngle + 360
   129 else if 360 < Gear^.DirAngle then Gear^.DirAngle:= Gear^.DirAngle - 360
   129 else if 360 < Gear^.DirAngle then Gear^.DirAngle:= Gear^.DirAngle - 360
   130 end;
   130 end;
   131 
   131 
   149 var isFalling: boolean;
   149 var isFalling: boolean;
   150 begin
   150 begin
   151 Gear^.State:= Gear^.State and not gstCollision;
   151 Gear^.State:= Gear^.State and not gstCollision;
   152 
   152 
   153 if Gear^.dY.isNegative then
   153 if Gear^.dY.isNegative then
   154 	begin
   154     begin
   155 	isFalling:= true;
   155     isFalling:= true;
   156 	if TestCollisionYwithGear(Gear, -1) then
   156     if TestCollisionYwithGear(Gear, -1) then
   157 		begin
   157         begin
   158 		Gear^.dX:=   Gear^.dX * Gear^.Friction;
   158         Gear^.dX:=   Gear^.dX * Gear^.Friction;
   159 		Gear^.dY:= - Gear^.dY * Gear^.Elasticity;
   159         Gear^.dY:= - Gear^.dY * Gear^.Elasticity;
   160 		Gear^.State:= Gear^.State or gstCollision
   160         Gear^.State:= Gear^.State or gstCollision
   161 		end
   161         end
   162 	end else
   162     end else
   163 	if TestCollisionYwithGear(Gear, 1) then
   163     if TestCollisionYwithGear(Gear, 1) then
   164 		begin
   164         begin
   165 		isFalling:= false;
   165         isFalling:= false;
   166 		Gear^.dX:=   Gear^.dX * Gear^.Friction;
   166         Gear^.dX:=   Gear^.dX * Gear^.Friction;
   167 		Gear^.dY:= - Gear^.dY * Gear^.Elasticity;
   167         Gear^.dY:= - Gear^.dY * Gear^.Elasticity;
   168 		Gear^.State:= Gear^.State or gstCollision
   168         Gear^.State:= Gear^.State or gstCollision
   169 		end else isFalling:= true;
   169         end else isFalling:= true;
   170 
   170 
   171 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
   171 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
   172 	begin
   172     begin
   173 	Gear^.dX:= - Gear^.dX * Gear^.Elasticity;
   173     Gear^.dX:= - Gear^.dX * Gear^.Elasticity;
   174 	Gear^.dY:=   Gear^.dY * Gear^.Elasticity;
   174     Gear^.dY:=   Gear^.dY * Gear^.Elasticity;
   175 	Gear^.State:= Gear^.State or gstCollision
   175     Gear^.State:= Gear^.State or gstCollision
   176 	end;
   176     end;
   177 
   177 
   178 if isFalling then Gear^.dY:= Gear^.dY + cGravity;
   178 if isFalling then Gear^.dY:= Gear^.dY + cGravity;
   179 
   179 
   180 Gear^.X:= Gear^.X + Gear^.dX;
   180 Gear^.X:= Gear^.X + Gear^.dX;
   181 Gear^.Y:= Gear^.Y + Gear^.dY;
   181 Gear^.Y:= Gear^.Y + Gear^.dY;
   182 CheckGearDrowning(Gear);
   182 CheckGearDrowning(Gear);
   183 if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and
   183 if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and
   184 	(not isFalling) then
   184     (not isFalling) then
   185 	Gear^.State:= Gear^.State and not gstMoving
   185     Gear^.State:= Gear^.State and not gstMoving
   186 else
   186 else
   187 	Gear^.State:= Gear^.State or      gstMoving
   187     Gear^.State:= Gear^.State or      gstMoving
   188 end;
   188 end;
   189 
   189 
   190 ////////////////////////////////////////////////////////////////////////////////
   190 ////////////////////////////////////////////////////////////////////////////////
   191 procedure doStepBomb(Gear: PGear);
   191 procedure doStepBomb(Gear: PGear);
   192 var i: LongInt;
   192 var i: LongInt;
   197 
   197 
   198 doStepFallingGear(Gear);
   198 doStepFallingGear(Gear);
   199 
   199 
   200 dec(Gear^.Timer);
   200 dec(Gear^.Timer);
   201 if Gear^.Timer = 1000 then // might need adjustments
   201 if Gear^.Timer = 1000 then // might need adjustments
   202 	case Gear^.Kind of
   202     case Gear^.Kind of
   203 		gtAmmo_Bomb: makeHogsWorry(Gear^.X, Gear^.Y, 50);
   203         gtAmmo_Bomb: makeHogsWorry(Gear^.X, Gear^.Y, 50);
   204 		gtClusterBomb: makeHogsWorry(Gear^.X, Gear^.Y, 20);
   204         gtClusterBomb: makeHogsWorry(Gear^.X, Gear^.Y, 20);
   205 		gtWatermelon: makeHogsWorry(Gear^.X, Gear^.Y, 75);
   205         gtWatermelon: makeHogsWorry(Gear^.X, Gear^.Y, 75);
   206 		gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90);
   206         gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90);
   207 	end;
   207     end;
   208 if Gear^.Timer = 0 then
   208 if Gear^.Timer = 0 then
   209 	begin
   209     begin
   210 	case Gear^.Kind of
   210     case Gear^.Kind of
   211 		gtAmmo_Bomb: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound);
   211         gtAmmo_Bomb: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound);
   212 		     gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, EXPLAutoSound);
   212              gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, EXPLAutoSound);
   213 		gtClusterBomb: begin
   213         gtClusterBomb: begin
   214 				doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, EXPLAutoSound);
   214                 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, EXPLAutoSound);
   215 				for i:= 0 to 4 do
   215                 for i:= 0 to 4 do
   216 					begin
   216                     begin
   217 					dX:= rndSign(GetRandom * _0_1);
   217                     dX:= rndSign(GetRandom * _0_1);
   218 					dY:= (GetRandom - _3) * _0_08;
   218                     dY:= (GetRandom - _3) * _0_08;
   219 					AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25);
   219                     AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25);
   220 					end
   220                     end
   221 				end;
   221                 end;
   222 		gtWatermelon: begin
   222         gtWatermelon: begin
   223 				doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, EXPLAutoSound);
   223                 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, EXPLAutoSound);
   224 				for i:= 0 to 5 do
   224                 for i:= 0 to 5 do
   225 					begin
   225                     begin
   226 					dX:= rndSign(GetRandom * _0_1);
   226                     dX:= rndSign(GetRandom * _0_1);
   227 					dY:= (GetRandom - _1_5) * _0_3;
   227                     dY:= (GetRandom - _1_5) * _0_3;
   228 					AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMelonPiece, 0, dX, dY, 75)^.DirAngle:= i * 60;
   228                     AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMelonPiece, 0, dX, dY, 75)^.DirAngle:= i * 60;
   229 					end
   229                     end
   230 				end;
   230                 end;
   231 		gtHellishBomb: begin
   231         gtHellishBomb: begin
   232 				doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 90, EXPLAutoSound);
   232                 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 90, EXPLAutoSound);
   233 				for i:= 0 to 127 do
   233                 for i:= 0 to 127 do
   234 					begin
   234                     begin
   235 					dX:= AngleCos(i * 16) * _0_5 * (GetRandom + _1);
   235                     dX:= AngleCos(i * 16) * _0_5 * (GetRandom + _1);
   236 					dY:= AngleSin(i * 16) * _0_5 * (GetRandom + _1);
   236                     dY:= AngleSin(i * 16) * _0_5 * (GetRandom + _1);
   237                     Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0);
   237                     Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0);
   238                     if i mod 2 = 0 then Fire^.State:= Fire^.State or gsttmpFlag;
   238                     if i mod 2 = 0 then Fire^.State:= Fire^.State or gsttmpFlag;
   239                     Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0);
   239                     Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0);
   240                     if i mod 2 <> 0 then Fire^.State:= Fire^.State or gsttmpFlag;
   240                     if i mod 2 <> 0 then Fire^.State:= Fire^.State or gsttmpFlag;
   241 					end
   241                     end
   242 				end;
   242                 end;
   243 		end;
   243         end;
   244 	DeleteGear(Gear);
   244     DeleteGear(Gear);
   245 	exit
   245     exit
   246 	end;
   246     end;
   247 
   247 
   248 CalcRotationDirAngle(Gear);
   248 CalcRotationDirAngle(Gear);
   249 
   249 
   250 if Gear^.Kind = gtHellishBomb then
   250 if Gear^.Kind = gtHellishBomb then
   251 	begin
   251     begin
   252 	if Gear^.Timer = 3000 then PlaySound(sndHellish);
   252     if Gear^.Timer = 3000 then PlaySound(sndHellish);
   253 
   253 
   254 	if (GameTicks and $3F) = 0 then
   254     if (GameTicks and $3F) = 0 then
   255 		if (Gear^.State and gstCollision) = 0 then
   255         if (Gear^.State and gstCollision) = 0 then
   256 			AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtEvilTrace, 0, _0, _0, 0);
   256             AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtEvilTrace, 0, _0, _0, 0);
   257 	end;
   257     end;
   258 
   258 
   259 if (Gear^.State and (gstCollision or gstMoving)) = (gstCollision or gstMoving) then
   259 if (Gear^.State and (gstCollision or gstMoving)) = (gstCollision or gstMoving) then
   260 	if (hwAbs(Gear^.dX) > _0_1) or
   260     if (hwAbs(Gear^.dX) > _0_1) or
   261 	   (hwAbs(Gear^.dY) > _0_1) then
   261        (hwAbs(Gear^.dY) > _0_1) then
   262 		PlaySound(sndGrenadeImpact)
   262         PlaySound(sndGrenadeImpact)
   263 end;
   263 end;
   264 ////////////////////////////////////////////////////////////////////////////////
   264 ////////////////////////////////////////////////////////////////////////////////
   265 procedure doStepMolotov(Gear: PGear);
   265 procedure doStepMolotov(Gear: PGear);
   266 var i: LongInt;
   266 var i: LongInt;
   267     dX, dY: hwFloat;
   267     dX, dY: hwFloat;
   268 	Fire: PGear;
   268     Fire: PGear;
   269 begin
   269 begin
   270 	AllInactive:= false;
   270     AllInactive:= false;
   271 	
   271     
   272 	doStepFallingGear(Gear);
   272     doStepFallingGear(Gear);
   273 	CalcRotationDirAngle(Gear);
   273     CalcRotationDirAngle(Gear);
   274 
   274 
   275 	if (Gear^.State and gstCollision) <> 0 then begin
   275     if (Gear^.State and gstCollision) <> 0 then begin
   276 		PlaySound(sndMolotov);
   276         PlaySound(sndMolotov);
   277 		//doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 5, EXPLAutoSound);
   277         //doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 5, EXPLAutoSound);
   278 		for i:= 0 to 20 do begin
   278         for i:= 0 to 20 do begin
   279 				dX:= AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandom + _1);
   279                 dX:= AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandom + _1);
   280 				dY:= AngleSin(i * 8) * _0_5 * (GetRandom + _1);
   280                 dY:= AngleSin(i * 8) * _0_5 * (GetRandom + _1);
   281 				Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0);
   281                 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0);
   282 				Fire^.State:= Fire^.State or gsttmpFlag;
   282                 Fire^.State:= Fire^.State or gsttmpFlag;
   283 				Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0);
   283                 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0);
   284 				Fire^.State:= Fire^.State or gsttmpFlag;
   284                 Fire^.State:= Fire^.State or gsttmpFlag;
   285 				Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, -dX, dY, 0);
   285                 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, -dX, dY, 0);
   286 				Fire^.State:= Fire^.State or gsttmpFlag;
   286                 Fire^.State:= Fire^.State or gsttmpFlag;
   287 				Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, -dX, -dY, 0);
   287                 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, -dX, -dY, 0);
   288 				Fire^.State:= Fire^.State or gsttmpFlag;
   288                 Fire^.State:= Fire^.State or gsttmpFlag;
   289 		end;
   289         end;
   290 		DeleteGear(Gear);
   290         DeleteGear(Gear);
   291 		exit
   291         exit
   292 	end;
   292     end;
   293 end;
   293 end;
   294 
   294 
   295 procedure doStepWatermelon(Gear: PGear);
   295 procedure doStepWatermelon(Gear: PGear);
   296 begin
   296 begin
   297 AllInactive:= false;
   297 AllInactive:= false;
   301 procedure doStepCluster(Gear: PGear);
   301 procedure doStepCluster(Gear: PGear);
   302 begin
   302 begin
   303 AllInactive:= false;
   303 AllInactive:= false;
   304 doStepFallingGear(Gear);
   304 doStepFallingGear(Gear);
   305 if (Gear^.State and gstCollision) <> 0 then
   305 if (Gear^.State and gstCollision) <> 0 then
   306 	begin
   306     begin
   307 	doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Timer, EXPLAutoSound);
   307     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Timer, EXPLAutoSound);
   308 	DeleteGear(Gear);
   308     DeleteGear(Gear);
   309 	exit
   309     exit
   310 	end;
   310     end;
   311 
   311 
   312 if Gear^.Kind = gtMelonPiece then
   312 if Gear^.Kind = gtMelonPiece then
   313 	CalcRotationDirAngle(Gear)
   313     CalcRotationDirAngle(Gear)
   314 else
   314 else
   315 	if (GameTicks and $1F) = 0 then
   315     if (GameTicks and $1F) = 0 then
   316 		AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0)
   316         AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0)
   317 end;
   317 end;
   318 
   318 
   319 ////////////////////////////////////////////////////////////////////////////////
   319 ////////////////////////////////////////////////////////////////////////////////
   320 procedure doStepGrenade(Gear: PGear);
   320 procedure doStepGrenade(Gear: PGear);
   321 begin
   321 begin
   322 AllInactive:= false;
   322 AllInactive:= false;
   323 Gear^.dX:= Gear^.dX + cWindSpeed;
   323 Gear^.dX:= Gear^.dX + cWindSpeed;
   324 doStepFallingGear(Gear);
   324 doStepFallingGear(Gear);
   325 if (Gear^.State and gstCollision) <> 0 then
   325 if (Gear^.State and gstCollision) <> 0 then
   326 	begin
   326     begin
   327 	doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound);
   327     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound);
   328 	DeleteGear(Gear);
   328     DeleteGear(Gear);
   329 	exit
   329     exit
   330 	end;
   330     end;
   331 if (GameTicks and $3F) = 0 then
   331 if (GameTicks and $3F) = 0 then
   332 	AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0)
   332     AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0)
   333 end;
   333 end;
   334 
   334 
   335 ////////////////////////////////////////////////////////////////////////////////
   335 ////////////////////////////////////////////////////////////////////////////////
   336 procedure doStepHealthTagWork(Gear: PGear);
   336 procedure doStepHealthTagWork(Gear: PGear);
   337 begin
   337 begin
   338 if Gear^.Kind = gtHealthTag then
   338 if Gear^.Kind = gtHealthTag then
   339 	AllInactive:= false;
   339     AllInactive:= false;
   340 
   340 
   341 dec(Gear^.Timer);
   341 dec(Gear^.Timer);
   342 Gear^.Y:= Gear^.Y + Gear^.dY;
   342 Gear^.Y:= Gear^.Y + Gear^.dY;
   343 
   343 
   344 if Gear^.Timer = 0 then
   344 if Gear^.Timer = 0 then
   345 	begin
   345     begin
   346 	if (Gear^.Kind = gtHealthTag) and (PHedgehog(Gear^.Hedgehog)^.Gear <> nil) then
   346     if (Gear^.Kind = gtHealthTag) and (PHedgehog(Gear^.Hedgehog)^.Gear <> nil) then
   347 		PHedgehog(Gear^.Hedgehog)^.Gear^.Active:= true; // to let current hh die
   347         PHedgehog(Gear^.Hedgehog)^.Gear^.Active:= true; // to let current hh die
   348 	DeleteGear(Gear)
   348     DeleteGear(Gear)
   349 	end
   349     end
   350 end;
   350 end;
   351 
   351 
   352 procedure doStepHealthTagWorkUnderWater(Gear: PGear);
   352 procedure doStepHealthTagWorkUnderWater(Gear: PGear);
   353 begin
   353 begin
   354 AllInactive:= false;
   354 AllInactive:= false;
   355 
   355 
   356 Gear^.Y:= Gear^.Y - _0_08;
   356 Gear^.Y:= Gear^.Y - _0_08;
   357 
   357 
   358 if hwRound(Gear^.Y) < cWaterLine + 10 then
   358 if hwRound(Gear^.Y) < cWaterLine + 10 then
   359 	DeleteGear(Gear)
   359     DeleteGear(Gear)
   360 end;
   360 end;
   361 
   361 
   362 procedure doStepHealthTag(Gear: PGear);
   362 procedure doStepHealthTag(Gear: PGear);
   363 var s: shortstring;
   363 var s: shortstring;
   364 begin
   364 begin
   367 
   367 
   368 str(Gear^.State, s);
   368 str(Gear^.State, s);
   369 Gear^.Tex:= RenderStringTex(s, PHedgehog(Gear^.Hedgehog)^.Team^.Clan^.Color, fnt16);
   369 Gear^.Tex:= RenderStringTex(s, PHedgehog(Gear^.Hedgehog)^.Team^.Clan^.Color, fnt16);
   370 
   370 
   371 if hwRound(Gear^.Y) < cWaterLine then
   371 if hwRound(Gear^.Y) < cWaterLine then
   372 	Gear^.doStep:= @doStepHealthTagWork
   372     Gear^.doStep:= @doStepHealthTagWork
   373 else
   373 else
   374 	Gear^.doStep:= @doStepHealthTagWorkUnderWater;
   374     Gear^.doStep:= @doStepHealthTagWorkUnderWater;
   375 
   375 
   376 Gear^.Y:= Gear^.Y - int2hwFloat(Gear^.Tex^.h)
   376 Gear^.Y:= Gear^.Y - int2hwFloat(Gear^.Tex^.h)
   377 end;
   377 end;
   378 
   378 
   379 ////////////////////////////////////////////////////////////////////////////////
   379 ////////////////////////////////////////////////////////////////////////////////
   457 procedure doStepShotIdle(Gear: PGear);
   457 procedure doStepShotIdle(Gear: PGear);
   458 begin
   458 begin
   459 AllInactive:= false;
   459 AllInactive:= false;
   460 inc(Gear^.Timer);
   460 inc(Gear^.Timer);
   461 if Gear^.Timer > 75 then
   461 if Gear^.Timer > 75 then
   462 	begin
   462     begin
   463 	DeleteGear(Gear);
   463     DeleteGear(Gear);
   464 	AfterAttack
   464     AfterAttack
   465 	end
   465     end
   466 end;
   466 end;
   467 
   467 
   468 procedure doStepShotgunShot(Gear: PGear);
   468 procedure doStepShotgunShot(Gear: PGear);
   469 var i: LongWord;
   469 var i: LongWord;
   470     shell: PVisualGear;
   470     shell: PVisualGear;
   471 begin
   471 begin
   472 AllInactive:= false;
   472 AllInactive:= false;
   473 
   473 
   474 if ((Gear^.State and gstAnimation) = 0) then
   474 if ((Gear^.State and gstAnimation) = 0) then
   475 	begin
   475     begin
   476 	dec(Gear^.Timer);
   476     dec(Gear^.Timer);
   477 	if Gear^.Timer = 0 then
   477     if Gear^.Timer = 0 then
   478 		begin
   478         begin
   479 		PlaySound(sndShotgunFire);
   479         PlaySound(sndShotgunFire);
   480 		shell:= AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell);
   480         shell:= AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell);
   481         if shell <> nil then
   481         if shell <> nil then
   482         begin 
   482         begin 
   483            shell^.dX:= gear^.dX / -4;
   483            shell^.dX:= gear^.dX / -4;
   484            shell^.dY:= gear^.dY / -4;
   484            shell^.dY:= gear^.dY / -4;
   485            shell^.Frame:= 0
   485            shell^.Frame:= 0
   486         end;
   486         end;
   487 		Gear^.State:= Gear^.State or gstAnimation
   487         Gear^.State:= Gear^.State or gstAnimation
   488 		end;
   488         end;
   489 	exit
   489     exit
   490 	end
   490     end
   491 	else inc(Gear^.Timer);
   491     else inc(Gear^.Timer);
   492 
   492 
   493 i:= 200;
   493 i:= 200;
   494 repeat
   494 repeat
   495 Gear^.X:= Gear^.X + Gear^.dX;
   495 Gear^.X:= Gear^.X + Gear^.dX;
   496 Gear^.Y:= Gear^.Y + Gear^.dY;
   496 Gear^.Y:= Gear^.Y + Gear^.dY;
   497 CheckCollision(Gear);
   497 CheckCollision(Gear);
   498 if (Gear^.State and gstCollision) <> 0 then
   498 if (Gear^.State and gstCollision) <> 0 then
   499 	begin
   499     begin
   500 	Gear^.X:= Gear^.X + Gear^.dX * 8;
   500     Gear^.X:= Gear^.X + Gear^.dX * 8;
   501 	Gear^.Y:= Gear^.Y + Gear^.dY * 8;
   501     Gear^.Y:= Gear^.Y + Gear^.dY * 8;
   502 	ShotgunShot(Gear);
   502     ShotgunShot(Gear);
   503 	Gear^.doStep:= @doStepShotIdle;
   503     Gear^.doStep:= @doStepShotIdle;
   504 	exit
   504     exit
   505 	end;
   505     end;
   506 dec(i)
   506 dec(i)
   507 until i = 0;
   507 until i = 0;
   508 if (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then
   508 if (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then
   509 	Gear^.doStep:= @doStepShotIdle
   509     Gear^.doStep:= @doStepShotIdle
   510 end;
   510 end;
   511 
   511 
   512 ////////////////////////////////////////////////////////////////////////////////
   512 ////////////////////////////////////////////////////////////////////////////////
   513 procedure doStepBulletWork(Gear: PGear);
   513 procedure doStepBulletWork(Gear: PGear);
   514 var i, x, y: LongWord;
   514 var i, x, y: LongWord;
   539    dec(Gear^.Health, Gear^.Damage);
   539    dec(Gear^.Health, Gear^.Damage);
   540    Gear^.Damage:= 0
   540    Gear^.Damage:= 0
   541    end;
   541    end;
   542 
   542 
   543 if (Gear^.Health <= 0)
   543 if (Gear^.Health <= 0)
   544 	or (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0)
   544     or (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0)
   545 	or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then
   545     or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then
   546     begin
   546     begin
   547     if (Gear^.Kind = gtSniperRifleShot) and ((GameFlags and gfLaserSight) = 0) then cLaserSighting:= false;
   547     if (Gear^.Kind = gtSniperRifleShot) and ((GameFlags and gfLaserSight) = 0) then cLaserSighting:= false;
   548     if (Gear^.Ammo^.NumPerTurn <= CurrentHedgehog^.MultiShootAttacks) and
   548     if (Gear^.Ammo^.NumPerTurn <= CurrentHedgehog^.MultiShootAttacks) and
   549        ((GameFlags and gfArtillery) = 0) then cArtillery:= false;
   549        ((GameFlags and gfArtillery) = 0) then cArtillery:= false;
   550 	Gear^.doStep:= @doStepShotIdle
   550     Gear^.doStep:= @doStepShotIdle
   551     end;
   551     end;
   552 end;
   552 end;
   553 
   553 
   554 procedure doStepDEagleShot(Gear: PGear);
   554 procedure doStepDEagleShot(Gear: PGear);
   555 begin
   555 begin
   598 
   598 
   599 if (TurnTimeLeft > 0) then
   599 if (TurnTimeLeft > 0) then
   600     dec(TurnTimeLeft)
   600     dec(TurnTimeLeft)
   601 else
   601 else
   602     begin
   602     begin
   603 	DeleteGear(Gear);
   603     DeleteGear(Gear);
   604 	AfterAttack
   604     AfterAttack
   605     end;
   605     end;
   606 end;
   606 end;
   607 
   607 
   608 ////////////////////////////////////////////////////////////////////////////////
   608 ////////////////////////////////////////////////////////////////////////////////
   609 procedure doStepActionTimer(Gear: PGear);
   609 procedure doStepActionTimer(Gear: PGear);
   643 begin
   643 begin
   644 AllInactive:= false;
   644 AllInactive:= false;
   645 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
   645 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
   646 dec(Gear^.Timer);
   646 dec(Gear^.Timer);
   647 if (Gear^.Timer = 0)or((Gear^.Message and gm_Destroy) <> 0)or((HHGear^.State and gstHHDriven) = 0) then
   647 if (Gear^.Timer = 0)or((Gear^.Message and gm_Destroy) <> 0)or((HHGear^.State and gstHHDriven) = 0) then
   648 	begin
   648     begin
   649 	StopSound(Gear^.SoundChannel);
   649     StopSound(Gear^.SoundChannel);
   650 	DeleteGear(Gear);
   650     DeleteGear(Gear);
   651 	AfterAttack;
   651     AfterAttack;
   652 	exit
   652     exit
   653 	end;
   653     end;
   654 
   654 
   655 if (Gear^.Timer mod 33) = 0 then
   655 if (Gear^.Timer mod 33) = 0 then
   656 	begin
   656     begin
   657 	HHGear^.State:= HHGear^.State or gstNoDamage;
   657     HHGear^.State:= HHGear^.State or gstNoDamage;
   658 	doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y) + 7, 6, EXPLDontDraw);
   658     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y) + 7, 6, EXPLDontDraw);
   659 	HHGear^.State:= HHGear^.State and not gstNoDamage
   659     HHGear^.State:= HHGear^.State and not gstNoDamage
   660 	end;
   660     end;
   661 
   661 
   662 if (Gear^.Timer mod 47) = 0 then
   662 if (Gear^.Timer mod 47) = 0 then
   663 	begin
   663     begin
   664 	i:= hwRound(Gear^.X) - Gear^.Radius - LongInt(GetRandom(2));
   664     i:= hwRound(Gear^.X) - Gear^.Radius - LongInt(GetRandom(2));
   665 	ei:= hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2));
   665     ei:= hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2));
   666 	while i <= ei do
   666     while i <= ei do
   667 		begin
   667         begin
   668 		DrawExplosion(i, hwRound(Gear^.Y) + 3, 3);
   668         DrawExplosion(i, hwRound(Gear^.Y) + 3, 3);
   669 		inc(i, 1)
   669         inc(i, 1)
   670 		end;
   670         end;
   671 
   671 
   672     if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9), COLOR_INDESTRUCTIBLE) then
   672     if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9), COLOR_INDESTRUCTIBLE) then
   673         begin
   673         begin
   674         Gear^.X:= Gear^.X + Gear^.dX;
   674         Gear^.X:= Gear^.X + Gear^.dX;
   675         Gear^.Y:= Gear^.Y + _1_9;
   675         Gear^.Y:= Gear^.Y + _1_9;
   676         end;
   676         end;
   677 	SetAllHHToActive;
   677     SetAllHHToActive;
   678 	end;
   678     end;
   679 if TestCollisionYwithGear(Gear, 1) then
   679 if TestCollisionYwithGear(Gear, 1) then
   680 	begin
   680     begin
   681 	Gear^.dY:= _0;
   681     Gear^.dY:= _0;
   682 	SetLittle(HHGear^.dX);
   682     SetLittle(HHGear^.dX);
   683 	HHGear^.dY:= _0;
   683     HHGear^.dY:= _0;
   684 	end else
   684     end else
   685 	begin
   685     begin
   686 	Gear^.dY:= Gear^.dY + cGravity;
   686     Gear^.dY:= Gear^.dY + cGravity;
   687 	Gear^.Y:= Gear^.Y + Gear^.dY;
   687     Gear^.Y:= Gear^.Y + Gear^.dY;
   688 	if hwRound(Gear^.Y) > cWaterLine then Gear^.Timer:= 1
   688     if hwRound(Gear^.Y) > cWaterLine then Gear^.Timer:= 1
   689 	end;
   689     end;
   690 
   690 
   691 Gear^.X:= Gear^.X + HHGear^.dX;
   691 Gear^.X:= Gear^.X + HHGear^.dX;
   692 HHGear^.X:= Gear^.X;
   692 HHGear^.X:= Gear^.X;
   693 HHGear^.Y:= Gear^.Y - int2hwFloat(cHHRadius);
   693 HHGear^.Y:= Gear^.Y - int2hwFloat(cHHRadius);
   694 
   694 
   729 ////////////////////////////////////////////////////////////////////////////////
   729 ////////////////////////////////////////////////////////////////////////////////
   730 var BTPrevAngle, BTSteps: LongInt;
   730 var BTPrevAngle, BTSteps: LongInt;
   731 
   731 
   732 procedure doStepBlowTorchWork(Gear: PGear);
   732 procedure doStepBlowTorchWork(Gear: PGear);
   733 var HHGear: PGear;
   733 var HHGear: PGear;
   734 	b: boolean;
   734     b: boolean;
   735 	prevX: LongInt;
   735     prevX: LongInt;
   736 begin
   736 begin
   737 AllInactive:= false;
   737 AllInactive:= false;
   738 dec(Gear^.Timer);
   738 dec(Gear^.Timer);
   739 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
   739 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
   740 
   740 
   741 HedgehogChAngle(HHGear);
   741 HedgehogChAngle(HHGear);
   742 
   742 
   743 b:= false;
   743 b:= false;
   744 
   744 
   745 if abs(LongInt(HHGear^.Angle) - BTPrevAngle) > 7  then
   745 if abs(LongInt(HHGear^.Angle) - BTPrevAngle) > 7  then
   746 	begin
   746     begin
   747 	Gear^.dX:= SignAs(AngleSin(HHGear^.Angle) * _0_5, HHGear^.dX);
   747     Gear^.dX:= SignAs(AngleSin(HHGear^.Angle) * _0_5, HHGear^.dX);
   748 	Gear^.dY:= AngleCos(HHGear^.Angle) * ( - _0_5);
   748     Gear^.dY:= AngleCos(HHGear^.Angle) * ( - _0_5);
   749 	BTPrevAngle:= HHGear^.Angle;
   749     BTPrevAngle:= HHGear^.Angle;
   750 	b:= true
   750     b:= true
   751 	end;
   751     end;
   752 
   752 
   753 if ((HHGear^.State and gstMoving) <> 0) then
   753 if ((HHGear^.State and gstMoving) <> 0) then
   754 	begin
   754     begin
   755 	doStepHedgehogMoving(HHGear);
   755     doStepHedgehogMoving(HHGear);
   756 	if (HHGear^.State and gstHHDriven) = 0 then Gear^.Timer:= 0
   756     if (HHGear^.State and gstHHDriven) = 0 then Gear^.Timer:= 0
   757 	end;
   757     end;
   758 
   758 
   759 if Gear^.Timer mod cHHStepTicks = 0 then
   759 if Gear^.Timer mod cHHStepTicks = 0 then
   760 	begin
   760     begin
   761 	b:= true;
   761     b:= true;
   762 	if Gear^.dX.isNegative then
   762     if Gear^.dX.isNegative then
   763 		HHGear^.Message:= (HHGear^.Message and (gm_Attack or gm_Up or gm_Down)) or gm_Left
   763         HHGear^.Message:= (HHGear^.Message and (gm_Attack or gm_Up or gm_Down)) or gm_Left
   764 	else
   764     else
   765 		HHGear^.Message:= (HHGear^.Message and (gm_Attack or gm_Up or gm_Down)) or gm_Right;
   765         HHGear^.Message:= (HHGear^.Message and (gm_Attack or gm_Up or gm_Down)) or gm_Right;
   766 
   766 
   767 	if ((HHGear^.State and gstMoving) = 0) then
   767     if ((HHGear^.State and gstMoving) = 0) then
   768 		begin
   768         begin
   769 		HHGear^.State:= HHGear^.State and not gstAttacking;
   769         HHGear^.State:= HHGear^.State and not gstAttacking;
   770 		prevX:= hwRound(HHGear^.X);
   770         prevX:= hwRound(HHGear^.X);
   771 
   771 
   772 // why the call to HedgehogStep then a further increment of X?
   772 // why the call to HedgehogStep then a further increment of X?
   773         if (prevX = hwRound(HHGear^.X)) and
   773         if (prevX = hwRound(HHGear^.X)) and
   774            CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y), COLOR_INDESTRUCTIBLE) then HedgehogStep(HHGear);
   774            CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y), COLOR_INDESTRUCTIBLE) then HedgehogStep(HHGear);
   775 
   775 
   776         if (prevX = hwRound(HHGear^.X)) and
   776         if (prevX = hwRound(HHGear^.X)) and
   777            CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y), COLOR_INDESTRUCTIBLE) then HHGear^.X:= HHGear^.X + SignAs(_1, HHGear^.dX);
   777            CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y), COLOR_INDESTRUCTIBLE) then HHGear^.X:= HHGear^.X + SignAs(_1, HHGear^.dX);
   778 		HHGear^.State:= HHGear^.State or gstAttacking
   778         HHGear^.State:= HHGear^.State or gstAttacking
   779 		end;
   779         end;
   780 
   780 
   781 	inc(BTSteps);
   781     inc(BTSteps);
   782 	if BTSteps = 7 then
   782     if BTSteps = 7 then
   783 		begin
   783         begin
   784 		BTSteps:= 0;
   784         BTSteps:= 0;
   785         if CheckLandValue(hwRound(HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC) + SignAs(_6,Gear^.dX)), hwRound(HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC)), COLOR_INDESTRUCTIBLE) then
   785         if CheckLandValue(hwRound(HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC) + SignAs(_6,Gear^.dX)), hwRound(HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC)), COLOR_INDESTRUCTIBLE) then
   786             begin
   786             begin
   787 		    Gear^.X:= HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC);
   787             Gear^.X:= HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC);
   788 		    Gear^.Y:= HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC);
   788             Gear^.Y:= HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC);
   789             end;
   789             end;
   790 		HHGear^.State:= HHGear^.State or gstNoDamage;
   790         HHGear^.State:= HHGear^.State or gstNoDamage;
   791 		AmmoShove(Gear, 2, 15);
   791         AmmoShove(Gear, 2, 15);
   792 		HHGear^.State:= HHGear^.State and not gstNoDamage
   792         HHGear^.State:= HHGear^.State and not gstNoDamage
   793 		end;
   793         end;
   794 	end;
   794     end;
   795 
   795 
   796 if b then
   796 if b then
   797    DrawTunnel(HHGear^.X - Gear^.dX * cHHRadius, HHGear^.Y - _4 - Gear^.dY * cHHRadius + hwAbs(Gear^.dY) * 7,
   797    DrawTunnel(HHGear^.X - Gear^.dX * cHHRadius, HHGear^.Y - _4 - Gear^.dY * cHHRadius + hwAbs(Gear^.dY) * 7,
   798               Gear^.dX, Gear^.dY,
   798               Gear^.dX, Gear^.dY,
   799               cHHRadius * 5, cHHRadius * 2 + 7);
   799               cHHRadius * 5, cHHRadius * 2 + 7);
   800 
   800 
   801 if (Gear^.Timer = 0) or ((HHGear^.Message and gm_Attack) <> 0) then
   801 if (Gear^.Timer = 0) or ((HHGear^.Message and gm_Attack) <> 0) then
   802 	begin
   802     begin
   803 	HHGear^.Message:= 0;
   803     HHGear^.Message:= 0;
   804 	HHGear^.State:= HHGear^.State and (not gstNotKickable);
   804     HHGear^.State:= HHGear^.State and (not gstNotKickable);
   805 	DeleteGear(Gear);
   805     DeleteGear(Gear);
   806 	AfterAttack
   806     AfterAttack
   807 	end
   807     end
   808 end;
   808 end;
   809 
   809 
   810 procedure doStepBlowTorch(Gear: PGear);
   810 procedure doStepBlowTorch(Gear: PGear);
   811 var HHGear: PGear;
   811 var HHGear: PGear;
   812 begin
   812 begin
   825 procedure doStepRopeAfterAttack(Gear: PGear);
   825 procedure doStepRopeAfterAttack(Gear: PGear);
   826 var HHGear: PGear;
   826 var HHGear: PGear;
   827 begin
   827 begin
   828 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
   828 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
   829 if ((HHGear^.State and gstHHDriven) = 0)
   829 if ((HHGear^.State and gstHHDriven) = 0)
   830 	or (CheckGearDrowning(HHGear))
   830     or (CheckGearDrowning(HHGear))
   831 	or TestCollisionYwithGear(HHGear, 1) then
   831     or TestCollisionYwithGear(HHGear, 1) then
   832 	begin
   832     begin
   833 	DeleteGear(Gear);
   833     DeleteGear(Gear);
   834 	isCursorVisible:= false;
   834     isCursorVisible:= false;
   835 	exit
   835     exit
   836 	end;
   836     end;
   837 
   837 
   838 HedgehogChAngle(HHGear);
   838 HedgehogChAngle(HHGear);
   839 
   839 
   840 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX);
   840 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX);
   841 
   841 
   843 HHGear^.X:= HHGear^.X + HHGear^.dX;
   843 HHGear^.X:= HHGear^.X + HHGear^.dX;
   844 HHGear^.Y:= HHGear^.Y + HHGear^.dY;
   844 HHGear^.Y:= HHGear^.Y + HHGear^.dY;
   845 HHGear^.dY:= HHGear^.dY + cGravity;
   845 HHGear^.dY:= HHGear^.dY + cGravity;
   846 
   846 
   847 if (Gear^.Message and gm_Attack) <> 0 then
   847 if (Gear^.Message and gm_Attack) <> 0 then
   848 	begin
   848     begin
   849 	Gear^.X:= HHGear^.X;
   849     Gear^.X:= HHGear^.X;
   850 	Gear^.Y:= HHGear^.Y;
   850     Gear^.Y:= HHGear^.Y;
   851 
   851 
   852 	ApplyAngleBounds(PHedgehog(Gear^.Hedgehog)^, amRope);
   852     ApplyAngleBounds(PHedgehog(Gear^.Hedgehog)^, amRope);
   853 
   853 
   854 	Gear^.dX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX);
   854     Gear^.dX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX);
   855 	Gear^.dY:= -AngleCos(HHGear^.Angle);
   855     Gear^.dY:= -AngleCos(HHGear^.Angle);
   856 	Gear^.Friction:= _450;
   856     Gear^.Friction:= _450;
   857 	Gear^.Elasticity:= _0;
   857     Gear^.Elasticity:= _0;
   858 	Gear^.State:= Gear^.State and not gsttmpflag;
   858     Gear^.State:= Gear^.State and not gsttmpflag;
   859 	Gear^.doStep:= @doStepRope
   859     Gear^.doStep:= @doStepRope
   860 	end
   860     end
   861 end;
   861 end;
   862 
   862 
   863 procedure doStepRopeWork(Gear: PGear);
   863 procedure doStepRopeWork(Gear: PGear);
   864 var HHGear: PGear;
   864 var HHGear: PGear;
   865 	len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat;
   865     len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat;
   866 	lx, ly: LongInt;
   866     lx, ly: LongInt;
   867 	haveCollision,
   867     haveCollision,
   868 	haveDivided: boolean;
   868     haveDivided: boolean;
   869 
   869 
   870 	procedure DeleteMe;
   870     procedure DeleteMe;
   871 	begin
   871     begin
   872 	with HHGear^ do
   872     with HHGear^ do
   873 		begin
   873         begin
   874 		Message:= Message and not gm_Attack;
   874         Message:= Message and not gm_Attack;
   875 		State:= (State or gstMoving) and not gstWinner;
   875         State:= (State or gstMoving) and not gstWinner;
   876 		end;
   876         end;
   877 	DeleteGear(Gear)
   877     DeleteGear(Gear)
   878 	end;
   878     end;
   879 
   879 
   880 	procedure WaitCollision;
   880     procedure WaitCollision;
   881 	begin
   881     begin
   882 	with HHGear^ do
   882     with HHGear^ do
   883 		begin
   883         begin
   884 		Message:= Message and not gm_Attack;
   884         Message:= Message and not gm_Attack;
   885 		State:= State or gstMoving;
   885         State:= State or gstMoving;
   886 		end;
   886         end;
   887 	RopePoints.Count:= 0;
   887     RopePoints.Count:= 0;
   888 	Gear^.Elasticity:= _0;
   888     Gear^.Elasticity:= _0;
   889 	Gear^.doStep:= @doStepRopeAfterAttack
   889     Gear^.doStep:= @doStepRopeAfterAttack
   890 	end;
   890     end;
   891 
   891 
   892 begin
   892 begin
   893 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
   893 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
   894 
   894 
   895 if ((HHGear^.State and gstHHDriven) = 0)
   895 if ((HHGear^.State and gstHHDriven) = 0)
   896 	or (CheckGearDrowning(HHGear)) then
   896     or (CheckGearDrowning(HHGear)) then
   897 	begin
   897     begin
   898 	DeleteMe;
   898     DeleteMe;
   899 	exit
   899     exit
   900 	end;
   900     end;
   901 
   901 
   902 if (Gear^.Message and gm_Left  <> 0) then HHGear^.dX:= HHGear^.dX - _0_0002 else
   902 if (Gear^.Message and gm_Left  <> 0) then HHGear^.dX:= HHGear^.dX - _0_0002 else
   903 if (Gear^.Message and gm_Right <> 0) then HHGear^.dX:= HHGear^.dX + _0_0002;
   903 if (Gear^.Message and gm_Right <> 0) then HHGear^.dX:= HHGear^.dX + _0_0002;
   904 
   904 
   905 if not TestCollisionYwithGear(HHGear, 1) then HHGear^.dY:= HHGear^.dY + cGravity;
   905 if not TestCollisionYwithGear(HHGear, 1) then HHGear^.dY:= HHGear^.dY + cGravity;
   915 
   915 
   916 Gear^.dX:= mdX; // for visual purposes only
   916 Gear^.dX:= mdX; // for visual purposes only
   917 Gear^.dY:= mdY;
   917 Gear^.dY:= mdY;
   918 
   918 
   919 /////
   919 /////
   920 	tx:= HHGear^.X;
   920     tx:= HHGear^.X;
   921 	ty:= HHGear^.Y;
   921     ty:= HHGear^.Y;
   922 
   922 
   923 	if ((Gear^.Message and gm_Down) <> 0) and (Gear^.Elasticity < Gear^.Friction) then
   923     if ((Gear^.Message and gm_Down) <> 0) and (Gear^.Elasticity < Gear^.Friction) then
   924 		if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx))
   924         if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx))
   925 				or TestCollisionYwithGear(HHGear, hwSign(ropeDy))) then
   925                 or TestCollisionYwithGear(HHGear, hwSign(ropeDy))) then
   926 					Gear^.Elasticity:= Gear^.Elasticity + _0_3;
   926                     Gear^.Elasticity:= Gear^.Elasticity + _0_3;
   927 
   927 
   928 	if ((Gear^.Message and gm_Up) <> 0) and (Gear^.Elasticity > _30) then
   928     if ((Gear^.Message and gm_Up) <> 0) and (Gear^.Elasticity > _30) then
   929 		if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx))
   929         if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx))
   930 				or TestCollisionYwithGear(HHGear, -hwSign(ropeDy))) then
   930                 or TestCollisionYwithGear(HHGear, -hwSign(ropeDy))) then
   931 					Gear^.Elasticity:= Gear^.Elasticity - _0_3;
   931                     Gear^.Elasticity:= Gear^.Elasticity - _0_3;
   932 
   932 
   933 	HHGear^.X:= Gear^.X + mdX * Gear^.Elasticity;
   933     HHGear^.X:= Gear^.X + mdX * Gear^.Elasticity;
   934 	HHGear^.Y:= Gear^.Y + mdY * Gear^.Elasticity;
   934     HHGear^.Y:= Gear^.Y + mdY * Gear^.Elasticity;
   935 
   935 
   936 	HHGear^.dX:= HHGear^.X - tx;
   936     HHGear^.dX:= HHGear^.X - tx;
   937 	HHGear^.dY:= HHGear^.Y - ty;
   937     HHGear^.dY:= HHGear^.Y - ty;
   938 ////
   938 ////
   939 
   939 
   940 
   940 
   941 	haveDivided:= false;
   941     haveDivided:= false;
   942 	// check whether rope needs dividing
   942     // check whether rope needs dividing
   943 	len:= _1 / Distance(ropeDx, ropeDy); // old rope pos
   943     len:= _1 / Distance(ropeDx, ropeDy); // old rope pos
   944 	nx:= ropeDx * len;
   944     nx:= ropeDx * len;
   945 	ny:= ropeDy * len;
   945     ny:= ropeDy * len;
   946 
   946 
   947 	len:= Gear^.Elasticity - _0_3x70;
   947     len:= Gear^.Elasticity - _0_3x70;
   948 	while len > _3 do
   948     while len > _3 do
   949 			begin
   949             begin
   950 			lx:= hwRound(Gear^.X + mdX * len);
   950             lx:= hwRound(Gear^.X + mdX * len);
   951 			ly:= hwRound(Gear^.Y + mdY * len);
   951             ly:= hwRound(Gear^.Y + mdY * len);
   952 			if ((ly and LAND_HEIGHT_MASK) = 0) and ((lx and LAND_WIDTH_MASK) = 0) and (Land[ly, lx] <> 0) then
   952             if ((ly and LAND_HEIGHT_MASK) = 0) and ((lx and LAND_WIDTH_MASK) = 0) and (Land[ly, lx] <> 0) then
   953 				begin
   953                 begin
   954 				with RopePoints.ar[RopePoints.Count] do
   954                 with RopePoints.ar[RopePoints.Count] do
   955 					begin
   955                     begin
   956 					X:= Gear^.X;
   956                     X:= Gear^.X;
   957 					Y:= Gear^.Y;
   957                     Y:= Gear^.Y;
   958 					if RopePoints.Count = 0 then RopePoints.HookAngle:= DxDy2Angle(Gear^.dY, Gear^.dX);
   958                     if RopePoints.Count = 0 then RopePoints.HookAngle:= DxDy2Angle(Gear^.dY, Gear^.dX);
   959 					b:= (nx * HHGear^.dY) > (ny * HHGear^.dX);
   959                     b:= (nx * HHGear^.dY) > (ny * HHGear^.dX);
   960 					dLen:= len
   960                     dLen:= len
   961 					end;
   961                     end;
   962 				with RopePoints.rounded[RopePoints.Count] do
   962                 with RopePoints.rounded[RopePoints.Count] do
   963 					begin
   963                     begin
   964 					X:= hwRound(Gear^.X);
   964                     X:= hwRound(Gear^.X);
   965 					Y:= hwRound(Gear^.Y);
   965                     Y:= hwRound(Gear^.Y);
   966 					end;
   966                     end;
   967 
   967 
   968 				Gear^.X:= Gear^.X + nx * len;
   968                 Gear^.X:= Gear^.X + nx * len;
   969 				Gear^.Y:= Gear^.Y + ny * len;
   969                 Gear^.Y:= Gear^.Y + ny * len;
   970 				inc(RopePoints.Count);
   970                 inc(RopePoints.Count);
   971 				TryDo(RopePoints.Count <= MAXROPEPOINTS, 'Rope points overflow', true);
   971                 TryDo(RopePoints.Count <= MAXROPEPOINTS, 'Rope points overflow', true);
   972 				Gear^.Elasticity:= Gear^.Elasticity - len;
   972                 Gear^.Elasticity:= Gear^.Elasticity - len;
   973 				Gear^.Friction:= Gear^.Friction - len;
   973                 Gear^.Friction:= Gear^.Friction - len;
   974 				haveDivided:= true;
   974                 haveDivided:= true;
   975 				break
   975                 break
   976 				end;
   976                 end;
   977 			len:= len - _0_3 // should be the same as increase step
   977             len:= len - _0_3 // should be the same as increase step
   978 			end;
   978             end;
   979 
   979 
   980 if not haveDivided then
   980 if not haveDivided then
   981 	if RopePoints.Count > 0 then // check whether the last dividing point could be removed
   981     if RopePoints.Count > 0 then // check whether the last dividing point could be removed
   982 		begin
   982         begin
   983 		tx:= RopePoints.ar[Pred(RopePoints.Count)].X;
   983         tx:= RopePoints.ar[Pred(RopePoints.Count)].X;
   984 		ty:= RopePoints.ar[Pred(RopePoints.Count)].Y;
   984         ty:= RopePoints.ar[Pred(RopePoints.Count)].Y;
   985 		if RopePoints.ar[Pred(RopePoints.Count)].b xor ((tx - Gear^.X) * (ty - HHGear^.Y) > (tx - HHGear^.X) * (ty - Gear^.Y)) then
   985         if RopePoints.ar[Pred(RopePoints.Count)].b xor ((tx - Gear^.X) * (ty - HHGear^.Y) > (tx - HHGear^.X) * (ty - Gear^.Y)) then
   986 			begin
   986             begin
   987 			dec(RopePoints.Count);
   987             dec(RopePoints.Count);
   988 			Gear^.X:= RopePoints.ar[RopePoints.Count].X;
   988             Gear^.X:= RopePoints.ar[RopePoints.Count].X;
   989 			Gear^.Y:= RopePoints.ar[RopePoints.Count].Y;
   989             Gear^.Y:= RopePoints.ar[RopePoints.Count].Y;
   990 			Gear^.Elasticity:= Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen;
   990             Gear^.Elasticity:= Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen;
   991 			Gear^.Friction:= Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen
   991             Gear^.Friction:= Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen
   992 			end
   992             end
   993 		end;
   993         end;
   994 
   994 
   995 haveCollision:= false;
   995 haveCollision:= false;
   996 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
   996 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
   997 	begin
   997     begin
   998 	HHGear^.dX:= -_0_6 * HHGear^.dX;
   998     HHGear^.dX:= -_0_6 * HHGear^.dX;
   999 	haveCollision:= true
   999     haveCollision:= true
  1000 	end;
  1000     end;
  1001 if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) then
  1001 if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) then
  1002 	begin
  1002     begin
  1003 	HHGear^.dY:= -_0_6 * HHGear^.dY;
  1003     HHGear^.dY:= -_0_6 * HHGear^.dY;
  1004 	haveCollision:= true
  1004     haveCollision:= true
  1005 	end;
  1005     end;
  1006 
  1006 
  1007 if haveCollision
  1007 if haveCollision
  1008 	and (Gear^.Message and (gm_Left or gm_Right) <> 0)
  1008     and (Gear^.Message and (gm_Left or gm_Right) <> 0)
  1009 	and (Gear^.Message and (gm_Up or gm_Down) <> 0) then
  1009     and (Gear^.Message and (gm_Up or gm_Down) <> 0) then
  1010 	begin
  1010     begin
  1011 	HHGear^.dX:= SignAs(hwAbs(HHGear^.dX) + _0_2, HHGear^.dX);
  1011     HHGear^.dX:= SignAs(hwAbs(HHGear^.dX) + _0_2, HHGear^.dX);
  1012 	HHGear^.dY:= SignAs(hwAbs(HHGear^.dY) + _0_2, HHGear^.dY)
  1012     HHGear^.dY:= SignAs(hwAbs(HHGear^.dY) + _0_2, HHGear^.dY)
  1013 	end;
  1013     end;
  1014 
  1014 
  1015 len:= Distance(HHGear^.dX, HHGear^.dY);
  1015 len:= Distance(HHGear^.dX, HHGear^.dY);
  1016 if len > _0_8 then
  1016 if len > _0_8 then
  1017 	begin
  1017     begin
  1018 	len:= _0_8 / len;
  1018     len:= _0_8 / len;
  1019 	HHGear^.dX:= HHGear^.dX * len;
  1019     HHGear^.dX:= HHGear^.dX * len;
  1020 	HHGear^.dY:= HHGear^.dY * len;
  1020     HHGear^.dY:= HHGear^.dY * len;
  1021 	end;
  1021     end;
  1022 
  1022 
  1023 if (Gear^.Message and gm_Attack) <> 0 then
  1023 if (Gear^.Message and gm_Attack) <> 0 then
  1024 	if (Gear^.State and gsttmpFlag) <> 0 then
  1024     if (Gear^.State and gsttmpFlag) <> 0 then
  1025 		with PHedgehog(Gear^.Hedgehog)^ do
  1025         with PHedgehog(Gear^.Hedgehog)^ do
  1026 			if Ammo^[CurSlot, CurAmmo].AmmoType <> amParachute then
  1026             if Ammo^[CurSlot, CurAmmo].AmmoType <> amParachute then
  1027 				WaitCollision
  1027                 WaitCollision
  1028 			else
  1028             else
  1029 				DeleteMe
  1029                 DeleteMe
  1030 	else
  1030     else
  1031 else
  1031 else
  1032 	if (Gear^.State and gsttmpFlag) = 0 then
  1032     if (Gear^.State and gsttmpFlag) = 0 then
  1033 		Gear^.State:= Gear^.State or gsttmpFlag;
  1033         Gear^.State:= Gear^.State or gsttmpFlag;
  1034 end;
  1034 end;
  1035 
  1035 
  1036 procedure doStepRopeAttach(Gear: PGear);
  1036 procedure doStepRopeAttach(Gear: PGear);
  1037 var HHGear: PGear;
  1037 var HHGear: PGear;
  1038 	tx, ty, tt: hwFloat;
  1038     tx, ty, tt: hwFloat;
  1039 
  1039 
  1040 	procedure RemoveFromAmmo;
  1040     procedure RemoveFromAmmo;
  1041 	begin
  1041     begin
  1042 	if (Gear^.State and gstAttacked) = 0 then
  1042     if (Gear^.State and gstAttacked) = 0 then
  1043 		begin
  1043         begin
  1044 		OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^);
  1044         OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^);
  1045 		Gear^.State:= Gear^.State or gstAttacked
  1045         Gear^.State:= Gear^.State or gstAttacked
  1046 		end;
  1046         end;
  1047 	ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^)
  1047     ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^)
  1048 	end;
  1048     end;
  1049 
  1049 
  1050 begin
  1050 begin
  1051 Gear^.X:= Gear^.X - Gear^.dX;
  1051 Gear^.X:= Gear^.X - Gear^.dX;
  1052 Gear^.Y:= Gear^.Y - Gear^.dY;
  1052 Gear^.Y:= Gear^.Y - Gear^.dY;
  1053 Gear^.Elasticity:= Gear^.Elasticity + _1;
  1053 Gear^.Elasticity:= Gear^.Elasticity + _1;
  1054 
  1054 
  1055 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1055 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1056 DeleteCI(HHGear);
  1056 DeleteCI(HHGear);
  1057 
  1057 
  1058 if (HHGear^.State and gstMoving) <> 0 then
  1058 if (HHGear^.State and gstMoving) <> 0 then
  1059 	begin
  1059     begin
  1060 	if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX);
  1060     if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX);
  1061 	if HHGear^.dY.isNegative and TestCollisionYwithGear(HHGear, -1) then HHGear^.dY:= _0;
  1061     if HHGear^.dY.isNegative and TestCollisionYwithGear(HHGear, -1) then HHGear^.dY:= _0;
  1062 
  1062 
  1063 	HHGear^.X:= HHGear^.X + HHGear^.dX;
  1063     HHGear^.X:= HHGear^.X + HHGear^.dX;
  1064 	Gear^.X:= Gear^.X + HHGear^.dX;
  1064     Gear^.X:= Gear^.X + HHGear^.dX;
  1065 
  1065 
  1066 	if TestCollisionYwithGear(HHGear, 1) then
  1066     if TestCollisionYwithGear(HHGear, 1) then
  1067 		begin
  1067         begin
  1068 		CheckHHDamage(HHGear);
  1068         CheckHHDamage(HHGear);
  1069 		HHGear^.dY:= _0;
  1069         HHGear^.dY:= _0;
  1070 		//HHGear^.State:= HHGear^.State and not (gstHHJumping or gstHHHJump);
  1070         //HHGear^.State:= HHGear^.State and not (gstHHJumping or gstHHHJump);
  1071 		end else
  1071         end else
  1072 		begin
  1072         begin
  1073 		HHGear^.Y:= HHGear^.Y + HHGear^.dY;
  1073         HHGear^.Y:= HHGear^.Y + HHGear^.dY;
  1074 		Gear^.Y:= Gear^.Y + HHGear^.dY;
  1074         Gear^.Y:= Gear^.Y + HHGear^.dY;
  1075 		HHGear^.dY:= HHGear^.dY + cGravity;
  1075         HHGear^.dY:= HHGear^.dY + cGravity;
  1076 		end;
  1076         end;
  1077 		
  1077         
  1078 	tt:= Gear^.Elasticity;
  1078     tt:= Gear^.Elasticity;
  1079 	tx:= _0;
  1079     tx:= _0;
  1080 	ty:= _0;
  1080     ty:= _0;
  1081 	while tt > _20 do
  1081     while tt > _20 do
  1082 		begin
  1082         begin
  1083 		if  TestCollisionXwithXYShift(Gear, tx, hwRound(ty), -hwSign(Gear^.dX))
  1083         if  TestCollisionXwithXYShift(Gear, tx, hwRound(ty), -hwSign(Gear^.dX))
  1084 		or TestCollisionYwithXYShift(Gear, hwRound(tx), hwRound(ty), -hwSign(Gear^.dY)) then
  1084         or TestCollisionYwithXYShift(Gear, hwRound(tx), hwRound(ty), -hwSign(Gear^.dY)) then
  1085 			begin
  1085             begin
  1086 			Gear^.X:= Gear^.X + tx;
  1086             Gear^.X:= Gear^.X + tx;
  1087 			Gear^.Y:= Gear^.Y + ty;
  1087             Gear^.Y:= Gear^.Y + ty;
  1088 			Gear^.Elasticity:= tt;
  1088             Gear^.Elasticity:= tt;
  1089 			Gear^.doStep:= @doStepRopeWork;
  1089             Gear^.doStep:= @doStepRopeWork;
  1090 			with HHGear^ do State:= State and not (gstAttacking or gstHHJumping or gstHHHJump);
  1090             with HHGear^ do State:= State and not (gstAttacking or gstHHJumping or gstHHHJump);
  1091 
  1091 
  1092 			RemoveFromAmmo;
  1092             RemoveFromAmmo;
  1093 
  1093 
  1094 			tt:= _0;
  1094             tt:= _0;
  1095 			exit
  1095             exit
  1096 			end;
  1096             end;
  1097 		tx:= tx + Gear^.dX + Gear^.dX;
  1097         tx:= tx + Gear^.dX + Gear^.dX;
  1098 		ty:= ty + Gear^.dY + Gear^.dY;
  1098         ty:= ty + Gear^.dY + Gear^.dY;
  1099 		tt:= tt - _2;
  1099         tt:= tt - _2;
  1100 		end;
  1100         end;
  1101 	end;
  1101     end;
  1102 
  1102 
  1103 CheckCollision(Gear);
  1103 CheckCollision(Gear);
  1104 
  1104 
  1105 if (Gear^.State and gstCollision) <> 0 then
  1105 if (Gear^.State and gstCollision) <> 0 then
  1106 	if Gear^.Elasticity < _10 then
  1106     if Gear^.Elasticity < _10 then
  1107 		Gear^.Elasticity:= _10000
  1107         Gear^.Elasticity:= _10000
  1108 	else
  1108     else
  1109 		begin
  1109         begin
  1110 		Gear^.doStep:= @doStepRopeWork;
  1110         Gear^.doStep:= @doStepRopeWork;
  1111 		with HHGear^ do State:= State and not (gstAttacking or gstHHJumping or gstHHHJump);
  1111         with HHGear^ do State:= State and not (gstAttacking or gstHHJumping or gstHHHJump);
  1112 
  1112 
  1113 		RemoveFromAmmo;
  1113         RemoveFromAmmo;
  1114 
  1114 
  1115 		exit
  1115         exit
  1116 		end;
  1116         end;
  1117 
  1117 
  1118 if (Gear^.Elasticity > Gear^.Friction)
  1118 if (Gear^.Elasticity > Gear^.Friction)
  1119 or ((Gear^.Message and gm_Attack) = 0)
  1119 or ((Gear^.Message and gm_Attack) = 0)
  1120 or ((HHGear^.State and gstHHDriven) = 0)
  1120 or ((HHGear^.State and gstHHDriven) = 0)
  1121 or (HHGear^.Damage > 0) then
  1121 or (HHGear^.Damage > 0) then
  1122 	begin
  1122     begin
  1123 	with PHedgehog(Gear^.Hedgehog)^.Gear^ do
  1123     with PHedgehog(Gear^.Hedgehog)^.Gear^ do
  1124 		begin
  1124         begin
  1125 		State:= State and not gstAttacking;
  1125         State:= State and not gstAttacking;
  1126 		Message:= Message and not gm_Attack
  1126         Message:= Message and not gm_Attack
  1127 		end;
  1127         end;
  1128 	DeleteGear(Gear)
  1128     DeleteGear(Gear)
  1129 	end
  1129     end
  1130 end;
  1130 end;
  1131 
  1131 
  1132 procedure doStepRope(Gear: PGear);
  1132 procedure doStepRope(Gear: PGear);
  1133 begin
  1133 begin
  1134 Gear^.dX:= - Gear^.dX;
  1134 Gear^.dX:= - Gear^.dX;
  1139 ////////////////////////////////////////////////////////////////////////////////
  1139 ////////////////////////////////////////////////////////////////////////////////
  1140 procedure doStepSmokeTrace(Gear: PGear);
  1140 procedure doStepSmokeTrace(Gear: PGear);
  1141 begin
  1141 begin
  1142 inc(Gear^.Timer);
  1142 inc(Gear^.Timer);
  1143 if Gear^.Timer > 64 then
  1143 if Gear^.Timer > 64 then
  1144 	begin
  1144     begin
  1145 	Gear^.Timer:= 0;
  1145     Gear^.Timer:= 0;
  1146 	dec(Gear^.State)
  1146     dec(Gear^.State)
  1147 	end;
  1147     end;
  1148 Gear^.dX:= Gear^.dX + cWindSpeed;
  1148 Gear^.dX:= Gear^.dX + cWindSpeed;
  1149 Gear^.X:= Gear^.X + Gear^.dX;
  1149 Gear^.X:= Gear^.X + Gear^.dX;
  1150 if Gear^.State = 0 then DeleteGear(Gear)
  1150 if Gear^.State = 0 then DeleteGear(Gear)
  1151 end;
  1151 end;
  1152 
  1152 
  1153 ////////////////////////////////////////////////////////////////////////////////
  1153 ////////////////////////////////////////////////////////////////////////////////
  1154 procedure doStepExplosionWork(Gear: PGear);
  1154 procedure doStepExplosionWork(Gear: PGear);
  1155 begin
  1155 begin
  1156 inc(Gear^.Timer);
  1156 inc(Gear^.Timer);
  1157 if Gear^.Timer > 75 then
  1157 if Gear^.Timer > 75 then
  1158 	begin
  1158     begin
  1159 	inc(Gear^.State);
  1159     inc(Gear^.State);
  1160 	Gear^.Timer:= 0;
  1160     Gear^.Timer:= 0;
  1161 	if Gear^.State > 5 then DeleteGear(Gear)
  1161     if Gear^.State > 5 then DeleteGear(Gear)
  1162 	end;
  1162     end;
  1163 end;
  1163 end;
  1164 
  1164 
  1165 procedure doStepExplosion(Gear: PGear);
  1165 procedure doStepExplosion(Gear: PGear);
  1166 var i: LongWord;
  1166 var i: LongWord;
  1167 begin
  1167 begin
  1173 
  1173 
  1174 ////////////////////////////////////////////////////////////////////////////////
  1174 ////////////////////////////////////////////////////////////////////////////////
  1175 procedure doStepMine(Gear: PGear);
  1175 procedure doStepMine(Gear: PGear);
  1176 begin
  1176 begin
  1177 if (Gear^.State and gstMoving) <> 0 then
  1177 if (Gear^.State and gstMoving) <> 0 then
  1178 	begin
  1178     begin
  1179 	DeleteCI(Gear);
  1179     DeleteCI(Gear);
  1180 	doStepFallingGear(Gear);
  1180     doStepFallingGear(Gear);
  1181 	if (Gear^.State and gstMoving) = 0 then
  1181     if (Gear^.State and gstMoving) = 0 then
  1182 		begin
  1182         begin
  1183 		AddGearCI(Gear);
  1183         AddGearCI(Gear);
  1184 		Gear^.dX:= _0;
  1184         Gear^.dX:= _0;
  1185 		Gear^.dY:= _0
  1185         Gear^.dY:= _0
  1186 		end;
  1186         end;
  1187 	CalcRotationDirAngle(Gear);
  1187     CalcRotationDirAngle(Gear);
  1188 	AllInactive:= false
  1188     AllInactive:= false
  1189 	end else
  1189     end else
  1190 	if ((GameTicks and $3F) = 25) then
  1190     if ((GameTicks and $3F) = 25) then
  1191 		doStepFallingGear(Gear);
  1191         doStepFallingGear(Gear);
  1192 
  1192 
  1193 if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then
  1193 if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then
  1194 	if ((Gear^.State and gstAttacking) = 0) then
  1194     if ((Gear^.State and gstAttacking) = 0) then
  1195 		begin
  1195         begin
  1196 		if ((GameTicks and $1F) = 0) then
  1196         if ((GameTicks and $1F) = 0) then
  1197 			if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then Gear^.State:= Gear^.State or gstAttacking
  1197             if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then Gear^.State:= Gear^.State or gstAttacking
  1198 		end else // gstAttacking <> 0
  1198         end else // gstAttacking <> 0
  1199 		begin
  1199         begin
  1200 		AllInactive:= false;
  1200         AllInactive:= false;
  1201 		if (Gear^.Timer and $FF) = 0 then PlaySound(sndMineTick);
  1201         if (Gear^.Timer and $FF) = 0 then PlaySound(sndMineTick);
  1202 		if Gear^.Timer = 0 then
  1202         if Gear^.Timer = 0 then
  1203 			begin
  1203             begin
  1204             if ((Gear^.State and gstWait) <> 0) or 
  1204             if ((Gear^.State and gstWait) <> 0) or 
  1205                (cMineDudPercent = 0) or
  1205                (cMineDudPercent = 0) or
  1206 		       (getRandom(100) > cMineDudPercent) then
  1206                (getRandom(100) > cMineDudPercent) then
  1207                begin
  1207                begin
  1208 			   doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound);
  1208                doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound);
  1209 			   DeleteGear(Gear)
  1209                DeleteGear(Gear)
  1210                end
  1210                end
  1211             else
  1211             else
  1212                begin
  1212                begin
  1213 			   AddVisualGear(hwRound(Gear^.X) - 4  + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
  1213                AddVisualGear(hwRound(Gear^.X) - 4  + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
  1214 		       PlaySound(sndVaporize);
  1214                PlaySound(sndVaporize);
  1215                Gear^.Health:= 0;
  1215                Gear^.Health:= 0;
  1216                end;
  1216                end;
  1217 			exit
  1217             exit
  1218 			end;
  1218             end;
  1219 		dec(Gear^.Timer);
  1219         dec(Gear^.Timer);
  1220 		end else // gsttmpFlag = 0
  1220         end else // gsttmpFlag = 0
  1221 	if TurnTimeLeft = 0 then Gear^.State:= Gear^.State or gsttmpFlag;
  1221     if TurnTimeLeft = 0 then Gear^.State:= Gear^.State or gsttmpFlag;
  1222 end;
  1222 end;
  1223 
  1223 
  1224 ////////////////////////////////////////////////////////////////////////////////
  1224 ////////////////////////////////////////////////////////////////////////////////
  1225 procedure doStepDynamite(Gear: PGear);
  1225 procedure doStepDynamite(Gear: PGear);
  1226 begin
  1226 begin
  1227 doStepFallingGear(Gear);
  1227 doStepFallingGear(Gear);
  1228 AllInactive:= false;
  1228 AllInactive:= false;
  1229 if Gear^.Timer mod 166 = 0 then inc(Gear^.Tag);
  1229 if Gear^.Timer mod 166 = 0 then inc(Gear^.Tag);
  1230 if Gear^.Timer = 1000 then // might need better timing
  1230 if Gear^.Timer = 1000 then // might need better timing
  1231 	makeHogsWorry(Gear^.X, Gear^.Y, 75);
  1231     makeHogsWorry(Gear^.X, Gear^.Y, 75);
  1232 if Gear^.Timer = 0 then
  1232 if Gear^.Timer = 0 then
  1233 	begin
  1233     begin
  1234 	doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, EXPLAutoSound);
  1234     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, EXPLAutoSound);
  1235 	DeleteGear(Gear);
  1235     DeleteGear(Gear);
  1236 	exit
  1236     exit
  1237 	end;
  1237     end;
  1238 dec(Gear^.Timer);
  1238 dec(Gear^.Timer);
  1239 end;
  1239 end;
  1240 
  1240 
  1241 ///////////////////////////////////////////////////////////////////////////////
  1241 ///////////////////////////////////////////////////////////////////////////////
  1242 
  1242 
  1245 Increase damage as barrel smokes?
  1245 Increase damage as barrel smokes?
  1246 Try tweaking friction some more
  1246 Try tweaking friction some more
  1247 *)
  1247 *)
  1248 procedure doStepRollingBarrel(Gear: PGear);
  1248 procedure doStepRollingBarrel(Gear: PGear);
  1249 var i: LongInt;
  1249 var i: LongInt;
  1250 	particle: PVisualGear;
  1250     particle: PVisualGear;
  1251 begin
  1251 begin
  1252 Gear^.State:= Gear^.State or gstAnimation;
  1252 Gear^.State:= Gear^.State or gstAnimation;
  1253 if ((Gear^.dX.QWordValue <> 0) or (Gear^.dY.QWordValue <> 0))  then
  1253 if ((Gear^.dX.QWordValue <> 0) or (Gear^.dY.QWordValue <> 0))  then
  1254     begin
  1254     begin
  1255     DeleteCI(Gear);
  1255     DeleteCI(Gear);
  1256     AllInactive:= false;
  1256     AllInactive:= false;
  1257     if not Gear^.dY.isNegative and (Gear^.dY > _0_03) and TestCollisionYwithGear(Gear, 1) then
  1257     if not Gear^.dY.isNegative and (Gear^.dY > _0_03) and TestCollisionYwithGear(Gear, 1) then
  1258         begin
  1258         begin
  1259         inc(Gear^.Damage, hwRound(Gear^.dY * _30));
  1259         inc(Gear^.Damage, hwRound(Gear^.dY * _30));
  1260 	    for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do 
  1260         for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do 
  1261             begin
  1261             begin
  1262 		    particle:= AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
  1262             particle:= AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
  1263             if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX / 5)
  1263             if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX / 5)
  1264             end
  1264             end
  1265         end
  1265         end
  1266     else if not Gear^.dX.isNegative and (Gear^.dX > _0_03) and TestCollisionXwithGear(Gear, 1) then
  1266     else if not Gear^.dX.isNegative and (Gear^.dX > _0_03) and TestCollisionXwithGear(Gear, 1) then
  1267         inc(Gear^.Damage, hwRound(Gear^.dX * _30))
  1267         inc(Gear^.Damage, hwRound(Gear^.dX * _30))
  1270     else if Gear^.dX.isNegative and (Gear^.dX < -_0_03) and TestCollisionXwithGear(Gear, -1) then
  1270     else if Gear^.dX.isNegative and (Gear^.dX < -_0_03) and TestCollisionXwithGear(Gear, -1) then
  1271         inc(Gear^.Damage, hwRound(Gear^.dX * -_30));
  1271         inc(Gear^.Damage, hwRound(Gear^.dX * -_30));
  1272     if Gear^.Damage <> 0 then PlaySound(sndGraveImpact);
  1272     if Gear^.Damage <> 0 then PlaySound(sndGraveImpact);
  1273     doStepFallingGear(Gear);
  1273     doStepFallingGear(Gear);
  1274     CalcRotationDirAngle(Gear);
  1274     CalcRotationDirAngle(Gear);
  1275 	CheckGearDrowning(Gear)
  1275     CheckGearDrowning(Gear)
  1276     end
  1276     end
  1277 else AddGearCI(Gear);
  1277 else AddGearCI(Gear);
  1278 (*
  1278 (*
  1279 Attempt to make a barrel knock itself over an edge.  Would need more checks to avoid issues like burn damage
  1279 Attempt to make a barrel knock itself over an edge.  Would need more checks to avoid issues like burn damage
  1280     begin
  1280     begin
  1281     x:= hwRound(Gear^.X);
  1281     x:= hwRound(Gear^.X);
  1282     y:= hwRound(Gear^.Y);
  1282     y:= hwRound(Gear^.Y);
  1283     if (((y+1) and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then
  1283     if (((y+1) and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then
  1284 	    if (Land[y+1, x] = 0) then
  1284         if (Land[y+1, x] = 0) then
  1285             begin
  1285             begin
  1286             if (((y+1) and LAND_HEIGHT_MASK) = 0) and (((x+Gear^.Radius-2) and LAND_WIDTH_MASK) = 0) and (Land[y+1, x+Gear^.Radius-2] = 0) then
  1286             if (((y+1) and LAND_HEIGHT_MASK) = 0) and (((x+Gear^.Radius-2) and LAND_WIDTH_MASK) = 0) and (Land[y+1, x+Gear^.Radius-2] = 0) then
  1287                 Gear^.dX:= -_0_08
  1287                 Gear^.dX:= -_0_08
  1288             else if (((y+1 and LAND_HEIGHT_MASK)) = 0) and (((x-(Gear^.Radius-2)) and LAND_WIDTH_MASK) = 0) and (Land[y+1, x-(Gear^.Radius-2)] = 0) then
  1288             else if (((y+1 and LAND_HEIGHT_MASK)) = 0) and (((x-(Gear^.Radius-2)) and LAND_WIDTH_MASK) = 0) and (Land[y+1, x-(Gear^.Radius-2)] = 0) then
  1289                 Gear^.dX:= _0_08;
  1289                 Gear^.dX:= _0_08;
  1305 
  1305 
  1306 end;
  1306 end;
  1307 
  1307 
  1308 procedure doStepCase(Gear: PGear);
  1308 procedure doStepCase(Gear: PGear);
  1309 var i, x, y: LongInt;
  1309 var i, x, y: LongInt;
  1310 	k: TGearType;
  1310     k: TGearType;
  1311 	exBoom: boolean;
  1311     exBoom: boolean;
  1312 	dX, dY: HWFloat;
  1312     dX, dY: HWFloat;
  1313 begin
  1313 begin
  1314 k:= Gear^.Kind;
  1314 k:= Gear^.Kind;
  1315 exBoom:= false;
  1315 exBoom:= false;
  1316 
  1316 
  1317 if (Gear^.Message and gm_Destroy) > 0 then
  1317 if (Gear^.Message and gm_Destroy) > 0 then
  1318 	begin
  1318     begin
  1319 	DeleteGear(Gear);
  1319     DeleteGear(Gear);
  1320 	FreeActionsList;
  1320     FreeActionsList;
  1321 	SetAllToActive; // something (hh, mine, etc...) could be on top of the case
  1321     SetAllToActive; // something (hh, mine, etc...) could be on top of the case
  1322 	with CurrentHedgehog^ do
  1322     with CurrentHedgehog^ do
  1323 		if Gear <> nil then Gear^.Message:= Gear^.Message and not (gm_LJump or gm_HJump);
  1323         if Gear <> nil then Gear^.Message:= Gear^.Message and not (gm_LJump or gm_HJump);
  1324 	exit
  1324     exit
  1325 	end;
  1325     end;
  1326 
  1326 
  1327 if k = gtExplosives then
  1327 if k = gtExplosives then
  1328 	begin
  1328     begin
  1329     //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation;
  1329     //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation;
  1330     if hwAbs(Gear^.dX) > _0_15 then Gear^.doStep:= @doStepRollingBarrel;
  1330     if hwAbs(Gear^.dX) > _0_15 then Gear^.doStep:= @doStepRollingBarrel;
  1331     
  1331     
  1332     if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
  1332     if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
  1333         if (cBarrelHealth div Gear^.Health) > 2 then 
  1333         if (cBarrelHealth div Gear^.Health) > 2 then 
  1334             AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke)
  1334             AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke)
  1335         else
  1335         else
  1336             AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite);
  1336             AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite);
  1337 	dec(Gear^.Health, Gear^.Damage);
  1337     dec(Gear^.Health, Gear^.Damage);
  1338 	Gear^.Damage:= 0;
  1338     Gear^.Damage:= 0;
  1339 	if Gear^.Health <= 0 then
  1339     if Gear^.Health <= 0 then
  1340 		exBoom:= true;
  1340         exBoom:= true;
  1341 	end;
  1341     end;
  1342 
  1342 
  1343 if (Gear^.Damage > 0) or exBoom then
  1343 if (Gear^.Damage > 0) or exBoom then
  1344 	begin
  1344     begin
  1345 	x:= hwRound(Gear^.X);
  1345     x:= hwRound(Gear^.X);
  1346 	y:= hwRound(Gear^.Y);
  1346     y:= hwRound(Gear^.Y);
  1347 	DeleteGear(Gear); // <-- delete gear!
  1347     DeleteGear(Gear); // <-- delete gear!
  1348 
  1348 
  1349 	if k = gtCase then
  1349     if k = gtCase then
  1350 		begin
  1350         begin
  1351 		doMakeExplosion(x, y, 25, EXPLAutoSound);
  1351         doMakeExplosion(x, y, 25, EXPLAutoSound);
  1352 		for i:= 0 to 63 do
  1352         for i:= 0 to 63 do
  1353 			AddGear(x, y, gtFlame, 0, _0, _0, 0);
  1353             AddGear(x, y, gtFlame, 0, _0, _0, 0);
  1354 		end
  1354         end
  1355 	else if k = gtExplosives then
  1355     else if k = gtExplosives then
  1356 		begin
  1356         begin
  1357 		doMakeExplosion(x, y, 75, EXPLAutoSound);
  1357         doMakeExplosion(x, y, 75, EXPLAutoSound);
  1358 		for i:= 0 to 31 do
  1358         for i:= 0 to 31 do
  1359 			begin
  1359             begin
  1360 			dX:= AngleCos(i * 64) * _0_5 * (getrandom + _1);
  1360             dX:= AngleCos(i * 64) * _0_5 * (getrandom + _1);
  1361 			dY:= AngleSin(i * 64) * _0_5 * (getrandom + _1);
  1361             dY:= AngleSin(i * 64) * _0_5 * (getrandom + _1);
  1362 			AddGear(x, y, gtFlame, 0, dX, dY, 0);
  1362             AddGear(x, y, gtFlame, 0, dX, dY, 0);
  1363 			AddGear(x, y, gtFlame, 0, -dX, -dY, 0)^.State:= gsttmpFlag;
  1363             AddGear(x, y, gtFlame, 0, -dX, -dY, 0)^.State:= gsttmpFlag;
  1364 			end
  1364             end
  1365 		end;
  1365         end;
  1366 	exit
  1366     exit
  1367 	end;
  1367     end;
  1368 
  1368 
  1369 if (Gear^.dY.QWordValue <> 0) or (not TestCollisionYwithGear(Gear, 1)) then
  1369 if (Gear^.dY.QWordValue <> 0) or (not TestCollisionYwithGear(Gear, 1)) then
  1370 	begin
  1370     begin
  1371 	AllInactive:= false;
  1371     AllInactive:= false;
  1372     Gear^.dY:= Gear^.dY + cGravity;
  1372     Gear^.dY:= Gear^.dY + cGravity;
  1373     Gear^.Y:= Gear^.Y + Gear^.dY;
  1373     Gear^.Y:= Gear^.Y + Gear^.dY;
  1374     if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then SetAllHHToActive;
  1374     if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then SetAllHHToActive;
  1375 	if (Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, -1) then Gear^.dY:= _0;
  1375     if (Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, -1) then Gear^.dY:= _0;
  1376 	if (not Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, 1) then
  1376     if (not Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, 1) then
  1377 		begin
  1377         begin
  1378         if (Gear^.dY > _0_02) and (k = gtExplosives) then
  1378         if (Gear^.dY > _0_02) and (k = gtExplosives) then
  1379             inc(Gear^.Damage, hwRound(Gear^.dY * _30));
  1379             inc(Gear^.Damage, hwRound(Gear^.dY * _30));
  1380 
  1380 
  1381 		if Gear^.dY > _0_2 then
  1381         if Gear^.dY > _0_2 then
  1382 	        for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do 
  1382             for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do 
  1383 		        AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
  1383                 AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
  1384 		Gear^.dY:= - Gear^.dY * Gear^.Elasticity;
  1384         Gear^.dY:= - Gear^.dY * Gear^.Elasticity;
  1385 		if Gear^.dY > - _0_001 then Gear^.dY:= _0
  1385         if Gear^.dY > - _0_001 then Gear^.dY:= _0
  1386 			else if Gear^.dY < - _0_03 then PlaySound(sndGraveImpact)
  1386             else if Gear^.dY < - _0_03 then PlaySound(sndGraveImpact)
  1387 		end;
  1387         end;
  1388 	//if Gear^.dY > - _0_001 then Gear^.dY:= _0
  1388     //if Gear^.dY > - _0_001 then Gear^.dY:= _0
  1389 	CheckGearDrowning(Gear);
  1389     CheckGearDrowning(Gear);
  1390 	end;
  1390     end;
  1391 
  1391 
  1392 if (Gear^.dY.QWordValue = 0) then AddGearCI(Gear)
  1392 if (Gear^.dY.QWordValue = 0) then AddGearCI(Gear)
  1393        else if (Gear^.dY.QWordValue <> 0) then DeleteCI(Gear)
  1393        else if (Gear^.dY.QWordValue <> 0) then DeleteCI(Gear)
  1394 end;
  1394 end;
  1395 
  1395 
  1396 ////////////////////////////////////////////////////////////////////////////////
  1396 ////////////////////////////////////////////////////////////////////////////////
  1397 
  1397 
  1398 procedure doStepTarget(Gear: PGear);
  1398 procedure doStepTarget(Gear: PGear);
  1399 begin
  1399 begin
  1400 if (Gear^.Timer = 0) and (Gear^.Tag = 0) then
  1400 if (Gear^.Timer = 0) and (Gear^.Tag = 0) then
  1401 	PlaySound(sndWarp);
  1401     PlaySound(sndWarp);
  1402 
  1402 
  1403 if (Gear^.Tag = 0) and (Gear^.Timer < 1000) then
  1403 if (Gear^.Tag = 0) and (Gear^.Timer < 1000) then
  1404 	inc(Gear^.Timer)
  1404     inc(Gear^.Timer)
  1405 else if Gear^.Tag = 1 then
  1405 else if Gear^.Tag = 1 then
  1406 	begin
  1406     begin
  1407 		Gear^.Tag:= 2;
  1407         Gear^.Tag:= 2;
  1408 		if (TrainingFlags and tfTimeTrial) <> 0 then
  1408         if (TrainingFlags and tfTimeTrial) <> 0 then
  1409 			begin
  1409             begin
  1410 			inc(TurnTimeLeft, TrainingTimeInc);
  1410             inc(TurnTimeLeft, TrainingTimeInc);
  1411 			
  1411             
  1412 			if TrainingTimeInc > TrainingTimeInM then
  1412             if TrainingTimeInc > TrainingTimeInM then
  1413 				dec(TrainingTimeInc, TrainingTimeInD);
  1413                 dec(TrainingTimeInc, TrainingTimeInD);
  1414 			if TurnTimeLeft > TrainingTimeMax then
  1414             if TurnTimeLeft > TrainingTimeMax then
  1415 				TurnTimeLeft:= TrainingTimeMax;
  1415                 TurnTimeLeft:= TrainingTimeMax;
  1416 			end;
  1416             end;
  1417 	end
  1417     end
  1418 else if Gear^.Tag = 2 then
  1418 else if Gear^.Tag = 2 then
  1419 	if Gear^.Timer > 0 then
  1419     if Gear^.Timer > 0 then
  1420 		dec(Gear^.Timer)
  1420         dec(Gear^.Timer)
  1421 	else
  1421     else
  1422 		begin
  1422         begin
  1423 			if (TrainingFlags and tfTargetRespawn) <> 0 then
  1423             if (TrainingFlags and tfTargetRespawn) <> 0 then
  1424 				begin
  1424                 begin
  1425 				TrainingTargetGear:= AddGear(0, 0, gtTarget, 0, _0, _0, 0);
  1425                 TrainingTargetGear:= AddGear(0, 0, gtTarget, 0, _0, _0, 0);
  1426 				FindPlace(TrainingTargetGear, false, 0, LAND_WIDTH);
  1426                 FindPlace(TrainingTargetGear, false, 0, LAND_WIDTH);
  1427 				end;
  1427                 end;
  1428 			DeleteGear(Gear);
  1428             DeleteGear(Gear);
  1429 			exit;
  1429             exit;
  1430 		end;
  1430         end;
  1431 
  1431 
  1432 doStepCase(Gear)
  1432 doStepCase(Gear)
  1433 end;
  1433 end;
  1434 
  1434 
  1435 ////////////////////////////////////////////////////////////////////////////////
  1435 ////////////////////////////////////////////////////////////////////////////////
  1436 procedure doStepIdle(Gear: PGear);
  1436 procedure doStepIdle(Gear: PGear);
  1437 begin
  1437 begin
  1438 AllInactive:= false;
  1438 AllInactive:= false;
  1439 dec(Gear^.Timer);
  1439 dec(Gear^.Timer);
  1440 if Gear^.Timer = 0 then
  1440 if Gear^.Timer = 0 then
  1441 	begin
  1441     begin
  1442 	DeleteGear(Gear);
  1442     DeleteGear(Gear);
  1443 	AfterAttack
  1443     AfterAttack
  1444 	end
  1444     end
  1445 end;
  1445 end;
  1446 
  1446 
  1447 procedure doStepShover(Gear: PGear);
  1447 procedure doStepShover(Gear: PGear);
  1448 var HHGear: PGear;
  1448 var HHGear: PGear;
  1449 begin
  1449 begin
  1466 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1466 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1467 HHGear^.State:= HHGear^.State or gstNoDamage;
  1467 HHGear^.State:= HHGear^.State or gstNoDamage;
  1468 DeleteCI(HHGear);
  1468 DeleteCI(HHGear);
  1469 
  1469 
  1470 for i:= 0 to 3 do
  1470 for i:= 0 to 3 do
  1471 	begin
  1471     begin
  1472 	AmmoShove(Gear, 30, 25);
  1472     AmmoShove(Gear, 30, 25);
  1473 	Gear^.X:= Gear^.X + Gear^.dX * 5
  1473     Gear^.X:= Gear^.X + Gear^.dX * 5
  1474 	end;
  1474     end;
  1475 
  1475 
  1476 HHGear^.State:= HHGear^.State and not gstNoDamage;
  1476 HHGear^.State:= HHGear^.State and not gstNoDamage;
  1477 Gear^.Timer:= 250;
  1477 Gear^.Timer:= 250;
  1478 Gear^.doStep:= @doStepIdle
  1478 Gear^.doStep:= @doStepIdle
  1479 end;
  1479 end;
  1483 var i: Integer;
  1483 var i: Integer;
  1484 begin
  1484 begin
  1485     if (Gear^.State and gsttmpFlag) = 0 then AllInactive:= false;
  1485     if (Gear^.State and gsttmpFlag) = 0 then AllInactive:= false;
  1486 
  1486 
  1487 if not TestCollisionYwithGear(Gear, 1) then
  1487 if not TestCollisionYwithGear(Gear, 1) then
  1488 	begin
  1488     begin
  1489     AllInactive:= false;
  1489     AllInactive:= false;
  1490 	if hwAbs(Gear^.dX) > _0_01 then
  1490     if hwAbs(Gear^.dX) > _0_01 then
  1491 		Gear^.dX:= Gear^.dX * _0_995;
  1491         Gear^.dX:= Gear^.dX * _0_995;
  1492 	 if (Gear^.State and gsttmpFlag) <> 0 then Gear^.dY:= Gear^.dY + _2*cGravity else
  1492      if (Gear^.State and gsttmpFlag) <> 0 then Gear^.dY:= Gear^.dY + _2*cGravity else
  1493 	Gear^.dY:= Gear^.dY + cGravity;
  1493     Gear^.dY:= Gear^.dY + cGravity;
  1494 	if hwAbs(Gear^.dY) > _0_2 then Gear^.dY:= Gear^.dY * _0_995;
  1494     if hwAbs(Gear^.dY) > _0_2 then Gear^.dY:= Gear^.dY * _0_995;
  1495 
  1495 
  1496 	if (Gear^.State and gsttmpFlag) <> 0 then Gear^.X:= Gear^.X + Gear^.dX else
  1496     if (Gear^.State and gsttmpFlag) <> 0 then Gear^.X:= Gear^.X + Gear^.dX else
  1497 	Gear^.X:= Gear^.X + Gear^.dX + cWindSpeed * 640;
  1497     Gear^.X:= Gear^.X + Gear^.dX + cWindSpeed * 640;
  1498 	Gear^.Y:= Gear^.Y + Gear^.dY;
  1498     Gear^.Y:= Gear^.Y + Gear^.dY;
  1499 
  1499 
  1500 	if (hwRound(Gear^.Y) > cWaterLine) then
  1500     if (hwRound(Gear^.Y) > cWaterLine) then
  1501 		begin
  1501         begin
  1502 		for i:= 0 to 3 do
  1502         for i:= 0 to 3 do
  1503 			AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 16 + Random(16), vgtSteam);
  1503             AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 16 + Random(16), vgtSteam);
  1504 		PlaySound(sndVaporize);
  1504         PlaySound(sndVaporize);
  1505 		DeleteGear(Gear);
  1505         DeleteGear(Gear);
  1506 		exit
  1506         exit
  1507 		end
  1507         end
  1508     end else begin
  1508     end else begin
  1509         if (Gear^.State and gsttmpFlag) <> 0 then 
  1509         if (Gear^.State and gsttmpFlag) <> 0 then 
  1510             begin
  1510             begin
  1511             Gear^.Radius:= 9;
  1511             Gear^.Radius:= 9;
  1512             AmmoShove(Gear, 2, 30);
  1512             AmmoShove(Gear, 2, 30);
  1513             Gear^.Radius:= 1
  1513             Gear^.Radius:= 1
  1514             end;
  1514             end;
  1515 	    if Gear^.Timer > 0 then
  1515         if Gear^.Timer > 0 then
  1516             begin
  1516             begin
  1517             dec(Gear^.Timer);
  1517             dec(Gear^.Timer);
  1518             inc(Gear^.Damage)
  1518             inc(Gear^.Damage)
  1519             end
  1519             end
  1520         else begin
  1520         else begin
  1538                     
  1538                     
  1539                     for i:= 0 to Random(3) do
  1539                     for i:= 0 to Random(3) do
  1540                       AddVisualGear(hwRound(Gear^.X) - 3 + Random(6), hwRound(Gear^.Y) - 2, vgtSmoke);
  1540                       AddVisualGear(hwRound(Gear^.X) - 3 + Random(6), hwRound(Gear^.Y) - 2, vgtSmoke);
  1541                 end;
  1541                 end;
  1542                 // This one is interesting.  I think I understand the purpose, but I wonder if a bit more fuzzy of kicking could be done with getrandom.
  1542                 // This one is interesting.  I think I understand the purpose, but I wonder if a bit more fuzzy of kicking could be done with getrandom.
  1543         	    Gear^.Timer:= 100 - Gear^.Tag * 3;
  1543                 Gear^.Timer:= 100 - Gear^.Tag * 3;
  1544                 if (Gear^.Damage > 3000+Gear^.Tag*1500) then Gear^.Health:= 0
  1544                 if (Gear^.Damage > 3000+Gear^.Tag*1500) then Gear^.Health:= 0
  1545                 end
  1545                 end
  1546             end
  1546             end
  1547         end;
  1547         end;
  1548 if Gear^.Health = 0 then begin
  1548 if Gear^.Health = 0 then begin
  1566 procedure doStepFirePunchWork(Gear: PGear);
  1566 procedure doStepFirePunchWork(Gear: PGear);
  1567 var HHGear: PGear;
  1567 var HHGear: PGear;
  1568 begin
  1568 begin
  1569 AllInactive:= false;
  1569 AllInactive:= false;
  1570 if ((Gear^.Message and gm_Destroy) <> 0) then
  1570 if ((Gear^.Message and gm_Destroy) <> 0) then
  1571 	begin
  1571     begin
  1572 	DeleteGear(Gear);
  1572     DeleteGear(Gear);
  1573 	AfterAttack;
  1573     AfterAttack;
  1574 	exit
  1574     exit
  1575 	end;
  1575     end;
  1576 
  1576 
  1577 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1577 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1578 if hwRound(HHGear^.Y) <= Gear^.Tag - 2 then
  1578 if hwRound(HHGear^.Y) <= Gear^.Tag - 2 then
  1579 	begin
  1579     begin
  1580 	Gear^.Tag:= hwRound(HHGear^.Y);
  1580     Gear^.Tag:= hwRound(HHGear^.Y);
  1581 	DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y - _1, _0_5, _0, cHHRadius * 4, 2);
  1581     DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y - _1, _0_5, _0, cHHRadius * 4, 2);
  1582 	HHGear^.State:= HHGear^.State or gstNoDamage;
  1582     HHGear^.State:= HHGear^.State or gstNoDamage;
  1583 	Gear^.Y:= HHGear^.Y;
  1583     Gear^.Y:= HHGear^.Y;
  1584 	AmmoShove(Gear, 30, 40);
  1584     AmmoShove(Gear, 30, 40);
  1585 	HHGear^.State:= HHGear^.State and not gstNoDamage
  1585     HHGear^.State:= HHGear^.State and not gstNoDamage
  1586 	end;
  1586     end;
  1587 
  1587 
  1588 HHGear^.dY:= HHGear^.dY + cGravity;
  1588 HHGear^.dY:= HHGear^.dY + cGravity;
  1589 if not (HHGear^.dY.isNegative) then
  1589 if not (HHGear^.dY.isNegative) then
  1590 	begin
  1590     begin
  1591 	HHGear^.State:= HHGear^.State or gstMoving;
  1591     HHGear^.State:= HHGear^.State or gstMoving;
  1592 	DeleteGear(Gear);
  1592     DeleteGear(Gear);
  1593 	AfterAttack;
  1593     AfterAttack;
  1594 	exit
  1594     exit
  1595 	end;
  1595     end;
  1596 
  1596 
  1597 if CheckLandValue(hwRound(HHGear^.X), hwRound(HHGear^.Y + HHGear^.dY + SignAs(_6,Gear^.dY)), COLOR_INDESTRUCTIBLE) then
  1597 if CheckLandValue(hwRound(HHGear^.X), hwRound(HHGear^.Y + HHGear^.dY + SignAs(_6,Gear^.dY)), COLOR_INDESTRUCTIBLE) then
  1598    HHGear^.Y:= HHGear^.Y + HHGear^.dY
  1598    HHGear^.Y:= HHGear^.Y + HHGear^.dY
  1599 end;
  1599 end;
  1600 
  1600 
  1626 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1626 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1627 
  1627 
  1628 inc(Gear^.Timer);
  1628 inc(Gear^.Timer);
  1629 
  1629 
  1630 if TestCollisionYwithGear(HHGear, 1)
  1630 if TestCollisionYwithGear(HHGear, 1)
  1631 	or ((HHGear^.State and gstHHDriven) = 0)
  1631     or ((HHGear^.State and gstHHDriven) = 0)
  1632 	or CheckGearDrowning(HHGear)
  1632     or CheckGearDrowning(HHGear)
  1633 	or ((Gear^.Message and gm_Attack) <> 0) then
  1633     or ((Gear^.Message and gm_Attack) <> 0) then
  1634 	begin
  1634     begin
  1635 	with HHGear^ do
  1635     with HHGear^ do
  1636 		begin
  1636         begin
  1637 		Message:= 0;
  1637         Message:= 0;
  1638 		SetLittle(dX);
  1638         SetLittle(dX);
  1639 		dY:= _0;
  1639         dY:= _0;
  1640 		State:= State or gstMoving;
  1640         State:= State or gstMoving;
  1641 		end;
  1641         end;
  1642 	DeleteGear(Gear);
  1642     DeleteGear(Gear);
  1643 	isCursorVisible:= false;
  1643     isCursorVisible:= false;
  1644 	exit
  1644     exit
  1645 	end;
  1645     end;
  1646 
  1646 
  1647 if not TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
  1647 if not TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
  1648 	HHGear^.X:= HHGear^.X + cWindSpeed * 200;
  1648     HHGear^.X:= HHGear^.X + cWindSpeed * 200;
  1649 
  1649 
  1650 if (Gear^.Message and gm_Left) <> 0 then HHGear^.X:= HHGear^.X - cMaxWindSpeed * 40
  1650 if (Gear^.Message and gm_Left) <> 0 then HHGear^.X:= HHGear^.X - cMaxWindSpeed * 40
  1651 else if (Gear^.Message and gm_Right) <> 0 then HHGear^.X:= HHGear^.X + cMaxWindSpeed * 40;
  1651 else if (Gear^.Message and gm_Right) <> 0 then HHGear^.X:= HHGear^.X + cMaxWindSpeed * 40;
  1652 if (Gear^.Message and gm_Up) <> 0 then HHGear^.Y:= HHGear^.Y - cGravity * 40
  1652 if (Gear^.Message and gm_Up) <> 0 then HHGear^.Y:= HHGear^.Y - cGravity * 40
  1653 else if (Gear^.Message and gm_Down) <> 0 then HHGear^.Y:= HHGear^.Y + cGravity * 40;
  1653 else if (Gear^.Message and gm_Down) <> 0 then HHGear^.Y:= HHGear^.Y + cGravity * 40;
  1682 begin
  1682 begin
  1683 AllInactive:= false;
  1683 AllInactive:= false;
  1684 Gear^.X:= Gear^.X + cAirPlaneSpeed * Gear^.Tag;
  1684 Gear^.X:= Gear^.X + cAirPlaneSpeed * Gear^.Tag;
  1685 
  1685 
  1686 if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then
  1686 if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then
  1687 	begin
  1687     begin
  1688 	dec(Gear^.Health);
  1688     dec(Gear^.Health);
  1689 	case Gear^.State of
  1689     case Gear^.State of
  1690 			0: FollowGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
  1690             0: FollowGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
  1691 			1: FollowGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine,    0, cBombsSpeed * Gear^.Tag, _0, 0);
  1691             1: FollowGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine,    0, cBombsSpeed * Gear^.Tag, _0, 0);
  1692 			2: for i:= -19 to 19 do
  1692             2: for i:= -19 to 19 do
  1693 				FollowGear:= AddGear(hwRound(Gear^.X) + i div 3, hwRound(Gear^.Y), gtFlame, 0, _0_001 * i, _0, 0);
  1693                 FollowGear:= AddGear(hwRound(Gear^.X) + i div 3, hwRound(Gear^.Y), gtFlame, 0, _0_001 * i, _0, 0);
  1694 			end;
  1694             end;
  1695 	Gear^.dX:= Gear^.dX + int2hwFloat(30 * Gear^.Tag)
  1695     Gear^.dX:= Gear^.dX + int2hwFloat(30 * Gear^.Tag)
  1696 	end;
  1696     end;
  1697 
  1697 
  1698 if (GameTicks and $3F) = 0 then
  1698 if (GameTicks and $3F) = 0 then
  1699 	AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0);
  1699     AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0);
  1700 
  1700 
  1701 if (hwRound(Gear^.X) > (LAND_WIDTH+1024)) or (hwRound(Gear^.X) < -1024) then DeleteGear(Gear)
  1701 if (hwRound(Gear^.X) > (LAND_WIDTH+1024)) or (hwRound(Gear^.X) < -1024) then DeleteGear(Gear)
  1702 end;
  1702 end;
  1703 
  1703 
  1704 procedure doStepAirAttack(Gear: PGear);
  1704 procedure doStepAirAttack(Gear: PGear);
  1705 begin
  1705 begin
  1706 AllInactive:= false;
  1706 AllInactive:= false;
  1707 
  1707 
  1708 if Gear^.X.QWordValue = 0 then
  1708 if Gear^.X.QWordValue = 0 then
  1709 	begin
  1709     begin
  1710 	Gear^.Tag:=  1;
  1710     Gear^.Tag:=  1;
  1711 	Gear^.X:= -_1024;
  1711     Gear^.X:= -_1024;
  1712 	end
  1712     end
  1713 else
  1713 else
  1714 	begin
  1714     begin
  1715 	Gear^.Tag:= -1;
  1715     Gear^.Tag:= -1;
  1716 	Gear^.X:= int2hwFloat(LAND_WIDTH + 1024);
  1716     Gear^.X:= int2hwFloat(LAND_WIDTH + 1024);
  1717 	end;
  1717     end;
  1718 
  1718 
  1719 Gear^.Y:= int2hwFloat(topY-300);
  1719 Gear^.Y:= int2hwFloat(topY-300);
  1720 Gear^.dX:= int2hwFloat(TargetPoint.X - 5 * Gear^.Tag * 15);
  1720 Gear^.dX:= int2hwFloat(TargetPoint.X - 5 * Gear^.Tag * 15);
  1721 
  1721 
  1722 if (int2hwFloat(TargetPoint.Y) - Gear^.Y > _0) and (Gear^.State <> 2) then
  1722 if (int2hwFloat(TargetPoint.Y) - Gear^.Y > _0) and (Gear^.State <> 2) then
  1723 	    Gear^.dX:= Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(TargetPoint.Y) - Gear^.Y) * 2 / cGravity) * Gear^.Tag;
  1723         Gear^.dX:= Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(TargetPoint.Y) - Gear^.Y) * 2 / cGravity) * Gear^.Tag;
  1724 
  1724 
  1725 Gear^.Health:= 6;
  1725 Gear^.Health:= 6;
  1726 Gear^.doStep:= @doStepAirAttackWork;
  1726 Gear^.doStep:= @doStepAirAttackWork;
  1727 end;
  1727 end;
  1728 
  1728 
  1731 procedure doStepAirBomb(Gear: PGear);
  1731 procedure doStepAirBomb(Gear: PGear);
  1732 begin
  1732 begin
  1733 AllInactive:= false;
  1733 AllInactive:= false;
  1734 doStepFallingGear(Gear);
  1734 doStepFallingGear(Gear);
  1735 if (Gear^.State and gstCollision) <> 0 then
  1735 if (Gear^.State and gstCollision) <> 0 then
  1736 	begin
  1736     begin
  1737 	doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound);
  1737     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound);
  1738 	DeleteGear(Gear);
  1738     DeleteGear(Gear);
  1739 	exit
  1739     exit
  1740 	end;
  1740     end;
  1741 if (GameTicks and $3F) = 0 then
  1741 if (GameTicks and $3F) = 0 then
  1742 	AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0)
  1742     AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0)
  1743 end;
  1743 end;
  1744 
  1744 
  1745 ////////////////////////////////////////////////////////////////////////////////
  1745 ////////////////////////////////////////////////////////////////////////////////
  1746 
  1746 
  1747 procedure doStepGirder(Gear: PGear);
  1747 procedure doStepGirder(Gear: PGear);
  1758 
  1758 
  1759 if (Distance(tx - x, ty - y) > _256) or
  1759 if (Distance(tx - x, ty - y) > _256) or
  1760    not TryPlaceOnLand(TargetPoint.X - SpritesData[sprAmGirder].Width div 2,
  1760    not TryPlaceOnLand(TargetPoint.X - SpritesData[sprAmGirder].Width div 2,
  1761                       TargetPoint.Y - SpritesData[sprAmGirder].Height div 2,
  1761                       TargetPoint.Y - SpritesData[sprAmGirder].Height div 2,
  1762                       sprAmGirder, Gear^.State, true) then
  1762                       sprAmGirder, Gear^.State, true) then
  1763 	begin
  1763     begin
  1764     PlaySound(sndDenied);
  1764     PlaySound(sndDenied);
  1765 	HHGear^.Message:= HHGear^.Message and not gm_Attack;
  1765     HHGear^.Message:= HHGear^.Message and not gm_Attack;
  1766 	HHGear^.State:= HHGear^.State and not gstAttacking;
  1766     HHGear^.State:= HHGear^.State and not gstAttacking;
  1767 	HHGear^.State:= HHGear^.State or gstHHChooseTarget;
  1767     HHGear^.State:= HHGear^.State or gstHHChooseTarget;
  1768 	isCursorVisible:= true;
  1768     isCursorVisible:= true;
  1769 	DeleteGear(Gear)
  1769     DeleteGear(Gear)
  1770 	end
  1770     end
  1771 else begin
  1771 else begin
  1772     PlaySound(sndPlaced);
  1772     PlaySound(sndPlaced);
  1773 	DeleteGear(Gear);
  1773     DeleteGear(Gear);
  1774     OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^);
  1774     OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^);
  1775     ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^)
  1775     ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^)
  1776 	end;
  1776     end;
  1777 
  1777 
  1778 HHGear^.State:= HHGear^.State and not (gstAttacking or gstAttacked);
  1778 HHGear^.State:= HHGear^.State and not (gstAttacking or gstAttacked);
  1779 HHGear^.Message:= HHGear^.Message and not gm_Attack;
  1779 HHGear^.Message:= HHGear^.Message and not gm_Attack;
  1780 TargetPoint.X:= NoPointX
  1780 TargetPoint.X:= NoPointX
  1781 end;
  1781 end;
  1787 PHedgehog(Gear^.Hedgehog)^.Unplaced:= false;
  1787 PHedgehog(Gear^.Hedgehog)^.Unplaced:= false;
  1788 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1788 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1789 HHGear^.Y:= HHGear^.Y + HHGear^.dY; // hedgehog falling to collect cases
  1789 HHGear^.Y:= HHGear^.Y + HHGear^.dY; // hedgehog falling to collect cases
  1790 HHGear^.dY:= HHGear^.dY + cGravity;
  1790 HHGear^.dY:= HHGear^.dY + cGravity;
  1791 if TestCollisionYwithGear(HHGear, 1)
  1791 if TestCollisionYwithGear(HHGear, 1)
  1792 	or CheckGearDrowning(HHGear) then
  1792     or CheckGearDrowning(HHGear) then
  1793 	begin
  1793     begin
  1794 	DeleteGear(Gear);
  1794     DeleteGear(Gear);
  1795 	AfterAttack
  1795     AfterAttack
  1796 	end
  1796     end
  1797 end;
  1797 end;
  1798 
  1798 
  1799 procedure doStepTeleportAnim(Gear: PGear);
  1799 procedure doStepTeleportAnim(Gear: PGear);
  1800 begin
  1800 begin
  1801 inc(Gear^.Timer);
  1801 inc(Gear^.Timer);
  1802 if Gear^.Timer = 65 then
  1802 if Gear^.Timer = 65 then
  1803 	begin
  1803     begin
  1804 	Gear^.Timer:= 0;
  1804     Gear^.Timer:= 0;
  1805 	inc(Gear^.Pos);
  1805     inc(Gear^.Pos);
  1806 	if Gear^.Pos = 11 then
  1806     if Gear^.Pos = 11 then
  1807 		Gear^.doStep:= @doStepTeleportAfter
  1807         Gear^.doStep:= @doStepTeleportAfter
  1808 	end;
  1808     end;
  1809 end;
  1809 end;
  1810 
  1810 
  1811 procedure doStepTeleport(Gear: PGear);
  1811 procedure doStepTeleport(Gear: PGear);
  1812 var HHGear: PGear;
  1812 var HHGear: PGear;
  1813 begin
  1813 begin
  1815 
  1815 
  1816 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1816 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1817 if not TryPlaceOnLand(TargetPoint.X - SpritesData[sprHHTelepMask].Width div 2,
  1817 if not TryPlaceOnLand(TargetPoint.X - SpritesData[sprHHTelepMask].Width div 2,
  1818                       TargetPoint.Y - SpritesData[sprHHTelepMask].Height div 2,
  1818                       TargetPoint.Y - SpritesData[sprHHTelepMask].Height div 2,
  1819                       sprHHTelepMask, 0, false) then
  1819                       sprHHTelepMask, 0, false) then
  1820 		begin
  1820         begin
  1821 		HHGear^.Message:= HHGear^.Message and not gm_Attack;
  1821         HHGear^.Message:= HHGear^.Message and not gm_Attack;
  1822 		HHGear^.State:= HHGear^.State and not gstAttacking;
  1822         HHGear^.State:= HHGear^.State and not gstAttacking;
  1823 		HHGear^.State:= HHGear^.State or gstHHChooseTarget;
  1823         HHGear^.State:= HHGear^.State or gstHHChooseTarget;
  1824 		DeleteGear(Gear);
  1824         DeleteGear(Gear);
  1825 		isCursorVisible:= true;
  1825         isCursorVisible:= true;
  1826 		PlaySound(sndDenied)
  1826         PlaySound(sndDenied)
  1827 		end
  1827         end
  1828 	else begin
  1828     else begin
  1829 		DeleteCI(HHGear);
  1829         DeleteCI(HHGear);
  1830 		SetAllHHToActive;
  1830         SetAllHHToActive;
  1831 		Gear^.doStep:= @doStepTeleportAnim;
  1831         Gear^.doStep:= @doStepTeleportAnim;
  1832 		Gear^.X:= HHGear^.X;
  1832         Gear^.X:= HHGear^.X;
  1833 		Gear^.Y:= HHGear^.Y;
  1833         Gear^.Y:= HHGear^.Y;
  1834 		HHGear^.X:= int2hwFloat(TargetPoint.X);
  1834         HHGear^.X:= int2hwFloat(TargetPoint.X);
  1835 		HHGear^.Y:= int2hwFloat(TargetPoint.Y);
  1835         HHGear^.Y:= int2hwFloat(TargetPoint.Y);
  1836 		HHGear^.State:= HHGear^.State or gstMoving;
  1836         HHGear^.State:= HHGear^.State or gstMoving;
  1837 		playSound(sndWarp)
  1837         playSound(sndWarp)
  1838 		end;
  1838         end;
  1839 TargetPoint.X:= NoPointX;
  1839 TargetPoint.X:= NoPointX;
  1840 
  1840 
  1841 end;
  1841 end;
  1842 
  1842 
  1843 ////////////////////////////////////////////////////////////////////////////////
  1843 ////////////////////////////////////////////////////////////////////////////////
  1846     Msg, State: Longword;
  1846     Msg, State: Longword;
  1847 begin
  1847 begin
  1848 AllInactive:= false;
  1848 AllInactive:= false;
  1849 
  1849 
  1850 if ((Gear^.Message and not gm_Switch) <> 0) or (TurnTimeLeft = 0) then
  1850 if ((Gear^.Message and not gm_Switch) <> 0) or (TurnTimeLeft = 0) then
  1851 	begin
  1851     begin
  1852 	HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1852     HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1853 	Msg:= Gear^.Message and not gm_Switch;
  1853     Msg:= Gear^.Message and not gm_Switch;
  1854 	DeleteGear(Gear);
  1854     DeleteGear(Gear);
  1855 	OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^);
  1855     OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^);
  1856 	ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^);
  1856     ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^);
  1857 
  1857 
  1858 	HHGear:= CurrentHedgehog^.Gear;
  1858     HHGear:= CurrentHedgehog^.Gear;
  1859 	ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^);
  1859     ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^);
  1860 	HHGear^.Message:= Msg;
  1860     HHGear^.Message:= Msg;
  1861 	exit
  1861     exit
  1862 	end;
  1862     end;
  1863 
  1863 
  1864 if (Gear^.Message and gm_Switch) <> 0 then
  1864 if (Gear^.Message and gm_Switch) <> 0 then
  1865 	begin
  1865     begin
  1866 	HHGear:= CurrentHedgehog^.Gear;
  1866     HHGear:= CurrentHedgehog^.Gear;
  1867 	HHGear^.Message:= HHGear^.Message and not gm_Switch;
  1867     HHGear^.Message:= HHGear^.Message and not gm_Switch;
  1868 	Gear^.Message:= Gear^.Message and not gm_Switch;
  1868     Gear^.Message:= Gear^.Message and not gm_Switch;
  1869 	State:= HHGear^.State;
  1869     State:= HHGear^.State;
  1870 	HHGear^.State:= 0;
  1870     HHGear^.State:= 0;
  1871 	HHGear^.Active:= false;
  1871     HHGear^.Active:= false;
  1872 	HHGear^.Z:= cHHZ;
  1872     HHGear^.Z:= cHHZ;
  1873 	RemoveGearFromList(HHGear);
  1873     RemoveGearFromList(HHGear);
  1874 	InsertGearToList(HHGear);
  1874     InsertGearToList(HHGear);
  1875 
  1875 
  1876 	PlaySound(sndSwitchHog);
  1876     PlaySound(sndSwitchHog);
  1877 	
  1877     
  1878 	repeat
  1878     repeat
  1879 		CurrentTeam^.CurrHedgehog:= Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber);
  1879         CurrentTeam^.CurrHedgehog:= Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber);
  1880 	until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil);
  1880     until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil);
  1881 
  1881 
  1882 	CurrentHedgehog:= @CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog];
  1882     CurrentHedgehog:= @CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog];
  1883 
  1883 
  1884 	HHGear:= CurrentHedgehog^.Gear;
  1884     HHGear:= CurrentHedgehog^.Gear;
  1885 	HHGear^.State:= State;
  1885     HHGear^.State:= State;
  1886 	HHGear^.Active:= true;
  1886     HHGear^.Active:= true;
  1887 	FollowGear:= HHGear;
  1887     FollowGear:= HHGear;
  1888 	HHGear^.Z:= cCurrHHZ;
  1888     HHGear^.Z:= cCurrHHZ;
  1889 	RemoveGearFromList(HHGear);
  1889     RemoveGearFromList(HHGear);
  1890 	InsertGearToList(HHGear);
  1890     InsertGearToList(HHGear);
  1891 	Gear^.X:= HHGear^.X;
  1891     Gear^.X:= HHGear^.X;
  1892 	Gear^.Y:= HHGear^.Y
  1892     Gear^.Y:= HHGear^.Y
  1893 	end;
  1893     end;
  1894 end;
  1894 end;
  1895 
  1895 
  1896 procedure doStepSwitcher(Gear: PGear);
  1896 procedure doStepSwitcher(Gear: PGear);
  1897 var HHGear: PGear;
  1897 var HHGear: PGear;
  1898 begin
  1898 begin
  1899 Gear^.doStep:= @doStepSwitcherWork;
  1899 Gear^.doStep:= @doStepSwitcherWork;
  1900 
  1900 
  1901 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1901 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  1902 with HHGear^ do
  1902 with HHGear^ do
  1903 	begin
  1903     begin
  1904 	State:= State and not gstAttacking;
  1904     State:= State and not gstAttacking;
  1905 	Message:= Message and not gm_Attack
  1905     Message:= Message and not gm_Attack
  1906 	end
  1906     end
  1907 end;
  1907 end;
  1908 
  1908 
  1909 ////////////////////////////////////////////////////////////////////////////////
  1909 ////////////////////////////////////////////////////////////////////////////////
  1910 procedure doStepMortar(Gear: PGear);
  1910 procedure doStepMortar(Gear: PGear);
  1911 var dX, dY: hwFloat;
  1911 var dX, dY: hwFloat;
  1916 dxn:= Gear^.dX.isNegative;
  1916 dxn:= Gear^.dX.isNegative;
  1917 dyn:= Gear^.dY.isNegative;
  1917 dyn:= Gear^.dY.isNegative;
  1918 
  1918 
  1919 doStepFallingGear(Gear);
  1919 doStepFallingGear(Gear);
  1920 if (Gear^.State and gstCollision) <> 0 then
  1920 if (Gear^.State and gstCollision) <> 0 then
  1921 	begin
  1921     begin
  1922 	doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, EXPLAutoSound);
  1922     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, EXPLAutoSound);
  1923 
  1923 
  1924 	Gear^.dX.isNegative:= not dxn;
  1924     Gear^.dX.isNegative:= not dxn;
  1925 	Gear^.dY.isNegative:= not dyn;
  1925     Gear^.dY.isNegative:= not dyn;
  1926 	for i:= 0 to 4 do
  1926     for i:= 0 to 4 do
  1927 		begin
  1927         begin
  1928 		dX:= Gear^.dX + (GetRandom - _0_5) * _0_03;
  1928         dX:= Gear^.dX + (GetRandom - _0_5) * _0_03;
  1929 		dY:= Gear^.dY + (GetRandom - _0_5) * _0_03;
  1929         dY:= Gear^.dY + (GetRandom - _0_5) * _0_03;
  1930 		AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25);
  1930         AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25);
  1931 		end;
  1931         end;
  1932 
  1932 
  1933 	DeleteGear(Gear);
  1933     DeleteGear(Gear);
  1934 	exit
  1934     exit
  1935 	end;
  1935     end;
  1936 
  1936 
  1937 if (GameTicks and $3F) = 0 then
  1937 if (GameTicks and $3F) = 0 then
  1938 	AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0)
  1938     AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0)
  1939 end;
  1939 end;
  1940 
  1940 
  1941 ////////////////////////////////////////////////////////////////////////////////
  1941 ////////////////////////////////////////////////////////////////////////////////
  1942 procedure doStepKamikazeWork(Gear: PGear);
  1942 procedure doStepKamikazeWork(Gear: PGear);
  1943 const upd: Longword = 0;
  1943 const upd: Longword = 0;
  1950 HHGear^.State:= HHGear^.State or gstNoDamage;
  1950 HHGear^.State:= HHGear^.State or gstNoDamage;
  1951 DeleteCI(HHGear);
  1951 DeleteCI(HHGear);
  1952 
  1952 
  1953 i:= 2;
  1953 i:= 2;
  1954 repeat
  1954 repeat
  1955 	Gear^.X:= Gear^.X + HHGear^.dX;
  1955     Gear^.X:= Gear^.X + HHGear^.dX;
  1956 	Gear^.Y:= Gear^.Y + HHGear^.dY;
  1956     Gear^.Y:= Gear^.Y + HHGear^.dY;
  1957 	HHGear^.X:= Gear^.X;
  1957     HHGear^.X:= Gear^.X;
  1958 	HHGear^.Y:= Gear^.Y;
  1958     HHGear^.Y:= Gear^.Y;
  1959 
  1959 
  1960 	inc(Gear^.Damage, 2);
  1960     inc(Gear^.Damage, 2);
  1961 
  1961 
  1962 //	if TestCollisionXwithGear(HHGear, hwSign(Gear^.dX))
  1962 //  if TestCollisionXwithGear(HHGear, hwSign(Gear^.dX))
  1963 //		or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY)) then inc(Gear^.Damage, 3);
  1963 //      or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY)) then inc(Gear^.Damage, 3);
  1964 
  1964 
  1965 	dec(i)
  1965     dec(i)
  1966 until (i = 0) or (Gear^.Damage > Gear^.Health);
  1966 until (i = 0) or (Gear^.Damage > Gear^.Health);
  1967 
  1967 
  1968 inc(upd);
  1968 inc(upd);
  1969 if upd > 3 then
  1969 if upd > 3 then
  1970 	begin
  1970     begin
  1971 	if Gear^.Health < 1500 then Gear^.Pos:= 2;
  1971     if Gear^.Health < 1500 then Gear^.Pos:= 2;
  1972 
  1972 
  1973 	AmmoShove(Gear, 30, 40);
  1973     AmmoShove(Gear, 30, 40);
  1974 
  1974 
  1975 	DrawTunnel(HHGear^.X - HHGear^.dX * 10,
  1975     DrawTunnel(HHGear^.X - HHGear^.dX * 10,
  1976 			HHGear^.Y - _2 - HHGear^.dY * 10 + hwAbs(HHGear^.dY) * 2,
  1976             HHGear^.Y - _2 - HHGear^.dY * 10 + hwAbs(HHGear^.dY) * 2,
  1977 			HHGear^.dX,
  1977             HHGear^.dX,
  1978 			HHGear^.dY,
  1978             HHGear^.dY,
  1979 			20 + cHHRadius * 2,
  1979             20 + cHHRadius * 2,
  1980 			cHHRadius * 2 + 6);
  1980             cHHRadius * 2 + 6);
  1981 
  1981 
  1982 	upd:= 0
  1982     upd:= 0
  1983 	end;
  1983     end;
  1984 
  1984 
  1985 if Gear^.Health < Gear^.Damage then
  1985 if Gear^.Health < Gear^.Damage then
  1986 	begin
  1986     begin
  1987 	doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound);
  1987     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound);
  1988 	AfterAttack;
  1988     AfterAttack;
  1989 	DeleteGear(Gear);
  1989     DeleteGear(Gear);
  1990 	DeleteGear(HHGear);
  1990     DeleteGear(HHGear);
  1991 	end else
  1991     end else
  1992 	begin
  1992     begin
  1993 	dec(Gear^.Health, Gear^.Damage);
  1993     dec(Gear^.Health, Gear^.Damage);
  1994 	Gear^.Damage:= 0
  1994     Gear^.Damage:= 0
  1995 	end
  1995     end
  1996 end;
  1996 end;
  1997 
  1997 
  1998 procedure doStepKamikazeIdle(Gear: PGear);
  1998 procedure doStepKamikazeIdle(Gear: PGear);
  1999 begin
  1999 begin
  2000 AllInactive:= false;
  2000 AllInactive:= false;
  2001 dec(Gear^.Timer);
  2001 dec(Gear^.Timer);
  2002 if Gear^.Timer = 0 then
  2002 if Gear^.Timer = 0 then
  2003 	begin
  2003     begin
  2004 	Gear^.Pos:= 1;
  2004     Gear^.Pos:= 1;
  2005 	PlaySound(sndKamikaze, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack);
  2005     PlaySound(sndKamikaze, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack);
  2006 	Gear^.doStep:= @doStepKamikazeWork
  2006     Gear^.doStep:= @doStepKamikazeWork
  2007 	end
  2007     end
  2008 end;
  2008 end;
  2009 
  2009 
  2010 procedure doStepKamikaze(Gear: PGear);
  2010 procedure doStepKamikaze(Gear: PGear);
  2011 var HHGear: PGear;
  2011 var HHGear: PGear;
  2012 begin
  2012 begin
  2027 
  2027 
  2028 ////////////////////////////////////////////////////////////////////////////////
  2028 ////////////////////////////////////////////////////////////////////////////////
  2029 const cakeh = 27;
  2029 const cakeh = 27;
  2030       cakeDmg = 75;
  2030       cakeDmg = 75;
  2031 var CakePoints: array[0..Pred(cakeh)] of record x, y: hwFloat; end;
  2031 var CakePoints: array[0..Pred(cakeh)] of record x, y: hwFloat; end;
  2032 	CakeI: Longword;
  2032     CakeI: Longword;
  2033 
  2033 
  2034 procedure doStepCakeExpl(Gear: PGear);
  2034 procedure doStepCakeExpl(Gear: PGear);
  2035 begin
  2035 begin
  2036 AllInactive:= false;
  2036 AllInactive:= false;
  2037 
  2037 
  2043 DeleteGear(Gear)
  2043 DeleteGear(Gear)
  2044 end;
  2044 end;
  2045 
  2045 
  2046 procedure doStepCakeDown(Gear: PGear);
  2046 procedure doStepCakeDown(Gear: PGear);
  2047 var gi: PGear;
  2047 var gi: PGear;
  2048 	dmg: LongInt;
  2048     dmg: LongInt;
  2049 begin
  2049 begin
  2050 AllInactive:= false;
  2050 AllInactive:= false;
  2051 
  2051 
  2052 inc(Gear^.Tag);
  2052 inc(Gear^.Tag);
  2053 if Gear^.Tag < 100 then exit;
  2053 if Gear^.Tag < 100 then exit;
  2054 Gear^.Tag:= 0;
  2054 Gear^.Tag:= 0;
  2055 
  2055 
  2056 if Gear^.Pos = 0 then
  2056 if Gear^.Pos = 0 then
  2057 	begin
  2057     begin
  2058 	gi:= GearsList;
  2058     gi:= GearsList;
  2059 	while gi <> nil do
  2059     while gi <> nil do
  2060 		begin
  2060         begin
  2061 		dmg:= cakeDmg * 2 - hwRound(Distance(gi^.X - Gear^.X, gi^.Y - Gear^.Y));
  2061         dmg:= cakeDmg * 2 - hwRound(Distance(gi^.X - Gear^.X, gi^.Y - Gear^.Y));
  2062 		if (dmg > 1) and (gi^.Kind = gtHedgehog) then
  2062         if (dmg > 1) and (gi^.Kind = gtHedgehog) then
  2063             if (CurrentHedgehog^.Gear = gi) and (not gi^.Invulnerable) then
  2063             if (CurrentHedgehog^.Gear = gi) and (not gi^.Invulnerable) then
  2064 			    gi^.State:= gi^.State or gstLoser
  2064                 gi^.State:= gi^.State or gstLoser
  2065             else
  2065             else
  2066 			    gi^.State:= gi^.State or gstWinner;
  2066                 gi^.State:= gi^.State or gstWinner;
  2067 		gi:= gi^.NextGear
  2067         gi:= gi^.NextGear
  2068 		end;
  2068         end;
  2069 	Gear^.doStep:= @doStepCakeExpl;
  2069     Gear^.doStep:= @doStepCakeExpl;
  2070 	PlaySound(sndCake)
  2070     PlaySound(sndCake)
  2071 	end else dec(Gear^.Pos)
  2071     end else dec(Gear^.Pos)
  2072 end;
  2072 end;
  2073 
  2073 
  2074 
  2074 
  2075 procedure doStepCakeWork(Gear: PGear);
  2075 procedure doStepCakeWork(Gear: PGear);
  2076 const dirs: array[0..3] of TPoint = ((x: 0; y: -1), (x: 1; y: 0),(x: 0; y: 1),(x: -1; y: 0));
  2076 const dirs: array[0..3] of TPoint = ((x: 0; y: -1), (x: 1; y: 0),(x: 0; y: 1),(x: -1; y: 0));
  2077 var xx, yy, xxn, yyn: LongInt;
  2077 var xx, yy, xxn, yyn: LongInt;
  2078 	da: LongInt;
  2078     da: LongInt;
  2079 	tdx, tdy: hwFloat;
  2079     tdx, tdy: hwFloat;
  2080 
  2080 
  2081 	procedure PrevAngle;
  2081     procedure PrevAngle;
  2082 	begin
  2082     begin
  2083 	Gear^.Angle:= (LongInt(Gear^.Angle) + 4 - dA) mod 4
  2083     Gear^.Angle:= (LongInt(Gear^.Angle) + 4 - dA) mod 4
  2084 	end;
  2084     end;
  2085 
  2085 
  2086 	procedure NextAngle;
  2086     procedure NextAngle;
  2087 	begin
  2087     begin
  2088 	Gear^.Angle:= (LongInt(Gear^.Angle) + 4 + dA) mod 4
  2088     Gear^.Angle:= (LongInt(Gear^.Angle) + 4 + dA) mod 4
  2089 	end;
  2089     end;
  2090 
  2090 
  2091 begin
  2091 begin
  2092 AllInactive:= false;
  2092 AllInactive:= false;
  2093 
  2093 
  2094 inc(Gear^.Tag);
  2094 inc(Gear^.Tag);
  2099 yy:= dirs[Gear^.Angle].y;
  2099 yy:= dirs[Gear^.Angle].y;
  2100 xxn:= dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].x;
  2100 xxn:= dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].x;
  2101 yyn:= dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].y;
  2101 yyn:= dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].y;
  2102 
  2102 
  2103 if (xx = 0) then
  2103 if (xx = 0) then
  2104 	if TestCollisionYwithGear(Gear, yy) then
  2104     if TestCollisionYwithGear(Gear, yy) then
  2105 		PrevAngle
  2105         PrevAngle
  2106 	else begin
  2106     else begin
  2107 		Gear^.Tag:= 0;
  2107         Gear^.Tag:= 0;
  2108 		Gear^.Y:= Gear^.Y + int2hwFloat(yy);
  2108         Gear^.Y:= Gear^.Y + int2hwFloat(yy);
  2109 		if not TestCollisionXwithGear(Gear, xxn) then
  2109         if not TestCollisionXwithGear(Gear, xxn) then
  2110 			begin
  2110             begin
  2111 			Gear^.X:= Gear^.X + int2hwFloat(xxn);
  2111             Gear^.X:= Gear^.X + int2hwFloat(xxn);
  2112 			NextAngle
  2112             NextAngle
  2113 			end;
  2113             end;
  2114 		end;
  2114         end;
  2115 
  2115 
  2116 if (yy = 0) then
  2116 if (yy = 0) then
  2117 	if TestCollisionXwithGear(Gear, xx) then
  2117     if TestCollisionXwithGear(Gear, xx) then
  2118 		PrevAngle
  2118         PrevAngle
  2119 	else begin
  2119     else begin
  2120 		Gear^.Tag:= 0;
  2120         Gear^.Tag:= 0;
  2121 		Gear^.X:= Gear^.X + int2hwFloat(xx);
  2121         Gear^.X:= Gear^.X + int2hwFloat(xx);
  2122 		if not TestCollisionYwithGear(Gear, yyn) then
  2122         if not TestCollisionYwithGear(Gear, yyn) then
  2123 			begin
  2123             begin
  2124 			Gear^.Y:= Gear^.Y + int2hwFloat(yyn);
  2124             Gear^.Y:= Gear^.Y + int2hwFloat(yyn);
  2125 			NextAngle
  2125             NextAngle
  2126 			end;
  2126             end;
  2127 		end;
  2127         end;
  2128 
  2128 
  2129 if Gear^.Tag = 0 then
  2129 if Gear^.Tag = 0 then
  2130 	begin
  2130     begin
  2131 	CakeI:= (CakeI + 1) mod cakeh;
  2131     CakeI:= (CakeI + 1) mod cakeh;
  2132 	tdx:= CakePoints[CakeI].x - Gear^.X;
  2132     tdx:= CakePoints[CakeI].x - Gear^.X;
  2133 	tdy:= - CakePoints[CakeI].y + Gear^.Y;
  2133     tdy:= - CakePoints[CakeI].y + Gear^.Y;
  2134 	CakePoints[CakeI].x:= Gear^.X;
  2134     CakePoints[CakeI].x:= Gear^.X;
  2135 	CakePoints[CakeI].y:= Gear^.Y;
  2135     CakePoints[CakeI].y:= Gear^.Y;
  2136 	Gear^.DirAngle:= DxDy2Angle(tdx, tdy);
  2136     Gear^.DirAngle:= DxDy2Angle(tdx, tdy);
  2137 	end;
  2137     end;
  2138 
  2138 
  2139 dec(Gear^.Health);
  2139 dec(Gear^.Health);
  2140 Gear^.Timer:= Gear^.Health*10; // This is not seconds, but at least it is *some* feedback
  2140 Gear^.Timer:= Gear^.Health*10; // This is not seconds, but at least it is *some* feedback
  2141 if (Gear^.Health = 0) or ((Gear^.Message and gm_Attack) <> 0) then
  2141 if (Gear^.Health = 0) or ((Gear^.Message and gm_Attack) <> 0) then
  2142 	begin
  2142     begin
  2143 	FollowGear:= Gear;
  2143     FollowGear:= Gear;
  2144     Gear^.RenderTimer:= false;
  2144     Gear^.RenderTimer:= false;
  2145 	Gear^.doStep:= @doStepCakeDown
  2145     Gear^.doStep:= @doStepCakeDown
  2146 	end
  2146     end
  2147 end;
  2147 end;
  2148 
  2148 
  2149 procedure doStepCakeUp(Gear: PGear);
  2149 procedure doStepCakeUp(Gear: PGear);
  2150 var i: Longword;
  2150 var i: Longword;
  2151 begin
  2151 begin
  2154 inc(Gear^.Tag);
  2154 inc(Gear^.Tag);
  2155 if Gear^.Tag < 100 then exit;
  2155 if Gear^.Tag < 100 then exit;
  2156 Gear^.Tag:= 0;
  2156 Gear^.Tag:= 0;
  2157 
  2157 
  2158 if Gear^.Pos = 6 then
  2158 if Gear^.Pos = 6 then
  2159 	begin
  2159     begin
  2160 	for i:= 0 to Pred(cakeh) do
  2160     for i:= 0 to Pred(cakeh) do
  2161 		begin
  2161         begin
  2162 		CakePoints[i].x:= Gear^.X;
  2162         CakePoints[i].x:= Gear^.X;
  2163 		CakePoints[i].y:= Gear^.Y
  2163         CakePoints[i].y:= Gear^.Y
  2164 		end;
  2164         end;
  2165 	CakeI:= 0;
  2165     CakeI:= 0;
  2166 	Gear^.doStep:= @doStepCakeWork
  2166     Gear^.doStep:= @doStepCakeWork
  2167 	end else inc(Gear^.Pos)
  2167     end else inc(Gear^.Pos)
  2168 end;
  2168 end;
  2169 
  2169 
  2170 procedure doStepCakeFall(Gear: PGear);
  2170 procedure doStepCakeFall(Gear: PGear);
  2171 begin
  2171 begin
  2172 AllInactive:= false;
  2172 AllInactive:= false;
  2173 
  2173 
  2174 Gear^.dY:= Gear^.dY + cGravity;
  2174 Gear^.dY:= Gear^.dY + cGravity;
  2175 if TestCollisionYwithGear(Gear, 1) then
  2175 if TestCollisionYwithGear(Gear, 1) then
  2176 	Gear^.doStep:= @doStepCakeUp
  2176     Gear^.doStep:= @doStepCakeUp
  2177 else
  2177 else
  2178 	begin
  2178     begin
  2179 	Gear^.Y:= Gear^.Y + Gear^.dY;
  2179     Gear^.Y:= Gear^.Y + Gear^.dY;
  2180 	if CheckGearDrowning(Gear) then AfterAttack
  2180     if CheckGearDrowning(Gear) then AfterAttack
  2181 	end
  2181     end
  2182 end;
  2182 end;
  2183 
  2183 
  2184 procedure doStepCake(Gear: PGear);
  2184 procedure doStepCake(Gear: PGear);
  2185 var HHGear: PGear;
  2185 var HHGear: PGear;
  2186 begin
  2186 begin
  2205 Gear^.Y:= Gear^.Y + Gear^.dY;
  2205 Gear^.Y:= Gear^.Y + Gear^.dY;
  2206 x:= hwRound(Gear^.X);
  2206 x:= hwRound(Gear^.X);
  2207 y:= hwRound(Gear^.Y);
  2207 y:= hwRound(Gear^.Y);
  2208 
  2208 
  2209 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then
  2209 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then
  2210 	if (Land[y, x] <> 0) then
  2210     if (Land[y, x] <> 0) then
  2211 		begin
  2211         begin
  2212 		Gear^.dX.isNegative:= not Gear^.dX.isNegative;
  2212         Gear^.dX.isNegative:= not Gear^.dX.isNegative;
  2213 		Gear^.dY.isNegative:= not Gear^.dY.isNegative;
  2213         Gear^.dY.isNegative:= not Gear^.dY.isNegative;
  2214 		Gear^.dX:= Gear^.dX * _1_5;
  2214         Gear^.dX:= Gear^.dX * _1_5;
  2215 		Gear^.dY:= Gear^.dY * _1_5 - _0_3;
  2215         Gear^.dY:= Gear^.dY * _1_5 - _0_3;
  2216 		AmmoShove(Gear, 0, 40);
  2216         AmmoShove(Gear, 0, 40);
  2217 		AfterAttack;
  2217         AfterAttack;
  2218 		DeleteGear(Gear)
  2218         DeleteGear(Gear)
  2219 		end
  2219         end
  2220 	else
  2220     else
  2221 else
  2221 else
  2222 	begin
  2222     begin
  2223 	AfterAttack;
  2223     AfterAttack;
  2224 	DeleteGear(Gear)
  2224     DeleteGear(Gear)
  2225 	end
  2225     end
  2226 end;
  2226 end;
  2227 
  2227 
  2228 procedure doStepSeductionWear(Gear: PGear);
  2228 procedure doStepSeductionWear(Gear: PGear);
  2229 begin
  2229 begin
  2230 AllInactive:= false;
  2230 AllInactive:= false;
  2231 inc(Gear^.Timer);
  2231 inc(Gear^.Timer);
  2232 if Gear^.Timer > 250 then
  2232 if Gear^.Timer > 250 then
  2233 	begin
  2233     begin
  2234 	Gear^.Timer:= 0;
  2234     Gear^.Timer:= 0;
  2235 	inc(Gear^.Pos);
  2235     inc(Gear^.Pos);
  2236 	if Gear^.Pos = 5 then
  2236     if Gear^.Pos = 5 then
  2237 		PlaySound(sndYoohoo, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack)
  2237         PlaySound(sndYoohoo, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack)
  2238 	end;
  2238     end;
  2239 
  2239 
  2240 if Gear^.Pos = 14 then
  2240 if Gear^.Pos = 14 then
  2241 	Gear^.doStep:= @doStepSeductionWork
  2241     Gear^.doStep:= @doStepSeductionWork
  2242 end;
  2242 end;
  2243 
  2243 
  2244 procedure doStepSeduction(Gear: PGear);
  2244 procedure doStepSeduction(Gear: PGear);
  2245 begin
  2245 begin
  2246 AllInactive:= false;
  2246 AllInactive:= false;
  2254 begin
  2254 begin
  2255 AllInactive:= false;
  2255 AllInactive:= false;
  2256 
  2256 
  2257 inc(Gear^.Timer);
  2257 inc(Gear^.Timer);
  2258 if Gear^.Timer = 17 then
  2258 if Gear^.Timer = 17 then
  2259 	Gear^.Timer:= 0
  2259     Gear^.Timer:= 0
  2260 else
  2260 else
  2261 	exit;
  2261     exit;
  2262 
  2262 
  2263 if cWaterLine > 0 then
  2263 if cWaterLine > 0 then
  2264 	begin
  2264     begin
  2265 	dec(cWaterLine);
  2265     dec(cWaterLine);
  2266 	for i:= 0 to LAND_WIDTH - 1 do
  2266     for i:= 0 to LAND_WIDTH - 1 do
  2267 		Land[cWaterLine, i]:= 0;
  2267         Land[cWaterLine, i]:= 0;
  2268 	SetAllToActive
  2268     SetAllToActive
  2269 	end;
  2269     end;
  2270 
  2270 
  2271 inc(Gear^.Tag);
  2271 inc(Gear^.Tag);
  2272 if (Gear^.Tag = 47) or (cWaterLine = 0) then
  2272 if (Gear^.Tag = 47) or (cWaterLine = 0) then
  2273 	DeleteGear(Gear)
  2273     DeleteGear(Gear)
  2274 end;
  2274 end;
  2275 
  2275 
  2276 ////////////////////////////////////////////////////////////////////////////////
  2276 ////////////////////////////////////////////////////////////////////////////////
  2277 procedure doStepDrillDrilling(Gear: PGear);
  2277 procedure doStepDrillDrilling(Gear: PGear);
  2278 var t: PGearArray;
  2278 var t: PGearArray;
  2279 	ox, oy: hwFloat;
  2279     ox, oy: hwFloat;
  2280 begin
  2280 begin
  2281 AllInactive:= false;
  2281 AllInactive:= false;
  2282 
  2282 
  2283 if (Gear^.Timer > 0) and ((Gear^.Timer mod 10) = 0) then
  2283 if (Gear^.Timer > 0) and ((Gear^.Timer mod 10) = 0) then
  2284 	begin
  2284     begin
  2285 	ox:= Gear^.X;
  2285     ox:= Gear^.X;
  2286 	oy:= Gear^.Y;
  2286     oy:= Gear^.Y;
  2287 	Gear^.X:= Gear^.X + Gear^.dX;
  2287     Gear^.X:= Gear^.X + Gear^.dX;
  2288 	Gear^.Y:= Gear^.Y + Gear^.dY;
  2288     Gear^.Y:= Gear^.Y + Gear^.dY;
  2289 	DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 2, 6);
  2289     DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 2, 6);
  2290     if(CheckGearDrowning(Gear)) then
  2290     if(CheckGearDrowning(Gear)) then
  2291         begin
  2291         begin
  2292         StopSound(Gear^.SoundChannel);
  2292         StopSound(Gear^.SoundChannel);
  2293 	    exit
  2293         exit
  2294         end
  2294         end
  2295 	end;
  2295     end;
  2296 
  2296 
  2297 t:= CheckGearsCollision(Gear); //fixes drill not exploding when touching HH bug
  2297 t:= CheckGearsCollision(Gear); //fixes drill not exploding when touching HH bug
  2298 if (Gear^.Timer = 0)
  2298 if (Gear^.Timer = 0)
  2299 or (t^.Count <> 0)
  2299 or (t^.Count <> 0)
  2300 or (not TestCollisionYWithGear(Gear, hwSign(Gear^.dY))
  2300 or (not TestCollisionYWithGear(Gear, hwSign(Gear^.dY))
  2301 and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX)))
  2301 and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX)))
  2302 or (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] = COLOR_INDESTRUCTIBLE) then
  2302 or (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] = COLOR_INDESTRUCTIBLE) then
  2303 	begin //out of time or exited ground
  2303     begin //out of time or exited ground
  2304     StopSound(Gear^.SoundChannel);
  2304     StopSound(Gear^.SoundChannel);
  2305 	doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound);
  2305     doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound);
  2306 	DeleteGear(Gear);
  2306     DeleteGear(Gear);
  2307 	exit
  2307     exit
  2308 	end;
  2308     end;
  2309 
  2309 
  2310 dec(Gear^.Timer);
  2310 dec(Gear^.Timer);
  2311 end;
  2311 end;
  2312 
  2312 
  2313 procedure doStepDrill(Gear: PGear);
  2313 procedure doStepDrill(Gear: PGear);
  2314 var t: PGearArray;
  2314 var t: PGearArray;
  2315 	oldDx, oldDy: hwFloat;
  2315     oldDx, oldDy: hwFloat;
  2316 	t2: hwFloat;
  2316     t2: hwFloat;
  2317 begin
  2317 begin
  2318 AllInactive:= false;
  2318 AllInactive:= false;
  2319 
  2319 
  2320 Gear^.dX:= Gear^.dX + cWindSpeed;
  2320 Gear^.dX:= Gear^.dX + cWindSpeed;
  2321 oldDx:= Gear^.dX;
  2321 oldDx:= Gear^.dX;
  2322 oldDy:= Gear^.dY;
  2322 oldDy:= Gear^.dY;
  2323 
  2323 
  2324 doStepFallingGear(Gear);
  2324 doStepFallingGear(Gear);
  2325 
  2325 
  2326 if (GameTicks and $3F) = 0 then
  2326 if (GameTicks and $3F) = 0 then
  2327 	AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0);
  2327     AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0);
  2328 
  2328 
  2329 if ((Gear^.State and gstCollision) <> 0) then begin //hit
  2329 if ((Gear^.State and gstCollision) <> 0) then begin //hit
  2330 	Gear^.dX:= oldDx;
  2330     Gear^.dX:= oldDx;
  2331 	Gear^.dY:= oldDy;
  2331     Gear^.dY:= oldDy;
  2332 
  2332 
  2333 	t:= CheckGearsCollision(Gear);
  2333     t:= CheckGearsCollision(Gear);
  2334 	if (t^.Count = 0) then begin //hit the ground not the HH
  2334     if (t^.Count = 0) then begin //hit the ground not the HH
  2335 		t2 := _0_5 / Distance(Gear^.dX, Gear^.dY);
  2335         t2 := _0_5 / Distance(Gear^.dX, Gear^.dY);
  2336 		Gear^.dX:= Gear^.dX * t2;
  2336         Gear^.dX:= Gear^.dX * t2;
  2337 		Gear^.dY:= Gear^.dY * t2;
  2337         Gear^.dY:= Gear^.dY * t2;
  2338 	end else begin //explode right on contact with HH
  2338     end else begin //explode right on contact with HH
  2339 		doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound);
  2339         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound);
  2340 		DeleteGear(Gear);
  2340         DeleteGear(Gear);
  2341 		exit;
  2341         exit;
  2342 		end;
  2342         end;
  2343 
  2343 
  2344     Gear^.SoundChannel:= LoopSound(sndPickhammer);
  2344     Gear^.SoundChannel:= LoopSound(sndPickhammer);
  2345 	Gear^.doStep:= @doStepDrillDrilling;
  2345     Gear^.doStep:= @doStepDrillDrilling;
  2346 	dec(Gear^.Timer)
  2346     dec(Gear^.Timer)
  2347 	end
  2347     end
  2348 end;
  2348 end;
  2349 
  2349 
  2350 ////////////////////////////////////////////////////////////////////////////////
  2350 ////////////////////////////////////////////////////////////////////////////////
  2351 procedure doStepBallgunWork(Gear: PGear);
  2351 procedure doStepBallgunWork(Gear: PGear);
  2352 var HHGear: PGear;
  2352 var HHGear: PGear;
  2353 	rx, ry: hwFloat;
  2353     rx, ry: hwFloat;
  2354 begin
  2354 begin
  2355 	AllInactive:= false;
  2355     AllInactive:= false;
  2356 	dec(Gear^.Timer);
  2356     dec(Gear^.Timer);
  2357 	HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  2357     HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  2358 	HedgehogChAngle(HHGear);
  2358     HedgehogChAngle(HHGear);
  2359 	if (Gear^.Timer mod 100) = 0 then
  2359     if (Gear^.Timer mod 100) = 0 then
  2360 		begin
  2360         begin
  2361 		rx:= rndSign(getRandom * _0_1);
  2361         rx:= rndSign(getRandom * _0_1);
  2362 		ry:= rndSign(getRandom * _0_1);
  2362         ry:= rndSign(getRandom * _0_1);
  2363 
  2363 
  2364 		AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtBall, 0,
  2364         AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtBall, 0,
  2365 				SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx,
  2365                 SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx,
  2366 				AngleCos(HHGear^.Angle) * ( - _0_8) + ry,
  2366                 AngleCos(HHGear^.Angle) * ( - _0_8) + ry,
  2367 				0);
  2367                 0);
  2368 
  2368 
  2369 		PlaySound(sndGun);
  2369         PlaySound(sndGun);
  2370 		end;
  2370         end;
  2371 
  2371 
  2372 	if (Gear^.Timer = 0) or (HHGear^.Damage <> 0) then
  2372     if (Gear^.Timer = 0) or (HHGear^.Damage <> 0) then
  2373 		begin
  2373         begin
  2374 		DeleteGear(Gear);
  2374         DeleteGear(Gear);
  2375 		AfterAttack
  2375         AfterAttack
  2376 		end
  2376         end
  2377 end;
  2377 end;
  2378 
  2378 
  2379 procedure doStepBallgun(Gear: PGear);
  2379 procedure doStepBallgun(Gear: PGear);
  2380 var HHGear: PGear;
  2380 var HHGear: PGear;
  2381 begin
  2381 begin
  2387 
  2387 
  2388 ////////////////////////////////////////////////////////////////////////////////
  2388 ////////////////////////////////////////////////////////////////////////////////
  2389 procedure doStepRCPlaneWork(Gear: PGear);
  2389 procedure doStepRCPlaneWork(Gear: PGear);
  2390 const cAngleSpeed = 3;
  2390 const cAngleSpeed = 3;
  2391 var HHGear: PGear;
  2391 var HHGear: PGear;
  2392 	i: LongInt;
  2392     i: LongInt;
  2393 	dX, dY: hwFloat;
  2393     dX, dY: hwFloat;
  2394 	fChanged: boolean;
  2394     fChanged: boolean;
  2395 	trueAngle: Longword;
  2395     trueAngle: Longword;
  2396 	t: PGear;
  2396     t: PGear;
  2397 begin
  2397 begin
  2398 AllInactive:= false;
  2398 AllInactive:= false;
  2399 
  2399 
  2400 if ((TrainingFlags and tfRCPlane) = 0) and (Gear^.Timer > 0) then dec(Gear^.Timer);
  2400 if ((TrainingFlags and tfRCPlane) = 0) and (Gear^.Timer > 0) then dec(Gear^.Timer);
  2401 
  2401 
  2404 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  2404 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  2405 FollowGear:= Gear;
  2405 FollowGear:= Gear;
  2406 
  2406 
  2407 fChanged:= false;
  2407 fChanged:= false;
  2408 if ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then
  2408 if ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then
  2409 	begin
  2409     begin
  2410 	fChanged:= true;
  2410     fChanged:= true;
  2411 	if Gear^.Angle > 2048 then dec(Gear^.Angle) else
  2411     if Gear^.Angle > 2048 then dec(Gear^.Angle) else
  2412 		if Gear^.Angle < 2048 then inc(Gear^.Angle) else fChanged:= false
  2412         if Gear^.Angle < 2048 then inc(Gear^.Angle) else fChanged:= false
  2413 	end
  2413     end
  2414 else
  2414 else
  2415 	begin
  2415     begin
  2416 	if ((Gear^.Message and gm_Left) <> 0) then
  2416     if ((Gear^.Message and gm_Left) <> 0) then
  2417 		begin
  2417         begin
  2418 		fChanged:= true;
  2418         fChanged:= true;
  2419 		Gear^.Angle:= (Gear^.Angle + (4096 - cAngleSpeed)) mod 4096
  2419         Gear^.Angle:= (Gear^.Angle + (4096 - cAngleSpeed)) mod 4096
  2420 		end;
  2420         end;
  2421 
  2421 
  2422 	if ((Gear^.Message and gm_Right) <> 0) then
  2422     if ((Gear^.Message and gm_Right) <> 0) then
  2423 		begin
  2423         begin
  2424 		fChanged:= true;
  2424         fChanged:= true;
  2425 		Gear^.Angle:= (Gear^.Angle + cAngleSpeed) mod 4096
  2425         Gear^.Angle:= (Gear^.Angle + cAngleSpeed) mod 4096
  2426 		end
  2426         end
  2427 	end;
  2427     end;
  2428 
  2428 
  2429 if fChanged then
  2429 if fChanged then
  2430 	begin
  2430     begin
  2431 	Gear^.dX.isNegative:= (Gear^.Angle > 2048);
  2431     Gear^.dX.isNegative:= (Gear^.Angle > 2048);
  2432 	if Gear^.dX.isNegative then
  2432     if Gear^.dX.isNegative then
  2433 		trueAngle:= 4096 - Gear^.Angle
  2433         trueAngle:= 4096 - Gear^.Angle
  2434 	else
  2434     else
  2435 		trueAngle:= Gear^.Angle;
  2435         trueAngle:= Gear^.Angle;
  2436 
  2436 
  2437 	Gear^.dX:= SignAs(AngleSin(trueAngle), Gear^.dX) * _0_25;
  2437     Gear^.dX:= SignAs(AngleSin(trueAngle), Gear^.dX) * _0_25;
  2438 	Gear^.dY:= AngleCos(trueAngle) * -_0_25;
  2438     Gear^.dY:= AngleCos(trueAngle) * -_0_25;
  2439 	end;
  2439     end;
  2440 
  2440 
  2441 Gear^.X:= Gear^.X + Gear^.dX;
  2441 Gear^.X:= Gear^.X + Gear^.dX;
  2442 Gear^.Y:= Gear^.Y + Gear^.dY;
  2442 Gear^.Y:= Gear^.Y + Gear^.dY;
  2443 
  2443 
  2444 if (TrainingFlags and tfRCPlane) = 0 then
  2444 if (TrainingFlags and tfRCPlane) = 0 then
  2445 	begin
  2445     begin
  2446 	if (GameTicks and $FF) = 0 then
  2446     if (GameTicks and $FF) = 0 then
  2447 		if Gear^.Timer < 3500 then
  2447         if Gear^.Timer < 3500 then
  2448 			AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtEvilTrace, 0, _0, _0, 0)
  2448             AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtEvilTrace, 0, _0, _0, 0)
  2449 		else
  2449         else
  2450 			AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0);
  2450             AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0);
  2451 
  2451 
  2452 	if ((HHGear^.Message and gm_Attack) <> 0) and (Gear^.Health <> 0) then
  2452     if ((HHGear^.Message and gm_Attack) <> 0) and (Gear^.Health <> 0) then
  2453 		begin
  2453         begin
  2454 		HHGear^.Message := HHGear^.Message and not gm_Attack;
  2454         HHGear^.Message := HHGear^.Message and not gm_Attack;
  2455 		AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY * _0_5, 0);
  2455         AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY * _0_5, 0);
  2456 		dec(Gear^.Health)
  2456         dec(Gear^.Health)
  2457 		end;
  2457         end;
  2458 
  2458 
  2459 	if ((HHGear^.Message and gm_LJump) <> 0)
  2459     if ((HHGear^.Message and gm_LJump) <> 0)
  2460 		and ((Gear^.State and gsttmpFlag) = 0) then
  2460         and ((Gear^.State and gsttmpFlag) = 0) then
  2461 		begin
  2461         begin
  2462 		Gear^.State:= Gear^.State or gsttmpFlag;
  2462         Gear^.State:= Gear^.State or gsttmpFlag;
  2463 		PauseMusic;
  2463         PauseMusic;
  2464 		playSound(sndRideOfTheValkyries);
  2464         playSound(sndRideOfTheValkyries);
  2465 		end;
  2465         end;
  2466 
  2466 
  2467 	// pickup bonuses
  2467     // pickup bonuses
  2468 	t:= CheckGearNear(Gear, gtCase, 36, 36);
  2468     t:= CheckGearNear(Gear, gtCase, 36, 36);
  2469 	if t <> nil then
  2469     if t <> nil then
  2470 		PickUp(HHGear, t);
  2470         PickUp(HHGear, t);
  2471 	end
  2471     end
  2472 else
  2472 else
  2473 	begin
  2473     begin
  2474 	if (GameTicks and $FF) = 0 then
  2474     if (GameTicks and $FF) = 0 then
  2475 		AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0);
  2475         AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0);
  2476 
  2476 
  2477 	// pickup targets
  2477     // pickup targets
  2478 	t:= CheckGearNear(Gear, gtTarget, 36, 36);
  2478     t:= CheckGearNear(Gear, gtTarget, 36, 36);
  2479 	if t <> nil then
  2479     if t <> nil then
  2480 		begin
  2480         begin
  2481 		if t^.Tag <> 0 then // collect it only once
  2481         if t^.Tag <> 0 then // collect it only once
  2482 			exit;
  2482             exit;
  2483 		PlaySound(sndShotgunReload);
  2483         PlaySound(sndShotgunReload);
  2484 		t^.Tag:= 1;
  2484         t^.Tag:= 1;
  2485 		TrainingTargetGear:= nil; // remove target cursor
  2485         TrainingTargetGear:= nil; // remove target cursor
  2486 		exit;
  2486         exit;
  2487 		end;
  2487         end;
  2488 
  2488 
  2489 	if (TurnTimeLeft > 0) then 
  2489     if (TurnTimeLeft > 0) then 
  2490 		dec(TurnTimeLeft)
  2490         dec(TurnTimeLeft)
  2491 	end;
  2491     end;
  2492 		
  2492         
  2493 CheckCollision(Gear);
  2493 CheckCollision(Gear);
  2494 
  2494 
  2495 if ((Gear^.State and gstCollision) <> 0) or (((TrainingFlags and tfRCPlane) <> 0) and (TurnTimeLeft = 0))
  2495 if ((Gear^.State and gstCollision) <> 0) or (((TrainingFlags and tfRCPlane) <> 0) and (TurnTimeLeft = 0))
  2496 	or CheckGearDrowning(Gear) then
  2496     or CheckGearDrowning(Gear) then
  2497 	begin
  2497     begin
  2498 	if ((TrainingFlags and tfRCPlane) <> 0) and ((TrainingFlags and tfTimeTrial) <> 0 ) and (TimeTrialStopTime = 0) then TimeTrialStopTime:= RealTicks;
  2498     if ((TrainingFlags and tfRCPlane) <> 0) and ((TrainingFlags and tfTimeTrial) <> 0 ) and (TimeTrialStopTime = 0) then TimeTrialStopTime:= RealTicks;
  2499 	StopSound(Gear^.SoundChannel);
  2499     StopSound(Gear^.SoundChannel);
  2500 	StopSound(sndRideOfTheValkyries);
  2500     StopSound(sndRideOfTheValkyries);
  2501 	ResumeMusic;
  2501     ResumeMusic;
  2502 
  2502 
  2503 	if ((Gear^.State and gstCollision) <> 0) or (((TrainingFlags and tfRCPlane) <> 0) and (TurnTimeLeft = 0)) then
  2503     if ((Gear^.State and gstCollision) <> 0) or (((TrainingFlags and tfRCPlane) <> 0) and (TurnTimeLeft = 0)) then
  2504 		begin
  2504         begin
  2505 		doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, EXPLAutoSound);
  2505         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, EXPLAutoSound);
  2506 		for i:= 0 to 32 do
  2506         for i:= 0 to 32 do
  2507 			begin
  2507             begin
  2508 			dX:= AngleCos(i * 64) * _0_5 * (GetRandom + _1);
  2508             dX:= AngleCos(i * 64) * _0_5 * (GetRandom + _1);
  2509 			dY:= AngleSin(i * 64) * _0_5 * (GetRandom + _1);
  2509             dY:= AngleSin(i * 64) * _0_5 * (GetRandom + _1);
  2510 			AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0);
  2510             AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0);
  2511 			AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0);
  2511             AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0);
  2512 			end;
  2512             end;
  2513 		DeleteGear(Gear)
  2513         DeleteGear(Gear)
  2514 		end;
  2514         end;
  2515 
  2515 
  2516 	AfterAttack;
  2516     AfterAttack;
  2517 	CurAmmoGear:= nil;
  2517     CurAmmoGear:= nil;
  2518 	TurnTimeLeft:= 14 * 125;
  2518     TurnTimeLeft:= 14 * 125;
  2519 	
  2519     
  2520 	if (TrainingFlags and tfRCPlane) <> 0 then
  2520     if (TrainingFlags and tfRCPlane) <> 0 then
  2521 		TurnTimeLeft:= 0; // HACK: RCPlane training allows unlimited plane starts in last 2 seconds
  2521         TurnTimeLeft:= 0; // HACK: RCPlane training allows unlimited plane starts in last 2 seconds
  2522 
  2522 
  2523 	HHGear^.Message:= 0;
  2523     HHGear^.Message:= 0;
  2524 	ParseCommand('/taunt '#1, true)
  2524     ParseCommand('/taunt '#1, true)
  2525 	end
  2525     end
  2526 end;
  2526 end;
  2527 
  2527 
  2528 procedure doStepRCPlane(Gear: PGear);
  2528 procedure doStepRCPlane(Gear: PGear);
  2529 var HHGear: PGear;
  2529 var HHGear: PGear;
  2530 begin
  2530 begin
  2597 
  2597 
  2598 if ((Gear^.State and gsttmpFlag) = 0) or (HHGear^.dY < _0) then doStepHedgehogMoving(HHGear);
  2598 if ((Gear^.State and gsttmpFlag) = 0) or (HHGear^.dY < _0) then doStepHedgehogMoving(HHGear);
  2599 
  2599 
  2600 if  (Gear^.Health = 0)
  2600 if  (Gear^.Health = 0)
  2601     or (HHGear^.Damage <> 0)
  2601     or (HHGear^.Damage <> 0)
  2602 	or CheckGearDrowning(HHGear)
  2602     or CheckGearDrowning(HHGear)
  2603     or (TurnTimeLeft = 0)
  2603     or (TurnTimeLeft = 0)
  2604     // allow brief ground touches - to be fair on this, might need another counter
  2604     // allow brief ground touches - to be fair on this, might need another counter
  2605     or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and TestCollisionYwithGear(HHGear, 1))
  2605     or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and TestCollisionYwithGear(HHGear, 1))
  2606 	or ((Gear^.Message and gm_Attack) <> 0) then
  2606     or ((Gear^.Message and gm_Attack) <> 0) then
  2607 	begin
  2607     begin
  2608 	with HHGear^ do
  2608     with HHGear^ do
  2609 		begin
  2609         begin
  2610 		Message:= 0;
  2610         Message:= 0;
  2611         Active:= true;
  2611         Active:= true;
  2612 		State:= State or gstMoving
  2612         State:= State or gstMoving
  2613 		end;
  2613         end;
  2614 	DeleteGear(Gear);
  2614     DeleteGear(Gear);
  2615 	isCursorVisible:= false;
  2615     isCursorVisible:= false;
  2616 //    if Gear^.Tex <> nil then FreeTexture(Gear^.Tex);
  2616 //    if Gear^.Tex <> nil then FreeTexture(Gear^.Tex);
  2617 //    Gear^.Tex:= RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(round(Gear^.Health / 20)) + '%', cWhiteColor, fntSmall)
  2617 //    Gear^.Tex:= RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(round(Gear^.Health / 20)) + '%', cWhiteColor, fntSmall)
  2618     //AddCaption(trmsg[sidFuel]+': '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
  2618     //AddCaption(trmsg[sidFuel]+': '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
  2619 	end
  2619     end
  2620 end;
  2620 end;
  2621 
  2621 
  2622 ////////////////////////////////////////////////////////////////////////////////
  2622 ////////////////////////////////////////////////////////////////////////////////
  2623 procedure doStepJetpack(Gear: PGear);
  2623 procedure doStepJetpack(Gear: PGear);
  2624 var HHGear: PGear;
  2624 var HHGear: PGear;
  2628 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  2628 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear;
  2629 FollowGear:= HHGear;
  2629 FollowGear:= HHGear;
  2630 OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^);
  2630 OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^);
  2631 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^);
  2631 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^);
  2632 with HHGear^ do
  2632 with HHGear^ do
  2633 	begin
  2633     begin
  2634 	State:= State and not gstAttacking;
  2634     State:= State and not gstAttacking;
  2635 	Message:= Message and not (gm_Attack or gm_Up or gm_Precise or gm_Left or gm_Right);
  2635     Message:= Message and not (gm_Attack or gm_Up or gm_Precise or gm_Left or gm_Right);
  2636     if (dY < _0_1) and (dY > -_0_1) then
  2636     if (dY < _0_1) and (dY > -_0_1) then
  2637         begin
  2637         begin
  2638         Gear^.State:= Gear^.State or gsttmpFlag;
  2638         Gear^.State:= Gear^.State or gsttmpFlag;
  2639         dY:= dY - _0_2
  2639         dY:= dY - _0_2
  2640         end
  2640         end
  2641 	end
  2641     end
  2642 end;
  2642 end;