55 procedure doStepDrowningGear(Gear: PGear); |
55 procedure doStepDrowningGear(Gear: PGear); |
56 |
56 |
57 |
57 |
58 implementation |
58 implementation |
59 uses uStore, uSound, uTeams, uRandom, uCollisions, uIO, uLandGraphics, |
59 uses uStore, uSound, uTeams, uRandom, uCollisions, uIO, uLandGraphics, |
60 uAIMisc, uLocale, uAI, uAmmos, uStats, uVisualGears, uScript, GLunit, uMobile, uVariables, |
60 uAIMisc, uLocale, uAI, uAmmos, uStats, uVisualGears, uScript, GLunit, uMobile, uVariables, |
61 uCommands, uUtils, uTextures, uRenderUtils, uGearsRender, uCaptions, uDebug, uLandTexture, |
61 uCommands, uUtils, uTextures, uRenderUtils, uGearsRender, uCaptions, uDebug, uLandTexture, |
62 uGearsHedgehog, uGearsUtils, uGearsList; |
62 uGearsHedgehog, uGearsUtils, uGearsList; |
63 |
63 |
64 |
64 |
65 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); forward; |
65 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); forward; |
66 //procedure AmmoFlameWork(Ammo: PGear); forward; |
66 //procedure AmmoFlameWork(Ammo: PGear); forward; |
67 function GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): TPGearArray; forward; |
67 function GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): TPGearArray; forward; |
98 Gear^.Health:= 0 |
99 Gear^.Health:= 0 |
99 end |
100 end |
100 else |
101 else |
101 dec(Gear^.Health, dmg); |
102 dec(Gear^.Health, dmg); |
102 |
103 |
103 if (Gear^.Hedgehog^.Team = CurrentTeam) and |
104 if (Gear^.Hedgehog^.Team = CurrentTeam) and (Gear^.Damage <> Gear^.Karma) |
104 (Gear^.Damage <> Gear^.Karma) and |
105 and (not Gear^.Hedgehog^.King) and (not Gear^.Hedgehog^.Effects[hePoisoned]) and (not SuddenDeathDmg) then |
105 (not Gear^.Hedgehog^.King) and |
|
106 (not Gear^.Hedgehog^.Effects[hePoisoned]) and |
|
107 (not SuddenDeathDmg) then |
|
108 Gear^.State:= Gear^.State or gstLoser; |
106 Gear^.State:= Gear^.State or gstLoser; |
109 |
107 |
110 spawnHealthTagForHH(Gear, dmg); |
108 spawnHealthTagForHH(Gear, dmg); |
111 |
109 |
112 RenderHealth(Gear^.Hedgehog^); |
110 RenderHealth(Gear^.Hedgehog^); |
113 RecountTeamHealth(Gear^.Hedgehog^.Team); |
111 RecountTeamHealth(Gear^.Hedgehog^.Team); |
114 |
112 |
115 end; |
113 end; |
116 if (not isInMultiShoot) then Gear^.Karma:= 0; |
114 if (not isInMultiShoot) then |
|
115 Gear^.Karma:= 0; |
117 Gear^.Damage:= 0 |
116 Gear^.Damage:= 0 |
118 end; |
117 end; |
119 Gear:= Gear^.NextGear |
118 Gear:= Gear^.NextGear |
120 end; |
119 end; |
121 end; |
120 end; |
122 |
121 |
123 procedure HealthMachine; |
122 procedure HealthMachine; |
124 var Gear: PGear; |
123 var Gear: PGear; |
125 team: PTeam; |
124 team: PTeam; |
126 i: LongWord; |
125 i: LongWord; |
127 flag: Boolean; |
126 flag: Boolean; |
128 tmp: LongWord; |
127 tmp: LongWord; |
129 begin |
128 begin |
130 Gear:= GearsList; |
129 Gear:= GearsList; |
131 |
130 |
132 while Gear <> nil do |
131 while Gear <> nil do |
133 begin |
132 begin |
135 begin |
134 begin |
136 tmp:= 0; |
135 tmp:= 0; |
137 if Gear^.Hedgehog^.Effects[hePoisoned] then |
136 if Gear^.Hedgehog^.Effects[hePoisoned] then |
138 begin |
137 begin |
139 inc(tmp, ModifyDamage(5, Gear)); |
138 inc(tmp, ModifyDamage(5, Gear)); |
140 if (GameFlags and gfResetHealth) <> 0 then dec(Gear^.Hedgehog^.InitialHealth) // does not need a minimum check since <= 1 basically disables it |
139 if (GameFlags and gfResetHealth) <> 0 then |
|
140 dec(Gear^.Hedgehog^.InitialHealth) // does not need a minimum check since <= 1 basically disables it |
141 end; |
141 end; |
142 if (TotalRounds > cSuddenDTurns - 1) then |
142 if (TotalRounds > cSuddenDTurns - 1) then |
143 begin |
143 begin |
144 inc(tmp, cHealthDecrease); |
144 inc(tmp, cHealthDecrease); |
145 if (GameFlags and gfResetHealth) <> 0 then dec(Gear^.Hedgehog^.InitialHealth, cHealthDecrease) |
145 if (GameFlags and gfResetHealth) <> 0 then |
|
146 dec(Gear^.Hedgehog^.InitialHealth, cHealthDecrease) |
146 end; |
147 end; |
147 if Gear^.Hedgehog^.King then |
148 if Gear^.Hedgehog^.King then |
148 begin |
149 begin |
149 flag:= false; |
150 flag:= false; |
150 team:= Gear^.Hedgehog^.Team; |
151 team:= Gear^.Hedgehog^.Team; |
151 for i:= 0 to Pred(team^.HedgehogsNumber) do |
152 for i:= 0 to Pred(team^.HedgehogsNumber) do |
152 if (team^.Hedgehogs[i].Gear <> nil) and |
153 if (team^.Hedgehogs[i].Gear <> nil) and (not team^.Hedgehogs[i].King) |
153 (not team^.Hedgehogs[i].King) and |
154 and (team^.Hedgehogs[i].Gear^.Health > team^.Hedgehogs[i].Gear^.Damage) then |
154 (team^.Hedgehogs[i].Gear^.Health > team^.Hedgehogs[i].Gear^.Damage) |
155 flag:= true; |
155 then flag:= true; |
|
156 if not flag then |
156 if not flag then |
157 begin |
157 begin |
158 inc(tmp, 5); |
158 inc(tmp, 5); |
159 if (GameFlags and gfResetHealth) <> 0 then dec(Gear^.Hedgehog^.InitialHealth, 5) |
159 if (GameFlags and gfResetHealth) <> 0 then |
|
160 dec(Gear^.Hedgehog^.InitialHealth, 5) |
160 end |
161 end |
161 end; |
162 end; |
162 if tmp > 0 then |
163 if tmp > 0 then |
163 begin |
164 begin |
164 inc(Gear^.Damage, min(tmp, max(0,Gear^.Health - 1 - Gear^.Damage))); |
165 inc(Gear^.Damage, min(tmp, max(0,Gear^.Health - 1 - Gear^.Damage))); |
170 end; |
171 end; |
171 end; |
172 end; |
172 |
173 |
173 procedure ProcessGears; |
174 procedure ProcessGears; |
174 const delay: LongWord = 0; |
175 const delay: LongWord = 0; |
175 delay2: LongWord = 0; |
176 delay2: LongWord = 0; |
176 step: (stDelay, stChDmg, stSweep, stTurnReact, |
177 step: (stDelay, stChDmg, stSweep, stTurnReact, |
177 stAfterDelay, stChWin, stWater, stChWin2, stHealth, |
178 stAfterDelay, stChWin, stWater, stChWin2, stHealth, |
178 stSpawn, stNTurn) = stDelay; |
179 stSpawn, stNTurn) = stDelay; |
179 var Gear, t: PGear; |
180 var Gear, t: PGear; |
180 i, AliveCount: LongInt; |
181 i, AliveCount: LongInt; |
181 s: shortstring; |
182 s: shortstring; |
182 begin |
183 begin |
183 PrvInactive:= AllInactive; |
184 PrvInactive:= AllInactive; |
213 end |
214 end |
214 end; |
215 end; |
215 |
216 |
216 if AllInactive then |
217 if AllInactive then |
217 case step of |
218 case step of |
218 stDelay: begin |
219 stDelay: |
|
220 begin |
219 if delay = 0 then |
221 if delay = 0 then |
220 delay:= cInactDelay |
222 delay:= cInactDelay |
221 else |
223 else |
222 dec(delay); |
224 dec(delay); |
223 |
225 |
224 if delay = 0 then |
226 if delay = 0 then |
225 inc(step) |
227 inc(step) |
226 end; |
228 end; |
227 stChDmg: if CheckNoDamage then inc(step) else step:= stDelay; |
229 |
228 stSweep: if SweepDirty then |
230 stChDmg: |
229 begin |
231 if CheckNoDamage then |
230 SetAllToActive; |
232 inc(step) |
231 step:= stChDmg |
233 else |
232 end else inc(step); |
234 step:= stDelay; |
233 stTurnReact: begin |
235 |
|
236 stSweep: |
|
237 if SweepDirty then |
|
238 begin |
|
239 SetAllToActive; |
|
240 step:= stChDmg |
|
241 end |
|
242 else |
|
243 inc(step); |
|
244 |
|
245 stTurnReact: |
|
246 begin |
234 if (not bBetweenTurns) and (not isInMultiShoot) then |
247 if (not bBetweenTurns) and (not isInMultiShoot) then |
235 begin |
248 begin |
236 uStats.TurnReaction; |
249 uStats.TurnReaction; |
237 inc(step) |
250 inc(step) |
238 end else |
251 end |
|
252 else |
239 inc(step, 2); |
253 inc(step, 2); |
240 end; |
254 end; |
241 stAfterDelay: begin |
255 |
|
256 stAfterDelay: |
|
257 begin |
242 if delay = 0 then |
258 if delay = 0 then |
243 delay:= cInactDelay |
259 delay:= cInactDelay |
244 else |
260 else |
245 dec(delay); |
261 dec(delay); |
246 |
262 |
247 if delay = 0 then |
263 if delay = 0 then |
|
264 inc(step) |
|
265 end; |
|
266 stChWin: |
|
267 begin |
|
268 CheckForWin; |
248 inc(step) |
269 inc(step) |
249 end; |
270 end; |
250 stChWin: begin |
271 stWater: |
251 CheckForWin; |
272 if (not bBetweenTurns) and (not isInMultiShoot) then |
252 inc(step) |
273 begin |
253 end; |
274 if TotalRounds = cSuddenDTurns + 1 then |
254 stWater: if (not bBetweenTurns) and (not isInMultiShoot) then |
275 bWaterRising:= true; |
255 begin |
276 if bWaterRising and (cWaterRise > 0) then |
256 if TotalRounds = cSuddenDTurns + 1 then bWaterRising:= true; |
277 AddGear(0, 0, gtWaterUp, 0, _0, _0, 0)^.Tag:= cWaterRise; |
257 |
278 inc(step) |
258 if bWaterRising and (cWaterRise > 0) then |
279 end |
259 AddGear(0, 0, gtWaterUp, 0, _0, _0, 0)^.Tag:= cWaterRise; |
280 else |
260 |
281 inc(step); |
261 inc(step) |
282 stChWin2: |
262 end else inc(step); |
283 begin |
263 stChWin2: begin |
284 CheckForWin; |
264 CheckForWin; |
285 inc(step) |
265 inc(step) |
286 end; |
266 end; |
287 |
267 stHealth: begin |
288 stHealth: |
268 if (cWaterRise <> 0) or (cHealthDecrease <> 0) then |
289 begin |
269 begin |
290 if (cWaterRise <> 0) or (cHealthDecrease <> 0) then |
270 if (TotalRounds = cSuddenDTurns) and (not SuddenDeath) and (not isInMultiShoot) then |
291 begin |
|
292 if (TotalRounds = cSuddenDTurns) and (not SuddenDeath) and (not isInMultiShoot) then |
|
293 begin |
|
294 SuddenDeath:= true; |
|
295 if cHealthDecrease <> 0 then |
271 begin |
296 begin |
272 SuddenDeath:= true; |
297 SuddenDeathDmg:= true; |
273 if cHealthDecrease <> 0 then |
|
274 begin |
|
275 SuddenDeathDmg:= true; |
|
276 |
298 |
277 // flash |
299 // flash |
278 ScreenFade:= sfFromWhite; |
300 ScreenFade:= sfFromWhite; |
279 ScreenFadeValue:= sfMax; |
301 ScreenFadeValue:= sfMax; |
280 ScreenFadeSpeed:= 1; |
302 ScreenFadeSpeed:= 1; |
281 |
303 |
282 ChangeToSDClouds; |
304 ChangeToSDClouds; |
283 ChangeToSDFlakes; |
305 ChangeToSDFlakes; |
284 glClearColor(SDSkyColor.r * (SDTint/255) / 255, SDSkyColor.g * (SDTint/255) / 255, SDSkyColor.b * (SDTint/255) / 255, 0.99); |
306 glClearColor(SDSkyColor.r * (SDTint/255) / 255, SDSkyColor.g * (SDTint/255) / 255, SDSkyColor.b * (SDTint/255) / 255, 0.99); |
285 Ammoz[amTardis].SkipTurns:= 9999; |
307 Ammoz[amTardis].SkipTurns:= 9999; |
286 Ammoz[amTardis].Probability:= 0; |
308 Ammoz[amTardis].Probability:= 0; |
287 end; |
309 end; |
288 AddCaption(trmsg[sidSuddenDeath], cWhiteColor, capgrpGameState); |
310 AddCaption(trmsg[sidSuddenDeath], cWhiteColor, capgrpGameState); |
289 playSound(sndSuddenDeath); |
311 playSound(sndSuddenDeath); |
290 StopMusic //No SDMusic for now |
312 StopMusic //No SDMusic for now |
291 //MusicFN:= SDMusic; |
313 //MusicFN:= SDMusic; |
292 //ChangeMusic |
314 //ChangeMusic |
293 end |
315 end |
294 else if (TotalRounds < cSuddenDTurns) and (not isInMultiShoot) then |
316 else if (TotalRounds < cSuddenDTurns) and (not isInMultiShoot) then |
295 begin |
317 begin |
300 else if (i = 2) or ((i > 0) and ((i mod 50 = 0) or ((i <= 25) and (i mod 5 = 0)))) then |
322 else if (i = 2) or ((i > 0) and ((i mod 50 = 0) or ((i <= 25) and (i mod 5 = 0)))) then |
301 AddCaption(Format(trmsg[sidRoundsSD], s), cWhiteColor, capgrpGameState); |
323 AddCaption(Format(trmsg[sidRoundsSD], s), cWhiteColor, capgrpGameState); |
302 end; |
324 end; |
303 end; |
325 end; |
304 if bBetweenTurns |
326 if bBetweenTurns |
305 or isInMultiShoot |
327 or isInMultiShoot |
306 or (TotalRounds = -1) then inc(step) |
328 or (TotalRounds = -1) then |
307 else begin |
329 inc(step) |
|
330 else |
|
331 begin |
308 bBetweenTurns:= true; |
332 bBetweenTurns:= true; |
309 HealthMachine; |
333 HealthMachine; |
310 step:= stChDmg |
334 step:= stChDmg |
311 end |
335 end |
312 end; |
336 end; |
313 stSpawn: begin |
337 stSpawn: |
314 if not isInMultiShoot then SpawnBoxOfSmth; |
338 begin |
315 inc(step) |
339 if not isInMultiShoot then |
316 end; |
340 SpawnBoxOfSmth; |
317 stNTurn: begin |
341 inc(step) |
318 if isInMultiShoot then |
342 end; |
319 isInMultiShoot:= false |
343 stNTurn: |
320 else begin |
344 begin |
321 // delayed till after 0.9.12 |
345 if isInMultiShoot then |
322 // reset to default zoom |
346 isInMultiShoot:= false |
323 //ZoomValue:= ZoomDefault; |
347 else |
324 with CurrentHedgehog^ do |
348 begin |
325 if (Gear <> nil) |
349 // delayed till after 0.9.12 |
326 and ((Gear^.State and gstAttacked) = 0) |
350 // reset to default zoom |
327 and (MultiShootAttacks > 0) then OnUsedAmmo(CurrentHedgehog^); |
351 //ZoomValue:= ZoomDefault; |
|
352 with CurrentHedgehog^ do |
|
353 if (Gear <> nil) |
|
354 and ((Gear^.State and gstAttacked) = 0) |
|
355 and (MultiShootAttacks > 0) then |
|
356 OnUsedAmmo(CurrentHedgehog^); |
328 |
357 |
329 EndTurnCleanup; |
358 EndTurnCleanup; |
330 |
359 |
331 FreeActionsList; // could send -left, -right and similar commands, so should be called before /nextturn |
360 FreeActionsList; // could send -left, -right and similar commands, so should be called before /nextturn |
332 |
361 |
345 delay2:= cInactDelay * 50 |
374 delay2:= cInactDelay * 50 |
346 else |
375 else |
347 begin |
376 begin |
348 dec(delay2); |
377 dec(delay2); |
349 |
378 |
350 if ((delay2 mod cInactDelay) = 0) and (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and (not CurrentHedgehog^.Unplaced) then |
379 if ((delay2 mod cInactDelay) = 0) and (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) |
351 begin |
380 and (not CurrentHedgehog^.Unplaced) then |
352 if (CurrentHedgehog^.Gear^.State and gstAttacked <> 0) and (Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0) then |
381 begin |
|
382 if (CurrentHedgehog^.Gear^.State and gstAttacked <> 0) |
|
383 and (Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0) then |
353 begin |
384 begin |
354 CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstHHChooseTarget; |
385 CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstHHChooseTarget; |
355 isCursorVisible := true |
386 isCursorVisible := true |
356 end; |
387 end; |
357 CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State and (not gstAttacked); |
388 CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State and (not gstAttacked); |
358 end; |
389 end; |
359 if delay2 = 0 then |
390 if delay2 = 0 then |
360 begin |
391 begin |
361 if (CurrentHedgehog^.Gear <> nil) and (CurrentHedgehog^.Gear^.State and gstAttacked = 0) and (CurAmmoGear = nil) then SweepDirty; |
392 if (CurrentHedgehog^.Gear <> nil) and (CurrentHedgehog^.Gear^.State and gstAttacked = 0) |
|
393 and (CurAmmoGear = nil) then |
|
394 SweepDirty; |
362 CheckNoDamage; |
395 CheckNoDamage; |
363 AliveCount:= 0; // shorter version of check for win to allow typical step activity to proceed |
396 AliveCount:= 0; // shorter version of check for win to allow typical step activity to proceed |
364 for i:= 0 to Pred(ClansCount) do |
397 for i:= 0 to Pred(ClansCount) do |
365 if ClansArray[i]^.ClanHealth > 0 then inc(AliveCount); |
398 if ClansArray[i]^.ClanHealth > 0 then |
|
399 inc(AliveCount); |
366 if (AliveCount <= 1) and ((GameFlags and gfOneClanMode) = 0) then |
400 if (AliveCount <= 1) and ((GameFlags and gfOneClanMode) = 0) then |
367 begin |
401 begin |
368 step:= stChDmg; |
402 step:= stChDmg; |
369 if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft; |
403 if TagTurnTimeLeft = 0 then |
|
404 TagTurnTimeLeft:= TurnTimeLeft; |
370 TurnTimeLeft:= 0 |
405 TurnTimeLeft:= 0 |
371 end |
406 end |
372 end |
407 end |
373 end |
408 end |
374 end; |
409 end; |
375 |
410 |
376 if TurnTimeLeft > 0 then |
411 if TurnTimeLeft > 0 then |
377 if CurrentHedgehog^.Gear <> nil then |
412 if CurrentHedgehog^.Gear <> nil then |
378 if ((CurrentHedgehog^.Gear^.State and gstAttacking) = 0) |
413 if ((CurrentHedgehog^.Gear^.State and gstAttacking) = 0) |
379 and (not isInMultiShoot) then |
414 and (not isInMultiShoot) then |
380 begin |
415 begin |
381 if (TurnTimeLeft = 5000) |
416 if (TurnTimeLeft = 5000) |
382 and (cHedgehogTurnTime >= 10000) |
417 and (cHedgehogTurnTime >= 10000) |
383 and (not PlacingHogs) |
418 and (not PlacingHogs) |
384 and (CurrentHedgehog^.Gear <> nil) |
419 and (CurrentHedgehog^.Gear <> nil) |
385 and ((CurrentHedgehog^.Gear^.State and gstAttacked) = 0) then |
420 and ((CurrentHedgehog^.Gear^.State and gstAttacked) = 0) then |
386 AddVoice(sndHurry, CurrentTeam^.voicepack); |
421 AddVoice(sndHurry, CurrentTeam^.voicepack); |
387 if ReadyTimeLeft > 0 then |
422 if ReadyTimeLeft > 0 then |
388 begin |
423 begin |
389 if ReadyTimeLeft = 2000 then |
424 if ReadyTimeLeft = 2000 then |
390 AddVoice(sndComeonthen, CurrentTeam^.voicepack); |
425 AddVoice(sndComeonthen, CurrentTeam^.voicepack); |
391 dec(ReadyTimeLeft) |
426 dec(ReadyTimeLeft) |
392 end |
427 end |
393 else |
428 else |
394 dec(TurnTimeLeft) |
429 dec(TurnTimeLeft) |
395 end; |
430 end; |
396 |
431 |
397 if skipFlag then |
432 if skipFlag then |
398 begin |
433 begin |
399 if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft; |
434 if TagTurnTimeLeft = 0 then |
|
435 TagTurnTimeLeft:= TurnTimeLeft; |
400 TurnTimeLeft:= 0; |
436 TurnTimeLeft:= 0; |
401 skipFlag:= false; |
437 skipFlag:= false; |
402 inc(CurrentHedgehog^.Team^.stats.TurnSkips); |
438 inc(CurrentHedgehog^.Team^.stats.TurnSkips); |
403 end; |
439 end; |
404 |
440 |
653 end |
690 end |
654 end; |
691 end; |
655 end; |
692 end; |
656 t:= t^.NextGear |
693 t:= t^.NextGear |
657 end; |
694 end; |
658 if (GameFlags and gfSolidLand) = 0 then DrawExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), cShotgunRadius) |
695 if (GameFlags and gfSolidLand) = 0 then |
|
696 DrawExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), cShotgunRadius) |
659 end; |
697 end; |
660 |
698 |
661 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); |
699 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); |
662 var t: PGearArray; |
700 var t: PGearArray; |
663 Gear: PGear; |
701 Gear: PGear; |
664 i, tmpDmg: LongInt; |
702 i, tmpDmg: LongInt; |
665 VGear: PVisualGear; |
703 VGear: PVisualGear; |
666 begin |
704 begin |
667 t:= CheckGearsCollision(Ammo); |
705 t:= CheckGearsCollision(Ammo); |
668 // Just to avoid hogs on rope dodging fire. |
706 // Just to avoid hogs on rope dodging fire. |
669 if (CurAmmoGear <> nil) and ((CurAmmoGear^.Kind = gtRope) or (CurAmmoGear^.Kind = gtJetpack) or (CurAmmoGear^.Kind = gtBirdy)) and |
707 if (CurAmmoGear <> nil) and ((CurAmmoGear^.Kind = gtRope) or (CurAmmoGear^.Kind = gtJetpack) or (CurAmmoGear^.Kind = gtBirdy)) |
670 (CurrentHedgehog^.Gear <> nil) and (CurrentHedgehog^.Gear^.CollisionIndex = -1) and |
708 and (CurrentHedgehog^.Gear <> nil) and (CurrentHedgehog^.Gear^.CollisionIndex = -1) |
671 (sqr(hwRound(Ammo^.X) - hwRound(CurrentHedgehog^.Gear^.X)) + sqr(hwRound(Ammo^.Y) - hwRound(CurrentHedgehog^.Gear^.Y)) <= sqr(cHHRadius + Ammo^.Radius)) then |
709 and (sqr(hwRound(Ammo^.X) - hwRound(CurrentHedgehog^.Gear^.X)) + sqr(hwRound(Ammo^.Y) - hwRound(CurrentHedgehog^.Gear^.Y)) <= sqr(cHHRadius + Ammo^.Radius)) then |
672 begin |
710 begin |
673 t^.ar[t^.Count]:= CurrentHedgehog^.Gear; |
711 t^.ar[t^.Count]:= CurrentHedgehog^.Gear; |
674 inc(t^.Count) |
712 inc(t^.Count) |
675 end; |
713 end; |
676 |
714 |
677 i:= t^.Count; |
715 i:= t^.Count; |
678 |
716 |
679 if (Ammo^.Kind = gtFlame) and (i > 0) then Ammo^.Health:= 0; |
717 if (Ammo^.Kind = gtFlame) and (i > 0) then |
|
718 Ammo^.Health:= 0; |
680 while i > 0 do |
719 while i > 0 do |
681 begin |
720 begin |
682 dec(i); |
721 dec(i); |
683 Gear:= t^.ar[i]; |
722 Gear:= t^.ar[i]; |
684 tmpDmg:= ModifyDamage(Damage, Gear); |
723 tmpDmg:= ModifyDamage(Damage, Gear); |
686 begin |
725 begin |
687 |
726 |
688 if (Ammo^.Kind = gtDEagleShot) or (Ammo^.Kind = gtSniperRifleShot) then |
727 if (Ammo^.Kind = gtDEagleShot) or (Ammo^.Kind = gtSniperRifleShot) then |
689 begin |
728 begin |
690 VGear := AddVisualGear(hwround(Ammo^.X), hwround(Ammo^.Y), vgtBulletHit); |
729 VGear := AddVisualGear(hwround(Ammo^.X), hwround(Ammo^.Y), vgtBulletHit); |
691 if VGear <> nil then VGear^.Angle := DxDy2Angle(-Ammo^.dX, Ammo^.dY); |
730 if VGear <> nil then |
692 end; |
731 VGear^.Angle := DxDy2Angle(-Ammo^.dX, Ammo^.dY); |
693 |
732 end; |
694 if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) and (Ammo^.Kind = gtShover) then Gear^.FlightTime:= 1; |
733 |
|
734 if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) and (Ammo^.Kind = gtShover) then |
|
735 Gear^.FlightTime:= 1; |
695 |
736 |
696 case Gear^.Kind of |
737 case Gear^.Kind of |
697 gtHedgehog, |
738 gtHedgehog, |
698 gtMine, |
739 gtMine, |
699 gtSMine, |
740 gtSMine, |
700 gtTarget, |
741 gtTarget, |
701 gtCase, |
742 gtCase, |
702 gtExplosives, |
743 gtExplosives, |
703 gtStructure: begin |
744 gtStructure: |
704 if (Ammo^.Kind = gtDrill) then begin Ammo^.Timer:= 0; exit; end; |
745 begin |
705 if (not Gear^.Invulnerable) then |
746 if (Ammo^.Kind = gtDrill) then |
706 ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg, dsShove) |
747 begin |
707 else |
748 Ammo^.Timer:= 0; |
708 Gear^.State:= Gear^.State or gstWinner; |
749 exit; |
709 if (Gear^.Kind = gtExplosives) and (Ammo^.Kind = gtBlowtorch) then |
750 end; |
710 begin |
751 if (not Gear^.Invulnerable) then |
711 if (Ammo^.Hedgehog^.Gear <> nil) then Ammo^.Hedgehog^.Gear^.State:= Ammo^.Hedgehog^.Gear^.State and (not gstNotKickable); |
752 ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg, dsShove) |
712 ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg * 100, dsUnknown); // crank up damage for explosives + blowtorch |
753 else |
713 end; |
754 Gear^.State:= Gear^.State or gstWinner; |
714 |
755 if (Gear^.Kind = gtExplosives) and (Ammo^.Kind = gtBlowtorch) then |
715 DeleteCI(Gear); |
756 begin |
716 if (Gear^.Kind = gtHedgehog) and Gear^.Hedgehog^.King then |
757 if (Ammo^.Hedgehog^.Gear <> nil) then |
717 begin |
758 Ammo^.Hedgehog^.Gear^.State:= Ammo^.Hedgehog^.Gear^.State and (not gstNotKickable); |
718 Gear^.dX:= Ammo^.dX * Power * _0_005; |
759 ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg * 100, dsUnknown); // crank up damage for explosives + blowtorch |
719 Gear^.dY:= Ammo^.dY * Power * _0_005 |
760 end; |
720 end |
761 |
721 else |
762 DeleteCI(Gear); |
722 begin |
763 if (Gear^.Kind = gtHedgehog) and Gear^.Hedgehog^.King then |
723 Gear^.dX:= Ammo^.dX * Power * _0_01; |
764 begin |
724 Gear^.dY:= Ammo^.dY * Power * _0_01 |
765 Gear^.dX:= Ammo^.dX * Power * _0_005; |
725 end; |
766 Gear^.dY:= Ammo^.dY * Power * _0_005 |
726 |
767 end |
727 Gear^.Active:= true; |
768 else |
728 Gear^.State:= Gear^.State or gstMoving; |
769 begin |
729 |
770 Gear^.dX:= Ammo^.dX * Power * _0_01; |
730 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
771 Gear^.dY:= Ammo^.dY * Power * _0_01 |
731 begin |
772 end; |
732 if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX)) |
773 |
733 or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1; |
774 Gear^.Active:= true; |
734 if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) |
775 Gear^.State:= Gear^.State or gstMoving; |
735 or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1; |
776 |
736 if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) |
777 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
737 or (TestCollisionYwithGear(Gear, -1) <> 0)) then Gear^.Y:= Gear^.Y - _1; |
778 begin |
738 end; |
779 if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX)) |
739 |
780 or (TestCollisionYwithGear(Gear, -1) <> 0)) then |
740 if (Ammo^.Kind <> gtFlame) or ((Ammo^.State and gsttmpFlag) = 0) then FollowGear:= Gear |
781 Gear^.Y:= Gear^.Y - _1; |
741 end; |
782 if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) |
|
783 or (TestCollisionYwithGear(Gear, -1) <> 0)) then |
|
784 Gear^.Y:= Gear^.Y - _1; |
|
785 if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) |
|
786 or (TestCollisionYwithGear(Gear, -1) <> 0)) then |
|
787 Gear^.Y:= Gear^.Y - _1; |
|
788 end; |
|
789 |
|
790 if (Ammo^.Kind <> gtFlame) or ((Ammo^.State and gsttmpFlag) = 0) then |
|
791 FollowGear:= Gear |
|
792 end; |
742 end |
793 end |
743 end; |
794 end; |
744 end; |
795 end; |
745 if i <> 0 then SetAllToActive |
796 if i <> 0 then |
|
797 SetAllToActive |
746 end; |
798 end; |
747 |
799 |
748 procedure AssignHHCoords; |
800 procedure AssignHHCoords; |
749 var i, t, p, j: LongInt; |
801 var i, t, p, j: LongInt; |
750 ar: array[0..Pred(cMaxHHs)] of PHedgehog; |
802 ar: array[0..Pred(cMaxHHs)] of PHedgehog; |
751 Count: Longword; |
803 Count: Longword; |
752 begin |
804 begin |
753 if (GameFlags and gfPlaceHog) <> 0 then PlacingHogs:= true; |
805 if (GameFlags and gfPlaceHog) <> 0 then |
|
806 PlacingHogs:= true; |
754 if (GameFlags and gfDivideTeams) <> 0 then |
807 if (GameFlags and gfDivideTeams) <> 0 then |
755 begin |
808 begin |
756 t:= 0; |
809 t:= 0; |
757 TryDo(ClansCount = 2, 'More or less than 2 clans on map in divided teams mode!', true); |
810 TryDo(ClansCount = 2, 'More or less than 2 clans on map in divided teams mode!', true); |
758 for p:= 0 to 1 do |
811 for p:= 0 to 1 do |
793 //it would be nice if divide teams, forts mode and hh per map could all be checked by the team widget, or maybe disable start button |
848 //it would be nice if divide teams, forts mode and hh per map could all be checked by the team widget, or maybe disable start button |
794 TryDo(Count <= MaxHedgehogs, 'Too many hedgehogs for this map! (max # is ' + inttostr(MaxHedgehogs) + ')', true); |
849 TryDo(Count <= MaxHedgehogs, 'Too many hedgehogs for this map! (max # is ' + inttostr(MaxHedgehogs) + ')', true); |
795 while (Count > 0) do |
850 while (Count > 0) do |
796 begin |
851 begin |
797 i:= GetRandom(Count); |
852 i:= GetRandom(Count); |
798 if PlacingHogs then ar[i]^.Unplaced:= true |
853 if PlacingHogs then |
799 else FindPlace(ar[i]^.Gear, false, 0, LAND_WIDTH); |
854 ar[i]^.Unplaced:= true |
|
855 else |
|
856 FindPlace(ar[i]^.Gear, false, 0, LAND_WIDTH); |
800 if ar[i]^.Gear <> nil then |
857 if ar[i]^.Gear <> nil then |
801 begin |
858 begin |
802 ar[i]^.Gear^.dX.isNegative:= hwRound(ar[i]^.Gear^.X) > LAND_WIDTH div 2; |
859 ar[i]^.Gear^.dX.isNegative:= hwRound(ar[i]^.Gear^.X) > LAND_WIDTH div 2; |
803 ar[i]^.Gear^.Pos:= GetRandom(19) |
860 ar[i]^.Gear^.Pos:= GetRandom(19) |
804 end; |
861 end; |
856 begin |
913 begin |
857 |
914 |
858 t:= GearsList; |
915 t:= GearsList; |
859 while t <> nil do |
916 while t <> nil do |
860 begin |
917 begin |
861 if t^.Kind = Kind then inc(count); |
918 if t^.Kind = Kind then |
|
919 inc(count); |
862 t:= t^.NextGear |
920 t:= t^.NextGear |
863 end; |
921 end; |
864 CountGears:= count; |
922 CountGears:= count; |
865 end; |
923 end; |
866 |
924 |
867 function SpawnCustomCrateAt(x, y: LongInt; crate: TCrateType; content: Longword): PGear; |
925 function SpawnCustomCrateAt(x, y: LongInt; crate: TCrateType; content: Longword): PGear; |
868 begin |
926 begin |
869 FollowGear := AddGear(x, y, gtCase, 0, _0, _0, 0); |
927 FollowGear := AddGear(x, y, gtCase, 0, _0, _0, 0); |
870 cCaseFactor := 0; |
928 cCaseFactor := 0; |
871 |
929 |
872 if (crate <> HealthCrate) and (content > ord(High(TAmmoType))) then content := ord(High(TAmmoType)); |
930 if (crate <> HealthCrate) and (content > ord(High(TAmmoType))) then |
|
931 content := ord(High(TAmmoType)); |
873 |
932 |
874 case crate of |
933 case crate of |
875 HealthCrate: begin |
934 HealthCrate: |
|
935 begin |
876 FollowGear^.Pos := posCaseHealth; |
936 FollowGear^.Pos := posCaseHealth; |
877 FollowGear^.Health := content; |
937 FollowGear^.Health := content; |
878 AddCaption(GetEventString(eidNewHealthPack), cWhiteColor, capgrpAmmoInfo); |
938 AddCaption(GetEventString(eidNewHealthPack), cWhiteColor, capgrpAmmoInfo); |
879 end; |
939 end; |
880 AmmoCrate: begin |
940 AmmoCrate: |
|
941 begin |
881 FollowGear^.Pos := posCaseAmmo; |
942 FollowGear^.Pos := posCaseAmmo; |
882 FollowGear^.AmmoType := TAmmoType(content); |
943 FollowGear^.AmmoType := TAmmoType(content); |
883 AddCaption(GetEventString(eidNewAmmoPack), cWhiteColor, capgrpAmmoInfo); |
944 AddCaption(GetEventString(eidNewAmmoPack), cWhiteColor, capgrpAmmoInfo); |
884 end; |
945 end; |
885 UtilityCrate: begin |
946 UtilityCrate: |
|
947 begin |
886 FollowGear^.Pos := posCaseUtility; |
948 FollowGear^.Pos := posCaseUtility; |
887 FollowGear^.AmmoType := TAmmoType(content); |
949 FollowGear^.AmmoType := TAmmoType(content); |
888 AddCaption(GetEventString(eidNewUtilityPack), cWhiteColor, capgrpAmmoInfo); |
950 AddCaption(GetEventString(eidNewUtilityPack), cWhiteColor, capgrpAmmoInfo); |
889 end; |
951 end; |
890 end; |
952 end; |
891 |
953 |
892 if ( (x = 0) and (y = 0) ) then FindPlace(FollowGear, true, 0, LAND_WIDTH); |
954 if ( (x = 0) and (y = 0) ) then |
|
955 FindPlace(FollowGear, true, 0, LAND_WIDTH); |
893 |
956 |
894 SpawnCustomCrateAt := FollowGear; |
957 SpawnCustomCrateAt := FollowGear; |
895 end; |
958 end; |
896 |
959 |
897 function SpawnFakeCrateAt(x, y: LongInt; crate: TCrateType; explode: boolean; poison: boolean): PGear; |
960 function SpawnFakeCrateAt(x, y: LongInt; crate: TCrateType; explode: boolean; poison: boolean): PGear; |
898 begin |
961 begin |
899 FollowGear := AddGear(x, y, gtCase, 0, _0, _0, 0); |
962 FollowGear := AddGear(x, y, gtCase, 0, _0, _0, 0); |
900 cCaseFactor := 0; |
963 cCaseFactor := 0; |
901 FollowGear^.Pos := posCaseDummy; |
964 FollowGear^.Pos := posCaseDummy; |
902 |
965 |
903 if explode then FollowGear^.Pos := FollowGear^.Pos + posCaseExplode; |
966 if explode then |
904 if poison then FollowGear^.Pos := FollowGear^.Pos + posCasePoison; |
967 FollowGear^.Pos := FollowGear^.Pos + posCaseExplode; |
|
968 if poison then |
|
969 FollowGear^.Pos := FollowGear^.Pos + posCasePoison; |
905 |
970 |
906 case crate of |
971 case crate of |
907 HealthCrate: begin |
972 HealthCrate: |
|
973 begin |
908 FollowGear^.Pos := FollowGear^.Pos + posCaseHealth; |
974 FollowGear^.Pos := FollowGear^.Pos + posCaseHealth; |
909 AddCaption(GetEventString(eidNewHealthPack), cWhiteColor, capgrpAmmoInfo); |
975 AddCaption(GetEventString(eidNewHealthPack), cWhiteColor, capgrpAmmoInfo); |
910 end; |
976 end; |
911 AmmoCrate: begin |
977 AmmoCrate: |
|
978 begin |
912 FollowGear^.Pos := FollowGear^.Pos + posCaseAmmo; |
979 FollowGear^.Pos := FollowGear^.Pos + posCaseAmmo; |
913 AddCaption(GetEventString(eidNewAmmoPack), cWhiteColor, capgrpAmmoInfo); |
980 AddCaption(GetEventString(eidNewAmmoPack), cWhiteColor, capgrpAmmoInfo); |
914 end; |
981 end; |
915 UtilityCrate: begin |
982 UtilityCrate: |
|
983 begin |
916 FollowGear^.Pos := FollowGear^.Pos + posCaseUtility; |
984 FollowGear^.Pos := FollowGear^.Pos + posCaseUtility; |
917 AddCaption(GetEventString(eidNewUtilityPack), cWhiteColor, capgrpAmmoInfo); |
985 AddCaption(GetEventString(eidNewUtilityPack), cWhiteColor, capgrpAmmoInfo); |
918 end; |
986 end; |
919 end; |
987 end; |
920 |
988 |
921 if ( (x = 0) and (y = 0) ) then FindPlace(FollowGear, true, 0, LAND_WIDTH); |
989 if ( (x = 0) and (y = 0) ) then |
|
990 FindPlace(FollowGear, true, 0, LAND_WIDTH); |
922 |
991 |
923 SpawnFakeCrateAt := FollowGear; |
992 SpawnFakeCrateAt := FollowGear; |
924 end; |
993 end; |
925 |
994 |
926 function GetAmmo(Hedgehog: PHedgehog): TAmmoType; |
995 function GetAmmo(Hedgehog: PHedgehog): TAmmoType; |
1100 t:= 0; |
1173 t:= 0; |
1101 x:= byte(s[1]); // speech type |
1174 x:= byte(s[1]); // speech type |
1102 if x < 4 then |
1175 if x < 4 then |
1103 begin |
1176 begin |
1104 t:= byte(s[2]); // team |
1177 t:= byte(s[2]); // team |
1105 if Length(s) > 2 then h:= byte(s[3]) // target hog |
1178 if Length(s) > 2 then |
|
1179 h:= byte(s[3]) // target hog |
1106 end; |
1180 end; |
1107 // allow targetting a hog by specifying a number as the first portion of the text |
1181 // allow targetting a hog by specifying a number as the first portion of the text |
1108 if (x < 4) and (h > byte('0')) and (h < byte('9')) then i:= h - 48; |
1182 if (x < 4) and (h > byte('0')) and (h < byte('9')) then |
1109 if i <> 0 then text:= copy(s, 4, Length(s) - 1) |
1183 i:= h - 48; |
1110 else if x < 4 then text:= copy(s, 3, Length(s) - 1) |
1184 if i <> 0 then |
|
1185 text:= copy(s, 4, Length(s) - 1) |
|
1186 else if x < 4 then |
|
1187 text:= copy(s, 3, Length(s) - 1) |
1111 else text:= copy(s, 2, Length(s) - 1); |
1188 else text:= copy(s, 2, Length(s) - 1); |
1112 |
1189 |
1113 (* |
1190 (* |
1114 if CheckNoTeamOrHH then |
1191 if CheckNoTeamOrHH then |
1115 begin |
1192 begin |