|
1 unit uGearUtils; |
|
2 interface |
|
3 uses uTypes; |
|
4 |
|
5 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord = $FFFFFFFF); |
|
6 |
|
7 implementation |
|
8 uses uGearsList; |
|
9 |
|
10 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord); |
|
11 var Gear: PGear; |
|
12 dmg, dmgRadius, dmgBase: LongInt; |
|
13 fX, fY: hwFloat; |
|
14 vg: PVisualGear; |
|
15 i, cnt: LongInt; |
|
16 begin |
|
17 if Radius > 4 then AddFileLog('Explosion: at (' + inttostr(x) + ',' + inttostr(y) + ')'); |
|
18 if Radius > 25 then KickFlakes(Radius, X, Y); |
|
19 |
|
20 if ((Mask and EXPLNoGfx) = 0) then |
|
21 begin |
|
22 vg:= nil; |
|
23 if Radius > 50 then vg:= AddVisualGear(X, Y, vgtBigExplosion) |
|
24 else if Radius > 10 then vg:= AddVisualGear(X, Y, vgtExplosion); |
|
25 if vg <> nil then |
|
26 vg^.Tint:= Tint; |
|
27 end; |
|
28 if (Mask and EXPLAutoSound) <> 0 then PlaySound(sndExplosion); |
|
29 |
|
30 if (Mask and EXPLAllDamageInRadius) = 0 then |
|
31 dmgRadius:= Radius shl 1 |
|
32 else |
|
33 dmgRadius:= Radius; |
|
34 dmgBase:= dmgRadius + cHHRadius div 2; |
|
35 fX:= int2hwFloat(X); |
|
36 fY:= int2hwFloat(Y); |
|
37 Gear:= GearsList; |
|
38 while Gear <> nil do |
|
39 begin |
|
40 dmg:= 0; |
|
41 //dmg:= dmgRadius + cHHRadius div 2 - hwRound(Distance(Gear^.X - int2hwFloat(X), Gear^.Y - int2hwFloat(Y))); |
|
42 //if (dmg > 1) and |
|
43 if (Gear^.State and gstNoDamage) = 0 then |
|
44 begin |
|
45 case Gear^.Kind of |
|
46 gtHedgehog, |
|
47 gtMine, |
|
48 gtBall, |
|
49 gtMelonPiece, |
|
50 gtGrenade, |
|
51 gtClusterBomb, |
|
52 // gtCluster, too game breaking I think |
|
53 gtSMine, |
|
54 gtCase, |
|
55 gtTarget, |
|
56 gtFlame, |
|
57 gtExplosives, |
|
58 gtStructure: begin |
|
59 // Run the calcs only once we know we have a type that will need damage |
|
60 if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then |
|
61 dmg:= dmgBase - max(hwRound(Distance(Gear^.X - fX, Gear^.Y - fY)),Gear^.Radius); |
|
62 if dmg > 1 then |
|
63 begin |
|
64 dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); |
|
65 //AddFileLog('Damage: ' + inttostr(dmg)); |
|
66 if (Mask and EXPLNoDamage) = 0 then |
|
67 begin |
|
68 if not Gear^.Invulnerable then |
|
69 ApplyDamage(Gear, AttackingHog, dmg, dsExplosion) |
|
70 else |
|
71 Gear^.State:= Gear^.State or gstWinner; |
|
72 end; |
|
73 if ((Mask and EXPLDoNotTouchAny) = 0) and (((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog)) then |
|
74 begin |
|
75 DeleteCI(Gear); |
|
76 if Gear^.Kind <> gtHedgehog then |
|
77 begin |
|
78 Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - fX)/Gear^.Density; |
|
79 Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, Gear^.Y - fY)/Gear^.Density; |
|
80 end |
|
81 else |
|
82 begin |
|
83 Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - fX); |
|
84 Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, Gear^.Y - fY); |
|
85 end; |
|
86 |
|
87 Gear^.State:= (Gear^.State or gstMoving) and (not gstLoser); |
|
88 if not Gear^.Invulnerable then |
|
89 Gear^.State:= (Gear^.State or gstMoving) and (not gstWinner); |
|
90 Gear^.Active:= true; |
|
91 if Gear^.Kind <> gtFlame then FollowGear:= Gear |
|
92 end; |
|
93 if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (not Gear^.Invulnerable) then |
|
94 Gear^.Hedgehog^.Effects[hePoisoned] := true; |
|
95 end; |
|
96 |
|
97 end; |
|
98 gtGrave: begin |
|
99 // Run the calcs only once we know we have a type that will need damage |
|
100 if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then |
|
101 dmg:= dmgBase - hwRound(Distance(Gear^.X - fX, Gear^.Y - fY)); |
|
102 if dmg > 1 then |
|
103 begin |
|
104 dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); |
|
105 Gear^.dY:= - _0_004 * dmg; |
|
106 Gear^.Active:= true |
|
107 end |
|
108 end; |
|
109 end; |
|
110 end; |
|
111 Gear:= Gear^.NextGear |
|
112 end; |
|
113 |
|
114 if (Mask and EXPLDontDraw) = 0 then |
|
115 if (GameFlags and gfSolidLand) = 0 then |
|
116 begin |
|
117 cnt:= DrawExplosion(X, Y, Radius) div 1608; // approx 2 16x16 circles to erase per chunk |
|
118 if (cnt > 0) and (SpritesData[sprChunk].Texture <> nil) then |
|
119 for i:= 0 to cnt do |
|
120 AddVisualGear(X, Y, vgtChunk) |
|
121 end; |
|
122 |
|
123 uAIMisc.AwareOfExplosion(0, 0, 0) |
|
124 end; |
|
125 |
|
126 end. |