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);
        }
Exemplo n.º 5
0
        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);
        }