@@ -160,13 +160,18 @@ bool ShieldClass::ShieldIsBrokenTEvent(ObjectClass* pAttached)
160
160
161
161
int ShieldClass::ReceiveDamage (args_ReceiveDamage* args)
162
162
{
163
- if (!this ->HP || this ->Temporal || *args->Damage == 0 )
164
- return *args->Damage ;
163
+ int & damage = *args->Damage ;
164
+ int & health = this ->HP ;
165
+
166
+ if (!health || this ->Temporal || damage == 0 )
167
+ return damage;
168
+
169
+ auto const pTechno = this ->Techno ;
165
170
166
171
// Handle a special case where parasite damages shield but not the unit and unit itself cannot be targeted by repair weapons.
167
- if (*args-> Damage < 0 )
172
+ if (damage < 0 )
168
173
{
169
- if (auto const pFoot = abstract_cast<FootClass*, true >(this -> Techno ))
174
+ if (auto const pFoot = abstract_cast<FootClass*, true >(pTechno ))
170
175
{
171
176
if (auto const pParasite = pFoot->ParasiteEatingMe )
172
177
{
@@ -177,108 +182,114 @@ int ShieldClass::ReceiveDamage(args_ReceiveDamage* args)
177
182
}
178
183
}
179
184
180
- auto const pWHExt = WarheadTypeExt::ExtMap.Find (args->WH );
181
- bool IC = pWHExt->CanAffectInvulnerable (this ->Techno );
185
+ auto const pWH = args->WH ;
186
+ auto const pWHExt = WarheadTypeExt::ExtMap.Find (pWH);
187
+ const bool IC = pWHExt->CanAffectInvulnerable (pTechno);
188
+
189
+ if (!IC || CanBePenetrated (pWH) || TechnoExt::IsTypeImmune (pTechno, args->Attacker ))
190
+ return damage;
182
191
183
- if (!IC || CanBePenetrated (args->WH ) || this ->Techno ->GetTechnoType ()->Immune || TechnoExt::IsTypeImmune (this ->Techno , args->Attacker ))
184
- return *args->Damage ;
192
+ auto const pTechnoType = pTechno->GetTechnoType ();
193
+
194
+ if (pTechnoType->Immune )
195
+ return damage;
185
196
186
197
int nDamage = 0 ;
187
198
int shieldDamage = 0 ;
188
199
int healthDamage = 0 ;
200
+ auto const pType = this ->Type ;
189
201
190
- if (pWHExt->CanTargetHouse (args->SourceHouse , this -> Techno ) && !args-> WH ->Temporal )
202
+ if (pWHExt->CanTargetHouse (args->SourceHouse , pTechno ) && !pWH ->Temporal )
191
203
{
192
- if (*args-> Damage > 0 )
193
- nDamage = MapClass::GetTotalDamage (*args-> Damage , args-> WH , this ->GetArmorType (), args->DistanceToEpicenter );
204
+ if (damage > 0 )
205
+ nDamage = MapClass::GetTotalDamage (damage, pWH , this ->GetArmorType (pTechnoType ), args->DistanceToEpicenter );
194
206
else
195
- nDamage = -MapClass::GetTotalDamage (-*args-> Damage , args-> WH , this ->GetArmorType (), args->DistanceToEpicenter );
207
+ nDamage = -MapClass::GetTotalDamage (damage, pWH , this ->GetArmorType (pTechnoType ), args->DistanceToEpicenter );
196
208
197
- bool affectsShield = pWHExt->Shield_AffectTypes .size () <= 0 || pWHExt->Shield_AffectTypes .Contains (this -> Type );
198
- double absorbPercent = affectsShield ? pWHExt->Shield_AbsorbPercent .Get (this -> Type -> AbsorbPercent ) : this -> Type ->AbsorbPercent ;
199
- double passPercent = affectsShield ? pWHExt->Shield_PassPercent .Get (this -> Type -> PassPercent ) : this -> Type ->PassPercent ;
209
+ const bool affectsShield = pWHExt->Shield_AffectTypes .size () <= 0 || pWHExt->Shield_AffectTypes .Contains (pType );
210
+ const double absorbPercent = affectsShield ? pWHExt->Shield_AbsorbPercent .Get (pType-> AbsorbPercent ) : pType ->AbsorbPercent ;
211
+ const double passPercent = affectsShield ? pWHExt->Shield_PassPercent .Get (pType-> PassPercent ) : pType ->PassPercent ;
200
212
201
213
shieldDamage = (int )((double )nDamage * absorbPercent);
202
214
// passthrough damage shouldn't be affected by shield armor
203
- healthDamage = (int )((double )*args-> Damage * passPercent);
215
+ healthDamage = (int )((double )damage * passPercent);
204
216
}
205
217
206
- int originalShieldDamage = shieldDamage;
207
- int min = pWHExt->Shield_ReceivedDamage_Minimum .Get (this -> Type ->ReceivedDamage_Minimum );
208
- int max = pWHExt->Shield_ReceivedDamage_Maximum .Get (this -> Type ->ReceivedDamage_Maximum );
209
- int minDmg = static_cast <int >(min * pWHExt->Shield_ReceivedDamage_MinMultiplier );
210
- int maxDmg = static_cast <int >(max * pWHExt->Shield_ReceivedDamage_MaxMultiplier );
218
+ const int originalShieldDamage = shieldDamage;
219
+ const int min = pWHExt->Shield_ReceivedDamage_Minimum .Get (pType ->ReceivedDamage_Minimum );
220
+ const int max = pWHExt->Shield_ReceivedDamage_Maximum .Get (pType ->ReceivedDamage_Maximum );
221
+ const int minDmg = static_cast <int >(min * pWHExt->Shield_ReceivedDamage_MinMultiplier );
222
+ const int maxDmg = static_cast <int >(max * pWHExt->Shield_ReceivedDamage_MaxMultiplier );
211
223
shieldDamage = Math::clamp (shieldDamage, minDmg, maxDmg);
212
224
213
225
if (Phobos::DisplayDamageNumbers && shieldDamage != 0 )
214
- GeneralUtils::DisplayDamageNumberString (shieldDamage, DamageDisplayType::Shield, this -> Techno -> GetRenderCoords (), TechnoExt::ExtMap.Find (this -> Techno )->DamageNumberOffset );
226
+ GeneralUtils::DisplayDamageNumberString (shieldDamage, DamageDisplayType::Shield, pTechno-> GetRenderCoords (), TechnoExt::ExtMap.Find (pTechno )->DamageNumberOffset );
215
227
216
228
if (shieldDamage > 0 )
217
229
{
218
- bool whModifiersApplied = this ->Timers .SelfHealing_WHModifier .InProgress ();
219
- bool restart = whModifiersApplied ? this ->SelfHealing_RestartInCombat_Warhead : this -> Type ->SelfHealing_RestartInCombat ;
230
+ const bool whModifiersApplied = this ->Timers .SelfHealing_WHModifier .InProgress ();
231
+ const bool restart = whModifiersApplied ? this ->SelfHealing_RestartInCombat_Warhead : pType ->SelfHealing_RestartInCombat ;
220
232
221
233
if (restart)
222
234
{
223
- int delay = whModifiersApplied ? this ->SelfHealing_RestartInCombatDelay_Warhead : this -> Type ->SelfHealing_RestartInCombatDelay ;
235
+ const int delay = whModifiersApplied ? this ->SelfHealing_RestartInCombatDelay_Warhead : pType ->SelfHealing_RestartInCombatDelay ;
224
236
225
237
if (delay > 0 )
226
238
{
227
- this ->Timers .SelfHealing_CombatRestart .Start (this -> Type -> SelfHealing_RestartInCombatDelay );
239
+ this ->Timers .SelfHealing_CombatRestart .Start (delay );
228
240
this ->Timers .SelfHealing .Stop ();
229
241
}
230
242
else
231
243
{
232
- const int rate = whModifiersApplied ? this ->SelfHealing_Rate_Warhead : this -> Type ->SelfHealing_Rate ;
244
+ const int rate = whModifiersApplied ? this ->SelfHealing_Rate_Warhead : pType ->SelfHealing_Rate ;
233
245
this ->Timers .SelfHealing .Start (rate); // when attacked, restart the timer
234
246
}
235
247
}
236
-
237
248
if (!pWHExt->Nonprovocative )
238
249
this ->ResponseAttack ();
239
250
240
251
if (pWHExt->DecloakDamagedTargets )
241
- this -> Techno ->Uncloak (false );
252
+ pTechno ->Uncloak (false );
242
253
243
- int residueDamage = shieldDamage - this -> HP ;
254
+ const int residueDamage = shieldDamage - health ;
244
255
245
256
if (residueDamage >= 0 )
246
257
{
247
- int actualResidueDamage = Math::max (0 , int ((double )(originalShieldDamage - this -> HP ) /
248
- GeneralUtils::GetWarheadVersusArmor (args-> WH , this ->GetArmorType ()))); // only absord percentage damage
258
+ const int actualResidueDamage = Math::max (0 , int ((double )(originalShieldDamage - health ) /
259
+ GeneralUtils::GetWarheadVersusArmor (pWH , this ->GetArmorType (pTechnoType )))); // only absord percentage damage
249
260
250
261
this ->BreakShield (pWHExt->Shield_BreakAnim , pWHExt->Shield_BreakWeapon .Get (nullptr ));
251
262
252
- return this -> Type ->AbsorbOverDamage ? healthDamage : actualResidueDamage + healthDamage;
263
+ return pType ->AbsorbOverDamage ? healthDamage : actualResidueDamage + healthDamage;
253
264
}
254
265
else
255
266
{
256
- if (this -> Type ->HitFlash && pWHExt->Shield_HitFlash )
267
+ if (pType ->HitFlash && pWHExt->Shield_HitFlash )
257
268
{
258
- int size = this -> Type ->HitFlash_FixedSize .Get ((shieldDamage * 2 ));
269
+ const int size = pType ->HitFlash_FixedSize .Get ((shieldDamage * 2 ));
259
270
SpotlightFlags flags = SpotlightFlags::NoColor;
260
271
261
- if (this -> Type ->HitFlash_Black )
272
+ if (pType ->HitFlash_Black )
262
273
{
263
274
flags = SpotlightFlags::NoColor;
264
275
}
265
276
else
266
277
{
267
- if (!this -> Type ->HitFlash_Red )
278
+ if (!pType ->HitFlash_Red )
268
279
flags = SpotlightFlags::NoRed;
269
- if (!this -> Type ->HitFlash_Green )
280
+ if (!pType ->HitFlash_Green )
270
281
flags |= SpotlightFlags::NoGreen;
271
- if (!this -> Type ->HitFlash_Blue )
282
+ if (!pType ->HitFlash_Blue )
272
283
flags |= SpotlightFlags::NoBlue;
273
284
}
274
285
275
- MapClass::FlashbangWarheadAt (size, args-> WH , this -> Techno ->Location , true , flags);
286
+ MapClass::FlashbangWarheadAt (size, pWH, pTechno ->Location , true , flags);
276
287
}
277
288
278
289
if (!pWHExt->Shield_SkipHitAnim )
279
290
this ->WeaponNullifyAnim (pWHExt->Shield_HitAnim );
280
291
281
- this -> HP = -residueDamage;
292
+ health = -residueDamage;
282
293
283
294
this ->UpdateIdleAnim ();
284
295
@@ -287,13 +298,13 @@ int ShieldClass::ReceiveDamage(args_ReceiveDamage* args)
287
298
}
288
299
else if (shieldDamage < 0 )
289
300
{
290
- const int nLostHP = this -> Type -> Strength - this -> HP ;
301
+ const int nLostHP = pType-> Strength - health ;
291
302
292
303
if (!nLostHP)
293
304
{
294
- int result = *args-> Damage ;
305
+ int result = damage ;
295
306
296
- if (result * GeneralUtils::GetWarheadVersusArmor (args-> WH , this -> Techno ->GetTechnoType ()->Armor ) > 0 )
307
+ if (result * GeneralUtils::GetWarheadVersusArmor (pWH, pTechno ->GetTechnoType ()->Armor ) > 0 )
297
308
result = 0 ;
298
309
299
310
return result;
@@ -302,9 +313,9 @@ int ShieldClass::ReceiveDamage(args_ReceiveDamage* args)
302
313
const int nRemainLostHP = nLostHP + shieldDamage;
303
314
304
315
if (nRemainLostHP < 0 )
305
- this -> HP = this -> Type ->Strength ;
316
+ health = pType ->Strength ;
306
317
else
307
- this -> HP -= shieldDamage;
318
+ health -= shieldDamage;
308
319
309
320
this ->UpdateIdleAnim ();
310
321
@@ -1006,13 +1017,14 @@ int ShieldClass::DrawShieldBar_PipAmount(int length) const
1006
1017
: 0 ;
1007
1018
}
1008
1019
1009
- ArmorType ShieldClass::GetArmorType () const
1020
+ ArmorType ShieldClass::GetArmorType (TechnoTypeClass* pTechnoType ) const
1010
1021
{
1011
1022
const auto pShieldType = this ->Type ;
1012
1023
1013
1024
if (this ->Techno && pShieldType->InheritArmorFromTechno )
1014
1025
{
1015
- const auto pTechnoType = this ->Techno ->GetTechnoType ();
1026
+ if (!pTechnoType)
1027
+ pTechnoType = this ->Techno ->GetTechnoType ();
1016
1028
1017
1029
if (pShieldType->InheritArmor_Allowed .empty () || pShieldType->InheritArmor_Allowed .Contains (pTechnoType)
1018
1030
&& (pShieldType->InheritArmor_Disallowed .empty () || !pShieldType->InheritArmor_Disallowed .Contains (pTechnoType)))
0 commit comments