author  unc0rr 
Sat, 05 May 2007 16:04:55 +0000  
changeset 506  0889d833d47e 
parent 505  fcba7d7aea0d 
child 509  fd58135a4407 
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 
unit uGears; 

20 
interface 

351  21 
uses SDLh, uConsts, uFloat; 
4  22 
{$INCLUDE options.inc} 
23 
const AllInactive: boolean = false; 

24 

25 
type PGear = ^TGear; 

26 
TGearStepProcedure = procedure (Gear: PGear); 

27 
TGear = record 

28 
NextGear, PrevGear: PGear; 

29 
Active: Boolean; 

188  30 
State : Longword; 
351  31 
X : hwFloat; 
32 
Y : hwFloat; 

33 
dX: hwFloat; 

34 
dY: hwFloat; 

42  35 
Kind: TGearType; 
36 
Pos: Longword; 

4  37 
doStep: TGearStepProcedure; 
371  38 
Radius: LongInt; 
188  39 
Angle, Power : Longword; 
351  40 
DirAngle: hwFloat; 
4  41 
Timer : LongWord; 
351  42 
Elasticity: hwFloat; 
43 
Friction : hwFloat; 

4  44 
Message : Longword; 
45 
Hedgehog: pointer; 

371  46 
Health, Damage: LongInt; 
4  47 
CollIndex: Longword; 
371  48 
Tag: LongInt; 
95  49 
Surf: PSDL_Surface; 
293  50 
Z: Longword; 
505
fcba7d7aea0d
Fix old bug with grenade(bomd, etc..) not colliding with attacking hedgehog
unc0rr
parents:
503
diff
changeset

51 
IntersectGear: PGear; 
4  52 
end; 
53 

371  54 
function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear; 
4  55 
procedure ProcessGears; 
56 
procedure SetAllToActive; 

57 
procedure SetAllHHToActive; 

58 
procedure DrawGears(Surface: PSDL_Surface); 

59 
procedure FreeGearsList; 

10  60 
procedure AddMiscGears; 
293  61 
procedure AddClouds; 
4  62 
procedure AssignHHCoords; 
294  63 
procedure InsertGearToList(Gear: PGear); 
64 
procedure RemoveGearFromList(Gear: PGear); 

4  65 

66 
var CurAmmoGear: PGear = nil; 

68  67 
GearsList: PGear = nil; 
307  68 
KilledHHs: Longword = 0; 
70  69 

4  70 
implementation 
81  71 
uses uWorld, uMisc, uStore, uConsole, uSound, uTeams, uRandom, uCollisions, 
295  72 
uLand, uIO, uLandGraphics, uAIMisc, uLocale, uAI, uAmmos; 
68  73 
var RopePoints: record 
4  74 
Count: Longword; 
371  75 
HookAngle: LongInt; 
4  76 
ar: array[0..300] of record 
351  77 
X, Y: hwFloat; 
78 
dLen: hwFloat; 

4  79 
b: boolean; 
80 
end; 

81 
end; 

307  82 
StepDamage: Longword = 0; 
4  83 

84 
procedure DeleteGear(Gear: PGear); forward; 

371  85 
procedure doMakeExplosion(X, Y, Radius: LongInt; Mask: LongWord); forward; 
86 
procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); forward; 

79  87 
procedure AmmoFlameWork(Ammo: PGear); forward; 
371  88 
function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear; forward; 
15  89 
procedure SpawnBoxOfSmth; forward; 
32
78bff13b11c0
With this patch the game doesn't crash when gaming by net
unc0rr
parents:
24
diff
changeset

90 
procedure AfterAttack; forward; 
371  91 
procedure FindPlace(Gear: PGear; withFall: boolean; Left, Right: LongInt); forward; 
302  92 
procedure HedgehogStep(Gear: PGear); forward; 
303
1659c4aad5ab
Now blow torch angle can be changed during blowing :)
unc0rr
parents:
302
diff
changeset

93 
procedure HedgehogChAngle(Gear: PGear); forward; 
506  94 
procedure ShotgunShot(Gear: PGear); forward; 
4  95 

96 
{$INCLUDE GSHandlers.inc} 

97 
{$INCLUDE HHHandlers.inc} 

98 

99 
const doStepHandlers: array[TGearType] of TGearStepProcedure = ( 

351  100 
@doStepCloud, 
101 
@doStepBomb, 

102 
@doStepHedgehog, 

103 
@doStepGrenade, 

104 
@doStepHealthTag, 

105 
@doStepGrave, 

106 
@doStepUFO, 

107 
@doStepShotgunShot, 

108 
@doStepPickHammer, 

109 
@doStepRope, 

110 
@doStepSmokeTrace, 

111 
@doStepExplosion, 

112 
@doStepMine, 

113 
@doStepCase, 

114 
@doStepDEagleShot, 

115 
@doStepDynamite, 

116 
@doStepTeamHealthSorter, 

117 
@doStepBomb, 

118 
@doStepCluster, 

119 
@doStepShover, 

120 
@doStepFlame, 

121 
@doStepFirePunch, 

122 
@doStepActionTimer, 

123 
@doStepActionTimer, 

124 
@doStepActionTimer, 

125 
@doStepParachute, 

126 
@doStepAirAttack, 

127 
@doStepAirBomb, 

409  128 
@doStepBlowTorch, 
129 
@doStepGirder 

4  130 
); 
131 

294  132 
procedure InsertGearToList(Gear: PGear); 
133 
var tmp: PGear; 

134 
begin 

135 
if GearsList = nil then 

136 
GearsList:= Gear 

137 
else begin 

138 
// WARNING: this code assumes that the first gears added to the list are clouds (have maximal Z) 

139 
tmp:= GearsList; 

351  140 
while (tmp <> nil) and (tmp^.Z < Gear^.Z) do 
141 
tmp:= tmp^.NextGear; 

294  142 

351  143 
if tmp^.PrevGear <> nil then tmp^.PrevGear^.NextGear:= Gear; 
144 
Gear^.PrevGear:= tmp^.PrevGear; 

145 
tmp^.PrevGear:= Gear; 

146 
Gear^.NextGear:= tmp; 

294  147 
if GearsList = tmp then GearsList:= Gear 
148 
end 

149 
end; 

150 

151 
procedure RemoveGearFromList(Gear: PGear); 

152 
begin 

351  153 
if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear; 
154 
if Gear^.PrevGear <> nil then Gear^.PrevGear^.NextGear:= Gear^.NextGear 

294  155 
else begin 
351  156 
GearsList:= Gear^.NextGear; 
157 
if GearsList <> nil then GearsList^.PrevGear:= nil 

294  158 
end; 
159 
end; 

160 

371  161 
function AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear; 
79  162 
const Counter: Longword = 0; 
351  163 
var Result: PGear; 
4  164 
begin 
79  165 
inc(Counter); 
108  166 
{$IFDEF DEBUGFILE}AddFileLog('AddGear: ('+inttostr(x)+','+inttostr(y)+'), d('+floattostr(dX)+','+floattostr(dY)+')');{$ENDIF} 
4  167 
New(Result); 
357  168 
{$IFDEF DEBUGFILE}AddFileLog('AddGear: type = ' + inttostr(ord(Kind)));{$ENDIF} 
4  169 
FillChar(Result^, sizeof(TGear), 0); 
498  170 
Result^.X:= int2hwFloat(X); 
171 
Result^.Y:= int2hwFloat(Y); 

351  172 
Result^.Kind := Kind; 
173 
Result^.State:= State; 

174 
Result^.Active:= true; 

175 
Result^.dX:= dX; 

176 
Result^.dY:= dY; 

177 
Result^.doStep:= doStepHandlers[Kind]; 

178 
Result^.CollIndex:= High(Longword); 

179 
Result^.Timer:= Timer; 

505
fcba7d7aea0d
Fix old bug with grenade(bomd, etc..) not colliding with attacking hedgehog
unc0rr
parents:
503
diff
changeset

180 

4  181 
if CurrentTeam <> nil then 
505
fcba7d7aea0d
Fix old bug with grenade(bomd, etc..) not colliding with attacking hedgehog
unc0rr
parents:
503
diff
changeset

182 
begin 
351  183 
Result^.Hedgehog:= @(CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]); 
505
fcba7d7aea0d
Fix old bug with grenade(bomd, etc..) not colliding with attacking hedgehog
unc0rr
parents:
503
diff
changeset

184 
Result^.IntersectGear:= CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear 
fcba7d7aea0d
Fix old bug with grenade(bomd, etc..) not colliding with attacking hedgehog
unc0rr
parents:
503
diff
changeset

185 
end; 
fcba7d7aea0d
Fix old bug with grenade(bomd, etc..) not colliding with attacking hedgehog
unc0rr
parents:
503
diff
changeset

186 

4  187 
case Kind of 
351  188 
gtCloud: Result^.Z:= High(Result^.Z); 
4  189 
gtAmmo_Bomb: begin 
351  190 
Result^.Radius:= 4; 
191 
Result^.Elasticity:= _0_6; 

192 
Result^.Friction:= _0_995; 

4  193 
end; 
194 
gtHedgehog: begin 

351  195 
Result^.Radius:= cHHRadius; 
196 
Result^.Elasticity:= _0_35; 

197 
Result^.Friction:= _0_999; 

198 
Result^.Angle:= cMaxAngle div 2; 

199 
Result^.Z:= cHHZ; 

4  200 
end; 
201 
gtAmmo_Grenade: begin 

351  202 
Result^.Radius:= 4; 
4  203 
end; 
204 
gtHealthTag: begin 

351  205 
Result^.Timer:= 1500; 
206 
Result^.Z:= 2000; 

4  207 
end; 
208 
gtGrave: begin 

351  209 
Result^.Radius:= 10; 
210 
Result^.Elasticity:= _0_6; 

4  211 
end; 
212 
gtUFO: begin 

351  213 
Result^.Radius:= 5; 
214 
Result^.Timer:= 500; 

215 
Result^.Elasticity:= _0_9 

4  216 
end; 
217 
gtShotgunShot: begin 

351  218 
Result^.Timer:= 900; 
219 
Result^.Radius:= 2 

4  220 
end; 
221 
gtPickHammer: begin 

351  222 
Result^.Radius:= 10; 
223 
Result^.Timer:= 4000 

4  224 
end; 
225 
gtSmokeTrace: begin 

498  226 
Result^.X:= Result^.X  _16; 
227 
Result^.Y:= Result^.Y  _16; 

351  228 
Result^.State:= 8 
4  229 
end; 
230 
gtRope: begin 

351  231 
Result^.Radius:= 3; 
498  232 
Result^.Friction:= _450; 
4  233 
RopePoints.Count:= 0; 
234 
end; 

9  235 
gtExplosion: begin 
498  236 
Result^.X:= Result^.X  _25; 
237 
Result^.Y:= Result^.Y  _25; 

9  238 
end; 
10  239 
gtMine: begin 
503  240 
Result^.State:= Result^.State or gstMoving; 
351  241 
Result^.Radius:= 3; 
242 
Result^.Elasticity:= _0_55; 

243 
Result^.Friction:= _0_995; 

244 
Result^.Timer:= 3000; 

10  245 
end; 
14
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
10
diff
changeset

246 
gtCase: begin 
351  247 
Result^.Radius:= 16; 
248 
Result^.Elasticity:= _0_4 

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

249 
end; 
37  250 
gtDEagleShot: begin 
351  251 
Result^.Radius:= 1; 
252 
Result^.Health:= 50 

37  253 
end; 
39  254 
gtDynamite: begin 
351  255 
Result^.Radius:= 3; 
256 
Result^.Elasticity:= _0_55; 

257 
Result^.Friction:= _0_03; 

258 
Result^.Timer:= 5000; 

39  259 
end; 
78  260 
gtClusterBomb: begin 
351  261 
Result^.Radius:= 4; 
262 
Result^.Elasticity:= _0_6; 

263 
Result^.Friction:= _0_995; 

78  264 
end; 
79  265 
gtFlame: begin 
351  266 
Result^.Angle:= Counter mod 64; 
267 
Result^.Radius:= 1; 

268 
Result^.Health:= 2; 

269 
Result^.dY:= (getrandom  _0_8) * _0_03; 

270 
Result^.dX:= (getrandom  _0_5) * _0_4 

79  271 
end; 
82  272 
gtFirePunch: begin 
351  273 
Result^.Radius:= 15; 
274 
Result^.Tag:= Y 

82  275 
end; 
302  276 
gtAirBomb: begin 
351  277 
Result^.Radius:= 10; 
302  278 
end; 
279 
gtBlowTorch: begin 

351  280 
Result^.Radius:= cHHRadius; 
281 
Result^.Timer:= 7500; 

302  282 
end; 
4  283 
end; 
351  284 
InsertGearToList(Result); 
285 
AddGear:= Result 

4  286 
end; 
287 

288 
procedure DeleteGear(Gear: PGear); 

48  289 
var team: PTeam; 
307  290 
t: Longword; 
4  291 
begin 
503  292 
DeleteCI(Gear); 
351  293 
if Gear^.Surf <> nil then SDL_FreeSurface(Gear^.Surf); 
294 
if Gear^.Kind = gtHedgehog then 

4  295 
if CurAmmoGear <> nil then 
296 
begin 

351  297 
Gear^.Message:= gm_Destroy; 
298 
CurAmmoGear^.Message:= gm_Destroy; 

4  299 
exit 
47  300 
end else 
301 
begin 

498  302 
if not (hwRound(Gear^.Y) < cWaterLine) then 
307  303 
begin 
351  304 
t:= max(Gear^.Damage, Gear^.Health); 
498  305 
AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtHealthTag, t, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog; 
307  306 
inc(StepDamage, t) 
307 
end; 

351  308 
team:= PHedgehog(Gear^.Hedgehog)^.Team; 
309 
if CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear = Gear then 

145  310 
FreeActionsList; // to avoid ThinkThread on drawned gear 
351  311 
PHedgehog(Gear^.Hedgehog)^.Gear:= nil; 
307  312 
inc(KilledHHs); 
48  313 
RecountTeamHealth(team); 
47  314 
end; 
357  315 
{$IFDEF DEBUGFILE}AddFileLog('DeleteGear');{$ENDIF} 
82  316 
if CurAmmoGear = Gear then CurAmmoGear:= nil; 
4  317 
if FollowGear = Gear then FollowGear:= nil; 
294  318 
RemoveGearFromList(Gear); 
4  319 
Dispose(Gear) 
320 
end; 

321 

322 
function CheckNoDamage: boolean; // returns TRUE in case of no damaged hhs 

323 
var Gear: PGear; 

324 
begin 

351  325 
CheckNoDamage:= true; 
4  326 
Gear:= GearsList; 
327 
while Gear <> nil do 

328 
begin 

351  329 
if Gear^.Kind = gtHedgehog then 
330 
if Gear^.Damage <> 0 then 

4  331 
begin 
351  332 
CheckNoDamage:= false; 
333 
inc(StepDamage, Gear^.Damage); 

334 
if Gear^.Health < Gear^.Damage then Gear^.Health:= 0 

335 
else dec(Gear^.Health, Gear^.Damage); 

336 
AddGear(hwRound(Gear^.X), hwRound(Gear^.Y)  cHHRadius  12  PHedgehog(Gear^.Hedgehog)^.HealthTag^.h, 

498  337 
gtHealthTag, Gear^.Damage, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog; 
351  338 
RenderHealth(PHedgehog(Gear^.Hedgehog)^); 
339 
RecountTeamHealth(PHedgehog(Gear^.Hedgehog)^.Team); 

340 

341 
Gear^.Damage:= 0 

4  342 
end; 
351  343 
Gear:= Gear^.NextGear 
83  344 
end; 
4  345 
end; 
346 

347 
procedure ProcessGears; 

371  348 
const delay: LongInt = cInactDelay; 
92
0c359a7a2356
 Fix win message to appear only after all hedgehogs death
unc0rr
parents:
89
diff
changeset

349 
step: (stDelay, stChDmg, stChWin, stSpawn, stNTurn) = stDelay; 
4  350 
var Gear, t: PGear; 
351 
{$IFDEF COUNTTICKS} 

352 
tickcntA, tickcntB: LongWord; 

353 
const cntSecTicks: LongWord = 0; 

354 
{$ENDIF} 

355 
begin 

356 
{$IFDEF COUNTTICKS} 

357 
asm 

358 
push eax 

359 
push edx 

360 
rdtsc 

361 
mov tickcntA, eax 

362 
mov tickcntB, edx 

363 
pop edx 

364 
pop eax 

365 
end; 

366 
{$ENDIF} 

367 
AllInactive:= true; 

368 
t:= GearsList; 

369 
while t<>nil do 

370 
begin 

371 
Gear:= t; 

351  372 
t:= Gear^.NextGear; 
373 
if Gear^.Active then Gear^.doStep(Gear); 

4  374 
end; 
89  375 

4  376 
if AllInactive then 
15  377 
case step of 
378 
stDelay: begin 

379 
dec(delay); 

380 
if delay = 0 then 

381 
begin 

382 
inc(step); 

383 
delay:= cInactDelay 

384 
end 

385 
end; 

386 
stChDmg: if CheckNoDamage then inc(step) else step:= stDelay; 

351  387 
stChWin: if not CheckForWin then inc(step) else step:= stDelay; 
15  388 
stSpawn: begin 
389 
if not isInMultiShoot then SpawnBoxOfSmth; 

390 
inc(step) 

391 
end; 

392 
stNTurn: begin 

351  393 
//AwareOfExplosion(0, 0, 0); 
15  394 
if isInMultiShoot then isInMultiShoot:= false 
307  395 
else begin 
351  396 
with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do 
307  397 
if MaxStepDamage < StepDamage then MaxStepDamage:= StepDamage; 
398 
StepDamage:= 0; 

351  399 
ParseCommand('/nextturn', true); 
307  400 
end; 
15  401 
step:= Low(step) 
402 
end; 

403 
end; 

404 

4  405 
if TurnTimeLeft > 0 then 
406 
if CurrentTeam <> nil then 

351  407 
if CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil then 
408 
if ((CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear^.State and gstAttacking) = 0) 

4  409 
and not isInMultiShoot then dec(TurnTimeLeft); 
351  410 

4  411 
inc(GameTicks); 
412 
{$IFDEF COUNTTICKS} 

413 
asm 

414 
push eax 

415 
push edx 

416 
rdtsc 

417 
sub eax, [tickcntA] 

418 
sbb edx, [tickcntB] 

419 
add [cntSecTicks], eax 

420 
pop edx 

421 
pop eax 

422 
end; 

423 
if (GameTicks and 1023) = 0 then 

424 
begin 

425 
cntTicks:= cntSecTicks shr 10; 

426 
{$IFDEF DEBUGFILE} 

427 
AddFileLog('<' + inttostr(cntTicks) + '>x1024 ticks'); 

428 
{$ENDIF} 

429 
cntSecTicks:= 0 

430 
end; 

431 
{$ENDIF} 

432 
end; 

433 

434 
procedure SetAllToActive; 

435 
var t: PGear; 

436 
begin 

437 
AllInactive:= false; 

438 
t:= GearsList; 

351  439 
while t <> nil do 
4  440 
begin 
351  441 
t^.Active:= true; 
442 
t:= t^.NextGear 

4  443 
end 
444 
end; 

445 

446 
procedure SetAllHHToActive; 

447 
var t: PGear; 

448 
begin 

449 
AllInactive:= false; 

450 
t:= GearsList; 

351  451 
while t <> nil do 
4  452 
begin 
351  453 
if t^.Kind = gtHedgehog then t^.Active:= true; 
454 
t:= t^.NextGear 

4  455 
end 
456 
end; 

457 

292  458 
procedure DrawHH(Gear: PGear; Surface: PSDL_Surface); 
371  459 
var t: LongInt; 
292  460 
begin 
503  461 
DrawHedgehog(hwRound(Gear^.X)  15 + WorldDx, hwRound(Gear^.Y)  18 + WorldDy, 
351  462 
hwSign(Gear^.dX), 0, 
463 
PHedgehog(Gear^.Hedgehog)^.visStepPos div 2, 

292  464 
Surface); 
465 

351  466 
with PHedgehog(Gear^.Hedgehog)^ do 
467 
if Gear^.State = 0 then 

292  468 
begin 
351  469 
t:= hwRound(Gear^.Y)  cHHRadius  10 + WorldDy; 
470 
dec(t, HealthTag^.h + 2); 

471 
DrawCentered(hwRound(Gear^.X) + WorldDx, t, HealthTag, Surface); 

472 
dec(t, NameTag^.h + 2); 

473 
DrawCentered(hwRound(Gear^.X) + WorldDx, t, NameTag, Surface); 

474 
dec(t, Team^.NameTag^.h + 2); 

475 
DrawCentered(hwRound(Gear^.X) + WorldDx, t, Team^.NameTag, Surface) 

292  476 
end else // Current hedgehog 
477 
begin 

351  478 
if bShowFinger and ((Gear^.State and gstHHDriven) <> 0) then 
479 
DrawSprite(sprFinger, hwRound(Gear^.X)  16 + WorldDx, hwRound(Gear^.Y)  64 + WorldDy, 

292  480 
GameTicks div 32 mod 16, Surface); 
351  481 
if (Gear^.State and (gstMoving or gstDrowning or gstFalling)) = 0 then 
482 
if (Gear^.State and gstHHThinking) <> 0 then 

483 
DrawGear(sQuestion, hwRound(Gear^.X)  10 + WorldDx, hwRound(Gear^.Y)  cHHRadius  34 + WorldDy, Surface) 

292  484 
else 
351  485 
if ShowCrosshair and ((Gear^.State and gstAttacked) = 0) then 
486 
DrawSurfSprite(Round(hwRound(Gear^.X) + hwSign(Gear^.dX) * Sin(Gear^.Angle*pi/cMaxAngle)*60) + WorldDx  11, 

487 
Round(hwRound(Gear^.Y)  Cos(Gear^.Angle*pi/cMaxAngle)*60) + WorldDy  12, 

371  488 
24, (18 + hwSign(Gear^.dX) * LongInt(((Gear^.Angle * 72 div cMaxAngle) + 1) div 2) mod 18) mod 18, 
351  489 
Team^.CrosshairSurf, Surface); 
292  490 
end; 
491 
end; 

492 

4  493 
procedure DrawGears(Surface: PSDL_Surface); 
494 
var Gear: PGear; 

495 
i: Longword; 

371  496 
roplen: LongInt; 
4  497 

371  498 
procedure DrawRopeLine(X1, Y1, X2, Y2: LongInt); 
499 
var eX, eY, dX, dY: LongInt; 

500 
i, sX, sY, x, y, d: LongInt; 

366  501 
b: boolean; 
4  502 
begin 
37  503 
if (X1 = X2) and (Y1 = Y2) then 
504 
begin 

351  505 
OutError('WARNING: zero length rope line!', false); 
37  506 
exit 
507 
end; 

366  508 
eX:= 0; 
509 
eY:= 0; 

510 
dX:= X2  X1; 

511 
dY:= Y2  Y1; 

512 

513 
if (dX > 0) then sX:= 1 

514 
else 

515 
if (dX < 0) then 

516 
begin 

517 
sX:= 1; 

518 
dX:= dX 

519 
end else sX:= dX; 

520 

521 
if (dY > 0) then sY:= 1 

522 
else 

523 
if (dY < 0) then 

4  524 
begin 
366  525 
sY:= 1; 
526 
dY:= dY 

527 
end else sY:= dY; 

528 

529 
if (dX > dY) then d:= dX 

530 
else d:= dY; 

531 

532 
x:= X1; 

533 
y:= Y1; 

534 

535 
for i:= 0 to d do 

536 
begin 

537 
inc(eX, dX); 

538 
inc(eY, dY); 

539 
b:= false; 

540 
if (eX > d) then 

35  541 
begin 
366  542 
dec(eX, d); 
543 
inc(x, sX); 

544 
b:= true 

35  545 
end; 
366  546 
if (eY > d) then 
35  547 
begin 
366  548 
dec(eY, d); 
549 
inc(y, sY); 

550 
b:= true 

35  551 
end; 
366  552 
if b then 
553 
begin 

554 
inc(roplen); 

555 
if (roplen mod 4) = 0 then DrawGear(sRopeNode, x  2, y  2, Surface) 

556 
end 

4  557 
end 
366  558 
end; 
4  559 

560 
begin 

561 
Gear:= GearsList; 

562 
while Gear<>nil do 

563 
begin 

351  564 
case Gear^.Kind of 
565 
gtCloud: DrawSprite(sprCloud , hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.State, Surface); 

566 
gtAmmo_Bomb: DrawSprite(sprBomb , hwRound(Gear^.X)  8 + WorldDx, hwRound(Gear^.Y)  8 + WorldDy, hwRound(Gear^.DirAngle), Surface); 

292  567 
gtHedgehog: DrawHH(Gear, Surface); 
370
c75410fe3133
 Repair bots: they can walk and use bazooka, possible cannot jump (why?)
unc0rr
parents:
366
diff
changeset

568 
gtAmmo_Grenade: DrawSprite(sprGrenade , hwRound(Gear^.X)  16 + WorldDx, hwRound(Gear^.Y)  16 + WorldDy, DxDy2Angle32(Gear^.dY, Gear^.dX), Surface); 
351  569 
gtHealthTag: if Gear^.Surf <> nil then DrawCentered(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.Surf, Surface); 
570 
gtGrave: DrawSpriteFromRect(PHedgehog(Gear^.Hedgehog)^.Team^.GraveRect, hwRound(Gear^.X) + WorldDx  16, hwRound(Gear^.Y) + WorldDy  16, 32, (GameTicks shr 7) and 7, Surface); 

571 
gtUFO: DrawSprite(sprUFO, hwRound(Gear^.X)  16 + WorldDx, hwRound(Gear^.Y)  16 + WorldDy, (GameTicks shr 7) mod 4, Surface); 

572 
gtSmokeTrace: if Gear^.State < 8 then DrawSprite(sprSmokeTrace, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.State, Surface); 

4  573 
gtRope: begin 
35  574 
roplen:= 0; 
4  575 
if RopePoints.Count > 0 then 
576 
begin 

577 
i:= 0; 

578 
while i < Pred(RopePoints.Count) do 

579 
begin 

351  580 
DrawRopeLine(hwRound(RopePoints.ar[i].X) + WorldDx, hwRound(RopePoints.ar[i].Y) + WorldDy, 
581 
hwRound(RopePoints.ar[Succ(i)].X) + WorldDx, hwRound(RopePoints.ar[Succ(i)].Y) + WorldDy); 

4  582 
inc(i) 
583 
end; 

351  584 
DrawRopeLine(hwRound(RopePoints.ar[i].X) + WorldDx, hwRound(RopePoints.ar[i].Y) + WorldDy, 
585 
hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy); 

586 
DrawRopeLine(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 

587 
hwRound(PHedgehog(Gear^.Hedgehog)^.Gear^.X) + WorldDx, hwRound(PHedgehog(Gear^.Hedgehog)^.Gear^.Y) + WorldDy); 

588 
DrawSprite(sprRopeHook, hwRound(RopePoints.ar[0].X) + WorldDx  16, hwRound(RopePoints.ar[0].Y) + WorldDy  16, RopePoints.HookAngle, Surface); 

4  589 
end else 
35  590 
begin 
351  591 
DrawRopeLine(hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, 
592 
hwRound(PHedgehog(Gear^.Hedgehog)^.Gear^.X) + WorldDx, hwRound(PHedgehog(Gear^.Hedgehog)^.Gear^.Y) + WorldDy); 

370
c75410fe3133
 Repair bots: they can walk and use bazooka, possible cannot jump (why?)
unc0rr
parents:
366
diff
changeset

593 
DrawSprite(sprRopeHook, hwRound(Gear^.X)  16 + WorldDx, hwRound(Gear^.Y)  16 + WorldDy, DxDy2Angle32(Gear^.dY, Gear^.dX), Surface); 
35  594 
end; 
4  595 
end; 
351  596 
gtExplosion: DrawSprite(sprExplosion50, hwRound(Gear^.X) + WorldDx, hwRound(Gear^.Y) + WorldDy, Gear^.State, Surface); 
597 
gtMine: if ((Gear^.State and gstAttacking) = 0)or((Gear^.Timer and $3FF) < 420) 

598 
then DrawSprite(sprMineOff , hwRound(Gear^.X)  8 + WorldDx, hwRound(Gear^.Y)  8 + WorldDy, hwRound(Gear^.DirAngle), Surface) 

599 
else DrawSprite(sprMineOn , hwRound(Gear^.X)  8 + WorldDx, hwRound(Gear^.Y)  8 + WorldDy, hwRound(Gear^.DirAngle), Surface); 

600 
gtDynamite: DrawSprite2(sprDynamite, hwRound(Gear^.X)  16 + WorldDx, hwRound(Gear^.Y)  25 + WorldDy, Gear^.Tag and 1, Gear^.Tag shr 1, Surface); 

601 
gtCase: case Gear^.Pos of 

602 
posCaseAmmo : DrawSprite(sprCase, hwRound(Gear^.X)  16 + WorldDx, hwRound(Gear^.Y)  16 + WorldDy, 0, Surface); 

603 
posCaseHealth: DrawSprite(sprFAid, hwRound(Gear^.X)  24 + WorldDx, hwRound(Gear^.Y)  24 + WorldDy, (GameTicks shr 6) mod 13, Surface); 

42  604 
end; 
351  605 
gtClusterBomb: DrawSprite(sprClusterBomb, hwRound(Gear^.X)  8 + WorldDx, hwRound(Gear^.Y)  8 + WorldDy, hwRound(Gear^.DirAngle), Surface); 
606 
gtCluster: DrawSprite(sprClusterParticle, hwRound(Gear^.X)  8 + WorldDx, hwRound(Gear^.Y)  8 + WorldDy, 0, Surface); 

607 
gtFlame: DrawSprite(sprFlame, hwRound(Gear^.X)  8 + WorldDx, hwRound(Gear^.Y)  8 + WorldDy,(GameTicks div 128 + Gear^.Angle) mod 8, Surface); 

370
c75410fe3133
 Repair bots: they can walk and use bazooka, possible cannot jump (why?)
unc0rr
parents:
366
diff
changeset

608 
gtAirBomb: DrawSprite(sprAirBomb , hwRound(Gear^.X)  16 + WorldDx, hwRound(Gear^.Y)  16 + WorldDy, DxDy2Angle32(Gear^.dY, Gear^.dX), Surface); 
408  609 
gtAirAttack: if Gear^.Tag > 0 then DrawSprite(sprAirplane, hwRound(Gear^.X)  60 + WorldDx, hwRound(Gear^.Y)  25 + WorldDy, 0, Surface) 
610 
else DrawSprite(sprAirplane, hwRound(Gear^.X)  60 + WorldDx, hwRound(Gear^.Y)  25 + WorldDy, 1, Surface) 

4  611 
end; 
351  612 
Gear:= Gear^.NextGear 
4  613 
end; 
614 
end; 

615 

616 
procedure FreeGearsList; 

617 
var t, tt: PGear; 

618 
begin 

619 
tt:= GearsList; 

620 
GearsList:= nil; 

621 
while tt<>nil do 

622 
begin 

623 
t:= tt; 

351  624 
tt:= tt^.NextGear; 
4  625 
Dispose(t) 
626 
end; 

627 
end; 

628 

10  629 
procedure AddMiscGears; 
371  630 
var i: LongInt; 
4  631 
begin 
498  632 
AddGear(0, 0, gtATStartGame, 0, _0, _0, 2000); 
22  633 
if (GameFlags and gfForts) = 0 then 
634 
for i:= 0 to 3 do 

498  635 
FindPlace(AddGear(0, 0, gtMine, 0, _0, _0, 0), false, 0, 2048); 
4  636 
end; 
637 

293  638 
procedure AddClouds; 
371  639 
var i: LongInt; 
360  640 
dx, dy: hwFloat; 
293  641 
begin 
642 
for i:= 0 to cCloudsNumber do 

360  643 
begin 
644 
dx.isNegative:= random(2) = 1; 

645 
dx.QWordValue:= random(214748364); 

646 
dy.isNegative:= (i and 1) = 1; 

647 
dy.QWordValue:= 21474836 + random(64424509); 

648 
AddGear(  cScreenWidth + i * ((cScreenWidth * 2 + 2304) div cCloudsNumber), 140, 

649 
gtCloud, random(4), dx, dy, 0) 

650 
end 

293  651 
end; 
652 

371  653 
procedure doMakeExplosion(X, Y, Radius: LongInt; Mask: LongWord); 
4  654 
var Gear: PGear; 
506  655 
dmg, dmgRadius: LongInt; 
4  656 
begin 
657 
TargetPoint.X:= NoPointX; 

658 
{$IFDEF DEBUGFILE}if Radius > 3 then AddFileLog('Explosion: at (' + inttostr(x) + ',' + inttostr(y) + ')');{$ENDIF} 

498  659 
if Radius = 50 then AddGear(X, Y, gtExplosion, 0, _0, _0, 0); 
355  660 
if (Mask and EXPLAutoSound) <> 0 then PlaySound(sndExplosion, false); 
506  661 
if (Mask and EXPLAllDamageInRadius)=0 then dmgRadius:= Radius shl 1 
662 
else dmgRadius:= Radius; 

4  663 
Gear:= GearsList; 
664 
while Gear <> nil do 

665 
begin 

506  666 
dmg:= dmgRadius  hwRound(Distance(Gear^.X  int2hwFloat(X), Gear^.Y  int2hwFloat(Y))); 
4  667 
if dmg > 0 then 
668 
begin 

355  669 
dmg:= dmg div 2; 
351  670 
case Gear^.Kind of 
10  671 
gtHedgehog, 
14
81f125629b25
 Mine checks whether a hedgehog is near less frequently
unc0rr
parents:
10
diff
changeset

672 
gtMine, 
79  673 
gtCase, 
674 
gtFlame: begin 

355  675 
{$IFDEF DEBUGFILE}AddFileLog('Damage: ' + inttostr(dmg));{$ENDIF} 
351  676 
if (Mask and EXPLNoDamage) = 0 then inc(Gear^.Damage, dmg); 
677 
if ((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog) then 

42  678 
begin 
506  679 
DeleteCI(Gear); 
498  680 
Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X  int2hwFloat(X)); 
681 
Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, Gear^.Y  int2hwFloat(Y)); 

503  682 
Gear^.State:= Gear^.State or gstMoving; 
351  683 
Gear^.Active:= true; 
42  684 
FollowGear:= Gear 
685 
end; 

4  686 
end; 
51  687 
gtGrave: begin 
351  688 
Gear^.dY:=  _0_004 * dmg; 
689 
Gear^.Active:= true; 

51  690 
end; 
4  691 
end; 
692 
end; 

351  693 
Gear:= Gear^.NextGear 
80  694 
end; 
506  695 
if (Mask and EXPLDontDraw) = 0 then DrawExplosion(X, Y, Radius); 
498  696 
uAIMisc.AwareOfExplosion(0, 0, 0) 
4  697 
end; 
698 

506  699 
procedure ShotgunShot(Gear: PGear); 
700 
var t: PGear; 

701 
dmg: integer; 

702 
begin 

703 
Gear^.Radius:= 22; 

704 
t:= GearsList; 

705 
while t <> nil do 

706 
begin 

707 
dmg:= min(Gear^.Radius + t^.Radius  hwRound(Distance(Gear^.X  t^.X, Gear^.Y  t^.Y)), 25); 

708 
if dmg >= 0 then 

709 
case t^.Kind of 

710 
gtHedgehog, 

711 
gtMine, 

712 
gtCase: begin 

713 
inc(t^.Damage, dmg); 

714 
DeleteCI(t); 

715 
t^.dX:= t^.dX + SignAs(Gear^.dX * dmg * _0_01 + cHHKick, t^.X  Gear^.X); 

716 
t^.dY:= t^.dY + Gear^.dY * dmg * _0_01; 

717 
t^.State:= t^.State or gstMoving; 

718 
t^.Active:= true; 

719 
FollowGear:= t 

720 
end; 

721 
gtGrave: begin 

722 
t^.dY:=  _0_1; 

723 
t^.Active:= true 

724 
end; 

725 
end; 

726 
t:= t^.NextGear 

727 
end; 

728 
DrawExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 22) 

729 
end; 

730 

371  731 
procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); 
53  732 
var t: PGearArray; 
371  733 
i: LongInt; 
307  734 
hh: PHedgehog; 
38  735 
begin 
53  736 
t:= CheckGearsCollision(Ammo); 
351  737 
i:= t^.Count; 
738 
hh:= Ammo^.Hedgehog; 

53  739 
while i > 0 do 
740 
begin 

741 
dec(i); 

351  742 
if (t^.ar[i]^.State and gstNoDamage) = 0 then 
743 
case t^.ar[i]^.Kind of 

53  744 
gtHedgehog, 
745 
gtMine, 

746 
gtCase: begin 

351  747 
inc(t^.ar[i]^.Damage, Damage); 
748 
inc(hh^.DamageGiven, Damage); 

749 
t^.ar[i]^.dX:= Ammo^.dX * Power * _0_01; 

750 
t^.ar[i]^.dY:= Ammo^.dY * Power * _0_01; 

751 
t^.ar[i]^.Active:= true; 

503  752 
t^.ar[i]^.State:= t^.ar[i]^.State or gstMoving; 
351  753 
DeleteCI(t^.ar[i]); 
754 
FollowGear:= t^.ar[i] 

53  755 
end; 
756 
end 

126  757 
end; 
758 
SetAllToActive 

38  759 
end; 
760 

4  761 
procedure AssignHHCoords; 
82  762 
var Team: PTeam; 
371  763 
i, t: LongInt; 
4  764 
begin 
82  765 
Team:= TeamsList; 
766 
t:= 0; 

767 
while Team <> nil do 

4  768 
begin 
82  769 
for i:= 0 to cMaxHHIndex do 
351  770 
with Team^.Hedgehogs[i] do 
82  771 
if Gear <> nil then 
772 
if (GameFlags and gfForts) = 0 then FindPlace(Gear, false, 0, 2048) 

773 
else FindPlace(Gear, false, t, t + 1024); 

774 
inc(t, 1024); 

351  775 
Team:= Team^.Next 
4  776 
end 
777 
end; 

778 

371  779 
function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear; 
10  780 
var t: PGear; 
781 
begin 

782 
t:= GearsList; 

783 
rX:= sqr(rX); 

784 
rY:= sqr(rY); 

785 
while t <> nil do 

786 
begin 

351  787 
if (t <> Gear) and (t^.Kind = Kind) then 
498  788 
if not((hwSqr(Gear^.X  t^.X) / rX + hwSqr(Gear^.Y  t^.Y) / rY) > _1) then 
351  789 
exit(t); 
790 
t:= t^.NextGear 

10  791 
end; 
351  792 
CheckGearNear:= nil 
15  793 
end; 
794 

79  795 
procedure AmmoFlameWork(Ammo: PGear); 
796 
var t: PGear; 

797 
begin 

798 
t:= GearsList; 

799 
while t <> nil do 

800 
begin 

351  801 
if (t^.Kind = gtHedgehog) and (t^.Y < Ammo^.Y) then 
498  802 
if not (hwSqr(Ammo^.X  t^.X) + hwSqr(Ammo^.Y  t^.Y  int2hwFloat(cHHRadius)) * 2 > _2) then 
79  803 
begin 
351  804 
inc(t^.Damage, 5); 
805 
t^.dX:= t^.dX + (t^.X  Ammo^.X) * _0_02; 

806 
t^.dY:=  _0_25; 

807 
t^.Active:= true; 

79  808 
DeleteCI(t); 
809 
FollowGear:= t 

810 
end; 

351  811 
t:= t^.NextGear 
79  812 
end; 
813 
end; 

814 

371  815 
function CheckGearsNear(mX, mY: LongInt; Kind: TGearsType; rX, rY: LongInt): PGear; 
16  816 
var t: PGear; 
817 
begin 

818 
t:= GearsList; 

819 
rX:= sqr(rX); 

820 
rY:= sqr(rY); 

821 
while t <> nil do 

822 
begin 

351  823 
if t^.Kind in Kind then 
498  824 
if not (hwSqr(int2hwFloat(mX)  t^.X) / rX + hwSqr(int2hwFloat(mY)  t^.Y) / rY > _1) then 
351  825 
exit(t); 
826 
t:= t^.NextGear 

16  827 
end; 
351  828 
CheckGearsNear:= nil 
16  829 
end; 
830 

831 
function CountGears(Kind: TGearType): Longword; 

832 
var t: PGear; 

351  833 
Result: Longword; 
16  834 
begin 
835 
Result:= 0; 

836 
t:= GearsList; 

837 
while t <> nil do 

838 
begin 

351  839 
if t^.Kind = Kind then inc(Result); 
840 
t:= t^.NextGear 

16  841 
end; 
351  842 
CountGears:= Result 
16  843 
end; 
844 

15  845 
procedure SpawnBoxOfSmth; 
394
4c017ae1226a
 Implement hack to let ammo stores work without needed assistance of frontend
unc0rr
parents:
393
diff
changeset

846 
var t: LongInt; 
4c017ae1226a
 Implement hack to let ammo stores work without needed assistance of frontend
unc0rr
parents:
393
diff
changeset

847 
i: TAmmoType; 
15  848 
begin 
295  849 
if (CountGears(gtCase) >= 5) or (getrandom(cCaseFactor) <> 0) then exit; 
498  850 
FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0); 
295  851 
case getrandom(2) of 
852 
0: begin 

351  853 
FollowGear^.Health:= 25; 
854 
FollowGear^.Pos:= posCaseHealth 

295  855 
end; 
856 
1: begin 

394
4c017ae1226a
 Implement hack to let ammo stores work without needed assistance of frontend
unc0rr
parents:
393
diff
changeset

857 
t:= 0; 
4c017ae1226a
 Implement hack to let ammo stores work without needed assistance of frontend
unc0rr
parents:
393
diff
changeset

858 
for i:= Low(TAmmoType) to High(TAmmoType) do 
4c017ae1226a
 Implement hack to let ammo stores work without needed assistance of frontend
unc0rr
parents:
393
diff
changeset

859 
inc(t, Ammoz[i].Probability); 
4c017ae1226a
 Implement hack to let ammo stores work without needed assistance of frontend
unc0rr
parents:
393
diff
changeset

860 
t:= GetRandom(t); 
4c017ae1226a
 Implement hack to let ammo stores work without needed assistance of frontend
unc0rr
parents:
393
diff
changeset

861 
i:= Low(TAmmoType); 
4c017ae1226a
 Implement hack to let ammo stores work without needed assistance of frontend
unc0rr
parents:
393
diff
changeset

862 
dec(t, Ammoz[i].Probability); 
4c017ae1226a
 Implement hack to let ammo stores work without needed assistance of frontend
unc0rr
parents:
393
diff
changeset

863 
while t >= 0 do 
4c017ae1226a
 Implement hack to let ammo stores work without needed assistance of frontend
unc0rr
parents:
393
diff
changeset

864 
begin 
4c017ae1226a
 Implement hack to let ammo stores work without needed assistance of frontend
unc0rr
parents:
393
diff
changeset

865 
inc(i); 
4c017ae1226a
 Implement hack to let ammo stores work without needed assistance of frontend
unc0rr
parents:
393
diff
changeset

866 
dec(t, Ammoz[i].Probability) 
4c017ae1226a
 Implement hack to let ammo stores work without needed assistance of frontend
unc0rr
parents:
393
diff
changeset

867 
end; 
351  868 
FollowGear^.Pos:= posCaseAmmo; 
394
4c017ae1226a
 Implement hack to let ammo stores work without needed assistance of frontend
unc0rr
parents:
393
diff
changeset

869 
FollowGear^.State:= Longword(i) 
295  870 
end; 
871 
end; 

70  872 
FindPlace(FollowGear, true, 0, 2048) 
873 
end; 

874 

371  875 
procedure FindPlace(Gear: PGear; withFall: boolean; Left, Right: LongInt); 
70  876 

371  877 
function CountNonZeroz(x, y, r: LongInt): LongInt; 
878 
var i: LongInt; 

879 
Result: LongInt; 

70  880 
begin 
881 
Result:= 0; 

882 
if (y and $FFFFFC00) <> 0 then exit; 

883 
for i:= max(x  r, 0) to min(x + r, 2043) do 

351  884 
if Land[y, i] <> 0 then inc(Result); 
885 
CountNonZeroz:= Result 

70  886 
end; 
887 

495  888 
var x: LongInt; 
371  889 
y, sy: LongInt; 
386  890 
ar: array[0..511] of TPoint; 
891 
ar2: array[0..1023] of TPoint; 

392  892 
cnt, cnt2: Longword; 
893 
delta: LongInt; 

70  894 
begin 
386  895 
delta:= 250; 
896 
cnt2:= 0; 

16  897 
repeat 
392  898 
x:= Left + LongInt(GetRandom(Delta)); 
70  899 
repeat 
386  900 
inc(x, Delta); 
70  901 
cnt:= 0; 
351  902 
y:= Gear^.Radius * 2; 
70  903 
while y < 1023 do 
16  904 
begin 
70  905 
repeat 
906 
inc(y, 2); 

351  907 
until (y > 1023) or (CountNonZeroz(x, y, Gear^.Radius  1) = 0); 
70  908 
sy:= y; 
909 
repeat 

910 
inc(y); 

351  911 
until (y > 1023) or (CountNonZeroz(x, y, Gear^.Radius  1) <> 0); 
912 
if (y  sy > Gear^.Radius * 2) 

70  913 
and (y < 1023) 
351  914 
and (CheckGearsNear(x, y  Gear^.Radius, [gtHedgehog, gtMine, gtCase], 110, 110) = nil) then 
70  915 
begin 
916 
ar[cnt].X:= x; 

351  917 
if withFall then ar[cnt].Y:= sy + Gear^.Radius 
918 
else ar[cnt].Y:= y  Gear^.Radius; 

70  919 
inc(cnt) 
920 
end; 

386  921 
inc(y, 45) 
16  922 
end; 
70  923 
if cnt > 0 then 
924 
with ar[GetRandom(cnt)] do 

925 
begin 

386  926 
ar2[cnt2].x:= x; 
927 
ar2[cnt2].y:= y; 

928 
inc(cnt2) 

70  929 
end 
386  930 
until (x + Delta > Right); 
931 
dec(Delta, 60) 

932 
until (cnt2 > 0) or (Delta < 70); 

933 
if cnt2 > 0 then 

934 
with ar2[GetRandom(cnt2)] do 

935 
begin 

498  936 
Gear^.X:= int2hwFloat(x); 
937 
Gear^.Y:= int2hwFloat(y); 

386  938 
{$IFDEF DEBUGFILE} 
939 
AddFileLog('Assigned Gear coordinates (' + inttostr(x) + ',' + inttostr(y) + ')'); 

940 
{$ENDIF} 

941 
end 

942 
else 

943 
begin 

944 
OutError('Can''t find place for Gear', false); 

945 
DeleteGear(Gear) 

946 
end 

10  947 
end; 
948 

4  949 
initialization 
950 

951 
finalization 

95  952 
FreeGearsList; 
4  953 

954 
end. 