21 unit uGearsHedgehog; |
21 unit uGearsHedgehog; |
22 interface |
22 interface |
23 uses uTypes; |
23 uses uTypes; |
24 |
24 |
25 procedure doStepHedgehog(Gear: PGear); |
25 procedure doStepHedgehog(Gear: PGear); |
26 procedure AfterAttack; |
26 procedure AfterAttack; |
27 procedure HedgehogStep(Gear: PGear); |
27 procedure HedgehogStep(Gear: PGear); |
28 procedure doStepHedgehogMoving(Gear: PGear); |
28 procedure doStepHedgehogMoving(Gear: PGear); |
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 |
32 |
33 implementation |
33 implementation |
34 uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions, |
34 uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions, |
35 uCommands, uLocale, uUtils, uVisualGears, uStats, uIO, uScript, |
35 uCommands, uLocale, uUtils, uVisualGears, uStats, uIO, uScript, |
36 uGearsList, uGears, uCollisions, uRandom, uStore, uTeams, |
36 uGearsList, uGears, uCollisions, uRandom, uStore, uTeams, |
37 uGearsUtils; |
37 uGearsUtils; |
38 |
38 |
39 var GHStepTicks: LongWord = 0; |
39 var GHStepTicks: LongWord = 0; |
40 |
40 |
41 // Shouldn't more of this ammo switching stuff be moved to uAmmos ? |
41 // Shouldn't more of this ammo switching stuff be moved to uAmmos ? |
79 ammoidx:= -1; |
79 ammoidx:= -1; |
80 //TryDo(i < 2, 'Engine bug: no ammo in current slot', true) |
80 //TryDo(i < 2, 'Engine bug: no ammo in current slot', true) |
81 end; |
81 end; |
82 until (i = 1) or ((Ammo^[slot, ammoidx].Count > 0) |
82 until (i = 1) or ((Ammo^[slot, ammoidx].Count > 0) |
83 and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns)) |
83 and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns)) |
84 |
84 |
85 end |
85 end |
86 else |
86 else |
87 begin |
87 begin |
88 i:= 0; |
88 i:= 0; |
89 // check whether there is ammo in slot |
89 // check whether there is ammo in slot |
90 while (i <= cMaxSlotAmmoIndex) and ((Ammo^[slot, i].Count = 0) |
90 while (i <= cMaxSlotAmmoIndex) and ((Ammo^[slot, i].Count = 0) |
103 LoadHedgehogHat(HHGear^.Hedgehog^, 'Reserved/chef') |
103 LoadHedgehogHat(HHGear^.Hedgehog^, 'Reserved/chef') |
104 else if prevAmmo = amKnife then |
104 else if prevAmmo = amKnife then |
105 LoadHedgehogHat(HHGear^.Hedgehog^, Hat); |
105 LoadHedgehogHat(HHGear^.Hedgehog^, Hat); |
106 end; |
106 end; |
107 // Try again in the next slot |
107 // Try again in the next slot |
108 if CurAmmoType = prevAmmo then |
108 if CurAmmoType = prevAmmo then |
109 begin |
109 begin |
110 if slot >= cMaxSlotIndex then slot:= 0 else inc(slot); |
110 if slot >= cMaxSlotIndex then slot:= 0 else inc(slot); |
111 HHGear^.MsgParam:= slot; |
111 HHGear^.MsgParam:= slot; |
112 ChangeAmmo(HHGear) |
112 ChangeAmmo(HHGear) |
113 end |
113 end |
276 amPickHammer: newGear:= AddGear(hwRound(lx), hwRound(ly) + cHHRadius, gtPickHammer, 0, _0, _0, 0); |
276 amPickHammer: newGear:= AddGear(hwRound(lx), hwRound(ly) + cHHRadius, gtPickHammer, 0, _0, _0, 0); |
277 amSkip: ParseCommand('/skip', true); |
277 amSkip: ParseCommand('/skip', true); |
278 amRope: newGear:= AddGear(hwRound(lx), hwRound(ly), gtRope, 0, xx, yy, 0); |
278 amRope: newGear:= AddGear(hwRound(lx), hwRound(ly), gtRope, 0, xx, yy, 0); |
279 amMine: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000); |
279 amMine: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000); |
280 amSMine: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSMine, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); |
280 amSMine: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSMine, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); |
281 amKnife: begin |
281 amKnife: begin |
282 newGear:= AddGear(hwRound(lx), hwRound(ly), gtKnife, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); |
282 newGear:= AddGear(hwRound(lx), hwRound(ly), gtKnife, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0); |
283 newGear^.State:= newGear^.State or gstMoving; |
283 newGear^.State:= newGear^.State or gstMoving; |
284 newGear^.Radius:= 6 // temporarily shrink so it doesn't instantly embed in the ground |
284 newGear^.Radius:= 6 // temporarily shrink so it doesn't instantly embed in the ground |
285 end; |
285 end; |
286 amDEagle: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0); |
286 amDEagle: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0); |
287 amSineGun: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSineGunShot, 0, xx * _0_5, yy * _0_5, 0); |
287 amSineGun: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSineGunShot, 0, xx * _0_5, yy * _0_5, 0); |
288 amPortalGun: begin |
288 amPortalGun: begin |
289 newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtPortal, 0, xx * _0_6, yy * _0_6, |
289 newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtPortal, 0, xx * _0_6, yy * _0_6, |
290 // set selected color |
290 // set selected color |
291 CurWeapon^.Pos); |
291 CurWeapon^.Pos); |
292 end; |
292 end; |
293 amSniperRifle: begin |
293 amSniperRifle: begin |
294 PlaySound(sndSniperReload); |
294 PlaySound(sndSniperReload); |
372 amLandGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtLandGun, 0, xx * _0_5, yy * _0_5, 0); |
372 amLandGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtLandGun, 0, xx * _0_5, yy * _0_5, 0); |
373 amResurrector: begin |
373 amResurrector: begin |
374 newGear:= AddGear(hwRound(lx), hwRound(ly), gtResurrector, 0, _0, _0, 0); |
374 newGear:= AddGear(hwRound(lx), hwRound(ly), gtResurrector, 0, _0, _0, 0); |
375 newGear^.SoundChannel := LoopSound(sndResurrector); |
375 newGear^.SoundChannel := LoopSound(sndResurrector); |
376 end; |
376 end; |
377 amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000); |
377 //amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000); |
378 amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000); |
378 amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000); |
379 amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0); |
379 amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0); |
380 end; |
380 end; |
381 if altUse and (newGear <> nil) then |
381 if altUse and (newGear <> nil) then |
382 begin |
382 begin |
383 newGear^.dX:= newDx / newGear^.Density; |
383 newGear^.dX:= newDx / newGear^.Density; |
384 newGear^.dY:= newDY / newGear^.Density |
384 newGear^.dY:= newDY / newGear^.Density |
385 end; |
385 end; |
386 |
386 |
387 case CurAmmoType of |
387 case CurAmmoType of |
388 amGrenade, amMolotov, |
388 amGrenade, amMolotov, |
389 amClusterBomb, amGasBomb, |
389 amClusterBomb, amGasBomb, |
390 amBazooka, amSnowball, |
390 amBazooka, amSnowball, |
391 amBee, amSMine, |
391 amBee, amSMine, |
392 amMortar, amWatermelon, |
392 amMortar, amWatermelon, |
393 amHellishBomb, amDrill: FollowGear:= newGear; |
393 amHellishBomb, amDrill: FollowGear:= newGear; |
394 |
394 |
395 amShotgun, amPickHammer, |
395 amShotgun, amPickHammer, |
402 amSwitch, amRCPlane, |
402 amSwitch, amRCPlane, |
403 amKamikaze, amCake, |
403 amKamikaze, amCake, |
404 amSeduction, amBallgun, |
404 amSeduction, amBallgun, |
405 amJetpack, amBirdy, |
405 amJetpack, amBirdy, |
406 amFlamethrower, amLandGun, |
406 amFlamethrower, amLandGun, |
407 amResurrector, amStructure, |
407 amResurrector, //amStructure, |
408 amTardis, amPiano, |
408 amTardis, amPiano, |
409 amIceGun: CurAmmoGear:= newGear; |
409 amIceGun: CurAmmoGear:= newGear; |
410 end; |
410 end; |
411 |
411 |
412 if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then |
412 if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then |
413 newGear^.FlightTime:= GameTicks + 1000 |
413 newGear^.FlightTime:= GameTicks + 1000 |
414 else if CurAmmoType = amDrill then |
414 else if CurAmmoType = amDrill then |
415 newGear^.FlightTime:= GameTicks + 250; |
415 newGear^.FlightTime:= GameTicks + 250; |
416 if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then |
416 if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then |
430 |
430 |
431 if elastic < _1 then |
431 if elastic < _1 then |
432 newGear^.Elasticity:= newGear^.Elasticity * elastic |
432 newGear^.Elasticity:= newGear^.Elasticity * elastic |
433 else if elastic > _1 then |
433 else if elastic > _1 then |
434 newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic); |
434 newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic); |
435 (* Experimented with friction modifier. Didn't seem helpful |
435 (* Experimented with friction modifier. Didn't seem helpful |
436 fric:= int2hwfloat(CurWeapon^.Bounciness) / _250; |
436 fric:= int2hwfloat(CurWeapon^.Bounciness) / _250; |
437 if fric < _1 then newGear^.Friction:= newGear^.Friction * fric |
437 if fric < _1 then newGear^.Friction:= newGear^.Friction * fric |
438 else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*) |
438 else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*) |
439 end; |
439 end; |
440 |
440 |
486 a:= CurAmmoType; |
486 a:= CurAmmoType; |
487 if HHGear <> nil then HHGear^.State:= HHGear^.State and (not gstAttacking); |
487 if HHGear <> nil then HHGear^.State:= HHGear^.State and (not gstAttacking); |
488 if (Ammoz[a].Ammo.Propz and ammoprop_Effect) = 0 then |
488 if (Ammoz[a].Ammo.Propz and ammoprop_Effect) = 0 then |
489 begin |
489 begin |
490 Inc(MultiShootAttacks); |
490 Inc(MultiShootAttacks); |
491 |
491 |
492 if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) then |
492 if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) then |
493 begin |
493 begin |
494 s:= inttostr(Ammoz[a].Ammo.NumPerTurn - MultiShootAttacks + 1); |
494 s:= inttostr(Ammoz[a].Ammo.NumPerTurn - MultiShootAttacks + 1); |
495 AddCaption(format(trmsg[sidRemaining], s), cWhiteColor, capgrpAmmostate); |
495 AddCaption(format(trmsg[sidRemaining], s), cWhiteColor, capgrpAmmostate); |
496 end; |
496 end; |
497 |
497 |
498 if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) |
498 if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) |
499 or ((GameFlags and gfMultiWeapon) <> 0) then |
499 or ((GameFlags and gfMultiWeapon) <> 0) then |
500 begin |
500 begin |
501 isInMultiShoot:= true |
501 isInMultiShoot:= true |
502 end |
502 end |
535 begin |
535 begin |
536 AllInactive:= false; |
536 AllInactive:= false; |
537 dec(Gear^.Timer); |
537 dec(Gear^.Timer); |
538 if (Gear^.Timer mod frametime) = 0 then |
538 if (Gear^.Timer mod frametime) = 0 then |
539 inc(Gear^.Pos) |
539 inc(Gear^.Pos) |
540 end |
540 end |
541 else if Gear^.Timer = 1 then |
541 else if Gear^.Timer = 1 then |
542 begin |
542 begin |
543 Gear^.State:= Gear^.State or gstNoDamage; |
543 Gear^.State:= Gear^.State or gstNoDamage; |
544 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound); |
544 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound); |
545 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog; |
545 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog; |
546 DeleteGear(Gear); |
546 DeleteGear(Gear); |
547 SetAllToActive |
547 SetAllToActive |
548 end |
548 end |
549 else // Gear^.Timer = 0 |
549 else // Gear^.Timer = 0 |
550 begin |
550 begin |
551 AllInactive:= false; |
551 AllInactive:= false; |
552 Gear^.Z:= cCurrHHZ; |
552 Gear^.Z:= cCurrHHZ; |
553 RemoveGearFromList(Gear); |
553 RemoveGearFromList(Gear); |
634 else |
634 else |
635 case Gear^.Pos of |
635 case Gear^.Pos of |
636 posCaseUtility, |
636 posCaseUtility, |
637 posCaseAmmo: begin |
637 posCaseAmmo: begin |
638 PlaySound(sndShotgunReload); |
638 PlaySound(sndShotgunReload); |
639 if Gear^.AmmoType <> amNothing then |
639 if Gear^.AmmoType <> amNothing then |
640 begin |
640 begin |
641 AddPickup(HH^.Hedgehog^, Gear^.AmmoType, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y)); |
641 AddPickup(HH^.Hedgehog^, Gear^.AmmoType, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y)); |
642 end |
642 end |
643 else |
643 else |
644 begin |
644 begin |
645 // Add spawning here... |
645 // Add spawning here... |
646 AddRandomness(GameTicks); |
646 AddRandomness(GameTicks); |
647 |
647 |
648 gi := GearsList; |
648 gi := GearsList; |
649 while gi <> nil do |
649 while gi <> nil do |
650 begin |
650 begin |
651 if (gi^.Kind = gtGenericFaller) and (gi^.State and gstInvisible <> 0) then |
651 if (gi^.Kind = gtGenericFaller) and (gi^.State and gstInvisible <> 0) then |
652 begin |
652 begin |
840 if ((GameFlags and gfMoreWind) <> 0) and (((Gear^.Damage <> 0) |
840 if ((GameFlags and gfMoreWind) <> 0) and (((Gear^.Damage <> 0) |
841 or ((CurAmmoGear <> nil) and ((CurAmmoGear^.AmmoType = amJetpack) or (CurAmmoGear^.AmmoType = amBirdy))) |
841 or ((CurAmmoGear <> nil) and ((CurAmmoGear^.AmmoType = amJetpack) or (CurAmmoGear^.AmmoType = amBirdy))) |
842 or ((Gear^.dY.QWordValue + Gear^.dX.QWordValue) > _0_55.QWordValue))) then |
842 or ((Gear^.dY.QWordValue + Gear^.dX.QWordValue) > _0_55.QWordValue))) then |
843 Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density |
843 Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density |
844 end |
844 end |
845 end |
845 end |
846 else |
846 else |
847 begin |
847 begin |
848 land:= TestCollisionYwithGear(Gear, 1); |
848 land:= TestCollisionYwithGear(Gear, 1); |
849 if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_55.QWordValue) and ((land and lfIce) = 0) |
849 if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_55.QWordValue) and ((land and lfIce) = 0) |
850 and ((Gear^.State and gstHHJumping) <> 0) then |
850 and ((Gear^.State and gstHHJumping) <> 0) then |
897 if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) then |
897 if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) then |
898 begin |
898 begin |
899 Gear^.X:= Gear^.X + Gear^.dX; |
899 Gear^.X:= Gear^.X + Gear^.dX; |
900 Gear^.dX:= Gear^.dX * _0_93; |
900 Gear^.dX:= Gear^.dX * _0_93; |
901 Gear^.Y:= Gear^.Y - _2 |
901 Gear^.Y:= Gear^.Y - _2 |
902 end |
902 end |
903 else |
903 else |
904 if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) then |
904 if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) then |
905 begin |
905 begin |
906 Gear^.X:= Gear^.X + Gear^.dX; |
906 Gear^.X:= Gear^.X + Gear^.dX; |
907 Gear^.dX:= Gear^.dX * _0_9 ; |
907 Gear^.dX:= Gear^.dX * _0_9 ; |
961 begin |
961 begin |
962 Gear^.State:= Gear^.State and (not gstAnimation); |
962 Gear^.State:= Gear^.State and (not gstAnimation); |
963 // ARTILLERY but not being moved by explosions |
963 // ARTILLERY but not being moved by explosions |
964 Gear^.X:= Gear^.X + Gear^.dX; |
964 Gear^.X:= Gear^.X + Gear^.dX; |
965 Gear^.Y:= Gear^.Y + Gear^.dY; |
965 Gear^.Y:= Gear^.Y + Gear^.dY; |
966 if (not Gear^.dY.isNegative) and (not TestCollisionYKick(Gear, 1)) |
966 if (not Gear^.dY.isNegative) and (not TestCollisionYKick(Gear, 1)) |
967 and TestCollisionYwithXYShift(Gear, 0, 1, 1) then |
967 and TestCollisionYwithXYShift(Gear, 0, 1, 1) then |
968 begin |
968 begin |
969 CheckHHDamage(Gear); |
969 CheckHHDamage(Gear); |
970 Gear^.dY:= _0; |
970 Gear^.dY:= _0; |
971 Gear^.Y:= Gear^.Y + _1 |
971 Gear^.Y:= Gear^.Y + _1 |
1206 |
1206 |
1207 //////////////////////////////////////////////////////////////////////////////// |
1207 //////////////////////////////////////////////////////////////////////////////// |
1208 procedure doStepHedgehog(Gear: PGear); |
1208 procedure doStepHedgehog(Gear: PGear); |
1209 (* |
1209 (* |
1210 var x,y,tx,ty: LongInt; |
1210 var x,y,tx,ty: LongInt; |
1211 tdX, tdY, slope: hwFloat; |
1211 tdX, tdY, slope: hwFloat; |
1212 land: Word; *) |
1212 land: Word; *) |
1213 var slope: hwFloat; |
1213 var slope: hwFloat; |
1214 begin |
1214 begin |
1215 CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel; |
1215 CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel; |
1216 if (Gear^.Message and gmDestroy) <> 0 then |
1216 if (Gear^.Message and gmDestroy) <> 0 then |
1217 begin |
1217 begin |
1218 DeleteGear(Gear); |
1218 DeleteGear(Gear); |