29 procedure HedgehogChAngle(HHGear: PGear); |
29 procedure HedgehogChAngle(HHGear: PGear); |
30 procedure PickUp(HH, Gear: PGear); |
30 procedure PickUp(HH, Gear: PGear); |
31 procedure AddPickup(HH: THedgehog; ammo: TAmmoType; cnt, X, Y: LongWord); |
31 procedure AddPickup(HH: THedgehog; ammo: TAmmoType; cnt, X, Y: LongWord); |
32 procedure CheckIce(Gear: PGear); inline; |
32 procedure CheckIce(Gear: PGear); inline; |
33 procedure PlayTaunt(taunt: Longword); |
33 procedure PlayTaunt(taunt: Longword); |
|
34 function HHGetTimer(Gear: PGear): LongWord; |
|
35 function HHGetTimerMsg(Gear: PGear): LongWord; |
|
36 function HHGetBounciness(Gear: PGear): LongWord; |
|
37 function HHGetBouncinessMsg(Gear: PGear): LongWord; |
34 |
38 |
35 implementation |
39 implementation |
36 uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions, |
40 uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions, |
37 uCommands, uLocale, uUtils, uStats, uIO, uScript, |
41 uCommands, uLocale, uUtils, uStats, uIO, uScript, |
38 uGearsList, uCollisions, uRandom, uStore, uTeams, |
42 uGearsList, uCollisions, uRandom, uStore, uTeams, |
180 color: LongWord; |
176 color: LongWord; |
181 begin |
177 begin |
182 Gear^.Message:= Gear^.Message and (not gmTimer); |
178 Gear^.Message:= Gear^.Message and (not gmTimer); |
183 CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^); |
179 CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^); |
184 with Gear^.Hedgehog^ do |
180 with Gear^.Hedgehog^ do |
|
181 if (((Gear^.State and gstAttacked) <> 0) and (GameFlags and gfInfAttack = 0)) |
|
182 or ((Gear^.State and gstHHDriven) = 0) then |
|
183 exit; |
185 if ((Gear^.Message and gmPrecise) <> 0) and ((CurWeapon^.Propz and ammoprop_SetBounce) <> 0) then |
184 if ((Gear^.Message and gmPrecise) <> 0) and ((CurWeapon^.Propz and ammoprop_SetBounce) <> 0) then |
186 begin |
185 begin |
187 color:= Gear^.Hedgehog^.Team^.Clan^.Color; |
186 color:= Gear^.Hedgehog^.Team^.Clan^.Color; |
|
187 |
188 case Gear^.MsgParam of |
188 case Gear^.MsgParam of |
189 1: begin |
189 1: begin |
190 AddCaption(FormatA(trmsg[sidBounce], trmsg[sidBounce1]), color, capgrpAmmostate); |
190 AddCaption(FormatA(trmsg[sidBounce], trmsg[sidBounce1]), color, capgrpAmmostate); |
191 CurWeapon^.Bounciness:= 350; |
|
192 end; |
191 end; |
193 2: begin |
192 2: begin |
194 AddCaption(FormatA(trmsg[sidBounce], trmsg[sidBounce2]), color, capgrpAmmostate); |
193 AddCaption(FormatA(trmsg[sidBounce], trmsg[sidBounce2]), color, capgrpAmmostate); |
195 CurWeapon^.Bounciness:= 700; |
|
196 end; |
194 end; |
197 3: begin |
195 3: begin |
198 AddCaption(FormatA(trmsg[sidBounce], trmsg[sidBounce3]), color, capgrpAmmostate); |
196 AddCaption(FormatA(trmsg[sidBounce], trmsg[sidBounce3]), color, capgrpAmmostate); |
199 CurWeapon^.Bounciness:= 1000; |
|
200 end; |
197 end; |
201 4: begin |
198 4: begin |
202 AddCaption(FormatA(trmsg[sidBounce], trmsg[sidBounce4]), color, capgrpAmmostate); |
199 AddCaption(FormatA(trmsg[sidBounce], trmsg[sidBounce4]), color, capgrpAmmostate); |
203 CurWeapon^.Bounciness:= 2000; |
|
204 end; |
200 end; |
205 5: begin |
201 5: begin |
206 AddCaption(FormatA(trmsg[sidBounce], trmsg[sidBounce5]), color, capgrpAmmostate); |
202 AddCaption(FormatA(trmsg[sidBounce], trmsg[sidBounce5]), color, capgrpAmmostate); |
207 CurWeapon^.Bounciness:= 4000; |
|
208 end |
203 end |
209 end |
204 end; |
|
205 CurWeapon^.Bounciness:= bouncinessLevels[Gear^.MsgParam - 1]; |
210 end |
206 end |
211 else if (CurWeapon^.Propz and ammoprop_Timerable) <> 0 then |
207 else if (CurWeapon^.Propz and ammoprop_Timerable) <> 0 then |
212 begin |
208 begin |
213 CurWeapon^.Timer:= 1000 * Gear^.MsgParam; |
209 CurWeapon^.Timer:= 1000 * Gear^.MsgParam; |
214 with CurrentTeam^ do |
210 with CurrentTeam^ do |
215 ApplyAmmoChanges(Hedgehogs[CurrHedgehog]); |
211 ApplyAmmoChanges(Hedgehogs[CurrHedgehog]); |
216 end; |
212 end; |
217 end; |
213 end; |
218 |
214 |
|
215 // Return timer (in ticks) of hogs current ammo or MSGPARAM_INVALID |
|
216 // if not timerable |
|
217 function HHGetTimer(Gear: PGear): LongWord; |
|
218 var CurWeapon: PAmmo; |
|
219 begin |
|
220 CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^); |
|
221 with Gear^.Hedgehog^ do |
|
222 if ((CurWeapon^.Propz and ammoprop_Timerable) <> 0) then |
|
223 HHGetTimer:= CurWeapon^.Timer |
|
224 else |
|
225 HHGetTimer:= MSGPARAM_INVALID; |
|
226 end; |
|
227 |
|
228 // Returns timer as a corresponding msgParam for /timer command |
|
229 function HHGetTimerMsg(Gear: PGear): LongWord; |
|
230 var timer: LongInt; |
|
231 begin |
|
232 timer:= HHGetTimer(Gear); |
|
233 if timer > -1 then |
|
234 HHGetTimerMsg:= timer div 1000 |
|
235 else |
|
236 HHGetTimerMsg:= MSGPARAM_INVALID |
|
237 end; |
|
238 |
|
239 // Returns the selected bounciness value for the hog gear's current ammo |
|
240 // or MSGPARAM_INVALID if current ammo has no settable bounciness |
|
241 function HHGetBounciness(Gear: PGear): LongWord; |
|
242 var CurWeapon: PAmmo; |
|
243 begin |
|
244 CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^); |
|
245 with Gear^.Hedgehog^ do |
|
246 if ((CurWeapon^.Propz and ammoprop_SetBounce) <> 0) then |
|
247 HHGetBounciness:= CurWeapon^.Bounciness |
|
248 else |
|
249 HHGetBounciness:= MSGPARAM_INVALID |
|
250 end; |
|
251 |
|
252 // Returns bounciness as a corresponding msgParam for /timer command |
|
253 function HHGetBouncinessMsg(Gear: PGear): LongWord; |
|
254 var bounciness, i: LongInt; |
|
255 begin |
|
256 bounciness:= HHGetBounciness(Gear); |
|
257 if bounciness > -1 then |
|
258 for i:=0 to High(bouncinessLevels) do |
|
259 if bounciness = bouncinessLevels[i] then |
|
260 begin |
|
261 HHGetBouncinessMsg:= i+1; |
|
262 exit |
|
263 end; |
|
264 HHGetBouncinessMsg:= MSGPARAM_INVALID |
|
265 end; |
219 |
266 |
220 procedure Attack(Gear: PGear); |
267 procedure Attack(Gear: PGear); |
221 var xx, yy, newDx, newDy, lx, ly: hwFloat; |
268 var xx, yy, newDx, newDy, lx, ly: hwFloat; |
222 speech: PVisualGear; |
269 speech: PVisualGear; |
223 newGear: PGear; |
270 newGear: PGear; |
224 CurWeapon: PAmmo; |
271 CurWeapon: PAmmo; |
225 usedAmmoType: TAmmoType; |
272 usedAmmoType: TAmmoType; |
226 altUse: boolean; |
273 altUse, faceLeft: boolean; |
227 elastic: hwFloat; |
274 elastic: hwFloat; |
228 begin |
275 begin |
229 newGear:= nil; |
276 newGear:= nil; |
230 bShowFinger:= false; |
277 bShowFinger:= false; |
231 CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^); |
278 CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^); |
336 amSniperRifle: begin |
383 amSniperRifle: begin |
337 PlaySound(sndSniperReload); |
384 PlaySound(sndSniperReload); |
338 newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSniperRifleShot, 0, xx * _0_5, yy * _0_5, 0); |
385 newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSniperRifleShot, 0, xx * _0_5, yy * _0_5, 0); |
339 end; |
386 end; |
340 amDynamite: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtDynamite, 0, SignAs(_0_03, dX), _0, 5000); |
387 amDynamite: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtDynamite, 0, SignAs(_0_03, dX), _0, 5000); |
341 amDuck: begin |
388 amCreeper: begin |
342 // Does duck spawn inside water? |
389 // TODO: Implement proper creeper spawning code. This is still the old rubber duck code. |
|
390 |
|
391 // Does it spawn inside water? |
343 if (LeftX > hwRound(Gear^.X) - Gear^.Karma) or (RightX < hwRound(Gear^.X) + Gear^.Karma) or (cWaterLine < hwRound(Gear^.Y) + Gear^.Karma) then |
392 if (LeftX > hwRound(Gear^.X) - Gear^.Karma) or (RightX < hwRound(Gear^.X) + Gear^.Karma) or (cWaterLine < hwRound(Gear^.Y) + Gear^.Karma) then |
344 PlaySound(sndDroplet2) |
393 PlaySound(sndDroplet2) |
345 else |
394 else |
346 // Duck spawned in air, normal drop sound |
395 // spawned in air, normal drop sound |
347 PlaySound(sndDuckDrop); |
396 PlaySound(sndCreeperDrop); |
348 newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtDuck, 0, SignAs(_0_03, dX), _0, 0); |
397 newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtCreeper, 0, SignAs(_0_03, dX), _0, 0); |
349 if not ((not dX.isNegative) xor ((State and gstHHHJump) <> 0)) then |
398 if not ((not dX.isNegative) xor ((State and gstHHHJump) <> 0)) then |
350 newGear^.Tag:= -1 |
399 newGear^.Tag:= -1 |
351 else |
400 else |
352 newGear^.Tag:= 1; |
401 newGear^.Tag:= 1; |
353 end; |
402 end; |
363 amBaseballBat: begin |
412 amBaseballBat: begin |
364 newGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtShover, gsttmpFlag, xx * _0_5, yy * _0_5, 0); |
413 newGear:= AddGear(hwRound(lx) + hwSign(dX) * 10, hwRound(ly), gtShover, gsttmpFlag, xx * _0_5, yy * _0_5, 0); |
365 PlaySound(sndBaseballBat) // TODO: Only play if something is hit? |
414 PlaySound(sndBaseballBat) // TODO: Only play if something is hit? |
366 end; |
415 end; |
367 amParachute: begin |
416 amParachute: begin |
|
417 faceLeft:= IsHogFacingLeft(Gear); |
368 newGear:= AddGear(hwRound(lx), hwRound(ly), gtParachute, 0, _0, _0, 0); |
418 newGear:= AddGear(hwRound(lx), hwRound(ly), gtParachute, 0, _0, _0, 0); |
|
419 if faceLeft then |
|
420 newGear^.Tag:= -1; |
369 PlaySound(sndParachute) |
421 PlaySound(sndParachute) |
370 end; |
422 end; |
371 // we save CurWeapon^.Pos (in this case: cursor direction) by using it as (otherwise irrelevant) X value of the new gear. |
423 // we save CurWeapon^.Pos (in this case: cursor direction) by using it as (otherwise irrelevant) X value of the new gear. |
372 amAirAttack: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 0, _0, _0, 0); |
424 amAirAttack: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 0, _0, _0, 0); |
373 amMineStrike: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 1, _0, _0, 0); |
425 amMineStrike: newGear:= AddGear(CurWeapon^.Pos, 0, gtAirAttack, 1, _0, _0, 0); |
406 cGravity:= cMaxWindSpeed; |
458 cGravity:= cMaxWindSpeed; |
407 cGravityf:= 0.00025; |
459 cGravityf:= 0.00025; |
408 cLowGravity := true |
460 cLowGravity := true |
409 end; |
461 end; |
410 amExtraDamage: begin |
462 amExtraDamage: begin |
411 PlaySound(sndHellishImpact4); |
463 PlaySound(sndExtraDamage); |
412 cDamageModifier:= _1_5 |
464 cDamageModifier:= _1_5 |
413 end; |
465 end; |
414 amInvulnerable: begin |
466 amInvulnerable: begin |
415 PlaySound(sndInvulnerable); |
467 PlaySound(sndInvulnerable); |
416 Effects[heInvulnerable]:= 1 |
468 Effects[heInvulnerable]:= 1 |
417 end; |
469 end; |
418 amExtraTime: begin |
470 amExtraTime: begin |
419 PlaySound(sndExtraTime); |
471 PlaySound(sndExtraTime); |
420 TurnTimeLeft:= TurnTimeLeft + 30000 |
472 if TurnTimeLeft <= (cMaxTurnTime - ExtraTime) then |
|
473 TurnTimeLeft:= TurnTimeLeft + ExtraTime |
|
474 else |
|
475 TurnTimeLeft:= cMaxTurnTime; |
421 end; |
476 end; |
422 amLaserSight: begin |
477 amLaserSight: begin |
423 PlaySound(sndLaserSight); |
478 PlaySound(sndLaserSight); |
424 cLaserSighting:= true |
479 cLaserSighting:= true |
425 end; |
480 end; |
426 amVampiric: begin |
481 amVampiric: begin |
427 PlaySoundV(sndOw1, Team^.voicepack); |
482 PlaySoundV(sndOw1, Team^.voicepack); |
428 cVampiric:= true; |
483 cVampiric:= true; |
429 end; |
484 end; |
430 amPiano: begin |
485 amPiano: newGear:= AddGear(TargetPoint.X, -1024, gtPiano, 0, _0, _0, 0); |
431 // Tuck the hedgehog away until the piano attack is completed |
|
432 Unplaced:= true; |
|
433 X:= _0; |
|
434 Y:= _0; |
|
435 newGear:= AddGear(TargetPoint.X, -1024, gtPiano, 0, _0, _0, 0); |
|
436 PauseMusic |
|
437 end; |
|
438 amFlamethrower: newGear:= AddGear(hwRound(X), hwRound(Y), gtFlamethrower, 0, xx * _0_5, yy * _0_5, 0); |
486 amFlamethrower: newGear:= AddGear(hwRound(X), hwRound(Y), gtFlamethrower, 0, xx * _0_5, yy * _0_5, 0); |
439 amLandGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtLandGun, 0, xx * _0_5, yy * _0_5, 0); |
487 amLandGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtLandGun, 0, xx * _0_5, yy * _0_5, 0); |
440 amResurrector: begin |
488 amResurrector: begin |
441 newGear:= AddGear(hwRound(lx), hwRound(ly), gtResurrector, 0, _0, _0, 0); |
489 newGear:= AddGear(hwRound(lx), hwRound(ly), gtResurrector, 0, _0, _0, 0); |
442 newGear^.SoundChannel := LoopSound(sndResurrector); |
490 newGear^.SoundChannel := LoopSound(sndResurrector); |
443 end; |
491 end; |
444 //amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000); |
|
445 amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 0); |
492 amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 0); |
446 amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0); |
493 amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0); |
447 end; |
494 end; |
448 if altUse and (newGear <> nil) and |
495 if altUse and (newGear <> nil) and |
449 ((CurAmmoGear = nil) or (CurAmmoGear^.AmmoType <> amJetpack) or (Gear^.Message and gmPrecise = 0)) then |
496 ((CurAmmoGear = nil) or (CurAmmoGear^.AmmoType <> amJetpack) or (Gear^.Message and gmPrecise = 0)) then |
474 amSwitch, amRCPlane, |
521 amSwitch, amRCPlane, |
475 amKamikaze, amCake, |
522 amKamikaze, amCake, |
476 amSeduction, amBallgun, |
523 amSeduction, amBallgun, |
477 amJetpack, amBirdy, |
524 amJetpack, amBirdy, |
478 amFlamethrower, amLandGun, |
525 amFlamethrower, amLandGun, |
479 amResurrector, //amStructure, |
526 amResurrector, amTardis, |
480 amTardis, amPiano, |
527 amPiano, amIceGun, |
481 amIceGun, amRubber, |
528 amAirAttack, amNapalm, |
482 amMinigun: CurAmmoGear:= newGear; |
529 amMineStrike, amDrillStrike, |
|
530 amRubber, amMinigun: CurAmmoGear:= newGear; |
483 end; |
531 end; |
484 if CurAmmoType = amCake then FollowGear:= newGear; |
532 if CurAmmoType = amCake then FollowGear:= newGear; |
485 if CurAmmoType = amAirMine then newGear^.Hedgehog:= nil; |
|
486 |
533 |
487 if ((CurAmmoType = amMine) or (CurAmmoType = amSMine) or (CurAmmoType = amAirMine)) and (GameFlags and gfInfAttack <> 0) then |
534 if ((CurAmmoType = amMine) or (CurAmmoType = amSMine) or (CurAmmoType = amAirMine)) and (GameFlags and gfInfAttack <> 0) then |
488 newGear^.FlightTime:= GameTicks + min(TurnTimeLeft,1000) |
535 newGear^.FlightTime:= GameTicks + min(TurnTimeLeft,1000) |
489 else if CurAmmoType = amDrill then |
536 else if CurAmmoType = amDrill then |
490 newGear^.FlightTime:= GameTicks + 250; |
537 newGear^.FlightTime:= GameTicks + 250; |
491 if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then |
538 if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then |
492 begin |
539 begin |
493 newGear^.Target.X:= TargetPoint.X; |
540 newGear^.Target.X:= TargetPoint.X; |
494 newGear^.Target.Y:= TargetPoint.Y |
541 newGear^.Target.Y:= TargetPoint.Y |
495 end; |
542 end; |
496 if (newGear <> nil) and (newGear^.CollisionMask and lfCurrentHog <> 0) then newGear^.CollisionMask:= newGear^.CollisionMask and (not lfCurrentHog); |
543 if (newGear <> nil) and (newGear^.CollisionMask and lfCurHogCrate <> 0) then newGear^.CollisionMask:= newGear^.CollisionMask and (not lfCurHogCrate); |
497 |
544 |
498 // Clear FollowGear if using on a rope/parachute/saucer etc so focus stays with the hog's movement |
545 // Clear FollowGear if using on a rope/parachute/saucer etc so focus stays with the hog's movement |
499 if altUse then |
546 if altUse then |
500 FollowGear:= nil; |
547 FollowGear:= nil; |
501 |
548 |
563 if HHGear <> nil then HHGear^.State:= HHGear^.State and (not gstAttacking); |
610 if HHGear <> nil then HHGear^.State:= HHGear^.State and (not gstAttacking); |
564 if (Ammoz[a].Ammo.Propz and ammoprop_Effect) = 0 then |
611 if (Ammoz[a].Ammo.Propz and ammoprop_Effect) = 0 then |
565 begin |
612 begin |
566 Inc(MultiShootAttacks); |
613 Inc(MultiShootAttacks); |
567 |
614 |
568 if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) then |
615 if (Ammoz[a].Ammo.NumPerTurn > 0) and ((GameFlags and gfMultiWeapon) = 0) then |
569 begin |
616 begin |
570 s:= ansistring(inttostr(Ammoz[a].Ammo.NumPerTurn - MultiShootAttacks + 1)); |
617 s:= ansistring(inttostr(Ammoz[a].Ammo.NumPerTurn - MultiShootAttacks + 1)); |
571 AddCaption(formatA(trmsg[sidRemaining], s), cWhiteColor, capgrpAmmostate); |
618 AddCaption(formatA(trmsg[sidRemaining], s), capcolDefault, capgrpAmmostate); |
572 end; |
619 end; |
573 |
620 |
574 if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) |
621 if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) |
575 or ((GameFlags and gfMultiWeapon) <> 0) then |
622 or ((GameFlags and gfMultiWeapon) <> 0) then |
576 begin |
623 begin |
581 OnUsedAmmo(CurrentHedgehog^); |
628 OnUsedAmmo(CurrentHedgehog^); |
582 if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (((GameFlags and gfInfAttack) = 0) or PlacingHogs) then |
629 if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (((GameFlags and gfInfAttack) = 0) or PlacingHogs) then |
583 begin |
630 begin |
584 if TagTurnTimeLeft = 0 then |
631 if TagTurnTimeLeft = 0 then |
585 TagTurnTimeLeft:= TurnTimeLeft; |
632 TagTurnTimeLeft:= TurnTimeLeft; |
586 if (CurAmmoGear <> nil) and (CurAmmoGear^.State and gstSubmersible <> 0) and CheckCoordInWater(hwRound(CurAmmoGear^.X), hwRound(CurAmmoGear^.Y)) then |
633 if (HHGear <> nil) and ((HHGear^.State and gstHHDriven) <> 0) then |
587 TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 25 |
634 begin |
588 else TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100; |
635 if (CurAmmoGear <> nil) and (CurAmmoGear^.State and gstSubmersible <> 0) and CheckCoordInWater(hwRound(CurAmmoGear^.X), hwRound(CurAmmoGear^.Y)) then |
589 IsGetAwayTime := true; |
636 TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 25 |
|
637 else TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100; |
|
638 IsGetAwayTime := true; |
|
639 end; |
590 end; |
640 end; |
591 if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (HHGear <> nil) then |
641 if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (HHGear <> nil) then |
592 HHGear^.State:= HHGear^.State or gstAttacked; |
642 HHGear^.State:= HHGear^.State or gstAttacked; |
593 if (a = amNothing) or ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) or |
643 if (a = amNothing) or ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) or |
594 (((GameFlags and gfInfAttack) <> 0) and ((Ammoz[a].Ammo.Propz and ammoprop_ForceTurnEnd) = 0)) then |
644 (((GameFlags and gfInfAttack) <> 0) and ((Ammoz[a].Ammo.Propz and ammoprop_ForceTurnEnd) = 0)) then |
728 end; |
783 end; |
729 |
784 |
730 //////////////////////////////////////////////////////////////////////////////// |
785 //////////////////////////////////////////////////////////////////////////////// |
731 procedure PickUp(HH, Gear: PGear); |
786 procedure PickUp(HH, Gear: PGear); |
732 var ag, gi: PGear; |
787 var ag, gi: PGear; |
|
788 healthBoost: LongInt; |
733 begin |
789 begin |
734 if Gear^.State and gstFrozen <> 0 then exit; |
790 if Gear^.State and gstFrozen <> 0 then exit; |
|
791 if Gear^.Message and gmDestroy <> 0 then exit; |
735 |
792 |
736 Gear^.Message:= gmDestroy; |
793 Gear^.Message:= gmDestroy; |
737 if (Gear^.Pos and posCaseExplode) <> 0 then |
794 if (Gear^.Pos and posCaseExplode) <> 0 then |
738 if (Gear^.Pos and posCasePoison) <> 0 then |
795 if (Gear^.Pos and posCasePoison) <> 0 then |
739 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound + EXPLPoisoned) |
796 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound + EXPLPoisoned) |
774 ag^.Power:= Gear^.Power |
831 ag^.Power:= Gear^.Power |
775 end; |
832 end; |
776 end; |
833 end; |
777 posCaseHealth: begin |
834 posCaseHealth: begin |
778 PlaySound(sndShotgunReload); |
835 PlaySound(sndShotgunReload); |
779 inc(HH^.Health, Gear^.Health); |
836 healthBoost:= IncHogHealth(HH^.Hedgehog, Gear^.Health); |
780 HH^.Hedgehog^.Effects[hePoisoned] := 0; |
837 HH^.Hedgehog^.Effects[hePoisoned] := 0; |
781 RenderHealth(HH^.Hedgehog^); |
838 RenderHealth(HH^.Hedgehog^); |
782 RecountTeamHealth(HH^.Hedgehog^.Team); |
839 RecountTeamHealth(HH^.Hedgehog^.Team); |
783 HHHeal(HH^.Hedgehog, Gear^.Health, true); |
840 HHHeal(HH^.Hedgehog, healthBoost, true); |
784 end; |
841 end; |
785 end |
842 end |
786 end; |
843 end; |
787 |
844 |
788 procedure HedgehogStep(Gear: PGear); |
845 procedure HedgehogStep(Gear: PGear); |
789 var PrevdX: LongInt; |
846 var PrevdX: LongInt; |
790 CurWeapon: PAmmo; |
847 CurWeapon: PAmmo; |
791 portals: PGearArrayS; |
|
792 begin |
848 begin |
793 CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^); |
849 CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^); |
794 if ((Gear^.State and (gstAttacking or gstMoving)) = 0) then |
850 if ((Gear^.State and (gstAttacking or gstMoving)) = 0) then |
795 begin |
851 begin |
796 if isCursorVisible then |
852 if isCursorVisible then |
797 with Gear^.Hedgehog^ do |
853 with Gear^.Hedgehog^ do |
798 with CurWeapon^ do |
854 with CurWeapon^ do |
799 begin |
855 begin |
800 if (Gear^.Message and gmLeft ) <> 0 then |
856 if Ammoz[AmmoType].PosCount < 2 then |
|
857 exit |
|
858 else if (Gear^.Message and gmLeft ) <> 0 then |
801 Pos:= (Pos - 1 + Ammoz[AmmoType].PosCount) mod Ammoz[AmmoType].PosCount |
859 Pos:= (Pos - 1 + Ammoz[AmmoType].PosCount) mod Ammoz[AmmoType].PosCount |
|
860 else if (Gear^.Message and gmRight ) <> 0 then |
|
861 Pos:= (Pos + 1) mod Ammoz[AmmoType].PosCount |
802 else |
862 else |
803 if (Gear^.Message and gmRight ) <> 0 then |
863 exit; |
804 Pos:= (Pos + 1) mod Ammoz[AmmoType].PosCount |
864 GHStepTicks:= 200; |
805 else |
865 exit |
|
866 end; |
|
867 |
|
868 if (Gear^.Hedgehog^.Unplaced) then |
806 exit; |
869 exit; |
807 GHStepTicks:= 200; |
|
808 exit |
|
809 end; |
|
810 |
870 |
811 if ((Gear^.Message and gmAnimate) <> 0) then |
871 if ((Gear^.Message and gmAnimate) <> 0) then |
812 begin |
872 begin |
813 Gear^.Message:= 0; |
873 Gear^.Message:= 0; |
814 Gear^.State:= Gear^.State or gstAnimation; |
874 Gear^.State:= Gear^.State or gstAnimation; |
849 Gear^.State:= Gear^.State or gstMoving or gstHHJumping; |
909 Gear^.State:= Gear^.State or gstMoving or gstHHJumping; |
850 PlaySoundV(sndJump3, Gear^.Hedgehog^.Team^.voicepack); |
910 PlaySoundV(sndJump3, Gear^.Hedgehog^.Team^.voicepack); |
851 exit |
911 exit |
852 end; |
912 end; |
853 |
913 |
854 if (Gear^.Message and (gmLeft or gmRight) <> 0) and (Gear^.State and gstMoving = 0) then |
914 if (Gear^.Message and (gmLeft or gmRight) <> 0) and (Gear^.State and gstMoving = 0) and |
855 begin |
915 (CheckGearNear(Gear, gtPortal, 26, 26) = nil) then |
856 // slightly inefficient since it doesn't halt after one portal, maybe could add a param to GearsNear for number desired. |
916 Gear^.PortalCounter:= 0; |
857 portals:= GearsNear(Gear^.X, Gear^.Y, gtPortal, 26); |
|
858 if portals.size = 0 then Gear^.PortalCounter:= 0 |
|
859 end; |
|
860 PrevdX:= hwSign(Gear^.dX); |
917 PrevdX:= hwSign(Gear^.dX); |
861 if (Gear^.Message and gmLeft )<>0 then |
918 if (Gear^.Message and gmLeft )<>0 then |
862 Gear^.dX:= -cLittle else |
919 Gear^.dX:= -cLittle else |
863 if (Gear^.Message and gmRight )<>0 then |
920 if (Gear^.Message and gmRight )<>0 then |
864 Gear^.dX:= cLittle |
921 Gear^.dX:= cLittle |
1206 isCursorVisible:= false |
1264 isCursorVisible:= false |
1207 end; |
1265 end; |
1208 if (not isZero(Gear^.dY)) and (Gear^.FlightTime > 0) and ((GameFlags and gfLowGravity) = 0) then |
1266 if (not isZero(Gear^.dY)) and (Gear^.FlightTime > 0) and ((GameFlags and gfLowGravity) = 0) then |
1209 begin |
1267 begin |
1210 inc(Gear^.FlightTime); |
1268 inc(Gear^.FlightTime); |
1211 if (Gear^.FlightTime > 1500) and ((hwRound(Gear^.X) < LongInt(leftX)-250) or (hwRound(Gear^.X) > LongInt(rightX)+250)) then |
1269 if (Gear^.FlightTime > 1500) and ((hwRound(Gear^.X) < leftX-250) or (hwRound(Gear^.X) > rightX+250)) then |
1212 begin |
1270 begin |
1213 Gear^.FlightTime:= 0; |
1271 Gear^.FlightTime:= 0; |
1214 s:= ansistring(CurrentHedgehog^.Name); |
1272 s:= ansistring(CurrentHedgehog^.Name); |
1215 AddCaption(FormatA(GetEventString(eidHomerun), s), cWhiteColor, capgrpMessage); |
1273 AddCaption(FormatA(GetEventString(eidHomerun), s), capcolDefault, capgrpMessage2); |
1216 PlaySound(sndHomerun) |
1274 PlaySound(sndHomerun) |
1217 end; |
1275 end; |
1218 end |
1276 end |
1219 else |
1277 else |
1220 begin |
1278 begin |
1221 uStats.hedgehogFlight(Gear, Gear^.FlightTime); |
1279 uStats.hedgehogFlight(Gear, Gear^.FlightTime); |
1222 Gear^.FlightTime:= 0; |
1280 Gear^.FlightTime:= 0; |
|
1281 end; |
|
1282 if (WorldEdge = weNone) and (not Gear^.Hedgehog^.FlownOffMap) and (not isZero(Gear^.dX)) and (not isUnderwater) and ((Gear^.State and gstHHDriven) = 0) and (hwRound(Gear^.Y) < cWaterLine-300) and ((hwRound(Gear^.X) < leftX-2048) or (hwRound(Gear^.X) > rightX+2048)) then |
|
1283 begin |
|
1284 PlaySoundV(sndFlyAway, Gear^.Hedgehog^.Team^.voicepack); |
|
1285 Gear^.Hedgehog^.FlownOffMap:= true; |
1223 end; |
1286 end; |
1224 |
1287 |
1225 end; |
1288 end; |
1226 |
1289 |
1227 procedure doStepHedgehogDriven(HHGear: PGear); |
1290 procedure doStepHedgehogDriven(HHGear: PGear); |
1239 if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Utility) <> 0) and isInMultiShoot then |
1302 if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Utility) <> 0) and isInMultiShoot then |
1240 AllInactive:= true |
1303 AllInactive:= true |
1241 else if not isInMultiShoot then |
1304 else if not isInMultiShoot then |
1242 AllInactive:= false; |
1305 AllInactive:= false; |
1243 |
1306 |
1244 if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) or (LuaEndTurnRequested = true) then |
1307 if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) or (HHGear^.Health = 0) or (((GameFlags and gfKing) <> 0) and (not Hedgehog^.Team^.hasKing)) or (LuaEndTurnRequested = true) then |
1245 begin |
1308 begin |
1246 if (Hedgehog^.CurAmmoType = amKnife) then |
1309 if (Hedgehog^.CurAmmoType = amKnife) then |
1247 LoadHedgehogHat(Hedgehog^, Hedgehog^.Hat); |
1310 LoadHedgehogHat(Hedgehog^, Hedgehog^.Hat); |
1248 if TagTurnTimeLeft = 0 then |
1311 if TagTurnTimeLeft = 0 then |
1249 TagTurnTimeLeft:= TurnTimeLeft; |
1312 TagTurnTimeLeft:= TurnTimeLeft; |
1250 TurnTimeLeft:= 0; |
1313 TurnTimeLeft:= 0; |
1251 if (GameOver = false) and ((GameFlags and gfInfAttack) = 0) and ((HHGear^.State and gstAttacked) = 0) and (HHGear^.Damage = 0) and (LuaNoEndTurnTaunts = false) then |
1314 if (GameOver = false) and ((GameFlags and gfInfAttack) = 0) and ((HHGear^.State and gstAttacked) = 0) and (HHGear^.Damage = 0) and (HHGear^.Health > 0) and (LuaNoEndTurnTaunts = false) and (uStats.getIsTurnSkipped() = false) then |
1252 begin |
1315 begin |
1253 AddVoice(sndBoring, Hedgehog^.Team^.voicepack); |
1316 AddVoice(sndBoring, Hedgehog^.Team^.voicepack); |
1254 if (GameFlags and gfInfAttack = 0) then |
1317 if (GameFlags and gfInfAttack = 0) then |
1255 begin |
1318 begin |
1256 s:= Hedgehog^.Name; |
1319 s:= Hedgehog^.Name; |
1257 AddCaption(FormatA(GetEventString(eidTimeout), s), cWhiteColor, capgrpMessage); |
1320 AddCaption(FormatA(GetEventString(eidTimeout), s), capcolDefault, capgrpMessage); |
1258 end; |
1321 end; |
1259 end; |
1322 end; |
1260 isCursorVisible:= false; |
1323 isCursorVisible:= false; |
1261 HHGear^.State:= HHGear^.State and (not (gstHHDriven or gstAnimation or gstAttacking)); |
1324 HHGear^.State:= HHGear^.State and (not (gstHHDriven or gstAnimation or gstAttacking)); |
1262 AttackBar:= 0; |
1325 AttackBar:= 0; |
1263 StopSound(sndThrowPowerUp); |
1326 StopSound(sndThrowPowerUp); |
1264 LuaEndTurnRequested:= false; |
1327 LuaEndTurnRequested:= false; |
1265 LuaNoEndTurnTaunts:= false; |
1328 LuaNoEndTurnTaunts:= false; |
1266 if HHGear^.Damage > 0 then |
1329 if (HHGear^.Damage > 0) or (HHGear^.Health = 0) then |
1267 HHGear^.State:= HHGear^.State and (not (gstHHJumping or gstHHHJump)); |
1330 HHGear^.State:= HHGear^.State and (not (gstHHJumping or gstHHHJump)); |
1268 exit |
1331 exit |
1269 end; |
1332 end; |
1270 |
1333 |
1271 if isAFK and (not CurrentTeam^.ExtDriven) and (CurrentHedgehog^.BotLevel = 0) then |
1334 if isAFK and (not CurrentTeam^.ExtDriven) and (CurrentHedgehog^.BotLevel = 0) then |
1421 Gear^.State:= (Gear^.State or gstHHDeath) and (not gstAnimation); |
1484 Gear^.State:= (Gear^.State or gstHHDeath) and (not gstAnimation); |
1422 Gear^.doStep:= @doStepHedgehogDead; |
1485 Gear^.doStep:= @doStepHedgehogDead; |
1423 // Death message |
1486 // Death message |
1424 s:= ansistring(Gear^.Hedgehog^.Name); |
1487 s:= ansistring(Gear^.Hedgehog^.Name); |
1425 if Gear^.Hedgehog^.King then |
1488 if Gear^.Hedgehog^.King then |
1426 AddCaption(FormatA(GetEventString(eidKingDied), s), cWhiteColor, capgrpMessage) |
1489 AddCaption(FormatA(GetEventString(eidKingDied), s), capcolDefault, capgrpMessage) |
1427 else |
1490 else |
1428 AddCaption(FormatA(GetEventString(eidDied), s), cWhiteColor, capgrpMessage); |
1491 AddCaption(FormatA(GetEventString(eidDied), s), capcolDefault, capgrpMessage); |
1429 end; |
1492 end; |
1430 end |
1493 end |
1431 else |
1494 else |
1432 begin |
1495 begin |
1433 Gear^.State:= Gear^.State and (not gstAnimation); |
1496 Gear^.State:= Gear^.State and (not gstAnimation); |
1434 Gear^.doStep:= @doStepHedgehogGone; |
1497 Gear^.doStep:= @doStepHedgehogGone; |
1435 |
1498 |
1436 // Gone message |
1499 // Gone message |
1437 s:= ansistring(Gear^.Hedgehog^.Name); |
1500 s:= ansistring(Gear^.Hedgehog^.Name); |
1438 AddCaption(FormatA(GetEventString(eidGone), s), cWhiteColor, capgrpMessage); |
1501 AddCaption(FormatA(GetEventString(eidGone), s), capcolDefault, capgrpMessage); |
1439 end |
1502 end |
1440 end; |
1503 end; |
1441 exit |
1504 exit |
1442 end; |
1505 end; |
1443 |
1506 |
1510 begin |
1575 begin |
1511 if (WorldEdge <> weBounce) and (Gear = CurrentHedgehog^.Gear) and |
1576 if (WorldEdge <> weBounce) and (Gear = CurrentHedgehog^.Gear) and |
1512 (CurAmmoGear <> nil) and (CurAmmoGear^.Kind =gtRope) and (CurAmmoGear^.Elasticity <> _0) then |
1577 (CurAmmoGear <> nil) and (CurAmmoGear^.Kind =gtRope) and (CurAmmoGear^.Elasticity <> _0) then |
1513 CurAmmoGear^.PortalCounter:= 1; |
1578 CurAmmoGear^.PortalCounter:= 1; |
1514 if (WorldEdge = weWrap) and ((TestCollisionXwithGear(Gear, 1) <> 0) or (TestCollisionXwithGear(Gear, -1) <> 0)) then |
1579 if (WorldEdge = weWrap) and ((TestCollisionXwithGear(Gear, 1) <> 0) or (TestCollisionXwithGear(Gear, -1) <> 0)) then |
1515 begin |
1580 // Stop hedgehog if it collides with land *just* behind other side of world wrap edge |
1516 Gear^.X:= tX; |
1581 if ((Gear^.State and gstNotKickable) = 0) then |
1517 Gear^.dX.isNegative:= (hwRound(tX) > LongInt(leftX) + Gear^.Radius * 2) |
1582 begin |
1518 end |
1583 if (hwRound(tX) > leftX + Gear^.Radius * 2) then |
|
1584 Gear^.X:= int2HwFloat(RightX) |
|
1585 else |
|
1586 Gear^.X:= int2HwFloat(LeftX); |
|
1587 Gear^.dX.QWordValue:= 0; |
|
1588 Gear^.State := Gear^.State or gstCollision; |
|
1589 end; |
1519 end; |
1590 end; |
1520 |
1591 |
1521 CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel; |
1592 CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel; |
1522 if (Gear^.Message and gmDestroy) <> 0 then |
1593 if (Gear^.Message and gmDestroy) <> 0 then |
1523 begin |
1594 begin |