45 dmg, dmgRadius, dmgBase: LongInt; |
45 dmg, dmgRadius, dmgBase: LongInt; |
46 fX, fY: hwFloat; |
46 fX, fY: hwFloat; |
47 vg: PVisualGear; |
47 vg: PVisualGear; |
48 i, cnt: LongInt; |
48 i, cnt: LongInt; |
49 begin |
49 begin |
50 if Radius > 4 then AddFileLog('Explosion: at (' + inttostr(x) + ',' + inttostr(y) + ')'); |
50 if Radius > 4 then AddFileLog('Explosion: at (' + inttostr(x) + ',' + inttostr(y) + ')'); |
51 if Radius > 25 then KickFlakes(Radius, X, Y); |
51 if Radius > 25 then KickFlakes(Radius, X, Y); |
52 |
52 |
53 if ((Mask and EXPLNoGfx) = 0) then |
53 if ((Mask and EXPLNoGfx) = 0) then |
54 begin |
54 begin |
55 vg:= nil; |
55 vg:= nil; |
56 if Radius > 50 then vg:= AddVisualGear(X, Y, vgtBigExplosion) |
56 if Radius > 50 then vg:= AddVisualGear(X, Y, vgtBigExplosion) |
57 else if Radius > 10 then vg:= AddVisualGear(X, Y, vgtExplosion); |
57 else if Radius > 10 then vg:= AddVisualGear(X, Y, vgtExplosion); |
58 if vg <> nil then |
58 if vg <> nil then |
59 vg^.Tint:= Tint; |
59 vg^.Tint:= Tint; |
|
60 end; |
|
61 if (Mask and EXPLAutoSound) <> 0 then PlaySound(sndExplosion); |
|
62 |
|
63 if (Mask and EXPLAllDamageInRadius) = 0 then |
|
64 dmgRadius:= Radius shl 1 |
|
65 else |
|
66 dmgRadius:= Radius; |
|
67 dmgBase:= dmgRadius + cHHRadius div 2; |
|
68 fX:= int2hwFloat(X); |
|
69 fY:= int2hwFloat(Y); |
|
70 Gear:= GearsList; |
|
71 while Gear <> nil do |
|
72 begin |
|
73 dmg:= 0; |
|
74 //dmg:= dmgRadius + cHHRadius div 2 - hwRound(Distance(Gear^.X - int2hwFloat(X), Gear^.Y - int2hwFloat(Y))); |
|
75 //if (dmg > 1) and |
|
76 if (Gear^.State and gstNoDamage) = 0 then |
|
77 begin |
|
78 case Gear^.Kind of |
|
79 gtHedgehog, |
|
80 gtMine, |
|
81 gtBall, |
|
82 gtMelonPiece, |
|
83 gtGrenade, |
|
84 gtClusterBomb, |
|
85 // gtCluster, too game breaking I think |
|
86 gtSMine, |
|
87 gtCase, |
|
88 gtTarget, |
|
89 gtFlame, |
|
90 gtExplosives, |
|
91 gtStructure: begin |
|
92 // Run the calcs only once we know we have a type that will need damage |
|
93 if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then |
|
94 dmg:= dmgBase - max(hwRound(Distance(Gear^.X - fX, Gear^.Y - fY)),Gear^.Radius); |
|
95 if dmg > 1 then |
|
96 begin |
|
97 dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); |
|
98 //AddFileLog('Damage: ' + inttostr(dmg)); |
|
99 if (Mask and EXPLNoDamage) = 0 then |
|
100 begin |
|
101 if not Gear^.Invulnerable then |
|
102 ApplyDamage(Gear, AttackingHog, dmg, dsExplosion) |
|
103 else |
|
104 Gear^.State:= Gear^.State or gstWinner; |
|
105 end; |
|
106 if ((Mask and EXPLDoNotTouchAny) = 0) and (((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog)) then |
|
107 begin |
|
108 DeleteCI(Gear); |
|
109 Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - fX)/(Gear^.Density/_3); |
|
110 Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, Gear^.Y - fY)/(Gear^.Density/_3); |
|
111 |
|
112 Gear^.State:= (Gear^.State or gstMoving) and (not gstLoser); |
|
113 if not Gear^.Invulnerable then |
|
114 Gear^.State:= (Gear^.State or gstMoving) and (not gstWinner); |
|
115 Gear^.Active:= true; |
|
116 if Gear^.Kind <> gtFlame then FollowGear:= Gear |
|
117 end; |
|
118 if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (not Gear^.Invulnerable) then |
|
119 Gear^.Hedgehog^.Effects[hePoisoned] := true; |
|
120 end; |
|
121 |
|
122 end; |
|
123 gtGrave: begin |
|
124 // Run the calcs only once we know we have a type that will need damage |
|
125 if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then |
|
126 dmg:= dmgBase - hwRound(Distance(Gear^.X - fX, Gear^.Y - fY)); |
|
127 if dmg > 1 then |
|
128 begin |
|
129 dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); |
|
130 Gear^.dY:= - _0_004 * dmg; |
|
131 Gear^.Active:= true |
|
132 end |
|
133 end; |
|
134 end; |
60 end; |
135 end; |
61 if (Mask and EXPLAutoSound) <> 0 then PlaySound(sndExplosion); |
136 Gear:= Gear^.NextGear |
62 |
137 end; |
63 if (Mask and EXPLAllDamageInRadius) = 0 then |
138 |
64 dmgRadius:= Radius shl 1 |
139 if (Mask and EXPLDontDraw) = 0 then |
65 else |
140 if (GameFlags and gfSolidLand) = 0 then |
66 dmgRadius:= Radius; |
141 begin |
67 dmgBase:= dmgRadius + cHHRadius div 2; |
142 cnt:= DrawExplosion(X, Y, Radius) div 1608; // approx 2 16x16 circles to erase per chunk |
68 fX:= int2hwFloat(X); |
143 if (cnt > 0) and (SpritesData[sprChunk].Texture <> nil) then |
69 fY:= int2hwFloat(Y); |
144 for i:= 0 to cnt do |
70 Gear:= GearsList; |
145 AddVisualGear(X, Y, vgtChunk) |
71 while Gear <> nil do |
|
72 begin |
|
73 dmg:= 0; |
|
74 //dmg:= dmgRadius + cHHRadius div 2 - hwRound(Distance(Gear^.X - int2hwFloat(X), Gear^.Y - int2hwFloat(Y))); |
|
75 //if (dmg > 1) and |
|
76 if (Gear^.State and gstNoDamage) = 0 then |
|
77 begin |
|
78 case Gear^.Kind of |
|
79 gtHedgehog, |
|
80 gtMine, |
|
81 gtBall, |
|
82 gtMelonPiece, |
|
83 gtGrenade, |
|
84 gtClusterBomb, |
|
85 // gtCluster, too game breaking I think |
|
86 gtSMine, |
|
87 gtCase, |
|
88 gtTarget, |
|
89 gtFlame, |
|
90 gtExplosives, |
|
91 gtStructure: begin |
|
92 // Run the calcs only once we know we have a type that will need damage |
|
93 if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then |
|
94 dmg:= dmgBase - max(hwRound(Distance(Gear^.X - fX, Gear^.Y - fY)),Gear^.Radius); |
|
95 if dmg > 1 then |
|
96 begin |
|
97 dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); |
|
98 //AddFileLog('Damage: ' + inttostr(dmg)); |
|
99 if (Mask and EXPLNoDamage) = 0 then |
|
100 begin |
|
101 if not Gear^.Invulnerable then |
|
102 ApplyDamage(Gear, AttackingHog, dmg, dsExplosion) |
|
103 else |
|
104 Gear^.State:= Gear^.State or gstWinner; |
|
105 end; |
|
106 if ((Mask and EXPLDoNotTouchAny) = 0) and (((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog)) then |
|
107 begin |
|
108 DeleteCI(Gear); |
|
109 if Gear^.Kind <> gtHedgehog then |
|
110 begin |
|
111 Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - fX)/Gear^.Density; |
|
112 Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, Gear^.Y - fY)/Gear^.Density; |
|
113 end |
|
114 else |
|
115 begin |
|
116 Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - fX); |
|
117 Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, Gear^.Y - fY); |
|
118 end; |
|
119 |
|
120 Gear^.State:= (Gear^.State or gstMoving) and (not gstLoser); |
|
121 if not Gear^.Invulnerable then |
|
122 Gear^.State:= (Gear^.State or gstMoving) and (not gstWinner); |
|
123 Gear^.Active:= true; |
|
124 if Gear^.Kind <> gtFlame then FollowGear:= Gear |
|
125 end; |
|
126 if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (not Gear^.Invulnerable) then |
|
127 Gear^.Hedgehog^.Effects[hePoisoned] := true; |
|
128 end; |
|
129 |
|
130 end; |
|
131 gtGrave: begin |
|
132 // Run the calcs only once we know we have a type that will need damage |
|
133 if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then |
|
134 dmg:= dmgBase - hwRound(Distance(Gear^.X - fX, Gear^.Y - fY)); |
|
135 if dmg > 1 then |
|
136 begin |
|
137 dmg:= ModifyDamage(min(dmg div 2, Radius), Gear); |
|
138 Gear^.dY:= - _0_004 * dmg; |
|
139 Gear^.Active:= true |
|
140 end |
|
141 end; |
|
142 end; |
|
143 end; |
|
144 Gear:= Gear^.NextGear |
|
145 end; |
146 end; |
146 |
147 |
147 if (Mask and EXPLDontDraw) = 0 then |
148 uAIMisc.AwareOfExplosion(0, 0, 0) |
148 if (GameFlags and gfSolidLand) = 0 then |
|
149 begin |
|
150 cnt:= DrawExplosion(X, Y, Radius) div 1608; // approx 2 16x16 circles to erase per chunk |
|
151 if (cnt > 0) and (SpritesData[sprChunk].Texture <> nil) then |
|
152 for i:= 0 to cnt do |
|
153 AddVisualGear(X, Y, vgtChunk) |
|
154 end; |
|
155 |
|
156 uAIMisc.AwareOfExplosion(0, 0, 0) |
|
157 end; |
149 end; |
158 |
150 |
159 function ModifyDamage(dmg: Longword; Gear: PGear): Longword; |
151 function ModifyDamage(dmg: Longword; Gear: PGear): Longword; |
160 var i: hwFloat; |
152 var i: hwFloat; |
161 begin |
153 begin |