Ejemplo n.º 1
0
        public void OnEventDidTrigger(RuleAttackRoll evt)
        {
            if (did_swap)
            {
                ThrowAnything.toggleThrown(base.Owner.Body.PrimaryHand.Weapon, evt.Initiator);
            }
            did_swap = false;
            RuleAttackRoll.ParryData parry = evt.Parry;
            if (((parry != null) ? parry.Initiator : null) != base.Owner.Unit)
            {
                return;
            }

            if (!evt.Parry.IsTriggered)
            {
                return;
            }

            evt.Target.Descriptor.Resources.Spend(resource, cost);

            if (evt.Result == AttackResult.Parried && evt.Target.Descriptor.Resources.GetResourceAmount(resource) >= cost)
            {
                Game.Instance.CombatEngagementController.ForceAttackOfOpportunity(base.Owner.Unit, evt.Initiator);
            }

            //base.Owner.RemoveFact(base.Fact); Unsure what this does in context of original parry

            IFactContextOwner factContextOwner = base.Fact as IFactContextOwner;

            if (factContextOwner != null)
            {
                factContextOwner.RunActionInContext(CreateActionList(Create <ContextActionRemoveSelf>()), evt.Initiator);
            }
        }
Ejemplo n.º 2
0
        static bool Prefix(RuleAttackRoll __instance, RulebookEventContext context)
        {
            FlankingParameters flankedParameters = new FlankingParameters(typeof(RuleAttackRoll_OnTrigger_Patch), __instance.Initiator);

            UnitCombatState_get_IsFlanked_Patch.PushFlankingParameters(flankedParameters);
            return(true);
        }
Ejemplo n.º 3
0
 static void Postfix(ref bool __result, RuleAttackRoll __instance)
 {
     if (UnitEntityDataUtils.CheckUnitEntityData(__instance.Initiator, settings.allHitsCritical))
     {
         __result = true;
     }
 }
 public void OnEventAboutToTrigger(RuleAttackRoll evt)
 {
     if (evt.Target.Descriptor == Descriptor)
     {
         evt.AddTemporaryModifier(evt.Initiator.Stats.AdditionalAttackBonus.AddModifier(_bonus, Source, (string)null, ModifierDescriptor.FavoredEnemy));
     }
 }
Ejemplo n.º 5
0
        public override IEnumerator <AbilityDeliveryTarget> Deliver(AbilityExecutionContext context, TargetWrapper target)
        {
            UnitEntityData caster = context.MaybeCaster;

            if (caster == null)
            {
                UberDebug.LogError("Caster is missing", Array.Empty <object>());
                yield break;
            }

            RulebookEventContext rulebookContext      = context.RulebookContext;
            RuleAttackWithWeapon attackWithWeapon     = (rulebookContext != null) ? rulebookContext.AllEvents.LastOfType <RuleAttackWithWeapon>() : null;
            RuleAttackWithWeapon ruleAttackWithWeapon = attackWithWeapon;
            RuleAttackRoll       attackRoll           = (ruleAttackWithWeapon != null) ? ruleAttackWithWeapon.AttackRoll : null;

            attackRoll = (attackRoll ?? context.TriggerRule <RuleAttackRoll>(new RuleAttackRoll(caster, target.Unit, caster.GetFirstWeapon(), 0)));
            if (attackWithWeapon == null)
            {
                attackRoll.ConsumeMirrorImageIfNecessary();
            }
            yield return(new AbilityDeliveryTarget(target)
            {
                AttackRoll = attackRoll
            });

            yield break;
        }
 public void OnEventAboutToTrigger(RuleAttackRoll evt)
 {
     if (this.Owner.Wielder == null || evt.Weapon != this.Owner)
     {
         return;
     }
     evt.AttackType = AttackType.Touch;
 }
Ejemplo n.º 7
0
        public void OnEventAboutToTrigger(RuleAttackRoll evt)
        {
            if (evt.Target.Descriptor.Resources.GetResourceAmount(resource) < cost)
            {
                return;
            }

            if ((base.Owner.Body.PrimaryHand.Weapon.Blueprint.Category == WeaponCategory.Dagger || base.Owner.Body.PrimaryHand.Weapon.Blueprint.Category == WeaponCategory.Starknife) && base.Owner.Body.PrimaryHand.Weapon.Blueprint.IsRanged)
            {
                ThrowAnything.toggleThrown(base.Owner.Body.PrimaryHand.Weapon, evt.Initiator);
                did_swap = true;
            }

            if (!evt.Weapon.Blueprint.IsMelee || evt.Parry != null || !base.Owner.Unit.IsEnemy(evt.Initiator))
            {
                return;
            }
            if (evt.Target != base.Owner.Unit)
            {
                return;
            }
            if (!base.Owner.Unit.IsReach(evt.Target, base.Owner.Body.PrimaryHand))
            {
                return;
            }
            //TODO - Conditions?

            /*
             * if (this.AttackerCondition.HasConditions)
             * {
             *  MechanicsContext maybeContext = base.Fact.MaybeContext;
             *  using ((maybeContext != null) ? maybeContext.GetDataScope(evt.Initiator) : null)
             *  {
             *      if (!this.AttackerCondition.Check(null))
             *      {
             *          return;
             *      }
             *  }
             * }
             */

            evt.TryParry(base.Owner.Unit, base.Owner.Body.PrimaryHand.Weapon, 0);
            if (evt.Parry == null)
            {
                return;
            }
            ModifiableValue additionalAttackBonus = base.Owner.Stats.AdditionalAttackBonus;
            int             num = evt.Initiator.Descriptor.State.Size - base.Owner.State.Size;

            if (num > 0)
            {
                int value = -2 * num;
                evt.AddTemporaryModifier(additionalAttackBonus.AddModifier(value, this, ModifierDescriptor.Penalty));
            }
        }
Ejemplo n.º 8
0
        public void OnEventDidTrigger(RuleAttackRoll evt)
        {
            if (!remove_after_attack)
            {
                return;
            }

            if (evt.Initiator == this.Fact.MaybeContext?.MaybeCaster)
            {
                this.Buff.Remove();
            }
        }
Ejemplo n.º 9
0
 static bool Prefix(RuleAttackRoll __instance, int value)
 {
     if (value > 0 &&
         __instance.Target.IsPlayerFaction &&
         Kineticist.hurricane_queen_feat != null &&
         __instance.Target.Descriptor.Progression.Features.HasFact(Kineticist.hurricane_queen_feat))
     {
         Harmony12.AccessTools.Property(typeof(RuleAttackRoll), "MissChance").SetValue(__instance, Math.Min(value, 100));
         return(false);
     }
     return(true);
 }
        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);
        }
Ejemplo n.º 11
0
 static bool Prefix(OutflankProvokeAttack __instance, RuleAttackRoll evt)
 {
     if (!evt.IsCriticalConfirmed || !evt.Target.isFlankedByAttacker(__instance.Owner.Unit))
     {
         return(false);
     }
     foreach (UnitEntityData attacker in evt.Target.CombatState.EngagedBy)
     {
         if ((((attacker.Descriptor.HasFact(__instance.OutflankFact) || (bool)__instance.Owner.State.Features.SoloTactics) && attacker != __instance.Owner.Unit)) &&
             evt.Target.isFlankedByAttacker(attacker))
         {
             Game.Instance.CombatEngagementController.ForceAttackOfOpportunity(attacker, evt.Target);
         }
     }
     return(false);
 }
        //force to always calcualte ruleAttackBonus
        static bool Prefix(RuleAttackRoll __instance)
        {
            var tr = Harmony12.Traverse.Create(__instance);

            if (!__instance.WeaponStats.IsTriggererd)
            {
                Rulebook.Trigger <RuleCalculateWeaponStats>(__instance.WeaponStats);
            }

            tr.Property("ACRule").SetValue(Rulebook.Trigger <RuleCalculateAC>(new RuleCalculateAC(__instance.Initiator, __instance.Target, __instance.AttackType)));
            tr.Property("IsTargetFlatFooted").SetValue(__instance.ACRule.IsTargetFlatFooted);
            tr.Property("TargetAC").SetValue(__instance.ACRule.TargetAC);
            tr.Property("AttackBonusRule").SetValue(Rulebook.Trigger <RuleCalculateAttackBonus>(new RuleCalculateAttackBonus(__instance.Initiator, __instance.Target, __instance.Weapon, __instance.AttackBonusPenalty)));
            tr.Property("AttackBonus").SetValue(__instance.AttackBonusRule.Result);

            return(true);
        }
Ejemplo n.º 13
0
 private void TryRunActions(RuleAttackRoll rule)
 {
     if (!this.CheckCondition(rule))
     {
         return;
     }
     if (!this.ActionsOnInitiator)
     {
         using (new ContextAttackData(rule, (Projectile)null))
             (this.Fact as IFactContextOwner)?.RunActionInContext(this.Action, (TargetWrapper)rule.Target);
     }
     else
     {
         using (new ContextAttackData(rule, (Projectile)null))
             (this.Fact as IFactContextOwner)?.RunActionInContext(this.Action, (TargetWrapper)rule.Initiator);
     }
 }
        public void OnEventAboutToTrigger(RuleAttackRoll evt)
        {
            var unit_part_fe = this.Owner.Get <UnitPartFavoredEnemy>();

            if (unit_part_fe == null)
            {
                return;
            }

            foreach (var fe in unit_part_fe.Entries)
            {
                if ((fe.CheckedFeatures).Any <BlueprintUnitFact>((Func <BlueprintUnitFact, bool>)(p => evt.Initiator.Descriptor.HasFact(p))))
                {
                    evt.AddTemporaryModifier(evt.Target.Stats.AC.AddModifier(this.value.Calculate(this.Fact.MaybeContext) * this.Fact.GetRank(), (GameLogicComponent)this, this.descriptor));
                    break;
                }
            }
        }
Ejemplo n.º 15
0
        internal static void OutflankProvokeAttackPatch(RuleAttackRoll attackRollInstance, RulebookEventContext context)
        {
            if (!attackRollInstance.IsCriticalConfirmed)
            {
                return;
            }

            var outflankFeature = library.Get <BlueprintFeature>("422dab7309e1ad343935f33a4d6e9f11");

            Func <UnitEntityData, UnitEntityData, UnitEntityData, bool> outflankParticipantConditions =
                (target, aooTestUnit, attacker) => aooTestUnit.Descriptor.State.Features.SoloTactics || aooTestUnit.Descriptor.HasFact(outflankFeature) && attacker.Descriptor.HasFact(outflankFeature);

            foreach (UnitEntityData aooTestUnit in attackRollInstance.Target.CombatState.EngagedBy)
            {
                if (attackRollInstance.Target.IsFlankedByUnits(aooTestUnit, attackRollInstance.Initiator, outflankParticipantConditions))
                {
                    Main.Logger?.Write("Outflank provoked AoO");
                    Game.Instance.CombatEngagementController.ForceAttackOfOpportunity(aooTestUnit, attackRollInstance.Target);
                }
            }
        }
Ejemplo n.º 16
0
        private bool CheckCondition(RuleAttackRoll evt)
        {
            Main.logger.Log(evt.Weapon.Blueprint.name);
            ItemEntity owner = (this.Fact as ItemEnchantment)?.Owner;

            if (owner != null && owner != evt.Weapon ||
                (this.WeaponType != null && this.WeaponType != evt.Weapon.Blueprint.Type || this.CheckWeaponCategory && this.Category != evt.Weapon.Blueprint.Category) ||
                (this.CheckWeaponRangeType && !AttackTypeAttackBonus.CheckRangeType(evt.Weapon.Blueprint, this.RangeType)) ||
                this.AllNaturalAndUnarmed && !evt.Weapon.Blueprint.Type.IsNatural && !evt.Weapon.Blueprint.Type.IsUnarmed)
            {
                return(false);
            }

            if (this.CheckDistance && (double)evt.Target.DistanceTo(evt.Initiator) > (double)this.DistanceLessEqual.Meters)
            {
                return(false);
            }
            bool flag = evt.Weapon.Blueprint.Category.HasSubCategory(WeaponSubCategory.Light) || evt.Weapon.Blueprint.Category.HasSubCategory(WeaponSubCategory.OneHandedPiercing) || (bool)evt.Initiator.Descriptor.State.Features.DuelingMastery && evt.Weapon.Blueprint.Category == WeaponCategory.DuelingSword || evt.Initiator.Descriptor.Ensure <DamageGracePart>().HasEntry(evt.Weapon.Blueprint.Category);

            return(!this.DuelistWeapon || flag);
        }
        internal static bool ignoreMirrorImage(UnitEntityData initiator, RuleAttackRoll rule_attack_roll)
        {
            var target = rule_attack_roll.Target;

            if (initiator.Descriptor.IsImmuneToVisualEffects)
            {
                return(true);
            }

            var unit_part_concealement = initiator.Get <UnitPartConcealment>();

            if (unit_part_concealement == null)
            {
                return(false);
            }

            List <Feet> m_BlindsightRanges = Harmony12.Traverse.Create(unit_part_concealement).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(true);
                }
            }

            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 void OnEventAboutToTrigger(RuleAttackRoll evt)
 {
     evt.AutoMiss = true;
 }
Ejemplo n.º 20
0
 static bool Prefix(OutflankProvokeAttack __instance, RuleAttackRoll evt)
 {
     return(false);
 }
Ejemplo n.º 21
0
 static void Postfix(RuleAttackRoll __instance, RulebookEventContext context)
 {
     OutflankPatch.OutflankProvokeAttackPatch(__instance, context);
 }
Ejemplo n.º 22
0
 static void Postfix(ProjectileController __instance, UnitEntityData launcher, TargetWrapper target, BlueprintProjectile projectileBlueprint, RuleAttackRoll attackRoll, RulebookEvent ruleOnHit, Projectile __result)
 {
     if (projectileBlueprint == thrown_weapon_proj)
     {
         var        weapon     = attackRoll.Weapon;
         GameObject gameObject = UnityEngine.Object.Instantiate <GameObject>(weapon.Blueprint.VisualParameters.Model, __result.View.transform);
         gameObject.transform.localPosition = Vector3.zero;
         gameObject.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
         gameObject.transform.localScale    = Vector3.one;
         __result.MaxRange = weapon.AttackRange.Meters;
     }
 }
Ejemplo n.º 23
0
 public void OnEventAboutToTrigger(RuleAttackRoll evt)
 {
     evt.AttackType = AttackType.Touch;
 }
 public void OnEventDidTrigger(RuleAttackRoll evt)
 {
 }
Ejemplo n.º 25
0
 static void Postfix(RuleAttackRoll __instance, RulebookEventContext context)
 {
     UnitCombatState_get_IsFlanked_Patch.PopFlankingParametersIfTypeMatches(typeof(RuleAttackRoll_OnTrigger_Patch));
 }
Ejemplo n.º 26
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);
        }
Ejemplo n.º 27
0
        public override void RunAction()
        {
            //Main.DebugLog($"[ActionDealDamage2] Target:{Target?.Unit?.CharacterName} AC:{Target?.Unit?.Stats?.AC?.ModifiedValue} Flat-AC:{Target?.Unit?.Stats?.AC?.FlatFooted} Touch-AC:{Target?.Unit?.Stats?.AC?.Touch} Caster:{Context?.MaybeCaster?.CharacterName}");
            //Main.DebugLog("Context[0] " + this.Context[AbilityRankType.Default].ToString());
            //AbilityRankType.DamageDice [1]
            //AbilitySharedValue.Damage [0]
            //AbilitySharedValue.Duration [2] only composite
            //for (int i = 0; i < 7; i++)
            //{
            //    Main.DebugLog("AbilitySharedValue:" + Context[(AbilitySharedValue)i].ToString());
            //}
            //for (int i = 0; i < 7; i++)
            //{
            //    Main.DebugLog("AbilityRankType:" + Context[(AbilityRankType)i].ToString());
            //}

            if (this.Target.Unit == null)
            {
                UberDebug.LogError(this, "Invalid target for effect '{0}'", this.GetType().Name);
            }
            else if (this.Context.MaybeCaster == null)
            {
                UberDebug.LogError(this, "Invalid caster for effect '{0}'", this.GetType().Name);
            }
            else
            {
                bool saveSuccess = this.Context.SavingThrow != null && (this.Context.SavingThrow.IsPassed || this.Context.SavingThrow.ImprovedEvasion) && this.HalfIfSaved;
                if (saveSuccess && this.Context.SavingThrow.Evasion && this.Context.SavingThrow.IsPassed)
                {
                    EventBus.RaiseEvent <IUnitEvasionHandler>(h => h.HandleEffectEvaded(this.Target.Unit, this.Context));
                }
                else
                {
                    RuleAttackRoll attackRoll;

                    if (WeaponOverride != null)
                    {
                        attackRoll = new RuleAttackRoll(Context.MaybeCaster, this.Target.Unit, WeaponOverride, 0);
                        if (this.Context[AbilitySharedValue.Heal] == 0)   // if this is the first attack this context
                        {
                            this.Context.TriggerRule(attackRoll);
                            this.Context[AbilitySharedValue.Heal] = attackRoll.Roll;    // save this for other targets
                        }
                        else
                        {
                            //attackRoll.ImmuneToCriticalHit = true; // only the first target may get a crit
                            attackRoll.SuspendCombatLog = true; // don't print, since the roll would be different
                            this.Context.TriggerRule(attackRoll);
                        }

                        int d20 = this.Context[AbilitySharedValue.Heal];    // result of attack roll
                        Main.DebugLog($"Attack:{d20} total:{d20 + attackRoll.AttackBonus} AC:{attackRoll.TargetAC} result:{attackRoll.Result.ToString()}");

                        if (attackRoll.Result == AttackResult.MirrorImage)
                        {
                            // battlelog notification that Mirror Image was hit?
                            attackRoll.ConsumeMirrorImageIfNecessary();
                            return;
                        }

                        if (!this.IsSuccessRoll(d20, attackRoll.AttackBonus, attackRoll.TargetAC))
                        {
                            return;
                        }

                        if (attackRoll.Result == AttackResult.Concealment)
                        {
                            // battlelog notification that concealment prevented hit
                            Kingmaker.Game.Instance.UI.BattleLogManager.LogView.AddLogEntry(attackRoll.AttackLogEntry);
                            return;
                        }
                    }
                    else
                    {
                        attackRoll = ElementsContext.GetData <ContextAttackData>()?.AttackRoll;
                    }

                    ContextActionDealDamage2.DamageInfo info = new ContextActionDealDamage2.DamageInfo()
                    {
                        Dices                  = new DiceFormula(this.Value.DiceCountValue.Calculate(this.Context), this.Value.DiceType),
                        Bonus                  = this.Value.BonusValue.Calculate(this.Context),
                        PreRolledValue         = !this.ReadPreRolledFromSharedValue ? new int?() : new int?(this.Context[this.PreRolledSharedValue]),
                        HalfBecauseSavingThrow = saveSuccess,
                        Empower                = this.Context.HasMetamagic(Metamagic.Empower),
                        Maximize               = this.Context.HasMetamagic(Metamagic.Maximize),
                        CriticalModifier       = this.IgnoreCritical || attackRoll == null || !attackRoll.IsCriticalConfirmed ? new DamageCriticalModifierType?() : new DamageCriticalModifierType?(this.AbilityContext == null ? attackRoll.Weapon.Blueprint.CriticalModifier : DamageCriticalModifierType.X2)
                    };

                    int num;
                    switch (this.M_Type)
                    {
                    case ContextActionDealDamage2.Type.Damage:
                        num = this.DealHitPointsDamage(info);
                        break;

                    case ContextActionDealDamage2.Type.AbilityDamage:
                        num = this.DealAbilityScoreDamage(info);
                        break;

                    case ContextActionDealDamage2.Type.EnergyDrain:
                        num = this.DrainEnergy(info);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                    if (this.WriteResultToSharedValue)
                    {
                        this.Context[this.ResultSharedValue] = num;
                    }
                    if (!this.WriteCriticalToSharedValue || attackRoll == null || !attackRoll.IsCriticalConfirmed)
                    {
                        return;
                    }
                    this.Context[this.CriticalSharedValue] = 1;
                }
            }
        }
Ejemplo n.º 28
0
        public override void RunAction()
        {
            UnitEntityData maybeCaster = this.Context.MaybeCaster;

            if (maybeCaster == null)
            {
                UberDebug.LogError((object)"Caster is missing", (object[])Array.Empty <object>());
            }
            else
            {
                var target = this.Target;
                if (target == null)
                {
                    return;
                }
                var            weapon           = maybeCaster.Body.PrimaryHand.MaybeWeapon;
                RuleAttackRoll attackWithWeapon = new RuleAttackRoll(maybeCaster, target.Unit, weapon, 0);
                attackWithWeapon.Reason     = (RuleReason)this.Context;
                attackWithWeapon.AttackType = AttackType.RangedTouch;
                RuleAttackRoll rule = attackWithWeapon;
                this.Context.TriggerRule <RuleAttackRoll>(rule);

                RuleCalculateWeaponStats weaponRule = new RuleCalculateWeaponStats(maybeCaster, weapon, (RuleAttackWithWeapon)null);
                this.Context.TriggerRule <RuleCalculateWeaponStats>(weaponRule);
                DamageBundle damage = (DamageBundle)null;
                foreach (DamageDescription damageDescription in weaponRule.DamageDescription)
                {
                    damageDescription.TypeDescription = new DamageTypeDescription()
                    {
                        Type   = DamageType.Energy,
                        Energy = this.damageType
                    };
                    if (damage == null)
                    {
                        damage = new DamageBundle(weapon, weaponRule.WeaponSize, damageDescription.CreateDamage());
                    }
                    else
                    {
                        damage.Add(damageDescription.CreateDamage());
                    }
                }

                if (rule.IsHit)
                {
                    action_on_success?.Run();
                    if (this.damageType == DamageEnergyType.PositiveEnergy)
                    {
                        if (target.Unit.Descriptor.HasFact(library.Get <BlueprintUnitFact>("734a29b693e9ec346ba2951b27987e33")))
                        {
                            this.Context.TriggerRule <RuleDealDamage>(new RuleDealDamage(this.Context.MaybeCaster, this.Target.Unit, damage));
                        }
                        else
                        {
                            foreach (var i in damage)
                            {
                                this.Context.TriggerRule <RuleHealDamage>(new RuleHealDamage(this.Context.MaybeCaster, this.Target.Unit, i.Dice, i.Bonus));
                            }
                        }
                    }
                    else
                    {
                        if (target.Unit.Descriptor.HasFact(library.Get <BlueprintUnitFact>("734a29b693e9ec346ba2951b27987e33")))
                        {
                            foreach (var i in damage)
                            {
                                this.Context.TriggerRule <RuleHealDamage>(new RuleHealDamage(this.Context.MaybeCaster, this.Target.Unit, i.Dice, i.Bonus));
                            }
                        }
                        else
                        {
                            this.Context.TriggerRule <RuleDealDamage>(new RuleDealDamage(this.Context.MaybeCaster, this.Target.Unit, damage));
                        }
                    }
                }
                else
                {
                    action_on_miss?.Run();
                }
            }
        }
Ejemplo n.º 29
0
 public void OnEventAboutToTrigger(RuleAttackRoll evt)
 {
 }
Ejemplo n.º 30
0
        static void RunTest(string name, UnitEntityData initiator, UnitEntityData target)
        {
            var weapon        = initiator.GetFirstWeapon();
            var rolls         = new ushort[NumberOfTests];
            var resultBuckets = new uint[Enum.GetNames(typeof(AttackResult)).Length];
            var weaponStats   = new RuleCalculateWeaponStats(initiator, weapon, null);

            Rulebook.Trigger(weaponStats);
            using (var sw = new StreamWriter($"{ModEntry.Path}/{name}_rolls.txt"))
            {
                for (int i = 0; i < NumberOfTests; i++)
                {
                    var rule = new RuleAttackRoll(initiator, target, weaponStats, 0);
                    rule.SuspendCombatLog = true;
                    var roll = Rulebook.Trigger(rule);
                    if (roll.Roll.Value > 20 || roll.Roll.Value < 1)
                    {
                        Error("Roll out of range");
                        return;
                    }
                    rolls[i] = (ushort)roll.Roll.Value;
                    resultBuckets[(int)roll.Result] += 1;
                    sw.WriteLine("Roll: {0} Result: {1}", roll.Roll.Value, roll.Result);
                }
            }
            var   buckets    = new ulong[20];
            ulong sum        = 0;
            var   max1Seq    = new SequenceCounter(SequenceType.LessThen, 2);
            var   max20Seq   = new SequenceCounter(SequenceType.GreaterThen, 19);
            var   maxHighSeq = new SequenceCounter(SequenceType.GreaterThen, 13);
            var   maxLowSeq  = new SequenceCounter(SequenceType.LessThen, 8);

            foreach (var roll in rolls)
            {
                buckets[roll - 1] += 1;
                var prevSum = sum;
                sum += roll;
                if (sum < prevSum)
                {
                    Error("Overflow while calculating sum");
                    break;
                }
                max1Seq.Add(roll);
                max20Seq.Add(roll);
                maxHighSeq.Add(roll);
                maxLowSeq.Add(roll);
            }
            var maxBucket        = buckets.Max();
            var minBucket        = buckets.Min();
            var bucketDifference = maxBucket - minBucket;
            var average          = sum / (double)NumberOfTests;

            using (var sw = new StreamWriter($"{ModEntry.Path}/{name}_summary.txt"))
            {
                sw.WriteLine("Initiator: {0}", initiator.CharacterName);
                sw.WriteLine("Target: {0}", target.CharacterName);
                sw.WriteLine("Weapon: {0}", weapon.Name);
                sw.WriteLine("Number of rolls: {0}", NumberOfTests);
                sw.WriteLine("Sum: {0}", sum);
                sw.WriteLine("Average: {0}", average);
                for (int i = 0; i < 20; i++)
                {
                    sw.WriteLine("Number of {0}: {1}", i + 1, buckets[i]);
                }
                sw.WriteLine("Highest count in set {0}", maxBucket);
                sw.WriteLine("Lowest count in set {0}", minBucket);
                sw.WriteLine("Difference {0}", bucketDifference);
                sw.WriteLine("Max 1 in a row: {0}", max1Seq.MaxLength);
                sw.WriteLine("Max 20 in a row: {0}", max20Seq.MaxLength);
                sw.WriteLine("Max > 13 in a row: {0}", maxHighSeq.MaxLength);
                sw.WriteLine("Max < 8 in a row: {0}", maxLowSeq.MaxLength);
                var resultNames = Enum.GetNames(typeof(AttackResult));
                for (int i = 0; i < resultNames.Length; i++)
                {
                    sw.WriteLine("{0} count: {1} ({2}%)", resultNames[i], resultBuckets[i], resultBuckets[i] / (float)NumberOfTests * 100f);
                }

                var rule = new RuleAttackRoll(initiator, target, weaponStats, 0);
                rule.SuspendCombatLog = true;
                var roll = Rulebook.Trigger(rule);
                sw.WriteLine("AttackBonus: {0}", roll.AttackBonus);
                sw.WriteLine("IsTargetFlatFooted: {0}", roll.IsTargetFlatFooted);
                sw.WriteLine("TargetAC: {0}", roll.TargetAC);
                sw.WriteLine("IsSneakAttack: {0}", roll.IsSneakAttack);
                sw.WriteLine("Target.IsFlanked: {0}", roll.Target.CombatState.IsFlanked);
                sw.WriteLine("Weapon.CriticalEdge: {0}", roll.WeaponStats.CriticalEdge);
                sw.WriteLine("ImmuneToCriticalHit: {0}", roll.ImmuneToCriticalHit);
                sw.WriteLine("ImmuneToSneakAttack: {0}", roll.ImmuneToSneakAttack);
                sw.WriteLine("TargetUseFortification: {0}", roll.TargetUseFortification);
            }
            var imageSize = (int)Math.Sqrt(NumberOfTests);

            if (imageSize > 2800)
            {
                imageSize = 2800;
            }
            if (imageSize > 0 && imageSize <= 2800)
            {
                var texture    = new Texture2D(imageSize, imageSize);
                int pixelIndex = 0;
                for (int y = 0; y < texture.height; y++)
                {
                    for (int x = 0; x < texture.width; x++)
                    {
                        texture.SetPixel(x, y, rolls[pixelIndex++] > 10 ? Color.white : Color.black);
                    }
                }
                var data = texture.EncodeToPNG();
                File.WriteAllBytes($"{ModEntry.Path}/{name}_image.png", data);
            }
        }