static void Prefix(RuleCheckTargetFlatFooted __instance) { bool ignore_initiative = (__instance.Target.Get <UnitPartNotFlatFootedBeforeInitiative>()?.active()).GetValueOrDefault(); bool is_flat_footed = __instance.ForceFlatFooted || !__instance.Target.CombatState.CanActInCombat && !__instance.IgnoreVisibility && !ignore_initiative || (__instance.Target.Descriptor.State.IsHelpless || __instance.Target.Descriptor.State.HasCondition(UnitCondition.Stunned) || !__instance.Target.Memory.Contains(__instance.Initiator) && !__instance.IgnoreVisibility) || (UnitPartConcealment.Calculate(__instance.Target, __instance.Initiator, false) == Concealment.Total && !__instance.IgnoreConcealment || __instance.Target.Descriptor.State.HasCondition(UnitCondition.LoseDexterityToAC)) || ((__instance.Target.Descriptor.State.HasCondition(UnitCondition.Shaken) || __instance.Target.Descriptor.State.HasCondition(UnitCondition.Frightened)) && (bool)__instance.Initiator.Descriptor.State.Features.ShatterDefenses); //TODO: fix shatter defenses not to apply on first hit var tr = Harmony12.Traverse.Create(__instance); tr.Property("IsFlatFooted").SetValue(is_flat_footed); }
static bool Prefix(UnitEntityData unit, UnitEntityData enemy, ref bool __result) { __result = false; if (!unit.Descriptor.State.CanAct) { return(false); } WeaponSlot threatHand = unit.GetThreatHand(); if (threatHand == null || !unit.IsReach(enemy, threatHand)) { var aoo_part = unit.Get <UnitPartSpecialAttackOfOportunity>(); if (aoo_part == null || !aoo_part.canMakeAoo(enemy)) { return(false); } } __result = UnitPartConcealment.Calculate(unit, enemy, false) != Concealment.Total; return(false); }