static bool Prefix(RuleCalculateAttackBonus __instance, RulebookEventContext context) { FlankingParameters flankedParameters = new FlankingParameters(typeof(RuleCalculateAttackBonus_OnTrigger_Patch), __instance.Initiator); UnitCombatState_get_IsFlanked_Patch.PushFlankingParameters(flankedParameters); return(true); }
static bool Prefix(RulePrepareDamage __instance, RulebookEventContext context) { FlankingParameters flankedParameters = new FlankingParameters(typeof(RulePrepareDamage_OnTrigger_Patch), __instance.Initiator, true, null, null); UnitCombatState_get_IsFlanked_Patch.PushFlankingParameters(flankedParameters); return(true); }
static bool Prefix(PreciseStrike __instance, RulePrepareDamage evt) { BlueprintUnitFact preciseStrikeFact = __instance.PreciseStrikeFact; Func <UnitEntityData, UnitEntityData, UnitEntityData, bool> hasPreciseStrike = (target, owner, flankingPartner) => owner.Descriptor.State.Features.SoloTactics || flankingPartner.Descriptor.HasFact(preciseStrikeFact); FlankingParameters flankingParameters = new FlankingParameters(typeof(PreciseStrike_OnEventAboutToTrigger_Patch), __instance.Owner.Unit, hasPreciseStrike); UnitCombatState_get_IsFlanked_Patch.PushFlankingParameters(flankingParameters); return(true); }
static bool Prefix(UnitCombatState __instance, ref bool __result) { __result = false; // Without flanking parameters, this won't work, so the result is always false. This means all methods that call IsFlanked need // to be made compatible, however the alternative would be to defer to the base IsFlanked behaviour, which would result in // unpredictable behaviour. if (flankingParameters.Count <= 0) { return(false); } FlankingParameters currentParameters = flankingParameters.Pop(); // Nonsensical parameters => false if (currentParameters.FlankedBy == null && !currentParameters.FlankedByAnyone || currentParameters.FlankedBy != null && currentParameters.FlankedByAnyone) { return(false); } // Check if a specific unit is flanking the target (with a possible extra preconditions test) if (currentParameters.FlankedBy != null && !currentParameters.FlankedByAnyone) { __result = __instance.Unit.IsFlankedByUnit(currentParameters.FlankedBy, currentParameters.FlankingPreconditions); } // Check if the target is by any two attackers (adhering to possible preconditions) else if (currentParameters.FlankedByAnyone) { foreach (UnitEntityData unitEntityData in __instance.EngagedBy) { // Ignore the ExceptFlankedBy unit (if it is not null) for the flanking test if (currentParameters.ExceptFlankedBy == null || unitEntityData != currentParameters.ExceptFlankedBy) { if (__instance.Unit.IsFlankedByUnit(unitEntityData, currentParameters.FlankingPreconditions)) { __result = true; break; } } } } return(false); }
public static void PushFlankingParameters(FlankingParameters parameters) { flankingParameters.Push(parameters); }