OverrideDefenseBypass
Tracking Issue: #1542
This feature allows mods to override the amount of armor mitigation, armor piercing, or minimum/mandatory armor mitigation for an attack on a case-by-case basis.
Normally this override would have been implemented as an event, but the implementing dev heard that events in To Hit Chance Calculation logic can cause issues, (see GetHitChanceEvents), and resorted to delegates in an attempt to resolve a crash he was unable to explain at the time.
This feature only applies to attacks using X2Effect_ApplyWeaponDamage,
or a subclass which has not overridden its GetDamagePreview() and CalculateDamageAmount
functions (except if they have included support for this feature).
Delegate structure
- array
AppliedDamageTypes: All damage types applied to the attack, to help determine the results. - out int bIgnoreArmor: Boolean value specifying whether the attack should ignore armor. Defaults to the corresponding value on the damage effect.
- out int bIgnoreShields: Boolean value specifying whether the attack should ignore ablative HP. Defaults to the corresponding value calculated by the damage effect.
- EffectAppliedData ApplyEffectParams: Effect context containing information such as the parent ability, source and target units, etc., to help determine the results.
- X2Effect_ApplyWeaponDamage Source: The effect itself, to help determine the results. Do not attempt to modify it or invoke functions which would have side effects.
- optional XComGameState NewGameState: The new game state after the attack resolves. If no game state was provided, then the delegate has been invoked by a damage preview.
How to use
Implement the following code in your mod's X2DownloadableContentInfo class:
static event OnPostTemplatesCreated()
{
local CHHelpers CHHelpersObj;
CHHelpersObj = class'CHHelpers'.static.GetCDO();
if (CHHelpersObj != none)
{
CHHelpersObj.AddOverrideDefenseBypassCallback(OverrideDefenseBypass);
}
}
// To avoid crashes associated with garbage collection failure when transitioning between Tactical and Strategy,
// this function must be bound to the ClassDefaultObject of your class. Having this function in a class that
// `extends X2DownloadableContentInfo` is the easiest way to ensure that.
static private function EHLDelegateReturn OverrideDefenseBypass(array<name> AppliedDamageTypes, out int bIgnoreArmor, out int bIgnoreShields, EffectAppliedData ApplyEffectParams, X2Effect_ApplyWeaponDamage Source, optional XComGameState NewGameState)
{
// Detect whether it's a damage preview. (... If you even care.)
// Then optionally modify either or both of bIgnoreArmor and bIgnoreShields.
// Return EHLDR_NoInterrupt or EHLDR_InterruptDelegates depending on
// if you want to allow other delegates to run after yours
// and potentially modify defense bypass further.
return EHLDR_NoInterrupt;
}
Delegate Priority
You can optionally specify callback Priority.
CHHelpersObj.AddOverrideDefenseBypassCallback(OverrideDefenseBypass, 45);
Delegates with higher Priority value are executed first.
Delegates with the same Priority are executed in the order they were added to CHHelpers,
which would normally be the same as DLCRunOrder.
This function will return true if the delegate was successfully registered.
Removing Delegates
If necessary, it's possible to remove a delegate.
CHHelpersObj.RemoveOverrideDefenseBypassCallback(OverrideDefenseBypass);
The function will return true if the Callback was successfully deleted, return false otherwise.