author  unc0rr 
Sun, 21 Jan 2007 19:51:02 +0000  
changeset 351  29bc9c36ad5f 
parent 346  fc1e0a4f152c 
child 355  40c68869899e 
permissions  rwrr 
4  1 
(* 
2 
* Hedgewars, a wormslike game 

79  3 
* Copyright (c) 2004, 2005, 2006 Andrey Korotaev <unC0Rr@gmail.com> 
4  4 
* 
183  5 
* This program is free software; you can redistribute it and/or modify 
6 
* it under the terms of the GNU General Public License as published by 

7 
* the Free Software Foundation; version 2 of the License 

4  8 
* 
183  9 
* This program is distributed in the hope that it will be useful, 
10 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 

11 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

12 
* GNU General Public License for more details. 

4  13 
* 
183  14 
* You should have received a copy of the GNU General Public License 
15 
* along with this program; if not, write to the Free Software 

16 
* Foundation, Inc., 59 Temple Place  Suite 330, Boston, MA 021111307, USA 

4  17 
*) 
18 

19 
procedure doStepDrowningGear(Gear: PGear); forward; 

20 

21 
function CheckGearDrowning(Gear: PGear): boolean; 

22 
begin 

351  23 
if cWaterLine < Gear^.Y + Gear^.Radius then 
4  24 
begin 
351  25 
CheckGearDrowning:= true; 
26 
Gear^.State:= gstDrowning; 

27 
Gear^.doStep:= @doStepDrowningGear; 

28 
PlaySound(sndSplash, false) 

29 
end else 

30 
CheckGearDrowning:= false 

4  31 
end; 
32 

33 
procedure CheckCollision(Gear: PGear); 

34 
begin 

351  35 
if TestCollisionXwithGear(Gear, hwSign(Gear^.X)) or TestCollisionYwithGear(Gear, hwSign(Gear^.Y)) 
36 
then Gear^.State:= Gear^.State or gstCollision 

37 
else Gear^.State:= Gear^.State and not gstCollision 

4  38 
end; 
39 

40 
procedure CheckHHDamage(Gear: PGear); 

41 
begin 

351  42 
if _0_4 < Gear^.dY then Gear^.Damage:= Gear^.Damage + 1 + hwRound(70 * (hwAbs(Gear^.dY)  _0_4)); 
4  43 
end; 
44 

45 
//////////////////////////////////////////////////////////////////////////////// 

46 
//////////////////////////////////////////////////////////////////////////////// 

47 
procedure CalcRotationDirAngle(Gear: PGear); 

351  48 
var dAngle: hwFloat; 
4  49 
begin 
351  50 
dAngle:= (hwAbs(Gear^.dX) + hwAbs(Gear^.dY)) * _0_1; 
51 
if not Gear^.dX.isNegative then Gear^.DirAngle:= Gear^.DirAngle + dAngle 

52 
else Gear^.DirAngle:= Gear^.DirAngle  dAngle; 

53 
if Gear^.DirAngle < 0 then Gear^.DirAngle:= Gear^.DirAngle + 16 

54 
else if 16 < Gear^.DirAngle then Gear^.DirAngle:= Gear^.DirAngle  16 

4  55 
end; 
56 

57 
//////////////////////////////////////////////////////////////////////////////// 

58 
procedure doStepDrowningGear(Gear: PGear); 

59 
begin 

60 
AllInactive:= false; 

351  61 
Gear^.Y:= Gear^.Y + cDrownSpeed; 
62 
if hwRound(Gear^.Y) > Gear^.Radius + cWaterLine + cVisibleWater then DeleteGear(Gear) 

4  63 
end; 
64 

65 
//////////////////////////////////////////////////////////////////////////////// 

66 
procedure doStepFallingGear(Gear: PGear); 

67 
var b: boolean; 

68 
begin 

351  69 
if TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) then 
4  70 
begin 
351  71 
Gear^.dX:= Gear^.dX * Gear^.Friction; 
72 
Gear^.dY:=  Gear^.dY * Gear^.Elasticity; 

4  73 
b:= false 
74 
end else b:= true; 

351  75 
if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then 
4  76 
begin 
351  77 
Gear^.dX:=  Gear^.dX * Gear^.Elasticity; 
78 
// Gear^.dY:= Gear^.dY; 

4  79 
b:= false 
80 
end; 

81 
if b then 

82 
begin 

351  83 
Gear^.dY:= Gear^.dY + cGravity; 
84 
Gear^.State:= Gear^.State and not gstCollision 

4  85 
end else 
86 
begin 

351  87 
if hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _1div100000 then 
88 
if (Gear^.Timer = 0) then Gear^.Active:= false 

4  89 
else begin 
351  90 
Gear^.dX:= 0; 
91 
Gear^.dY:= 0 

4  92 
end; 
351  93 
Gear^.State:= Gear^.State or gstCollision 
4  94 
end; 
351  95 
Gear^.X:= Gear^.X + Gear^.dX; 
96 
Gear^.Y:= Gear^.Y + Gear^.dY; 

4  97 
CheckGearDrowning(Gear); 
351  98 
if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_003) then Gear^.State:= Gear^.State and not gstMoving 
99 
else Gear^.State:= Gear^.State or gstMoving 

4  100 
end; 
101 

102 
//////////////////////////////////////////////////////////////////////////////// 

103 
procedure doStepCloud(Gear: PGear); 

104 
begin 

351  105 
Gear^.X:= Gear^.X + cWindSpeed * 200 + Gear^.dX; 
106 
if Gear^.Y > 160 then Gear^.dY:= Gear^.dY  _1div50000 

107 
else Gear^.dY:= Gear^.dY + _1div50000; 

108 
Gear^.Y:= Gear^.Y + Gear^.dY; 

109 
if Gear^.X < cScreenWidth  256 then Gear^.X:= cScreenWidth + 2048 else 

110 
if Gear^.X > cScreenWidth + 2048 then Gear^.X:= cScreenWidth  256 

4  111 
end; 
112 

113 
//////////////////////////////////////////////////////////////////////////////// 

114 
procedure doStepBomb(Gear: PGear); 

78  115 
var i: integer; 
4  116 
begin 
117 
AllInactive:= false; 

118 
doStepFallingGear(Gear); 

351  119 
dec(Gear^.Timer); 
120 
if Gear^.Timer = 0 then 

4  121 
begin 
351  122 
case Gear^.Kind of 
123 
gtAmmo_Bomb: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); 

78  124 
gtClusterBomb: begin 
351  125 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound); 
78  126 
for i:= 0 to 4 do 
351  127 
AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, (getrandom  _0_5) * _0_2, (getrandom  3) * _0_08, 0); 
78  128 
end 
129 
end; 

4  130 
DeleteGear(Gear); 
131 
exit 

132 
end; 

133 
CalcRotationDirAngle(Gear); 

351  134 
if (Gear^.State and (gstCollision or gstMoving)) = (gstCollision or gstMoving) then PlaySound(sndGrenadeImpact, false) 
4  135 
end; 
136 

78  137 
procedure doStepCluster(Gear: PGear); 
138 
begin 

139 
AllInactive:= false; 

140 
doStepFallingGear(Gear); 

351  141 
if (Gear^.State and gstCollision) <> 0 then 
78  142 
begin 
351  143 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, EXPLAutoSound); 
78  144 
DeleteGear(Gear); 
145 
exit 

146 
end; 

147 
if (GameTicks and $1F) = 0 then 

351  148 
AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, 0, 0, 0) 
78  149 
end; 
150 

4  151 
//////////////////////////////////////////////////////////////////////////////// 
152 
procedure doStepGrenade(Gear: PGear); 

153 
begin 

154 
AllInactive:= false; 

351  155 
Gear^.dX:= Gear^.dX + cWindSpeed; 
4  156 
doStepFallingGear(Gear); 
351  157 
if (Gear^.State and gstCollision) <> 0 then 
4  158 
begin 
351  159 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); 
4  160 
DeleteGear(Gear); 
161 
exit 

162 
end; 

163 
if (GameTicks and $3F) = 0 then 

351  164 
AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, 0, 0, 0) 
4  165 
end; 
166 

167 
//////////////////////////////////////////////////////////////////////////////// 

95  168 
procedure doStepHealthTagWork(Gear: PGear); 
4  169 
begin 
170 
AllInactive:= false; 

351  171 
dec(Gear^.Timer); 
172 
Gear^.Y:= Gear^.Y  _0_08; 

173 
if Gear^.Timer = 0 then 

4  174 
begin 
351  175 
PHedgehog(Gear^.Hedgehog)^.Gear^.Active:= true; // to let current hh die 
4  176 
DeleteGear(Gear) 
177 
end 

178 
end; 

179 

263  180 
procedure doStepHealthTagWorkUnderWater(Gear: PGear); 
181 
begin 

182 
AllInactive:= false; 

351  183 
Gear^.Y:= Gear^.Y  _0_08; 
184 
if Gear^.Y < cWaterLine + 10 then 

263  185 
DeleteGear(Gear) 
186 
end; 

187 

95  188 
procedure doStepHealthTag(Gear: PGear); 
189 
var s: shortstring; 

190 
begin 

191 
AllInactive:= false; 

351  192 
str(Gear^.State, s); 
193 
Gear^.Surf:= RenderString(s, PHedgehog(Gear^.Hedgehog)^.Team^.Color, fnt16); 

194 
if Gear^.Y < cWaterLine then Gear^.doStep:= @doStepHealthTagWork 

195 
else Gear^.doStep:= @doStepHealthTagWorkUnderWater 

95  196 
end; 
197 

4  198 
//////////////////////////////////////////////////////////////////////////////// 
199 
procedure doStepGrave(Gear: PGear); 

200 
begin 

201 
AllInactive:= false; 

351  202 
if Gear^.dY < 0 then 
203 
if TestCollisionY(Gear, 1) then Gear^.dY:= 0; 

4  204 

351  205 
if not Gear^.dY.isNegative then 
68  206 
if TestCollisionY(Gear, 1) then 
4  207 
begin 
351  208 
Gear^.dY:=  Gear^.dY * Gear^.Elasticity; 
209 
if Gear^.dY >  _1div1024 then 

4  210 
begin 
351  211 
Gear^.Active:= false; 
4  212 
exit 
351  213 
end else if Gear^.dY <  _0_03 then PlaySound(sndGraveImpact, false) 
4  214 
end; 
351  215 
Gear^.Y:= Gear^.Y + Gear^.dY; 
4  216 
CheckGearDrowning(Gear); 
351  217 
Gear^.dY:= Gear^.dY + cGravity 
4  218 
end; 
219 

220 
//////////////////////////////////////////////////////////////////////////////// 

221 
procedure doStepUFOWork(Gear: PGear); 

351  222 
var t: hwFloat; 
4  223 
begin 
224 
AllInactive:= false; 

351  225 
t:= Distance(Gear^.dX, Gear^.dY); 
226 
Gear^.dX:= Gear^.Elasticity * (Gear^.dX + _0_000004 * (TargetPoint.X  hwRound(Gear^.X))); 

227 
Gear^.dY:= Gear^.Elasticity * (Gear^.dY + _0_000004 * (TargetPoint.Y  hwRound(Gear^.Y))); 

228 
t:= t / Distance(Gear^.dX, Gear^.dY); 

229 
Gear^.dX:= Gear^.dX * t; 

230 
Gear^.dY:= Gear^.dY * t; 

231 
Gear^.X:= Gear^.X + Gear^.dX; 

232 
Gear^.Y:= Gear^.Y + Gear^.dY; 

4  233 
CheckCollision(Gear); 
351  234 
dec(Gear^.Timer); 
235 
if ((Gear^.State and gstCollision) <> 0) or (Gear^.Timer = 0) then 

4  236 
begin 
351  237 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); 
4  238 
DeleteGear(Gear); 
239 
end; 

240 
end; 

241 

242 
procedure doStepUFO(Gear: PGear); 

243 
begin 

244 
AllInactive:= false; 

351  245 
Gear^.X:= Gear^.X + Gear^.dX; 
246 
Gear^.Y:= Gear^.Y + Gear^.dY; 

247 
Gear^.dY:= Gear^.dY + cGravity; 

4  248 
CheckCollision(Gear); 
351  249 
if (Gear^.State and gstCollision) <> 0 then 
4  250 
begin 
351  251 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); 
4  252 
DeleteGear(Gear); 
253 
exit 

254 
end; 

351  255 
dec(Gear^.Timer); 
256 
if Gear^.Timer = 0 then 

4  257 
begin 
351  258 
Gear^.Timer:= 5000; 
259 
Gear^.doStep:= @doStepUFOWork 

4  260 
end; 
261 
end; 

262 

263 
//////////////////////////////////////////////////////////////////////////////// 

264 
procedure doStepShotgunShot(Gear: PGear); 

265 
var i: LongWord; 

266 
begin 

267 
AllInactive:= false; 

351  268 
if Gear^.Timer > 0 then 
4  269 
begin 
351  270 
dec(Gear^.Timer); 
271 
if Gear^.Timer = 0 then PlaySound(sndShotgunFire, false); 

4  272 
exit 
273 
end; 

274 
i:= 200; 

275 
repeat 

351  276 
Gear^.X:= Gear^.X + Gear^.dX; 
277 
Gear^.Y:= Gear^.Y + Gear^.dY; 

4  278 
CheckCollision(Gear); 
351  279 
if (Gear^.State and gstCollision) <> 0 then 
4  280 
begin 
75  281 
AmmoShove(Gear, 25, 25); 
351  282 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, EXPLNoDamage or EXPLDoNotTouchHH); 
4  283 
DeleteGear(Gear); 
75  284 
AfterAttack; 
4  285 
exit 
286 
end; 

287 
dec(i) 

288 
until i = 0; 

351  289 
if (Gear^.X < 0) or (Gear^.Y < 0) or (Gear^.X > 2048) or (Gear^.Y > 1024) then 
95  290 
begin 
291 
DeleteGear(Gear); 

292 
AfterAttack 

293 
end 

4  294 
end; 
295 

296 
//////////////////////////////////////////////////////////////////////////////// 

38  297 
procedure doStepDEagleShot(Gear: PGear); 
298 
var i, x, y: LongWord; 

351  299 
oX, oY: hwFloat; 
38  300 
begin 
301 
AllInactive:= false; 

37  302 
i:= 80; 
351  303 
oX:= Gear^.X; 
304 
oY:= Gear^.Y; 

37  305 
repeat 
351  306 
Gear^.X:= Gear^.X + Gear^.dX; 
307 
Gear^.Y:= Gear^.Y + Gear^.dY; 

308 
x:= hwRound(Gear^.X); 

309 
y:= hwRound(Gear^.Y); 

38  310 
if ((y and $FFFFFC00) = 0) and ((x and $FFFFF800) = 0) 
351  311 
and (Land[y, x] <> 0) then inc(Gear^.Damage); 
75  312 
AmmoShove(Gear, 7, 20); 
38  313 
dec(i) 
351  314 
until (i = 0) or (Gear^.Damage > Gear^.Health); 
315 
if Gear^.Damage > 0 then 

37  316 
begin 
351  317 
DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 82  i, 1); 
318 
dec(Gear^.Health, Gear^.Damage); 

319 
Gear^.Damage:= 0 

37  320 
end; 
351  321 
if (Gear^.Health <= 0) or (Gear^.X < 0) or (Gear^.Y < 0) or (Gear^.X > 2048) or (Gear^.Y > 1024) then 
37  322 
DeleteGear(Gear) 
323 
end; 

324 

325 
//////////////////////////////////////////////////////////////////////////////// 

4  326 
procedure doStepActionTimer(Gear: PGear); 
327 
begin 

351  328 
dec(Gear^.Timer); 
329 
case Gear^.Kind of 

83  330 
gtATStartGame: begin 
4  331 
AllInactive:= false; 
351  332 
if Gear^.Timer = 0 then 
83  333 
AddCaption(trmsg[sidStartFight], $FFFFFF, capgrpGameState); 
4  334 
end; 
83  335 
gtATSmoothWindCh: begin 
351  336 
if Gear^.Timer = 0 then 
6  337 
begin 
351  338 
if WindBarWidth < Gear^.Tag then inc(WindBarWidth) 
339 
else if WindBarWidth > Gear^.Tag then dec(WindBarWidth); 

340 
if WindBarWidth <> Gear^.Tag then Gear^.Timer:= 10; 

83  341 
end 
342 
end; 

343 
gtATFinishGame: begin 

344 
AllInactive:= false; 

351  345 
if Gear^.Timer = 0 then 
113  346 
begin 
347 
SendIPC('N'); 

324
f4c109c82a0c
Don't show game stats in case of interrupted by command '/quit' game
unc0rr
parents:
306
diff
changeset

348 
SendIPC('q'); 
83  349 
GameState:= gsExit 
113  350 
end 
6  351 
end; 
4  352 
end; 
351  353 
if Gear^.Timer = 0 then DeleteGear(Gear) 
4  354 
end; 
355 

356 
//////////////////////////////////////////////////////////////////////////////// 

357 
procedure doStepPickHammerWork(Gear: PGear); 

358 
var i, ei: integer; 

359 
HHGear: PGear; 

360 
begin 

70  361 
AllInactive:= false; 
351  362 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 
363 
dec(Gear^.Timer); 

364 
if (Gear^.Timer = 0)or((Gear^.Message and gm_Destroy) <> 0)or((HHGear^.State and gstHHDriven) = 0) then 

4  365 
begin 
282  366 
StopSound(sndPickhammer); 
4  367 
DeleteGear(Gear); 
368 
AfterAttack; 

369 
exit 

370 
end; 

351  371 
if (Gear^.Timer and $3F) = 0 then 
4  372 
begin 
351  373 
i:= hwRound(Gear^.X)  Gear^.Radius  GetRandom(2); 
374 
ei:= hwRound(Gear^.X) + Gear^.Radius + GetRandom(2); 

4  375 
while i <= ei do 
376 
begin 

351  377 
doMakeExplosion(i, hwRound(Gear^.Y) + 3, 3, 0); 
4  378 
inc(i, 1) 
379 
end; 

351  380 
Gear^.X:= Gear^.X + Gear^.dX; 
381 
Gear^.Y:= Gear^.Y + _1_9; 

42  382 
SetAllHHToActive; 
4  383 
end; 
384 
if TestCollisionYwithGear(Gear, 1) then 

385 
begin 

351  386 
Gear^.dY:= 0; 
387 
SetLittle(HHGear^.dX); 

388 
HHGear^.dY:= 0; 

4  389 
end else 
390 
begin 

351  391 
Gear^.dY:= Gear^.dY + cGravity; 
392 
Gear^.Y:= Gear^.Y + Gear^.dY; 

393 
if Gear^.Y > 1024 then Gear^.Timer:= 1 

4  394 
end; 
395 

351  396 
Gear^.X:= Gear^.X + HHGear^.dX; 
397 
HHGear^.X:= Gear^.X; 

398 
HHGear^.Y:= Gear^.Y  cHHRadius; 

4  399 

351  400 
if (Gear^.Message and gm_Attack) <> 0 then 
401 
if (Gear^.State and gsttmpFlag) <> 0 then Gear^.Timer:= 1 else else 

402 
if (Gear^.State and gsttmpFlag) = 0 then Gear^.State:= Gear^.State or gsttmpFlag; 

403 
if ((Gear^.Message and gm_Left) <> 0) then Gear^.dX:=  _0_3 else 

404 
if ((Gear^.Message and gm_Right) <> 0) then Gear^.dX:= _0_3 

405 
else Gear^.dX:= 0; 

4  406 
end; 
407 

408 
procedure doStepPickHammer(Gear: PGear); 

409 
var i, y: integer; 

410 
ar: TRangeArray; 

411 
begin 

412 
i:= 0; 

351  413 
y:= hwRound(Gear^.Y)  cHHRadius*2; 
414 
while y < hwRound(Gear^.Y) do 

4  415 
begin 
351  416 
ar[i].Left := hwRound(Gear^.X)  Gear^.Radius  GetRandom(2); 
417 
ar[i].Right:= hwRound(Gear^.X) + Gear^.Radius + GetRandom(2); 

4  418 
inc(y, 2); 
419 
inc(i) 

420 
end; 

351  421 
DrawHLinesExplosions(@ar, 3, hwRound(Gear^.Y)  cHHRadius*2, 2, Pred(i)); 
422 
Gear^.dY:= PHedgehog(Gear^.Hedgehog)^.Gear^.dY; 

282  423 
PlaySound(sndPickhammer, true); 
4  424 
doStepPickHammerWork(Gear); 
351  425 
Gear^.doStep:= @doStepPickHammerWork 
4  426 
end; 
427 

428 
//////////////////////////////////////////////////////////////////////////////// 

305  429 
var BTPrevAngle, BTSteps: Longword; 
302  430 

303
1659c4aad5ab
Now blow torch angle can be changed during blowing :)
unc0rr
parents:
302
diff
changeset

431 
procedure doStepBlowTorchWork(Gear: PGear); 
302  432 
var HHGear: PGear; 
305  433 
b: boolean; 
302  434 
begin 
435 
AllInactive:= false; 

351  436 
dec(Gear^.Timer); 
437 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 

303
1659c4aad5ab
Now blow torch angle can be changed during blowing :)
unc0rr
parents:
302
diff
changeset

438 

1659c4aad5ab
Now blow torch angle can be changed during blowing :)
unc0rr
parents:
302
diff
changeset

439 
HedgehogChAngle(HHGear); 
1659c4aad5ab
Now blow torch angle can be changed during blowing :)
unc0rr
parents:
302
diff
changeset

440 

305  441 
b:= false; 
442 

351  443 
if (HHGear^.Angle <> BTPrevAngle) then 
305  444 
begin 
351  445 
Gear^.dX:= hwSign(HHGear^.dX) * _0_5;//hwSign(HHGear^.dX) * Sin(HHGear^.Angle * pi / cMaxAngle) * _0_5; 
446 
Gear^.dY:= 0;//Cos(HHGear^.Angle * pi / cMaxAngle) * (0.5); 

447 
BTPrevAngle:= HHGear^.Angle; 

305  448 
b:= true 
449 
end; 

450 

351  451 
if Gear^.Timer mod cHHStepTicks = 0 then 
302  452 
begin 
305  453 
b:= true; 
351  454 
if Gear^.dX < 0 then HHGear^.Message:= (HHGear^.Message or gm_Left) and not gm_Right 
455 
else HHGear^.Message:= (HHGear^.Message or gm_Right) and not gm_Left; 

302  456 
HedgehogStep(HHGear); 
305  457 

458 
inc(BTSteps); 

306  459 
if BTSteps = 11 then 
305  460 
begin 
461 
BTSteps:= 0; 

351  462 
Gear^.X:= HHGear^.X + Gear^.dX * cHHRadius * 2; 
463 
Gear^.Y:= HHGear^.Y + Gear^.dY * cHHRadius * 2; 

464 
HHGear^.State:= HHGear^.State or gstNoDamage; 

305  465 
AmmoShove(Gear, 3, 14); 
351  466 
HHGear^.State:= HHGear^.State and not gstNoDamage 
305  467 
end; 
468 

351  469 
if (HHGear^.State and gstFalling) <> 0 then Gear^.Timer:= 0 
302  470 
end; 
305  471 

472 
if b then 

351  473 
DrawTunnel(HHGear^.X  Gear^.dX * cHHRadius, HHGear^.Y  4  Gear^.dY * cHHRadius + hwAbs(Gear^.dY) * 7, 
474 
Gear^.dX, Gear^.dY, 

306  475 
cHHRadius * 5, cHHRadius * 2 + 6); 
305  476 

351  477 
if (Gear^.Timer = 0) or ((HHGear^.Message and gm_Attack) <> 0) then 
302  478 
begin 
351  479 
HHGear^.Message:= 0; 
302  480 
DeleteGear(Gear); 
481 
AfterAttack 

482 
end 

483 
end; 

484 

303
1659c4aad5ab
Now blow torch angle can be changed during blowing :)
unc0rr
parents:
302
diff
changeset

485 
procedure doStepBlowTorch(Gear: PGear); 
1659c4aad5ab
Now blow torch angle can be changed during blowing :)
unc0rr
parents:
302
diff
changeset

486 
var HHGear: PGear; 
1659c4aad5ab
Now blow torch angle can be changed during blowing :)
unc0rr
parents:
302
diff
changeset

487 
begin 
305  488 
BTPrevAngle:= High(Longword); 
489 
BTSteps:= 0; 

351  490 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 
491 
HHGear^.State:= HHGear^.State and not gstAttacking; 

492 
HHGear^.Message:= 0; 

493 
Gear^.doStep:= @doStepBlowTorchWork 

303
1659c4aad5ab
Now blow torch angle can be changed during blowing :)
unc0rr
parents:
302
diff
changeset

494 
end; 
1659c4aad5ab
Now blow torch angle can be changed during blowing :)
unc0rr
parents:
302
diff
changeset

495 

302  496 
//////////////////////////////////////////////////////////////////////////////// 
497 

4  498 
procedure doStepRopeWork(Gear: PGear); 
70  499 
const flCheck: boolean = false; 
4  500 
var HHGear: PGear; 
351  501 
len, cs, cc, tx, ty: hwFloat; 
108  502 
lx, ly: LongInt; 
4  503 

504 
procedure DeleteMe; 

505 
begin 

506 
with HHGear^ do 

507 
begin 

508 
Message:= Message and not gm_Attack; 

509 
State:= State or gstFalling; 

510 
end; 

511 
DeleteGear(Gear); 

351  512 
OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^.Ammo); 
513 
ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^) 

4  514 
end; 
515 

516 
begin 

351  517 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 
108  518 

351  519 
if ((HHGear^.State and gstHHDriven) = 0) 
80  520 
or (CheckGearDrowning(HHGear)) then 
4  521 
begin 
522 
DeleteMe; 

523 
exit 

524 
end; 

351  525 
Gear^.dX:= HHGear^.X  Gear^.X; 
526 
Gear^.dY:= HHGear^.Y  Gear^.Y; 

4  527 

351  528 
if (Gear^.Message and gm_Left <> 0) then HHGear^.dX:= HHGear^.dX  _0_0002 else 
529 
if (Gear^.Message and gm_Right <> 0) then HHGear^.dX:= HHGear^.dX + _0_0002; 

4  530 

351  531 
if not TestCollisionYwithGear(HHGear, 1) then HHGear^.dY:= HHGear^.dY + cGravity; 
4  532 

351  533 
cs:= Gear^.dY + HHGear^.dY; 
534 
cc:= Gear^.dX + HHGear^.dX; 

535 
len:= 1 / Distance(cc, cs); 

108  536 
cc:= cc * len; 
537 
cs:= cs * len; 

4  538 

539 
flCheck:= not flCheck; 

540 
if flCheck then // check whether rope needs dividing 

541 
begin 

351  542 
len:= Gear^.Elasticity  20; 
4  543 
while len > 5 do 
544 
begin 

545 
tx:= cc*len; 

546 
ty:= cs*len; 

351  547 
lx:= hwRound(Gear^.X + tx) + hwSign(HHGear^.dX); 
548 
ly:= hwRound(Gear^.Y + ty) + hwSign(HHGear^.dY); 

4  549 
if ((ly and $FFFFFC00) = 0) and ((lx and $FFFFF800) = 0)and (Land[ly, lx] <> 0) then 
550 
begin 

551 
with RopePoints.ar[RopePoints.Count] do 

552 
begin 

351  553 
X:= Gear^.X; 
554 
Y:= Gear^.Y; 

555 
if RopePoints.Count = 0 then RopePoints.HookAngle:= 0;//DxDy2Angle32(Gear^.dY, Gear^.dX); 

556 
b:= (cc * HHGear^.dY) > (cs * HHGear^.dX); 

4  557 
dLen:= len 
558 
end; 

351  559 
Gear^.X:= Gear^.X + tx; 
560 
Gear^.Y:= Gear^.Y + ty; 

4  561 
inc(RopePoints.Count); 
351  562 
Gear^.Elasticity:= Gear^.Elasticity  len; 
563 
Gear^.Friction:= Gear^.Friction  len; 

4  564 
break 
565 
end; 

566 
len:= len  3 

567 
end; 

568 
end else 

569 
if RopePoints.Count > 0 then // check whether the last dividing point could be removed 

570 
begin 

571 
tx:= RopePoints.ar[Pred(RopePoints.Count)].X; 

572 
ty:= RopePoints.ar[Pred(RopePoints.Count)].Y; 

351  573 
if RopePoints.ar[Pred(RopePoints.Count)].b xor ((tx  Gear^.X) * (ty  HHGear^.Y) > (tx  HHGear^.X) * (ty  Gear^.Y)) then 
4  574 
begin 
575 
dec(RopePoints.Count); 

351  576 
Gear^.X:=RopePoints.ar[RopePoints.Count].X; 
577 
Gear^.Y:=RopePoints.ar[RopePoints.Count].Y; 

578 
Gear^.Elasticity:= Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen; 

579 
Gear^.Friction:= Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen 

4  580 
end 
581 
end; 

582 

351  583 
Gear^.dX:= HHGear^.X  Gear^.X; 
584 
Gear^.dY:= HHGear^.Y  Gear^.Y; 

108  585 

351  586 
cs:= Gear^.dY + HHGear^.dY; 
587 
cc:= Gear^.dX + HHGear^.dX; 

588 
len:= 1 / Distance(cc, cs); 

108  589 
cc:= cc * len; 
590 
cs:= cs * len; 

4  591 

351  592 
HHGear^.dX:= HHGear^.X; 
593 
HHGear^.dY:= HHGear^.Y; 

4  594 

351  595 
if ((Gear^.Message and gm_Down) <> 0) and (Gear^.Elasticity < Gear^.Friction) then 
596 
if not (TestCollisionXwithGear(HHGear, hwSign(Gear^.dX)) 

597 
or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY))) then Gear^.Elasticity:= Gear^.Elasticity + _0_3; 

4  598 

351  599 
if ((Gear^.Message and gm_Up) <> 0) and (Gear^.Elasticity > 30) then 
600 
if not (TestCollisionXwithGear(HHGear, hwSign(Gear^.dX)) 

601 
or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY))) then Gear^.Elasticity:= Gear^.Elasticity  _0_3; 

4  602 

351  603 
HHGear^.X:= Gear^.X + cc*Gear^.Elasticity; 
604 
HHGear^.Y:= Gear^.Y + cs*Gear^.Elasticity; 

4  605 

351  606 
HHGear^.dX:= HHGear^.X  HHGear^.dX; 
607 
HHGear^.dY:= HHGear^.Y  HHGear^.dY; 

4  608 

351  609 
if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then 
610 
HHGear^.dX:= _0_6 * HHGear^.dX; 

611 
if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) then 

612 
HHGear^.dY:= _0_6 * HHGear^.dY; 

4  613 

351  614 
if (Gear^.Message and gm_Attack) <> 0 then 
615 
if (Gear^.State and gsttmpFlag) <> 0 then DeleteMe else 

616 
else if (Gear^.State and gsttmpFlag) = 0 then Gear^.State:= Gear^.State or gsttmpFlag; 

4  617 
end; 
618 

619 

620 
procedure doStepRopeAttach(Gear: PGear); 

621 
var HHGear: PGear; 

351  622 
tx, ty, tt: hwFloat; 
4  623 
begin 
351  624 
Gear^.X:= Gear^.X  Gear^.dX; 
625 
Gear^.Y:= Gear^.Y  Gear^.dY; 

626 
Gear^.Elasticity:= Gear^.Elasticity + 1; 

627 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 

628 
if (HHGear^.State and gstFalling) <> 0 then 

68  629 
if TestCollisionYwithGear(HHGear, 1) then 
4  630 
begin 
351  631 
HHGear^.dY:= 0; 
4  632 
CheckHHDamage(HHGear); 
351  633 
HHGear^.State:= HHGear^.State and not (gstFalling or gstHHJumping); 
4  634 
end else 
635 
begin 

351  636 
if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX); 
637 
HHGear^.X:= HHGear^.X + HHGear^.dX; 

638 
HHGear^.Y:= HHGear^.Y + HHGear^.dY; 

639 
Gear^.X:= Gear^.X + HHGear^.dX; 

640 
Gear^.Y:= Gear^.Y + HHGear^.dY; 

641 
HHGear^.dY:= HHGear^.dY + cGravity; 

642 
tt:= Gear^.Elasticity; 

4  643 
tx:= 0; 
644 
ty:= 0; 

645 
while tt > 20 do 

646 
begin 

351  647 
if TestCollisionXwithXYShift(Gear, hwRound(tx), hwRound(ty), hwSign(Gear^.dX)) 
648 
or TestCollisionYwithXYShift(Gear, hwRound(tx), hwRound(ty), hwSign(Gear^.dY)) then 

4  649 
begin 
351  650 
Gear^.X:= Gear^.X + tx; 
651 
Gear^.Y:= Gear^.Y + ty; 

652 
Gear^.Elasticity:= tt; 

653 
Gear^.doStep:= @doStepRopeWork; 

4  654 
with HHGear^ do State:= State and not gstAttacking; 
655 
tt:= 0 

656 
end; 

351  657 
tx:= tx + Gear^.dX  Gear^.dX; 
658 
ty:= ty + Gear^.dY  Gear^.dY; 

659 
tt:= tt  2; 

4  660 
end; 
661 
end; 

662 
CheckCollision(Gear); 

351  663 
if (Gear^.State and gstCollision) <> 0 then 
4  664 
begin 
351  665 
Gear^.doStep:= @doStepRopeWork; 
4  666 
with HHGear^ do State:= State and not gstAttacking; 
351  667 
if Gear^.Elasticity < 10 then 
668 
Gear^.Elasticity:= 10000; 

4  669 
end; 
670 

351  671 
if (Gear^.Elasticity > Gear^.Friction) or ((Gear^.Message and gm_Attack) = 0) then 
4  672 
begin 
351  673 
with PHedgehog(Gear^.Hedgehog)^.Gear^ do 
4  674 
begin 
675 
State:= State and not gstAttacking; 

676 
Message:= Message and not gm_Attack 

677 
end; 

678 
DeleteGear(Gear) 

679 
end 

680 
end; 

681 

682 
procedure doStepRope(Gear: PGear); 

683 
begin 

351  684 
Gear^.dX:=  Gear^.dX; 
685 
Gear^.dY:=  Gear^.dY; 

686 
Gear^.doStep:= @doStepRopeAttach 

4  687 
end; 
688 

689 
//////////////////////////////////////////////////////////////////////////////// 

690 
procedure doStepSmokeTrace(Gear: PGear); 

691 
begin 

351  692 
inc(Gear^.Timer); 
693 
if Gear^.Timer > 64 then 

4  694 
begin 
351  695 
Gear^.Timer:= 0; 
696 
dec(Gear^.State) 

4  697 
end; 
351  698 
Gear^.dX:= Gear^.dX + cWindSpeed; 
699 
Gear^.X:= Gear^.X + Gear^.dX; 

700 
if Gear^.State = 0 then DeleteGear(Gear) 

4  701 
end; 
9  702 

703 
//////////////////////////////////////////////////////////////////////////////// 

704 
procedure doStepExplosion(Gear: PGear); 

705 
begin 

351  706 
inc(Gear^.Timer); 
707 
if Gear^.Timer > 75 then 

9  708 
begin 
351  709 
inc(Gear^.State); 
710 
Gear^.Timer:= 0; 

711 
if Gear^.State > 5 then DeleteGear(Gear) 

9  712 
end; 
713 
end; 

10  714 

715 
//////////////////////////////////////////////////////////////////////////////// 

716 
procedure doStepMine(Gear: PGear); 

717 
begin 

351  718 
if (Gear^.dX.QWordValue <> 0) or (Gear^.dY.QWordValue <> 0) then 
10  719 
begin 
351  720 
if Gear^.CollIndex < High(Longword) then DeleteCI(Gear); 
10  721 
doStepFallingGear(Gear); 
351  722 
if Gear^.Active = false then 
13  723 
begin 
351  724 
if Gear^.CollIndex = High(Longword) then AddGearCI(Gear); 
725 
Gear^.dX:= 0; 

726 
Gear^.dY:= 0 

13  727 
end; 
728 
CalcRotationDirAngle(Gear); 

10  729 
AllInactive:= false 
730 
end; 

351  731 

732 
if ((Gear^.State and gsttmpFlag) <> 0) then 

733 
if ((Gear^.State and gstAttacking) = 0) then 

14
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

734 
begin 
39  735 
if ((GameTicks and $F) = 0) then 
351  736 
if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then Gear^.State:= Gear^.State or gstAttacking 
14
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

737 
end else // gstAttacking <> 0 
10  738 
begin 
739 
AllInactive:= false; 

351  740 
if (Gear^.Timer and $FF) = 0 then PlaySound(sndMineTick, false); 
741 
if Gear^.Timer = 0 then 

10  742 
begin 
351  743 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); 
10  744 
DeleteGear(Gear) 
745 
end; 

351  746 
dec(Gear^.Timer); 
13  747 
end else // gsttmpFlag = 0 
351  748 
if TurnTimeLeft = 0 then Gear^.State:= Gear^.State or gsttmpFlag; 
10  749 
end; 
57  750 

39  751 
//////////////////////////////////////////////////////////////////////////////// 
752 
procedure doStepDynamite(Gear: PGear); 

753 
begin 

43  754 
doStepFallingGear(Gear); 
755 
AllInactive:= false; 

351  756 
if Gear^.Timer mod 166 = 0 then inc(Gear^.Tag); 
757 
if Gear^.Timer = 0 then 

39  758 
begin 
351  759 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, EXPLAutoSound); 
43  760 
DeleteGear(Gear); 
761 
exit 

39  762 
end; 
351  763 
dec(Gear^.Timer); 
39  764 
end; 
14
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

765 

351  766 
/////////////////////////////////////////////////////////////////////////////// 
14
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

767 
procedure doStepCase(Gear: PGear); 
89  768 
var i, x, y: integer; 
14
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

769 
begin 
351  770 
if (Gear^.Message and gm_Destroy) > 0 then 
15  771 
begin 
772 
DeleteGear(Gear); 

773 
exit 

774 
end; 

775 

351  776 
if Gear^.Damage > 0 then 
79  777 
begin 
351  778 
x:= hwRound(Gear^.X); 
779 
y:= hwRound(Gear^.Y); 

79  780 
DeleteGear(Gear); 
89  781 
doMakeExplosion(x, y, 25, EXPLAutoSound); 
79  782 
for i:= 0 to 63 do 
351  783 
AddGear(x, y, gtFlame, 0, 0, 0, 0); 
79  784 
exit 
785 
end; 

786 

351  787 
if (Gear^.dY.QWordValue <> 0) or (not TestCollisionYwithGear(Gear, 1)) then 
14
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

788 
begin 
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

789 
AllInactive:= false; 
351  790 
Gear^.dY:= Gear^.dY + cGravity; 
791 
Gear^.Y:= Gear^.Y + Gear^.dY; 

792 
if (Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, 1) then Gear^.dY:= 0 else 

793 
if (Gear^.dY.QWordValue <> 0) and TestCollisionYwithGear(Gear, 1) then 

14
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

794 
begin 
351  795 
Gear^.dY:=  Gear^.dY * Gear^.Elasticity; 
796 
if Gear^.dY >  _0_001 then Gear^.dY:= 0 

797 
else if Gear^.dY <  _0_03 then PlaySound(sndGraveImpact, false); 

14
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

798 
end; 
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

799 
CheckGearDrowning(Gear); 
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

800 
end; 
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

801 

351  802 
if (Gear^.CollIndex = High(Longword)) and (Gear^.dY.QWordValue = 0) then AddGearCI(Gear) 
803 
else if (Gear^.CollIndex < High(Longword)) and (Gear^.dY.QWordValue <> 0) then DeleteCI(Gear); 

14
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

804 
end; 
49  805 

806 
//////////////////////////////////////////////////////////////////////////////// 

807 
var thexchar: array[0..5] of record 

808 
oy, ny: integer; 

809 
team: PTeam; 

810 
end; 

811 
thexchcnt: Longword; 

143  812 
currsorter: PGear; 
49  813 

814 
procedure doStepTeamHealthSorterWork(Gear: PGear); 

815 
var i: integer; 

816 
begin 

817 
AllInactive:= false; 

351  818 
dec(Gear^.Timer); 
819 
if (Gear^.Timer and 15) = 0 then 

49  820 
for i:= 0 to Pred(thexchcnt) do 
821 
with thexchar[i] do 

822 
{$WARNINGS OFF} 

351  823 
team^.DrawHealthY:= ny + (oy  ny) * Gear^.Timer div 640; 
49  824 
{$WARNINGS ON} 
351  825 
if (Gear^.Timer = 0) or (currsorter <> Gear) then 
143  826 
begin 
827 
if currsorter = Gear then currsorter:= nil; 

49  828 
DeleteGear(Gear) 
143  829 
end 
49  830 
end; 
831 

832 
procedure doStepTeamHealthSorter(Gear: PGear); 

833 
var team: PTeam; 

834 
i, t: Longword; 

835 
begin 

836 
AllInactive:= false; 

837 
team:= TeamsList; 

838 
i:= 0; 

839 
while team <> nil do 

840 
begin 

351  841 
thexchar[i].oy:= team^.DrawHealthY; 
49  842 
thexchar[i].team:= team; 
843 
inc(i); 

351  844 
team:= team^.Next 
49  845 
end; 
846 
thexchcnt:= i; 

847 
for i:= 1 to thexchcnt do 

848 
for t:= 0 to thexchcnt  2 do 

351  849 
if thexchar[t].team^.TeamHealthBarWidth > thexchar[Succ(t)].team^.TeamHealthBarWidth then 
49  850 
begin 
851 
thexchar[5]:= thexchar[t]; 

852 
thexchar[t]:= thexchar[Succ(t)]; 

853 
thexchar[Succ(t)]:= thexchar[5] 

854 
end; 

855 
t:= cScreenHeight  4; 

856 
for i:= 0 to Pred(thexchcnt) do 

857 
with thexchar[i] do 

858 
begin 

351  859 
dec(t, team^.HealthRect.h + 2); 
49  860 
ny:= t 
861 
end; 

351  862 
Gear^.Timer:= 640; 
863 
Gear^.doStep:= @doStepTeamHealthSorterWork; 

143  864 
currsorter:= Gear 
49  865 
end; 
866 

79  867 
//////////////////////////////////////////////////////////////////////////////// 
868 
procedure doStepShover(Gear: PGear); 

869 
var HHGear: PGear; 

870 
begin 

351  871 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 
872 
HHGear^.State:= HHGear^.State or gstNoDamage; 

79  873 
AmmoShove(Gear, 30, 115); 
351  874 
HHGear^.State:= HHGear^.State and not gstNoDamage; 
79  875 
DeleteGear(Gear) 
876 
end; 

877 

878 
//////////////////////////////////////////////////////////////////////////////// 

879 
procedure doStepFlame(Gear: PGear); 

880 
begin 

881 
AllInactive:= false; 

882 
if not TestCollisionYwithGear(Gear, 1) then 

883 
begin 

351  884 
Gear^.dX:= Gear^.dX + cWindSpeed; 
885 
Gear^.dY:= Gear^.dY + cGravity; 

886 
if hwAbs(Gear^.dX) > _0_1 then Gear^.dX:= Gear^.dX * _0_5; 

887 
if Gear^.dY > _0_1 then Gear^.dY:= Gear^.dY * _0_995; 

888 
Gear^.X:= Gear^.X + Gear^.dX; 

889 
Gear^.Y:= Gear^.Y + Gear^.dY; 

890 
if Gear^.Y > 1023 then 

79  891 
begin 
892 
DeleteGear(Gear); 

893 
exit 

894 
end 

895 
end else begin 

351  896 
if Gear^.Timer > 0 then dec(Gear^.Timer) 
79  897 
else begin 
351  898 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 2, 0); 
899 
dec(Gear^.Health); 

900 
Gear^.Timer:= 1250  Gear^.Angle * 12 

79  901 
end 
902 
end; 

903 

351  904 
if (((GameTicks div 8) mod 64) = Gear^.Angle) then 
79  905 
AmmoFlameWork(Gear); 
906 

351  907 
if Gear^.Health = 0 then 
79  908 
DeleteGear(Gear) 
909 
end; 

82  910 

911 
//////////////////////////////////////////////////////////////////////////////// 

912 
procedure doStepFirePunchWork(Gear: PGear); 

913 
var HHGear: PGear; 

914 
begin 

915 
AllInactive:= false; 

351  916 
if ((Gear^.Message and gm_Destroy) <> 0) then 
82  917 
begin 
918 
DeleteGear(Gear); 

919 
AfterAttack; 

920 
exit 

921 
end; 

922 

351  923 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 
924 
if hwRound(HHGear^.Y) <= Gear^.Tag  2 then 

82  925 
begin 
351  926 
Gear^.Tag:= hwRound(HHGear^.Y); 
927 
DrawTunnel(HHGear^.X  cHHRadius, HHGear^.Y  1, _0_5, 0, cHHRadius * 4, 2); 

928 
HHGear^.State:= HHGear^.State or gstNoDamage; 

929 
Gear^.Y:= HHGear^.Y; 

82  930 
AmmoShove(Gear, 30, 40); 
351  931 
HHGear^.State:= HHGear^.State and not gstNoDamage 
82  932 
end; 
351  933 

934 
HHGear^.dY:= HHGear^.dY + cGravity; 

935 
if not (HHGear^.dY.isNegative) then 

82  936 
begin 
351  937 
HHGear^.State:= HHGear^.State or gstFalling; 
82  938 
DeleteGear(Gear); 
939 
AfterAttack; 

940 
exit 

941 
end; 

351  942 
HHGear^.Y:= HHGear^.Y + HHGear^.dY 
82  943 
end; 
944 

945 
procedure doStepFirePunch(Gear: PGear); 

946 
var HHGear: PGear; 

947 
begin 

948 
AllInactive:= false; 

351  949 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 
950 
HHGear^.X:= hwRound(HHGear^.X)  _0_5; 

951 
SetLittle(HHGear^.dX); 

952 
HHGear^.dY:=  _0_3; 

82  953 

351  954 
Gear^.X:= HHGear^.X; 
955 
Gear^.dX:= hwSign(HHGear^.dX) * _0_45; 

956 
Gear^.dY:=  _0_9; 

957 
Gear^.doStep:= @doStepFirePunchWork; 

958 
DrawTunnel(HHGear^.X  cHHRadius, HHGear^.Y + 1, _0_5, 0, cHHRadius * 4, 5); 

82  959 
end; 
960 

263  961 
//////////////////////////////////////////////////////////////////////////////// 
962 

211  963 
procedure doStepParachute(Gear: PGear); 
964 
var HHGear: PGear; 

965 
begin 

351  966 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 
967 
HHGear^.State:= HHGear^.State and not gstAttacking; 

82  968 

212  969 
if TestCollisionYwithGear(HHGear, 1) 
351  970 
or ((HHGear^.State and gstHHDriven) = 0) 
212  971 
or CheckGearDrowning(HHGear) then 
211  972 
begin 
973 
with HHGear^ do 

974 
begin 

975 
Message:= 0; 

351  976 
SetLittle(dx); 
211  977 
dY:= 0; 
978 
State:= State and not (gstAttacking or gstAttacked); 

979 
State:= State or gstFalling; 

980 
end; 

981 
DeleteGear(Gear); 

351  982 
OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^.Ammo); 
983 
ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); 

211  984 
exit 
985 
end; 

986 

351  987 
if not TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then 
988 
HHGear^.X:= HHGear^.X + cWindSpeed * 200; 

211  989 

351  990 
if (Gear^.Message and gm_Left) <> 0 then HHGear^.X:= HHGear^.X  cMaxWindSpeed * 40 
991 
else if (Gear^.Message and gm_Right) <> 0 then HHGear^.X:= HHGear^.X + cMaxWindSpeed * 40; 

992 
if (Gear^.Message and gm_Up) <> 0 then HHGear^.Y:= HHGear^.Y  cGravity * 40 

993 
else if (Gear^.Message and gm_Down) <> 0 then HHGear^.Y:= HHGear^.Y + cGravity * 40; 

211  994 

351  995 
HHGear^.Y:= HHGear^.Y + cGravity * 100; 
263  996 
end; 
211  997 

263  998 
//////////////////////////////////////////////////////////////////////////////// 
351  999 
const cAirPlaneSpeed: hwFloat = (isNegative: false; QWordValue: 6012954214); // 1.4 
1000 
cBombsDistance: hwFloat = (isNegative: false; QWordValue: 128849018880); // 30 

1001 
cBombsSpeed : hwFloat = (isNegative: false; QWordValue: 429496729); 

263  1002 

1003 
procedure doStepAirAttackWork(Gear: PGear); 

1004 
begin 

1005 
AllInactive:= false; 

351  1006 
Gear^.X:= Gear^.X + cAirPlaneSpeed; 
1007 
if (Gear^.Health > 0)and( not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then 

263  1008 
begin 
351  1009 
dec(Gear^.Health); 
1010 
case Gear^.State of 

1011 
0: AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed, 0, 0); 

1012 
1: AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine, 0, cBombsSpeed, 0, 0); 

285  1013 
end; 
351  1014 
Gear^.dX:= Gear^.dX + cBombsDistance 
263  1015 
end; 
351  1016 
if Gear^.X > 3072 then DeleteGear(Gear) 
263  1017 
end; 
1018 

1019 
procedure doStepAirAttack(Gear: PGear); 

1020 
begin 

1021 
AllInactive:= false; 

351  1022 
Gear^.X:= 1024; 
1023 
Gear^.Y:= 128; 

1024 
Gear^.dX:= TargetPoint.X  

1025 
cBombsDistance * 5 / 2;{  

1026 
cBombsSpeed * sqrt(2 * (TargetPoint.Y  Gear^.Y) / cGravity);} 

1027 
Gear^.Health:= 6; 

1028 
Gear^.doStep:= @doStepAirAttackWork 

263  1029 
end; 
1030 

1031 
//////////////////////////////////////////////////////////////////////////////// 

1032 

1033 
procedure doStepAirBomb(Gear: PGear); 

1034 
begin 

1035 
AllInactive:= false; 

1036 
doStepFallingGear(Gear); 

351  1037 
if (Gear^.State and gstCollision) <> 0 then 
263  1038 
begin 
351  1039 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound); 
263  1040 
DeleteGear(Gear); 
1041 
exit 

1042 
end; 

1043 
if (GameTicks and $3F) = 0 then 

351  1044 
AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, 0, 0, 0) 
211  1045 
end; 