@@ -160,13 +160,17 @@ 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
+
165
+ if (!this ->HP || this ->Temporal || damage == 0 )
166
+ return damage;
167
+
168
+ auto const pTechno = this ->Techno ;
165
169
166
170
// 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 )
171
+ if (damage < 0 )
168
172
{
169
- if (auto const pFoot = abstract_cast<FootClass*, true >(this -> Techno ))
173
+ if (auto const pFoot = abstract_cast<FootClass*, true >(pTechno ))
170
174
{
171
175
if (auto const pParasite = pFoot->ParasiteEatingMe )
172
176
{
@@ -177,59 +181,64 @@ int ShieldClass::ReceiveDamage(args_ReceiveDamage* args)
177
181
}
178
182
}
179
183
180
- auto const pWHExt = WarheadTypeExt::ExtMap.Find (args->WH );
181
- bool IC = pWHExt->CanAffectInvulnerable (this ->Techno );
184
+ auto const pWH = args->WH ;
185
+ auto const pWHExt = WarheadTypeExt::ExtMap.Find (pWH);
186
+ const bool IC = pWHExt->CanAffectInvulnerable (pTechno);
182
187
183
- if (!IC || CanBePenetrated (args-> WH ) || this -> Techno -> GetTechnoType ()->Immune || TechnoExt::IsTypeImmune (this -> Techno , args->Attacker ))
184
- return *args-> Damage ;
188
+ if (!IC || CanBePenetrated (pWH ) || pTechno-> GetTechnoType ()->Immune || TechnoExt::IsTypeImmune (pTechno , args->Attacker ))
189
+ return damage ;
185
190
186
191
int nDamage = 0 ;
187
192
int shieldDamage = 0 ;
188
193
int healthDamage = 0 ;
194
+ auto const pType = this ->Type ;
189
195
190
- if (pWHExt->CanTargetHouse (args->SourceHouse , this -> Techno ) && !args-> WH ->Temporal )
196
+ if (pWHExt->CanTargetHouse (args->SourceHouse , pTechno ) && !pWH ->Temporal )
191
197
{
192
- if (*args-> Damage > 0 )
193
- nDamage = MapClass::GetTotalDamage (*args-> Damage , args-> WH , this ->GetArmorType (), args->DistanceToEpicenter );
198
+ if (damage > 0 )
199
+ nDamage = MapClass::GetTotalDamage (damage, pWH , this ->GetArmorType (), args->DistanceToEpicenter );
194
200
else
195
- nDamage = -MapClass::GetTotalDamage (-*args-> Damage , args-> WH , this ->GetArmorType (), args->DistanceToEpicenter );
201
+ nDamage = -MapClass::GetTotalDamage (damage, pWH , this ->GetArmorType (), args->DistanceToEpicenter );
196
202
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 ;
203
+ const bool affectsShield = pWHExt->Shield_AffectTypes .size () <= 0 || pWHExt->Shield_AffectTypes .Contains (pType );
204
+ const double absorbPercent = affectsShield ? pWHExt->Shield_AbsorbPercent .Get (pType-> AbsorbPercent ) : pType ->AbsorbPercent ;
205
+ const double passPercent = affectsShield ? pWHExt->Shield_PassPercent .Get (pType-> PassPercent ) : pType ->PassPercent ;
200
206
201
207
shieldDamage = (int )((double )nDamage * absorbPercent);
202
208
// passthrough damage shouldn't be affected by shield armor
203
- healthDamage = (int )((double )*args-> Damage * passPercent);
209
+ healthDamage = (int )((double )damage * passPercent);
204
210
}
205
211
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 );
212
+ const int originalShieldDamage = shieldDamage;
213
+ const int min = pWHExt->Shield_ReceivedDamage_Minimum .Get (pType ->ReceivedDamage_Minimum );
214
+ const int max = pWHExt->Shield_ReceivedDamage_Maximum .Get (pType ->ReceivedDamage_Maximum );
215
+ const int minDmg = static_cast <int >(min * pWHExt->Shield_ReceivedDamage_MinMultiplier );
216
+ const int maxDmg = static_cast <int >(max * pWHExt->Shield_ReceivedDamage_MaxMultiplier );
211
217
shieldDamage = Math::clamp (shieldDamage, minDmg, maxDmg);
212
218
219
+ if (shieldDamage < 0 && TechnoExt::ExtMap.Find (pTechno)->AE .PreventNegativeDamage )
220
+ shieldDamage = 0 ;
221
+
213
222
if (Phobos::DisplayDamageNumbers && shieldDamage != 0 )
214
- GeneralUtils::DisplayDamageNumberString (shieldDamage, DamageDisplayType::Shield, this -> Techno -> GetRenderCoords (), TechnoExt::ExtMap.Find (this -> Techno )->DamageNumberOffset );
223
+ GeneralUtils::DisplayDamageNumberString (shieldDamage, DamageDisplayType::Shield, pTechno-> GetRenderCoords (), TechnoExt::ExtMap.Find (pTechno )->DamageNumberOffset );
215
224
216
225
if (shieldDamage > 0 )
217
226
{
218
- bool whModifiersApplied = this ->Timers .SelfHealing_WHModifier .InProgress ();
219
- bool restart = whModifiersApplied ? this ->SelfHealing_RestartInCombat_Warhead : this -> Type ->SelfHealing_RestartInCombat ;
227
+ const bool whModifiersApplied = this ->Timers .SelfHealing_WHModifier .InProgress ();
228
+ const bool restart = whModifiersApplied ? this ->SelfHealing_RestartInCombat_Warhead : pType ->SelfHealing_RestartInCombat ;
220
229
221
230
if (restart)
222
231
{
223
- int delay = whModifiersApplied ? this ->SelfHealing_RestartInCombatDelay_Warhead : this -> Type ->SelfHealing_RestartInCombatDelay ;
232
+ const int delay = whModifiersApplied ? this ->SelfHealing_RestartInCombatDelay_Warhead : pType ->SelfHealing_RestartInCombatDelay ;
224
233
225
234
if (delay > 0 )
226
235
{
227
- this ->Timers .SelfHealing_CombatRestart .Start (this -> Type ->SelfHealing_RestartInCombatDelay );
236
+ this ->Timers .SelfHealing_CombatRestart .Start (pType ->SelfHealing_RestartInCombatDelay );
228
237
this ->Timers .SelfHealing .Stop ();
229
238
}
230
239
else
231
240
{
232
- const int rate = whModifiersApplied ? this ->SelfHealing_Rate_Warhead : this -> Type ->SelfHealing_Rate ;
241
+ const int rate = whModifiersApplied ? this ->SelfHealing_Rate_Warhead : pType ->SelfHealing_Rate ;
233
242
this ->Timers .SelfHealing .Start (rate); // when attacked, restart the timer
234
243
}
235
244
}
@@ -238,41 +247,41 @@ int ShieldClass::ReceiveDamage(args_ReceiveDamage* args)
238
247
this ->ResponseAttack ();
239
248
240
249
if (pWHExt->DecloakDamagedTargets )
241
- this -> Techno ->Uncloak (false );
250
+ pTechno ->Uncloak (false );
242
251
243
- int residueDamage = shieldDamage - this ->HP ;
252
+ const int residueDamage = shieldDamage - this ->HP ;
244
253
245
254
if (residueDamage >= 0 )
246
255
{
247
- int actualResidueDamage = Math::max (0 , int ((double )(originalShieldDamage - this ->HP ) /
248
- GeneralUtils::GetWarheadVersusArmor (args-> WH , this ->GetArmorType ()))); // only absord percentage damage
256
+ const int actualResidueDamage = Math::max (0 , int ((double )(originalShieldDamage - this ->HP ) /
257
+ GeneralUtils::GetWarheadVersusArmor (pWH , this ->GetArmorType ()))); // only absord percentage damage
249
258
250
259
this ->BreakShield (pWHExt->Shield_BreakAnim , pWHExt->Shield_BreakWeapon .Get (nullptr ));
251
260
252
- return this -> Type ->AbsorbOverDamage ? healthDamage : actualResidueDamage + healthDamage;
261
+ return pType ->AbsorbOverDamage ? healthDamage : actualResidueDamage + healthDamage;
253
262
}
254
263
else
255
264
{
256
- if (this -> Type ->HitFlash && pWHExt->Shield_HitFlash )
265
+ if (pType ->HitFlash && pWHExt->Shield_HitFlash )
257
266
{
258
- int size = this -> Type ->HitFlash_FixedSize .Get ((shieldDamage * 2 ));
267
+ const int size = pType ->HitFlash_FixedSize .Get ((shieldDamage * 2 ));
259
268
SpotlightFlags flags = SpotlightFlags::NoColor;
260
269
261
- if (this -> Type ->HitFlash_Black )
270
+ if (pType ->HitFlash_Black )
262
271
{
263
272
flags = SpotlightFlags::NoColor;
264
273
}
265
274
else
266
275
{
267
- if (!this -> Type ->HitFlash_Red )
276
+ if (!pType ->HitFlash_Red )
268
277
flags = SpotlightFlags::NoRed;
269
- if (!this -> Type ->HitFlash_Green )
278
+ if (!pType ->HitFlash_Green )
270
279
flags |= SpotlightFlags::NoGreen;
271
- if (!this -> Type ->HitFlash_Blue )
280
+ if (!pType ->HitFlash_Blue )
272
281
flags |= SpotlightFlags::NoBlue;
273
282
}
274
283
275
- MapClass::FlashbangWarheadAt (size, args-> WH , this -> Techno ->Location , true , flags);
284
+ MapClass::FlashbangWarheadAt (size, pWH, pTechno ->Location , true , flags);
276
285
}
277
286
278
287
if (!pWHExt->Shield_SkipHitAnim )
0 commit comments