コード例 #1
0
        public static bool TriggerAttackReplacementCombatManeuver(this UnitEntityData initiator, UnitEntityData target, ItemEntityWeapon weapon, int attackBonusPenalty, CombatManeuver combatManeuver)
        {
            var combatManeuverRule = new RuleCombatManeuver(initiator, target, combatManeuver);

            combatManeuverRule.ReplaceAttackBonus = new int?(initiator.Stats.BaseAttackBonus + attackBonusPenalty);

            BlueprintAbility combatManeuverAbility = Main.Library.Get <BlueprintAbility>(CombatManeuverData.combatManeuverActionIds[combatManeuver]);
            var abilityData = new Kingmaker.UnitLogic.Abilities.AbilityData(combatManeuverAbility, initiator.Descriptor);
            var context     = abilityData.CreateExecutionContext(target);

            Game.Instance.UI.BattleLogManager.HandleUseAbility(abilityData, null);

            var combatTextManager = initiator.GetCombatTextManager();

            if (combatTextManager != null)
            {
                /*MethodInfo settingsForbidsMethod = combatTextManager.GetType().GetMethod("SettingForbids", BindingFlags.NonPublic | BindingFlags.Instance);
                 * bool forbids = (bool)settingsForbidsMethod.Invoke(combatTextManager, new object[] { SettingsRoot.Instance.ShowSpellNameInCombatText });
                 * if (!forbids)
                 *  combatTextManager.AddCombatText(combatManeuverAbility.Name, combatTextManager.DefaultColor, true, combatManeuverAbility.Icon);*/

                var mockSpellRule = new RuleCastSpell(abilityData, target);
                combatTextManager.OnEventDidTrigger(mockSpellRule);
            }

            return(context.TriggerRule(combatManeuverRule).Success);
        }
コード例 #2
0
 static void Postfix(RuleCombatManeuver __instance, ref bool __result)
 {
     if (__instance.AutoFailure || //already includes immunity to specific maneuvers
         __instance.Target.Descriptor.State.HasCondition(UnitCondition.ImmuneToCombatManeuvers) ||
         (__instance.Target.Descriptor.State.HasConditionImmunity(UnitCondition.Prone) &&
          (__instance.Type == CombatManeuver.Trip || __instance.Type == CombatManeuverTypeExtender.AwesomeBlow.ToCombatManeuverType())
         )
         )
     {
         //TODO: should probably add checks for validity of other maneuvers but currently it is only used in greater trip, greater bull rush, so it looks sufficient
         __result = false;
     }
 }
コード例 #3
0
        static bool Prefix(RuleCombatManeuver __instance, RulebookEventContext context)
        {
            bool provokeAoO;

            if (!provokeAoOOnCombatManeuverAttempt.TryGetValue(__instance.Initiator.UniqueId, out provokeAoO) || provokeAoO)
            {
                if (!__instance.Target.CombatState.IsEngage(__instance.Initiator))
                {
                    return(true);
                }

                __instance.Target.CombatState.AttackOfOpportunity(__instance.Initiator);
            }
            return(true);
        }
コード例 #4
0
            static bool checkExtraManeuvers(RuleCombatManeuver evt)
            {
                switch (evt.Type)
                {
                case (CombatManeuver)CombatManeuverTypeExtender.AwesomeBlow:
                {
                    if (evt.Target.CanBeKnockedOff())
                    {
                        evt.Target.Descriptor.State.Prone.ShouldBeActive = true;
                        EventBus.RaiseEvent <IKnockOffHandler>((Action <IKnockOffHandler>)(h => h.HandleKnockOff(evt.Initiator, evt.Target)));
                    }
                }
                break;

                default:
                    throw new Exception("Unsupported combat maneuver type: " + (object)evt.Type);
                }
                return(true);
            }
コード例 #5
0
        internal static bool CheckTandemTrip(ModifyD20 modifyD20Instance, RuleCombatManeuver evt)
        {
            if (evt.Type != CombatManeuver.Trip || !modifyD20Instance.Owner.Unit.IsEngage(evt.Target))
            {
                return(false);
            }

            if (modifyD20Instance.Owner.State.Features.SoloTactics)
            {
                return(true);
            }

            foreach (UnitEntityData unitEntityData in evt.Target.CombatState.EngagedBy)
            {
                if (unitEntityData != modifyD20Instance.Owner.Unit && unitEntityData.Descriptor.HasFact(modifyD20Instance.TandemTripFeature))
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #6
0
        public override void OnEventDidTrigger(RuleAttackWithWeapon evt)
        {
            if (evt.Weapon == null)
            {
                return;
            }

            if (use_swift_action && evt.Initiator.CombatState.Cooldown.SwiftAction > 0.0f)
            {
                return;
            }


            if (!categories.Empty() && !categories.Contains(evt.Weapon.Blueprint.Category))
            {
                return;
            }

            if (!evt.AttackRoll.IsHit)
            {
                return;
            }

            if (this.maneuver == CombatManeuver.Trip && (evt.Target.Descriptor.State.Prone.Active || (bool)(evt.Target.View) && evt.Target.View.IsGetUp))
            {
                return;
            }

            var rule = new RuleCombatManeuver(this.Owner.Unit, evt.Target, this.maneuver);

            rule.AddBonus(this.bonus.Calculate(this.Fact.MaybeContext), this.Fact);
            Rulebook.Trigger <RuleCombatManeuver>(new RuleCombatManeuver(this.Owner.Unit, evt.Target, this.maneuver));

            if (use_swift_action)
            {
                evt.Initiator.CombatState.Cooldown.SwiftAction = 6.0f;
            }
        }
コード例 #7
0
 static void Postfix(RuleCombatManeuver __instance, RulebookEventContext context)
 {
     provokeAoOOnCombatManeuverAttempt[__instance.Initiator.UniqueId] = true;
 }
コード例 #8
0
 static bool Prefix(ModifyD20 __instance, RuleCombatManeuver evt, ref bool __result)
 {
     __result = TandemTrip.CheckTandemTrip(__instance, evt);
     return(false);
 }
コード例 #9
0
        public override bool maybeReplaceAttackWithAction(RuleAttackWithWeapon attack_rule)
        {
            //Main.logger.Log("Checking for replacement with: " + maneuver.ToString() );
            if (!attack_rule.IsFullAttack && only_full_attack)
            {
                return(false);
            }


            if (!attack_rule.IsCharge && only_charge)
            {
                return(false);
            }

            if (attack_rule.AttackNumber != 0 && only_first_attack)
            {
                return(false);
            }

            if (!attack_rule.Weapon.Blueprint.IsMelee)
            {
                return(false);
            }

            //Main.logger.Log("First Conditions Ok");
            if (maneuver == CombatManeuver.Trip)
            {
                UnitState state = attack_rule.Target.Descriptor.State;
                // same checks as in UnitProneController, if this is true (and the unit is not in a cutscene), state.Prone.Active will be true on the next tick and we also don't want to trip again.
                if (state.Prone.Active || state.Prone.ShouldBeActive || !state.IsConscious || state.HasCondition(UnitCondition.Prone) || state.HasCondition(UnitCondition.Sleeping) || state.HasCondition(UnitCondition.Unconscious))
                {
                    return(false);
                }
            }
            else if (maneuver == CombatManeuver.Disarm)
            {
                // same checks as in RuleCombatManeuver. If the unit cannot be disarmed (further), don't attempt to disarm.
                ItemEntityWeapon maybe_weapon  = attack_rule.Target.Body.PrimaryHand.MaybeWeapon;
                ItemEntityWeapon maybe_weapon2 = attack_rule.Target.Body.SecondaryHand.MaybeWeapon;
                bool             can_disarm    = false;
                if (maybe_weapon != null && !maybe_weapon.Blueprint.IsUnarmed && !maybe_weapon.Blueprint.IsNatural && !attack_rule.Target.Descriptor.Buffs.HasFact(BlueprintRoot.Instance.SystemMechanics.DisarmMainHandBuff))
                {
                    can_disarm = true;
                }
                else if (maybe_weapon2 != null && !maybe_weapon2.Blueprint.IsUnarmed && !maybe_weapon2.Blueprint.IsNatural && !attack_rule.Target.Descriptor.Buffs.HasFact(BlueprintRoot.Instance.SystemMechanics.DisarmOffHandBuff))
                {
                    can_disarm = true;
                }

                if (!can_disarm)
                {
                    return(false);
                }
            }
            else if (maneuver == CombatManeuver.SunderArmor)
            {
                if (attack_rule.Target.Descriptor.Buffs.HasFact(BlueprintRoot.Instance.SystemMechanics.SunderArmorBuff))
                {
                    return(false);
                }
            }
            else if (maneuver == CombatManeuver.DirtyTrickBlind)
            {
                if (attack_rule.Target.Descriptor.Buffs.HasFact(BlueprintRoot.Instance.SystemMechanics.DirtyTrickBlindnessBuff))
                {
                    return(false);
                }
            }
            else if (maneuver == CombatManeuver.DirtyTrickEntangle)
            {
                if (attack_rule.Target.Descriptor.Buffs.HasFact(BlueprintRoot.Instance.SystemMechanics.DirtyTrickEntangledBuff))
                {
                    return(false);
                }
            }
            else if (maneuver == CombatManeuver.DirtyTrickSickened)
            {
                if (attack_rule.Target.Descriptor.Buffs.HasFact(BlueprintRoot.Instance.SystemMechanics.DirtyTrickSickenedBuff))
                {
                    return(false);
                }
            }
            else if (maneuver == CombatManeuver.BullRush)
            {
                //no checks should always work ?
            }
            else
            {
                Main.logger.Log("Trying to replace attack with unsupported maneuver type: " + maneuver.ToString());
                return(false);
            }

            //Main.logger.Log("Second Conditions Ok");
            attack_rule.Initiator.Ensure <CombatManeuverBonus.UnitPartUseWeaponForCombatManeuver>().force(attack_rule.Weapon, attack_rule.AttackBonusPenalty);
            RuleCombatManeuver rule = new RuleCombatManeuver(this.Context.MaybeCaster, attack_rule.Target, maneuver);

            var result = Rulebook.CurrentContext.Trigger <RuleCombatManeuver>(rule);

            attack_rule.Initiator.Ensure <CombatManeuverBonus.UnitPartUseWeaponForCombatManeuver>().unForce();

            //Main.logger.Log("Maneuver Ok");
            Harmony12.Traverse.Create(attack_rule).Property("AttackRoll").SetValue(new RuleAttackRoll(attack_rule.Initiator, attack_rule.Target, attack_rule.Weapon, attack_rule.AttackBonusPenalty));
            Harmony12.Traverse.Create(attack_rule).Property("AttackRoll").Property("Result").SetValue(result.Success ? AttackResult.Hit : AttackResult.Miss);
            Harmony12.Traverse.Create(attack_rule).Property("AttackRoll").Property("Roll").SetValue(result.InitiatorRoll);
            Harmony12.Traverse.Create(attack_rule).Property("AttackRoll").Property("AttackBonus").SetValue(result.InitiatorCMB);
            Harmony12.Traverse.Create(attack_rule).Property("AttackRoll").Property("TargetAC").SetValue(result.TargetCMD);

            //Main.logger.Log("Attack Rule Updated");
            return(true);
        }