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);
        }
Example #4
0
        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);
        }
Example #5
0
 public static void PushFlankingParameters(FlankingParameters parameters)
 {
     flankingParameters.Push(parameters);
 }