public static Concealment Calculate([NotNull] UnitEntityData initiator, [NotNull] UnitEntityData target, bool attack = false) { UnitPartConcealment unitPartConcealment = initiator.Get <UnitPartConcealment>(); UnitPartOutgoingConcealment unitPartOutgoingConcealment = initiator.Get <UnitPartOutgoingConcealment>(); if (unitPartOutgoingConcealment?.m_Concealments == null) { return(Concealment.None); //no concelement update } bool has_true_seeing = initiator.Descriptor.State.HasCondition(UnitCondition.TrueSeeing); Concealment a = Concealment.None; var ignore_fog_concealement_part = initiator.Get <UnitPartIgnoreFogConcealement>(); foreach (UnitPartConcealment.ConcealmentEntry concealment in unitPartOutgoingConcealment.m_Concealments) { if (concealment.Descriptor == ConcealmentDescriptor.Fog && ignore_fog_concealement_part != null && ignore_fog_concealement_part.active()) { continue; } if (concealment.Descriptor != ConcealmentDescriptor.Fog && concealment.Descriptor != ConcealmentDescriptor.InitiatorIsBlind && has_true_seeing) { continue; } if (!concealment.OnlyForAttacks || attack) { if (concealment.DistanceGreater > 0.Feet()) { float num1 = initiator.DistanceTo(target); float num2 = initiator.View.Corpulence + target.View.Corpulence; if ((double)num1 <= (double)concealment.DistanceGreater.Meters + (double)num2) { continue; } } if (concealment.RangeType.HasValue) { RuleAttackRoll ruleAttackRoll = Rulebook.CurrentContext.LastEvent <RuleAttackRoll>(); ItemEntityWeapon itemEntityWeapon = ruleAttackRoll == null?initiator.GetFirstWeapon() : ruleAttackRoll.Weapon; if (itemEntityWeapon == null || !AttackTypeAttackBonus.CheckRangeType(itemEntityWeapon.Blueprint, concealment.RangeType.Value)) { continue; } } a = UnitPartOutgoingConcealment.Max(a, concealment.Concealment); } } return(a); }
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); }
public static bool Prefix(UnitEntityData initiator, UnitEntityData target, bool attack, ref Concealment __result) { UnitPartConcealment unitPartConcealment1 = initiator.Get <UnitPartConcealment>(); UnitPartConcealment unitPartConcealment2 = target.Get <UnitPartConcealment>(); bool has_true_seeing = initiator.Descriptor.State.HasCondition(UnitCondition.TrueSeeing); if (unitPartConcealment1 != null && unitPartConcealment1.IgnoreAll) { __result = Concealment.None; return(false); } List <Feet> m_BlindsightRanges = Harmony12.Traverse.Create(unitPartConcealment1).Field("m_BlindsightRanges").GetValue <List <Feet> >(); if (m_BlindsightRanges != null) { Feet feet = 0.Feet(); foreach (Feet blindsightRange in m_BlindsightRanges) { if (feet < blindsightRange) { feet = blindsightRange; } } float num = initiator.View.Corpulence + target.View.Corpulence; if ((double)initiator.DistanceTo(target) - (double)num <= (double)feet.Meters) { __result = Concealment.None; return(false); } } Concealment a = Concealment.None; if (!initiator.Descriptor.IsSeeInvisibility && target.Descriptor.State.HasCondition(UnitCondition.Invisible)) { a = Concealment.Total; } var ignore_fog_concealement_part = initiator.Get <UnitPartIgnoreFogConcealement>(); List <UnitPartConcealment.ConcealmentEntry> m_Concealments = Harmony12.Traverse.Create(unitPartConcealment2).Field("m_Concealments").GetValue <List <UnitPartConcealment.ConcealmentEntry> >(); var all_concealements = m_Concealments?.ToArray() ?? new UnitPartConcealment.ConcealmentEntry[0]; var specific_concealment_part = target.Get <UnitPartISpecificConcealment>(); if (specific_concealment_part != null) { all_concealements = all_concealements.AddToArray(specific_concealment_part.GetConcealments(initiator)); } if (a < Concealment.Total && !all_concealements.Empty()) { foreach (UnitPartConcealment.ConcealmentEntry concealment in all_concealements) { if (concealment.Descriptor == ConcealmentDescriptor.Fog && ignore_fog_concealement_part != null && ignore_fog_concealement_part.active()) { continue; } if (concealment.Descriptor != ConcealmentDescriptor.Fog && concealment.Descriptor != ConcealmentDescriptor.InitiatorIsBlind && has_true_seeing) { continue; } if (!concealment.OnlyForAttacks || attack) { if (concealment.DistanceGreater > 0.Feet()) { float num1 = initiator.DistanceTo(target); float num2 = initiator.View.Corpulence + target.View.Corpulence; if ((double)num1 <= (double)concealment.DistanceGreater.Meters + (double)num2) { continue; } } if (concealment.RangeType.HasValue) { RuleAttackRoll ruleAttackRoll = Rulebook.CurrentContext.LastEvent <RuleAttackRoll>(); ItemEntityWeapon itemEntityWeapon = ruleAttackRoll == null?initiator.GetFirstWeapon() : ruleAttackRoll.Weapon; if (itemEntityWeapon == null || !AttackTypeAttackBonus.CheckRangeType(itemEntityWeapon.Blueprint, concealment.RangeType.Value)) { continue; } } a = a > concealment.Concealment ? a : concealment.Concealment; } } } if (unitPartConcealment2 != null && unitPartConcealment2.Disable) { a = Concealment.None; } if (initiator.Descriptor.State.HasCondition(UnitCondition.Blindness)) { a = Concealment.Total; } if (initiator.Descriptor.State.HasCondition(UnitCondition.PartialConcealmentOnAttacks)) { a = Concealment.Partial; } if (a == Concealment.None && (ignore_fog_concealement_part == null || !ignore_fog_concealement_part.active()) && Game.Instance.Player.Weather.ActualWeather >= BlueprintRoot.Instance.WeatherSettings.ConcealmentBeginsOn) { RuleAttackRoll ruleAttackRoll = Rulebook.CurrentContext.LastEvent <RuleAttackRoll>(); ItemEntityWeapon itemEntityWeapon = ruleAttackRoll == null?initiator.GetFirstWeapon() : ruleAttackRoll.Weapon; if (itemEntityWeapon != null && AttackTypeAttackBonus.CheckRangeType(itemEntityWeapon.Blueprint, AttackTypeAttackBonus.WeaponRangeType.Ranged)) { a = Concealment.Partial; } } a = UnitPartOutgoingConcealment.Max(UnitPartOutgoingConcealment.Calculate(initiator, target, attack), a); if (unitPartConcealment1 != null && unitPartConcealment1.IgnorePartial && a == Concealment.Partial) { a = Concealment.None; } if (unitPartConcealment1 != null && unitPartConcealment1.TreatTotalAsPartial && a == Concealment.Total) { a = Concealment.Partial; } __result = a; return(false); }
public static Concealment Calculate([NotNull] UnitEntityData initiator, [NotNull] UnitEntityData target, bool attack = false) { UnitPartConcealment unitPartConcealment = initiator.Get <UnitPartConcealment>(); UnitPartOutgoingConcealment unitPartOutgoingConcealment = initiator.Get <UnitPartOutgoingConcealment>(); if (unitPartOutgoingConcealment?.m_Concealments == null) { return(Concealment.None); //no concelement update } if (unitPartConcealment != null) { List <Feet> m_BlindsightRanges = Harmony12.Traverse.Create(unitPartConcealment).Field("m_BlindsightRanges").GetValue <List <Feet> >(); if (m_BlindsightRanges != null) { Feet feet = 0.Feet(); foreach (Feet blindsightRange in m_BlindsightRanges) { if (feet < blindsightRange) { feet = blindsightRange; } } float num = initiator.View.Corpulence + target.View.Corpulence; if ((double)initiator.DistanceTo(target) - (double)num <= (double)feet.Meters) { return(Concealment.None); } } } Concealment a = Concealment.None; foreach (UnitPartConcealment.ConcealmentEntry concealment in unitPartOutgoingConcealment.m_Concealments) { if (!concealment.OnlyForAttacks || attack) { if (concealment.DistanceGreater > 0.Feet()) { float num1 = initiator.DistanceTo(target); float num2 = initiator.View.Corpulence + target.View.Corpulence; if ((double)num1 <= (double)concealment.DistanceGreater.Meters + (double)num2) { continue; } } if (concealment.RangeType.HasValue) { RuleAttackRoll ruleAttackRoll = Rulebook.CurrentContext.LastEvent <RuleAttackRoll>(); ItemEntityWeapon itemEntityWeapon = ruleAttackRoll == null?initiator.GetFirstWeapon() : ruleAttackRoll.Weapon; if (itemEntityWeapon == null || !AttackTypeAttackBonus.CheckRangeType(itemEntityWeapon.Blueprint, concealment.RangeType.Value)) { continue; } } a = UnitPartOutgoingConcealment.Max(a, concealment.Concealment); } } return(a); }