author  unc0rr 
Sat, 26 Apr 2008 14:35:01 +0000  
changeset 876  d5b6e0ae5755 
parent 854  fef7f2d908bf 
child 883  07a568ba44e0 
permissions  rwrr 
4  1 
(* 
2 
* Hedgewars, a wormslike game 

393  3 
* Copyright (c) 20042007 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 

498  23 
if cWaterLine < hwRound(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); 

522  41 
var dmg: Longword; 
4  42 
begin 
522  43 
if _0_4 < Gear^.dY then 
44 
begin 

45 
dmg:= 1 + hwRound((hwAbs(Gear^.dY)  _0_4) * 70); 

46 
inc(Gear^.Damage, dmg); 

47 
AddDamageTag(hwRound(Gear^.X), hwRound(Gear^.Y) + cHHRadius, dmg, Gear); 

48 
end 

4  49 
end; 
50 

51 
//////////////////////////////////////////////////////////////////////////////// 

52 
//////////////////////////////////////////////////////////////////////////////// 

53 
procedure CalcRotationDirAngle(Gear: PGear); 

776
8fc7e59d9cb4
Convert the rest of rotated sprites to be rotated by OpenGL
unc0rr
parents:
764
diff
changeset

54 
var dAngle: real; 
4  55 
begin 
776
8fc7e59d9cb4
Convert the rest of rotated sprites to be rotated by OpenGL
unc0rr
parents:
764
diff
changeset

56 
dAngle:= (hwAbs(Gear^.dX) + hwAbs(Gear^.dY)).QWordValue / $80000000; 
351  57 
if not Gear^.dX.isNegative then Gear^.DirAngle:= Gear^.DirAngle + dAngle 
58 
else Gear^.DirAngle:= Gear^.DirAngle  dAngle; 

776
8fc7e59d9cb4
Convert the rest of rotated sprites to be rotated by OpenGL
unc0rr
parents:
764
diff
changeset

59 
if Gear^.DirAngle < 0 then Gear^.DirAngle:= Gear^.DirAngle + 360 
8fc7e59d9cb4
Convert the rest of rotated sprites to be rotated by OpenGL
unc0rr
parents:
764
diff
changeset

60 
else if 360 < Gear^.DirAngle then Gear^.DirAngle:= Gear^.DirAngle  360 
4  61 
end; 
62 

63 
//////////////////////////////////////////////////////////////////////////////// 

64 
procedure doStepDrowningGear(Gear: PGear); 

65 
begin 

66 
AllInactive:= false; 

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

4  69 
end; 
70 

71 
//////////////////////////////////////////////////////////////////////////////// 

72 
procedure doStepFallingGear(Gear: PGear); 

542  73 
var isFalling: boolean; 
4  74 
begin 
503  75 
Gear^.State:= Gear^.State and not gstCollision; 
76 

77 
if Gear^.dY.isNegative then 

4  78 
begin 
542  79 
isFalling:= true; 
503  80 
if TestCollisionYwithGear(Gear, 1) then 
81 
begin 

82 
Gear^.dX:= Gear^.dX * Gear^.Friction; 

83 
Gear^.dY:=  Gear^.dY * Gear^.Elasticity; 

84 
Gear^.State:= Gear^.State or gstCollision 

85 
end 

86 
end else 

87 
if TestCollisionYwithGear(Gear, 1) then 

88 
begin 

542  89 
isFalling:= false; 
503  90 
Gear^.dX:= Gear^.dX * Gear^.Friction; 
91 
Gear^.dY:=  Gear^.dY * Gear^.Elasticity; 

92 
Gear^.State:= Gear^.State or gstCollision 

542  93 
end else isFalling:= true; 
503  94 

351  95 
if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then 
4  96 
begin 
351  97 
Gear^.dX:=  Gear^.dX * Gear^.Elasticity; 
98 
Gear^.State:= Gear^.State or gstCollision 

4  99 
end; 
503  100 

542  101 
if isFalling then Gear^.dY:= Gear^.dY + cGravity; 
503  102 

351  103 
Gear^.X:= Gear^.X + Gear^.dX; 
104 
Gear^.Y:= Gear^.Y + Gear^.dY; 

4  105 
CheckGearDrowning(Gear); 
503  106 
if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and 
542  107 
(not isFalling) then Gear^.State:= Gear^.State and not gstMoving 
108 
else Gear^.State:= Gear^.State or gstMoving 

4  109 
end; 
110 

111 
//////////////////////////////////////////////////////////////////////////////// 

112 
procedure doStepBomb(Gear: PGear); 

371  113 
var i: LongInt; 
4  114 
begin 
115 
AllInactive:= false; 

116 
doStepFallingGear(Gear); 

351  117 
dec(Gear^.Timer); 
118 
if Gear^.Timer = 0 then 

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

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

4  128 
DeleteGear(Gear); 
129 
exit 

130 
end; 

131 
CalcRotationDirAngle(Gear); 

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

78  135 
procedure doStepCluster(Gear: PGear); 
136 
begin 

137 
AllInactive:= false; 

138 
doStepFallingGear(Gear); 

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

144 
end; 

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

498  146 
AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0) 
78  147 
end; 
148 

4  149 
//////////////////////////////////////////////////////////////////////////////// 
150 
procedure doStepGrenade(Gear: PGear); 

151 
begin 

152 
AllInactive:= false; 

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

160 
end; 

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

498  162 
AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0) 
4  163 
end; 
164 

165 
//////////////////////////////////////////////////////////////////////////////// 

95  166 
procedure doStepHealthTagWork(Gear: PGear); 
4  167 
begin 
522  168 
if Gear^.Kind = gtHealthTag then 
169 
AllInactive:= false; 

351  170 
dec(Gear^.Timer); 
522  171 
Gear^.Y:= Gear^.Y + Gear^.dY; 
351  172 
if Gear^.Timer = 0 then 
4  173 
begin 
522  174 
if Gear^.Kind = gtHealthTag then 
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; 
498  184 
if hwRound(Gear^.Y) < cWaterLine + 10 then 
263  185 
DeleteGear(Gear) 
186 
end; 

187 

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

522  190 
font: THWFont; 
95  191 
begin 
522  192 
if Gear^.Kind = gtHealthTag then 
193 
begin 

813  194 
AllInactive:= false; 
522  195 
font:= fnt16; 
196 
Gear^.dY:= _0_08 

197 
end else 

198 
begin 

199 
font:= fntSmall; 

200 
Gear^.dY:= _0_02 

201 
end; 

202 

351  203 
str(Gear^.State, s); 
762  204 
Gear^.Tex:= RenderStringTex(s, PHedgehog(Gear^.Hedgehog)^.Team^.Clan^.Color, font); 
498  205 
if hwRound(Gear^.Y) < cWaterLine then Gear^.doStep:= @doStepHealthTagWork 
522  206 
else Gear^.doStep:= @doStepHealthTagWorkUnderWater; 
762  207 
Gear^.Y:= Gear^.Y  int2hwFloat(Gear^.Tex^.h) 
95  208 
end; 
209 

4  210 
//////////////////////////////////////////////////////////////////////////////// 
211 
procedure doStepGrave(Gear: PGear); 

212 
begin 

213 
AllInactive:= false; 

498  214 
if Gear^.dY.isNegative then 
215 
if TestCollisionY(Gear, 1) then Gear^.dY:= _0; 

4  216 

351  217 
if not Gear^.dY.isNegative then 
68  218 
if TestCollisionY(Gear, 1) then 
4  219 
begin 
351  220 
Gear^.dY:=  Gear^.dY * Gear^.Elasticity; 
221 
if Gear^.dY >  _1div1024 then 

4  222 
begin 
351  223 
Gear^.Active:= false; 
4  224 
exit 
351  225 
end else if Gear^.dY <  _0_03 then PlaySound(sndGraveImpact, false) 
4  226 
end; 
351  227 
Gear^.Y:= Gear^.Y + Gear^.dY; 
4  228 
CheckGearDrowning(Gear); 
351  229 
Gear^.dY:= Gear^.dY + cGravity 
4  230 
end; 
231 

232 
//////////////////////////////////////////////////////////////////////////////// 

233 
procedure doStepUFOWork(Gear: PGear); 

351  234 
var t: hwFloat; 
374  235 
y: LongInt; 
4  236 
begin 
237 
AllInactive:= false; 

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

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

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

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

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

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

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

374  246 

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

248 
begin 

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

250 
if y + Gear^.Radius < cWaterLine then 

498  251 
AddGear(hwRound(Gear^.X), y, gtSmokeTrace, 0, _0, _0, 0); 
374  252 
end; 
253 

4  254 
CheckCollision(Gear); 
351  255 
dec(Gear^.Timer); 
256 
if ((Gear^.State and gstCollision) <> 0) or (Gear^.Timer = 0) then 

4  257 
begin 
560  258 
StopSound(sndUFO); 
351  259 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); 
4  260 
DeleteGear(Gear); 
261 
end; 

262 
end; 

263 

264 
procedure doStepUFO(Gear: PGear); 

265 
begin 

266 
AllInactive:= false; 

351  267 
Gear^.X:= Gear^.X + Gear^.dX; 
268 
Gear^.Y:= Gear^.Y + Gear^.dY; 

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

4  270 
CheckCollision(Gear); 
351  271 
if (Gear^.State and gstCollision) <> 0 then 
4  272 
begin 
351  273 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); 
4  274 
DeleteGear(Gear); 
275 
exit 

276 
end; 

351  277 
dec(Gear^.Timer); 
278 
if Gear^.Timer = 0 then 

4  279 
begin 
560  280 
PlaySound(sndUFO, true); 
351  281 
Gear^.Timer:= 5000; 
282 
Gear^.doStep:= @doStepUFOWork 

4  283 
end; 
284 
end; 

285 

286 
//////////////////////////////////////////////////////////////////////////////// 

876  287 
procedure doStepShotIdle(Gear: PGear); 
288 
begin 

289 
AllInactive:= false; 

290 
inc(Gear^.Timer); 

291 
if Gear^.Timer > 75 then 

292 
begin 

293 
DeleteGear(Gear); 

294 
AfterAttack 

295 
end 

296 
end; 

297 

4  298 
procedure doStepShotgunShot(Gear: PGear); 
299 
var i: LongWord; 

300 
begin 

301 
AllInactive:= false; 

876  302 

303 
if ((Gear^.State and gstAnimation) = 0) then 

304 
begin 

305 
dec(Gear^.Timer); 

306 
if Gear^.Timer = 0 then 

307 
begin 

308 
PlaySound(sndShotgunFire, false); 

309 
Gear^.State:= Gear^.State or gstAnimation 

310 
end; 

311 
exit 

312 
end 

313 
else inc(Gear^.Timer); 

314 

4  315 
i:= 200; 
316 
repeat 

351  317 
Gear^.X:= Gear^.X + Gear^.dX; 
318 
Gear^.Y:= Gear^.Y + Gear^.dY; 

4  319 
CheckCollision(Gear); 
351  320 
if (Gear^.State and gstCollision) <> 0 then 
876  321 
begin 
322 
Gear^.X:= Gear^.X + Gear^.dX * 8; 

323 
Gear^.Y:= Gear^.Y + Gear^.dY * 8; 

324 
ShotgunShot(Gear); 

325 
Gear^.doStep:= @doStepShotIdle; 

326 
exit 

327 
end; 

4  328 
dec(i) 
329 
until i = 0; 

498  330 
if (Gear^.X < _0) or (Gear^.Y < _0) or (Gear^.X > _2048) or (Gear^.Y > _1024) then 
876  331 
Gear^.doStep:= @doStepShotIdle 
4  332 
end; 
333 

334 
//////////////////////////////////////////////////////////////////////////////// 

559  335 
procedure doStepDEagleShotWork(Gear: PGear); 
38  336 
var i, x, y: LongWord; 
351  337 
oX, oY: hwFloat; 
38  338 
begin 
339 
AllInactive:= false; 

876  340 
inc(Gear^.Timer); 
37  341 
i:= 80; 
351  342 
oX:= Gear^.X; 
343 
oY:= Gear^.Y; 

37  344 
repeat 
351  345 
Gear^.X:= Gear^.X + Gear^.dX; 
346 
Gear^.Y:= Gear^.Y + Gear^.dY; 

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

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

38  349 
if ((y and $FFFFFC00) = 0) and ((x and $FFFFF800) = 0) 
351  350 
and (Land[y, x] <> 0) then inc(Gear^.Damage); 
519  351 
if Gear^.Damage > 5 then AmmoShove(Gear, 7, 20); 
38  352 
dec(i) 
351  353 
until (i = 0) or (Gear^.Damage > Gear^.Health); 
354 
if Gear^.Damage > 0 then 

37  355 
begin 
351  356 
DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 82  i, 1); 
357 
dec(Gear^.Health, Gear^.Damage); 

358 
Gear^.Damage:= 0 

37  359 
end; 
498  360 
if (Gear^.Health <= 0) or (Gear^.X < _0) or (Gear^.Y < _0) or (Gear^.X > _2048) or (Gear^.Y > _1024) then 
876  361 
Gear^.doStep:= @doStepShotIdle 
37  362 
end; 
363 

559  364 
procedure doStepDEagleShot(Gear: PGear); 
365 
begin 

366 
PlaySound(sndGun, false); 

367 
Gear^.doStep:= @doStepDEagleShotWork 

368 
end; 

369 

37  370 
//////////////////////////////////////////////////////////////////////////////// 
4  371 
procedure doStepActionTimer(Gear: PGear); 
372 
begin 

351  373 
dec(Gear^.Timer); 
374 
case Gear^.Kind of 

83  375 
gtATStartGame: begin 
4  376 
AllInactive:= false; 
351  377 
if Gear^.Timer = 0 then 
83  378 
AddCaption(trmsg[sidStartFight], $FFFFFF, capgrpGameState); 
4  379 
end; 
83  380 
gtATSmoothWindCh: begin 
351  381 
if Gear^.Timer = 0 then 
6  382 
begin 
351  383 
if WindBarWidth < Gear^.Tag then inc(WindBarWidth) 
384 
else if WindBarWidth > Gear^.Tag then dec(WindBarWidth); 

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

83  386 
end 
387 
end; 

388 
gtATFinishGame: begin 

389 
AllInactive:= false; 

351  390 
if Gear^.Timer = 0 then 
113  391 
begin 
392 
SendIPC('N'); 

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

393 
SendIPC('q'); 
83  394 
GameState:= gsExit 
113  395 
end 
6  396 
end; 
4  397 
end; 
351  398 
if Gear^.Timer = 0 then DeleteGear(Gear) 
4  399 
end; 
400 

401 
//////////////////////////////////////////////////////////////////////////////// 

402 
procedure doStepPickHammerWork(Gear: PGear); 

371  403 
var i, ei: LongInt; 
4  404 
HHGear: PGear; 
405 
begin 

70  406 
AllInactive:= false; 
351  407 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 
408 
dec(Gear^.Timer); 

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

4  410 
begin 
282  411 
StopSound(sndPickhammer); 
4  412 
DeleteGear(Gear); 
413 
AfterAttack; 

414 
exit 

415 
end; 

845  416 

422  417 
if (Gear^.Timer mod 33) = 0 then 
418 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y) + 6, 6, EXPLDontDraw); 

419 

420 
if (Gear^.Timer mod 47) = 0 then 

4  421 
begin 
371  422 
i:= hwRound(Gear^.X)  Gear^.Radius  LongInt(GetRandom(2)); 
423 
ei:= hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2)); 

4  424 
while i <= ei do 
425 
begin 

422  426 
DrawExplosion(i, hwRound(Gear^.Y) + 3, 3); 
4  427 
inc(i, 1) 
428 
end; 

351  429 
Gear^.X:= Gear^.X + Gear^.dX; 
430 
Gear^.Y:= Gear^.Y + _1_9; 

42  431 
SetAllHHToActive; 
4  432 
end; 
433 
if TestCollisionYwithGear(Gear, 1) then 

434 
begin 

498  435 
Gear^.dY:= _0; 
351  436 
SetLittle(HHGear^.dX); 
498  437 
HHGear^.dY:= _0; 
4  438 
end else 
439 
begin 

351  440 
Gear^.dY:= Gear^.dY + cGravity; 
441 
Gear^.Y:= Gear^.Y + Gear^.dY; 

498  442 
if Gear^.Y > _1024 then Gear^.Timer:= 1 
4  443 
end; 
444 

351  445 
Gear^.X:= Gear^.X + HHGear^.dX; 
446 
HHGear^.X:= Gear^.X; 

498  447 
HHGear^.Y:= Gear^.Y  int2hwFloat(cHHRadius); 
4  448 

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

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

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

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

498  454 
else Gear^.dX:= _0; 
4  455 
end; 
456 

457 
procedure doStepPickHammer(Gear: PGear); 

371  458 
var i, y: LongInt; 
4  459 
ar: TRangeArray; 
460 
begin 

461 
i:= 0; 

498  462 
y:= hwRound(Gear^.Y)  cHHRadius * 2; 
351  463 
while y < hwRound(Gear^.Y) do 
4  464 
begin 
371  465 
ar[i].Left := hwRound(Gear^.X)  Gear^.Radius  LongInt(GetRandom(2)); 
466 
ar[i].Right:= hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2)); 

4  467 
inc(y, 2); 
468 
inc(i) 

469 
end; 

498  470 
DrawHLinesExplosions(@ar, 3, hwRound(Gear^.Y)  cHHRadius * 2, 2, Pred(i)); 
351  471 
Gear^.dY:= PHedgehog(Gear^.Hedgehog)^.Gear^.dY; 
282  472 
PlaySound(sndPickhammer, true); 
4  473 
doStepPickHammerWork(Gear); 
351  474 
Gear^.doStep:= @doStepPickHammerWork 
4  475 
end; 
476 

477 
//////////////////////////////////////////////////////////////////////////////// 

371  478 
var BTPrevAngle, BTSteps: LongInt; 
302  479 

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

480 
procedure doStepBlowTorchWork(Gear: PGear); 
302  481 
var HHGear: PGear; 
305  482 
b: boolean; 
302  483 
begin 
484 
AllInactive:= false; 

351  485 
dec(Gear^.Timer); 
486 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 

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

487 

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

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

489 

305  490 
b:= false; 
491 

371  492 
if abs(LongInt(HHGear^.Angle)  BTPrevAngle) > 7 then 
305  493 
begin 
498  494 
Gear^.dX:= SignAs(AngleSin(HHGear^.Angle) * _0_5, HHGear^.dX); 
355  495 
Gear^.dY:= AngleCos(HHGear^.Angle) * (  _0_5); 
351  496 
BTPrevAngle:= HHGear^.Angle; 
358  497 
b:= true 
305  498 
end; 
499 

351  500 
if Gear^.Timer mod cHHStepTicks = 0 then 
302  501 
begin 
305  502 
b:= true; 
498  503 
if Gear^.dX.isNegative then HHGear^.Message:= (HHGear^.Message or gm_Left) and not gm_Right 
504 
else HHGear^.Message:= (HHGear^.Message or gm_Right) and not gm_Left; 

357  505 

506 
HHGear^.State:= HHGear^.State and not gstAttacking; 

302  507 
HedgehogStep(HHGear); 
357  508 
HHGear^.State:= HHGear^.State or gstAttacking; 
305  509 

510 
inc(BTSteps); 

511  511 
if BTSteps = 7 then 
305  512 
begin 
513 
BTSteps:= 0; 

511  514 
Gear^.X:= HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC); 
515 
Gear^.Y:= HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC); 

351  516 
HHGear^.State:= HHGear^.State or gstNoDamage; 
511  517 
AmmoShove(Gear, 2, 14); 
351  518 
HHGear^.State:= HHGear^.State and not gstNoDamage 
305  519 
end; 
520 

542  521 
if (HHGear^.State and gstMoving) <> 0 then Gear^.Timer:= 0 
302  522 
end; 
305  523 

524 
if b then 

498  525 
DrawTunnel(HHGear^.X  Gear^.dX * cHHRadius, HHGear^.Y  _4  Gear^.dY * cHHRadius + hwAbs(Gear^.dY) * 7, 
351  526 
Gear^.dX, Gear^.dY, 
306  527 
cHHRadius * 5, cHHRadius * 2 + 6); 
305  528 

351  529 
if (Gear^.Timer = 0) or ((HHGear^.Message and gm_Attack) <> 0) then 
302  530 
begin 
351  531 
HHGear^.Message:= 0; 
302  532 
DeleteGear(Gear); 
533 
AfterAttack 

534 
end 

535 
end; 

536 

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

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

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

539 
begin 
371  540 
BTPrevAngle:= High(LongInt); 
305  541 
BTSteps:= 0; 
351  542 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 
543 
HHGear^.Message:= 0; 

544 
Gear^.doStep:= @doStepBlowTorchWork 

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

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

546 

302  547 
//////////////////////////////////////////////////////////////////////////////// 
548 

4  549 
procedure doStepRopeWork(Gear: PGear); 
70  550 
const flCheck: boolean = false; 
4  551 
var HHGear: PGear; 
789  552 
len, cs, cc, tx, ty, nx, ny: hwFloat; 
108  553 
lx, ly: LongInt; 
4  554 

555 
procedure DeleteMe; 

556 
begin 

557 
with HHGear^ do 

558 
begin 

559 
Message:= Message and not gm_Attack; 

542  560 
State:= State or gstMoving; 
4  561 
end; 
562 
DeleteGear(Gear); 

534  563 
OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^); 
351  564 
ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^) 
4  565 
end; 
566 

567 
begin 

351  568 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 
108  569 

351  570 
if ((HHGear^.State and gstHHDriven) = 0) 
80  571 
or (CheckGearDrowning(HHGear)) then 
4  572 
begin 
573 
DeleteMe; 

574 
exit 

575 
end; 

351  576 
Gear^.dX:= HHGear^.X  Gear^.X; 
577 
Gear^.dY:= HHGear^.Y  Gear^.Y; 

4  578 

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

4  581 

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

351  584 
cs:= Gear^.dY + HHGear^.dY; 
585 
cc:= Gear^.dX + HHGear^.dX; 

498  586 
len:= _1 / Distance(cc, cs); 
789  587 
cc:= cc * len; // rope vector plus hedgehog direction vector normalized 
108  588 
cs:= cs * len; 
4  589 

789  590 
nx:= hwAbs(cs) * hwSign(HHGear^.dX) * 3; // hedgehog direction normalized with length 3 
591 
ny:= hwAbs(cc) * hwSign(HHGear^.dY) * 3; 

592 

4  593 
flCheck:= not flCheck; 
594 
if flCheck then // check whether rope needs dividing 

595 
begin 

498  596 
len:= Gear^.Elasticity  _20; 
597 
while len > _5 do 

4  598 
begin 
599 
tx:= cc*len; 

600 
ty:= cs*len; 

789  601 
lx:= hwRound(Gear^.X + tx + nx); 
602 
ly:= hwRound(Gear^.Y + ty + ny); 

652  603 
if ((ly and $FFFFFC00) = 0) and ((lx and $FFFFF800) = 0) and (Land[ly, lx] <> 0) then 
4  604 
begin 
605 
with RopePoints.ar[RopePoints.Count] do 

606 
begin 

351  607 
X:= Gear^.X; 
608 
Y:= Gear^.Y; 

776
8fc7e59d9cb4
Convert the rest of rotated sprites to be rotated by OpenGL
unc0rr
parents:
764
diff
changeset

609 
if RopePoints.Count = 0 then RopePoints.HookAngle:= DxDy2Angle(Gear^.dY, Gear^.dX); 
351  610 
b:= (cc * HHGear^.dY) > (cs * HHGear^.dX); 
4  611 
dLen:= len 
612 
end; 

351  613 
Gear^.X:= Gear^.X + tx; 
614 
Gear^.Y:= Gear^.Y + ty; 

4  615 
inc(RopePoints.Count); 
789  616 
TryDo(RopePoints.Count <= MAXROPEPOINTS, 'Rope points overflow', true); 
351  617 
Gear^.Elasticity:= Gear^.Elasticity  len; 
618 
Gear^.Friction:= Gear^.Friction  len; 

4  619 
break 
620 
end; 

789  621 
len:= len  _2 
4  622 
end; 
623 
end else 

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

625 
begin 

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

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

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

351  631 
Gear^.X:=RopePoints.ar[RopePoints.Count].X; 
632 
Gear^.Y:=RopePoints.ar[RopePoints.Count].Y; 

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

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

4  635 
end 
636 
end; 

637 

351  638 
Gear^.dX:= HHGear^.X  Gear^.X; 
639 
Gear^.dY:= HHGear^.Y  Gear^.Y; 

108  640 

351  641 
cs:= Gear^.dY + HHGear^.dY; 
642 
cc:= Gear^.dX + HHGear^.dX; 

498  643 
len:= _1 / Distance(cc, cs); 
108  644 
cc:= cc * len; 
645 
cs:= cs * len; 

4  646 

351  647 
HHGear^.dX:= HHGear^.X; 
648 
HHGear^.dY:= HHGear^.Y; 

4  649 

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

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

4  653 

498  654 
if ((Gear^.Message and gm_Up) <> 0) and (Gear^.Elasticity > _30) then 
351  655 
if not (TestCollisionXwithGear(HHGear, hwSign(Gear^.dX)) 
656 
or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY))) then Gear^.Elasticity:= Gear^.Elasticity  _0_3; 

4  657 

351  658 
HHGear^.X:= Gear^.X + cc*Gear^.Elasticity; 
659 
HHGear^.Y:= Gear^.Y + cs*Gear^.Elasticity; 

4  660 

351  661 
HHGear^.dX:= HHGear^.X  HHGear^.dX; 
662 
HHGear^.dY:= HHGear^.Y  HHGear^.dY; 

4  663 

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

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

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

4  668 

789  669 
len:= Distance(HHGear^.dX, HHGear^.dY); 
670 
if len > _0_5 then 

671 
begin 

672 
len:= _0_5 / len; 

673 
HHGear^.dX:= HHGear^.dX * len; 

674 
HHGear^.dY:= HHGear^.dY * len; 

675 
end; 

676 

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

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

4  680 
end; 
681 

682 

683 
procedure doStepRopeAttach(Gear: PGear); 

684 
var HHGear: PGear; 

351  685 
tx, ty, tt: hwFloat; 
4  686 
begin 
351  687 
Gear^.X:= Gear^.X  Gear^.dX; 
688 
Gear^.Y:= Gear^.Y  Gear^.dY; 

498  689 
Gear^.Elasticity:= Gear^.Elasticity + _1; 
351  690 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 
517  691 
DeleteCI(HHGear); 
542  692 
if (HHGear^.State and gstMoving) <> 0 then 
68  693 
if TestCollisionYwithGear(HHGear, 1) then 
4  694 
begin 
820
a26537586400
Fix fall without damage trick, which could be performed with not attached rope
unc0rr
parents:
819
diff
changeset

695 
CheckHHDamage(HHGear); 
498  696 
HHGear^.dY:= _0; 
542  697 
HHGear^.State:= HHGear^.State and not (gstMoving or gstHHJumping); 
4  698 
end else 
699 
begin 

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

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

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

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

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

706 
tt:= Gear^.Elasticity; 

498  707 
tx:= _0; 
708 
ty:= _0; 

709 
while tt > _20 do 

4  710 
begin 
517  711 
if TestCollisionXwithXYShift(Gear, tx, hwRound(ty), hwSign(Gear^.dX)) 
712 
or TestCollisionYwithXYShift(Gear, hwRound(tx), hwRound(ty), hwSign(Gear^.dY)) then 

4  713 
begin 
351  714 
Gear^.X:= Gear^.X + tx; 
715 
Gear^.Y:= Gear^.Y + ty; 

716 
Gear^.Elasticity:= tt; 

717 
Gear^.doStep:= @doStepRopeWork; 

4  718 
with HHGear^ do State:= State and not gstAttacking; 
498  719 
tt:= _0 
4  720 
end; 
517  721 
tx:= tx + Gear^.dX + Gear^.dX; 
722 
ty:= ty + Gear^.dY + Gear^.dY; 

498  723 
tt:= tt  _2; 
4  724 
end; 
725 
end; 

726 
CheckCollision(Gear); 

351  727 
if (Gear^.State and gstCollision) <> 0 then 
4  728 
begin 
351  729 
Gear^.doStep:= @doStepRopeWork; 
4  730 
with HHGear^ do State:= State and not gstAttacking; 
498  731 
if Gear^.Elasticity < _10 then 
732 
Gear^.Elasticity:= _10000; 

4  733 
end; 
734 

351  735 
if (Gear^.Elasticity > Gear^.Friction) or ((Gear^.Message and gm_Attack) = 0) then 
4  736 
begin 
351  737 
with PHedgehog(Gear^.Hedgehog)^.Gear^ do 
4  738 
begin 
739 
State:= State and not gstAttacking; 

740 
Message:= Message and not gm_Attack 

741 
end; 

742 
DeleteGear(Gear) 

743 
end 

744 
end; 

745 

746 
procedure doStepRope(Gear: PGear); 

747 
begin 

351  748 
Gear^.dX:=  Gear^.dX; 
749 
Gear^.dY:=  Gear^.dY; 

750 
Gear^.doStep:= @doStepRopeAttach 

4  751 
end; 
752 

753 
//////////////////////////////////////////////////////////////////////////////// 

754 
procedure doStepSmokeTrace(Gear: PGear); 

755 
begin 

351  756 
inc(Gear^.Timer); 
757 
if Gear^.Timer > 64 then 

4  758 
begin 
351  759 
Gear^.Timer:= 0; 
760 
dec(Gear^.State) 

4  761 
end; 
351  762 
Gear^.dX:= Gear^.dX + cWindSpeed; 
763 
Gear^.X:= Gear^.X + Gear^.dX; 

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

4  765 
end; 
9  766 

767 
//////////////////////////////////////////////////////////////////////////////// 

768 
procedure doStepExplosion(Gear: PGear); 

769 
begin 

351  770 
inc(Gear^.Timer); 
771 
if Gear^.Timer > 75 then 

9  772 
begin 
351  773 
inc(Gear^.State); 
774 
Gear^.Timer:= 0; 

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

9  776 
end; 
777 
end; 

10  778 

779 
//////////////////////////////////////////////////////////////////////////////// 

780 
procedure doStepMine(Gear: PGear); 

781 
begin 

542  782 
if (Gear^.State and gstMoving) <> 0 then 
10  783 
begin 
503  784 
DeleteCI(Gear); 
10  785 
doStepFallingGear(Gear); 
542  786 
if (Gear^.State and gstMoving) = 0 then 
13  787 
begin 
503  788 
AddGearCI(Gear); 
498  789 
Gear^.dX:= _0; 
790 
Gear^.dY:= _0 

13  791 
end; 
792 
CalcRotationDirAngle(Gear); 

10  793 
AllInactive:= false 
794 
end; 

351  795 

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

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

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

798 
begin 
39  799 
if ((GameTicks and $F) = 0) then 
351  800 
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

801 
end else // gstAttacking <> 0 
10  802 
begin 
803 
AllInactive:= false; 

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

10  806 
begin 
351  807 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); 
521  808 
DeleteGear(Gear); 
809 
exit 

10  810 
end; 
351  811 
dec(Gear^.Timer); 
13  812 
end else // gsttmpFlag = 0 
351  813 
if TurnTimeLeft = 0 then Gear^.State:= Gear^.State or gsttmpFlag; 
10  814 
end; 
57  815 

39  816 
//////////////////////////////////////////////////////////////////////////////// 
817 
procedure doStepDynamite(Gear: PGear); 

818 
begin 

43  819 
doStepFallingGear(Gear); 
820 
AllInactive:= false; 

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

39  823 
begin 
351  824 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, EXPLAutoSound); 
43  825 
DeleteGear(Gear); 
826 
exit 

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

830 

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

832 
procedure doStepCase(Gear: PGear); 
371  833 
var i, x, y: LongInt; 
14
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

834 
begin 
351  835 
if (Gear^.Message and gm_Destroy) > 0 then 
15  836 
begin 
837 
DeleteGear(Gear); 

435  838 
FreeActionsList; 
602  839 
with CurrentHedgehog^ do 
441  840 
if Gear <> nil then Gear^.Message:= Gear^.Message and not (gm_LJump or gm_HJump); 
15  841 
exit 
842 
end; 

843 

351  844 
if Gear^.Damage > 0 then 
79  845 
begin 
351  846 
x:= hwRound(Gear^.X); 
847 
y:= hwRound(Gear^.Y); 

79  848 
DeleteGear(Gear); 
590  849 
if Gear^.Kind = gtCase then 
850 
begin 

851 
doMakeExplosion(x, y, 25, EXPLAutoSound); 

852 
for i:= 0 to 63 do 

853 
AddGear(x, y, gtFlame, 0, _0, _0, 0); 

854 
end; 

79  855 
exit 
856 
end; 

857 

351  858 
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

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

860 
AllInactive:= false; 
351  861 
Gear^.dY:= Gear^.dY + cGravity; 
862 
Gear^.Y:= Gear^.Y + Gear^.dY; 

498  863 
if (Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, 1) then Gear^.dY:= _0 else 
439  864 
if (not Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, 1) then 
14
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
13
diff
changeset

865 
begin 
351  866 
Gear^.dY:=  Gear^.dY * Gear^.Elasticity; 
498  867 
if Gear^.dY >  _0_001 then Gear^.dY:= _0 
351  868 
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

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

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

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

872 

511  873 
if (Gear^.dY.QWordValue = 0) then AddGearCI(Gear) 
874 
else if (Gear^.dY.QWordValue <> 0) then DeleteCI(Gear) 

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

875 
end; 
49  876 

877 
//////////////////////////////////////////////////////////////////////////////// 

557  878 
const cSorterWorkTime = 640; 
879 
var thexchar: array[0..cMaxTeams] of 

880 
record 

881 
dy, ny, dw: LongInt; 

49  882 
team: PTeam; 
557  883 
SortFactor: QWord; 
49  884 
end; 
601
78a68cc4d846
Special game mode allowing the only clan on map for training mode
unc0rr
parents:
590
diff
changeset

885 
currsorter: PGear = nil; 
49  886 

887 
procedure doStepTeamHealthSorterWork(Gear: PGear); 

371  888 
var i: LongInt; 
49  889 
begin 
890 
AllInactive:= false; 

351  891 
dec(Gear^.Timer); 
892 
if (Gear^.Timer and 15) = 0 then 

557  893 
for i:= 0 to Pred(TeamsCount) do 
49  894 
with thexchar[i] do 
557  895 
begin 
49  896 
{$WARNINGS OFF} 
557  897 
team^.DrawHealthY:= ny + dy * Gear^.Timer div 640; 
898 
team^.TeamHealthBarWidth:= team^.NewTeamHealthBarWidth + dw * Gear^.Timer div cSorterWorkTime; 

49  899 
{$WARNINGS ON} 
557  900 
end; 
351  901 
if (Gear^.Timer = 0) or (currsorter <> Gear) then 
143  902 
begin 
903 
if currsorter = Gear then currsorter:= nil; 

49  904 
DeleteGear(Gear) 
143  905 
end 
49  906 
end; 
907 

908 
procedure doStepTeamHealthSorter(Gear: PGear); 

547  909 
var i, t: Longword; 
557  910 
b: boolean; 
49  911 
begin 
912 
AllInactive:= false; 

557  913 

547  914 
for t:= 0 to Pred(TeamsCount) do 
557  915 
with thexchar[t] do 
49  916 
begin 
557  917 
dy:= TeamsArray[t]^.DrawHealthY; 
918 
dw:= TeamsArray[t]^.TeamHealthBarWidth  TeamsArray[t]^.NewTeamHealthBarWidth; 

919 
team:= TeamsArray[t]; 

920 
SortFactor:= TeamsArray[t]^.Clan^.ClanHealth; 

921 
SortFactor:= (SortFactor shl 3) + TeamsArray[t]^.Clan^.ClanIndex; 

922 
SortFactor:= (SortFactor shl 30) + TeamsArray[t]^.TeamHealth; 

49  923 
end; 
547  924 

601
78a68cc4d846
Special game mode allowing the only clan on map for training mode
unc0rr
parents:
590
diff
changeset

925 
if TeamsCount > 1 then 
78a68cc4d846
Special game mode allowing the only clan on map for training mode
unc0rr
parents:
590
diff
changeset

926 
repeat 
557  927 
b:= true; 
928 
for t:= 0 to TeamsCount  2 do 

929 
if (thexchar[t].SortFactor > thexchar[Succ(t)].SortFactor) then 

49  930 
begin 
557  931 
thexchar[cMaxTeams]:= thexchar[t]; 
49  932 
thexchar[t]:= thexchar[Succ(t)]; 
557  933 
thexchar[Succ(t)]:= thexchar[cMaxTeams]; 
934 
b:= false 

935 
end 

601
78a68cc4d846
Special game mode allowing the only clan on map for training mode
unc0rr
parents:
590
diff
changeset

936 
until b; 
557  937 

49  938 
t:= cScreenHeight  4; 
557  939 
for i:= 0 to Pred(TeamsCount) do 
49  940 
with thexchar[i] do 
941 
begin 

764
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset

942 
dec(t, team^.HealthTex^.h + 2); 
557  943 
ny:= t; 
944 
dy:= dy  ny 

49  945 
end; 
764
7513452b1d51
Now game looks almost like it did before switching to OpenGL
unc0rr
parents:
762
diff
changeset

946 

557  947 
Gear^.Timer:= cSorterWorkTime; 
351  948 
Gear^.doStep:= @doStepTeamHealthSorterWork; 
143  949 
currsorter:= Gear 
49  950 
end; 
951 

79  952 
//////////////////////////////////////////////////////////////////////////////// 
854  953 
procedure doStepIdle(Gear: PGear); 
954 
begin 

955 
AllInactive:= false; 

956 
dec(Gear^.Timer);addfilelog(inttostr(Gear^.Timer)); 

957 
if Gear^.Timer = 0 then 

958 
begin 

959 
DeleteGear(Gear); 

960 
AfterAttack 

961 
end 

962 
end; 

963 

79  964 
procedure doStepShover(Gear: PGear); 
965 
var HHGear: PGear; 

966 
begin 

351  967 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 
968 
HHGear^.State:= HHGear^.State or gstNoDamage; 

79  969 
AmmoShove(Gear, 30, 115); 
351  970 
HHGear^.State:= HHGear^.State and not gstNoDamage; 
854  971 
Gear^.Timer:= 250; 
972 
Gear^.doStep:= @doStepIdle 

79  973 
end; 
974 

975 
//////////////////////////////////////////////////////////////////////////////// 

976 
procedure doStepFlame(Gear: PGear); 

977 
begin 

978 
AllInactive:= false; 

979 
if not TestCollisionYwithGear(Gear, 1) then 

980 
begin 

351  981 
Gear^.dX:= Gear^.dX + cWindSpeed; 
982 
Gear^.dY:= Gear^.dY + cGravity; 

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

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

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

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

498  987 
if not (Gear^.Y < _1024) then 
79  988 
begin 
989 
DeleteGear(Gear); 

990 
exit 

991 
end 

992 
end else begin 

351  993 
if Gear^.Timer > 0 then dec(Gear^.Timer) 
79  994 
else begin 
506  995 
// doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 2, 0); 
351  996 
dec(Gear^.Health); 
997 
Gear^.Timer:= 1250  Gear^.Angle * 12 

79  998 
end 
999 
end; 

1000 

351  1001 
if (((GameTicks div 8) mod 64) = Gear^.Angle) then 
79  1002 
AmmoFlameWork(Gear); 
1003 

351  1004 
if Gear^.Health = 0 then 
79  1005 
DeleteGear(Gear) 
1006 
end; 

82  1007 

1008 
//////////////////////////////////////////////////////////////////////////////// 

1009 
procedure doStepFirePunchWork(Gear: PGear); 

1010 
var HHGear: PGear; 

1011 
begin 

1012 
AllInactive:= false; 

351  1013 
if ((Gear^.Message and gm_Destroy) <> 0) then 
82  1014 
begin 
1015 
DeleteGear(Gear); 

1016 
AfterAttack; 

1017 
exit 

1018 
end; 

1019 

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

82  1022 
begin 
351  1023 
Gear^.Tag:= hwRound(HHGear^.Y); 
498  1024 
DrawTunnel(HHGear^.X  int2hwFloat(cHHRadius), HHGear^.Y  _1, _0_5, _0, cHHRadius * 4, 2); 
351  1025 
HHGear^.State:= HHGear^.State or gstNoDamage; 
1026 
Gear^.Y:= HHGear^.Y; 

82  1027 
AmmoShove(Gear, 30, 40); 
351  1028 
HHGear^.State:= HHGear^.State and not gstNoDamage 
82  1029 
end; 
351  1030 

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

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

82  1033 
begin 
542  1034 
HHGear^.State:= HHGear^.State or gstMoving; 
82  1035 
DeleteGear(Gear); 
1036 
AfterAttack; 

1037 
exit 

1038 
end; 

351  1039 
HHGear^.Y:= HHGear^.Y + HHGear^.dY 
82  1040 
end; 
1041 

1042 
procedure doStepFirePunch(Gear: PGear); 

1043 
var HHGear: PGear; 

1044 
begin 

1045 
AllInactive:= false; 

351  1046 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 
514  1047 
DeleteCI(HHGear); 
498  1048 
HHGear^.X:= int2hwFloat(hwRound(HHGear^.X))  _0_5; 
351  1049 
SetLittle(HHGear^.dX); 
1050 
HHGear^.dY:=  _0_3; 

82  1051 

351  1052 
Gear^.X:= HHGear^.X; 
498  1053 
Gear^.dX:= SignAs(_0_45, HHGear^.dX); 
351  1054 
Gear^.dY:=  _0_9; 
1055 
Gear^.doStep:= @doStepFirePunchWork; 

498  1056 
DrawTunnel(HHGear^.X  int2hwFloat(cHHRadius), HHGear^.Y + _1, _0_5, _0, cHHRadius * 4, 5); 
82  1057 
end; 
1058 

263  1059 
//////////////////////////////////////////////////////////////////////////////// 
1060 

211  1061 
procedure doStepParachute(Gear: PGear); 
1062 
var HHGear: PGear; 

817  1063 
Timer: Longword; 
211  1064 
begin 
351  1065 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 
1066 
HHGear^.State:= HHGear^.State and not gstAttacking; 

517  1067 
DeleteCI(HHGear); 
82  1068 

516  1069 
inc(Gear^.Timer); 
1070 

212  1071 
if TestCollisionYwithGear(HHGear, 1) 
351  1072 
or ((HHGear^.State and gstHHDriven) = 0) 
212  1073 
or CheckGearDrowning(HHGear) then 
211  1074 
begin 
1075 
with HHGear^ do 

1076 
begin 

1077 
Message:= 0; 

568  1078 
SetLittle(dX); 
498  1079 
dY:= _0; 
211  1080 
State:= State and not (gstAttacking or gstAttacked); 
542  1081 
State:= State or gstMoving; 
211  1082 
end; 
817  1083 
Timer:= Gear^.Timer; 
211  1084 
DeleteGear(Gear); 
817  1085 
if Timer > 10 then 
516  1086 
begin 
534  1087 
OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^); 
516  1088 
ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^) 
1089 
end; 

211  1090 
exit 
1091 
end; 

1092 

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

211  1095 

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

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

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

211  1100 

351  1101 
HHGear^.Y:= HHGear^.Y + cGravity * 100; 
568  1102 
Gear^.X:= HHGear^.X; 
1103 
Gear^.Y:= HHGear^.Y 

263  1104 
end; 
211  1105 

263  1106 
//////////////////////////////////////////////////////////////////////////////// 
1107 
procedure doStepAirAttackWork(Gear: PGear); 

1108 
begin 

1109 
AllInactive:= false; 

498  1110 
Gear^.X:= Gear^.X + cAirPlaneSpeed * Gear^.Tag; 
543
465e2ec8f05f
 Better randomness of placing hedgehogs on the land
unc0rr
parents:
542
diff
changeset

1111 
if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then 
263  1112 
begin 
351  1113 
dec(Gear^.Health); 
1114 
case Gear^.State of 

498  1115 
0: FollowGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0); 
1116 
1: FollowGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine, 0, cBombsSpeed * Gear^.Tag, _0, 0); 

285  1117 
end; 
543
465e2ec8f05f
 Better randomness of placing hedgehogs on the land
unc0rr
parents:
542
diff
changeset

1118 
Gear^.dX:= Gear^.dX + int2hwFloat(30 * Gear^.Tag) 
263  1119 
end; 
498  1120 
if (hwRound(Gear^.X) > 3072) or (hwRound(Gear^.X) < 1024) then DeleteGear(Gear) 
263  1121 
end; 
1122 

1123 
procedure doStepAirAttack(Gear: PGear); 

1124 
begin 

1125 
AllInactive:= false; 

543
465e2ec8f05f
 Better randomness of placing hedgehogs on the land
unc0rr
parents:
542
diff
changeset

1126 

408  1127 
if Gear^.X.QWordValue = 0 then Gear^.Tag:= 1 
1128 
else Gear^.Tag:= 1; 

498  1129 
Gear^.X:= _1024  _2048 * Gear^.Tag; 
1130 
Gear^.Y:= _128; 

543
465e2ec8f05f
 Better randomness of placing hedgehogs on the land
unc0rr
parents:
542
diff
changeset

1131 
Gear^.dX:= int2hwFloat(TargetPoint.X  5 * Gear^.Tag * 15); 
357  1132 

543
465e2ec8f05f
 Better randomness of placing hedgehogs on the land
unc0rr
parents:
542
diff
changeset

1133 
if int2hwFloat(TargetPoint.Y)  Gear^.Y > _0 then 
498  1134 
Gear^.dX:= Gear^.dX  cBombsSpeed * hwSqrt((int2hwFloat(TargetPoint.Y)  Gear^.Y) * 2 / cGravity) * Gear^.Tag; 
543
465e2ec8f05f
 Better randomness of placing hedgehogs on the land
unc0rr
parents:
542
diff
changeset

1135 

351  1136 
Gear^.Health:= 6; 
801  1137 
Gear^.doStep:= @doStepAirAttackWork; 
1138 
PlaySound(sndIncoming, false) 

263  1139 
end; 
1140 

1141 
//////////////////////////////////////////////////////////////////////////////// 

1142 

1143 
procedure doStepAirBomb(Gear: PGear); 

1144 
begin 

1145 
AllInactive:= false; 

1146 
doStepFallingGear(Gear); 

351  1147 
if (Gear^.State and gstCollision) <> 0 then 
263  1148 
begin 
351  1149 
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound); 
263  1150 
DeleteGear(Gear); 
1151 
exit 

1152 
end; 

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

498  1154 
AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0) 
211  1155 
end; 
409  1156 

1157 
//////////////////////////////////////////////////////////////////////////////// 

1158 

1159 
procedure doStepGirder(Gear: PGear); 

415  1160 
var HHGear: PGear; 
409  1161 
begin 
1162 
AllInactive:= false; 

415  1163 

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

409  1165 
if not TryPlaceOnLand(TargetPoint.X  SpritesData[sprAmGirder].Width div 2, 
1166 
TargetPoint.Y  SpritesData[sprAmGirder].Height div 2, 

520  1167 
sprAmGirder, Gear^.State, true) then 
409  1168 
begin 
415  1169 
HHGear^.Message:= HHGear^.Message and not gm_Attack; 
1170 
HHGear^.State:= HHGear^.State and not gstAttacking; 

1171 
HHGear^.State:= HHGear^.State or gstHHChooseTarget; 

1172 
DeleteGear(Gear); 

1173 
isCursorVisible:= true 

409  1174 
end 
415  1175 
else begin 
1176 
DeleteGear(Gear); 

1177 
AfterAttack 

1178 
end; 

1179 
TargetPoint.X:= NoPointX 

409  1180 
end; 
520  1181 

1182 
//////////////////////////////////////////////////////////////////////////////// 

525  1183 
procedure doStepTeleportAfter(Gear: PGear); 
1184 
begin 

853  1185 
inc(Gear^.Timer); 
1186 
if Gear^.Timer = 65 then 

1187 
begin 

1188 
Gear^.Timer:= 0; 

1189 
inc(Gear^.Pos); 

1190 
if Gear^.Pos = 11 then 

1191 
begin 

1192 
DeleteGear(Gear); 

1193 
AfterAttack 

1194 
end 

1195 
end 

525  1196 
end; 
520  1197 

1198 
procedure doStepTeleport(Gear: PGear); 

1199 
var HHGear: PGear; 

1200 
begin 

1201 
AllInactive:= false; 

1202 

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

1204 
if not TryPlaceOnLand(TargetPoint.X  SpritesData[sprHHTelepMask].Width div 2, 

1205 
TargetPoint.Y  SpritesData[sprHHTelepMask].Height div 2, 

1206 
sprHHTelepMask, 0, false) then 

853  1207 
begin 
1208 
HHGear^.Message:= HHGear^.Message and not gm_Attack; 

1209 
HHGear^.State:= HHGear^.State and not gstAttacking; 

1210 
HHGear^.State:= HHGear^.State or gstHHChooseTarget; 

1211 
DeleteGear(Gear); 

1212 
isCursorVisible:= true 

1213 
end 

1214 
else begin 

1215 
DeleteCI(HHGear); 

1216 
SetAllHHToActive; 

1217 
Gear^.doStep:= @doStepTeleportAfter; 

1218 
Gear^.X:= HHGear^.X; 

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

1220 
HHGear^.X:= int2hwFloat(TargetPoint.X); 

1221 
HHGear^.Y:= int2hwFloat(TargetPoint.Y); 

1222 
HHGear^.State:= HHGear^.State or gstMoving 

1223 
end; 

520  1224 
TargetPoint.X:= NoPointX 
1225 
end; 

534  1226 

1227 
//////////////////////////////////////////////////////////////////////////////// 

1228 
procedure doStepSwitcherWork(Gear: PGear); 

1229 
var HHGear: PGear; 

1230 
Msg, State: Longword; 

1231 
begin 

1232 
AllInactive:= false; 

1233 

540  1234 
if ((Gear^.Message and not gm_Switch) <> 0) or (TurnTimeLeft = 0) then 
534  1235 
begin 
1236 
HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; 

1237 
Msg:= Gear^.Message and not gm_Switch; 

1238 
DeleteGear(Gear); 

538  1239 
OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^); 
1240 
ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); 

534  1241 

602  1242 
HHGear:= CurrentHedgehog^.Gear; 
538  1243 
ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); 
534  1244 
HHGear^.Message:= Msg; 
1245 
exit 

1246 
end; 

1247 

1248 
if (Gear^.Message and gm_Switch) <> 0 then 

1249 
begin 

602  1250 
HHGear:= CurrentHedgehog^.Gear; 
534  1251 
HHGear^.Message:= HHGear^.Message and not gm_Switch; 
809  1252 
Gear^.Message:= Gear^.Message and not gm_Switch; 
534  1253 
State:= HHGear^.State; 
1254 
HHGear^.State:= 0; 

1255 
HHGear^.Active:= false; 

1256 
HHGear^.Z:= cHHZ; 

1257 
RemoveGearFromList(HHGear); 

1258 
InsertGearToList(HHGear); 

1259 

1260 
repeat 

551  1261 
CurrentTeam^.CurrHedgehog:= Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber); 
652  1262 
until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil); 
1263 

1264 
CurrentHedgehog:= @CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]; 

534  1265 

602  1266 
HHGear:= CurrentHedgehog^.Gear; 
534  1267 
HHGear^.State:= State; 
1268 
HHGear^.Active:= true; 

1269 
FollowGear:= HHGear; 

1270 
HHGear^.Z:= cCurrHHZ; 

1271 
RemoveGearFromList(HHGear); 

1272 
InsertGearToList(HHGear); 

1273 
Gear^.X:= HHGear^.X; 

1274 
Gear^.Y:= HHGear^.Y 

1275 
end; 

1276 
end; 

1277 

1278 
procedure doStepSwitcher(Gear: PGear); 

1279 
var HHGear: PGear; 

1280 
begin 

1281 
Gear^.doStep:= @doStepSwitcherWork; 

1282 

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

1284 
with HHGear^ do 

1285 
begin 

1286 
State:= State and not gstAttacking; 

1287 
Message:= Message and not gm_Attack 

1288 
end 

1289 
end; 