public static bool IsAbleToAct(this UnitEntityData unit)
        {
            UnitState            state            = unit.Descriptor.State;
            UnitAnimationManager animationManager = unit.View?.AnimationManager;
            bool isProne        = state.Prone.Active;
            int  exclusiveState = 0;

            state.Prone.Active = false;
            if (animationManager && ((exclusiveState = animationManager.GetExclusiveState()) == 1 || exclusiveState == 2))
            {
                animationManager.SetExclusiveState(0);
            }

            bool result = (state.CanAct || state.CanMove) && !state.HasCondition(UnitCondition.Prone);

            state.Prone.Active = isProne;
            if (exclusiveState == 1 || exclusiveState == 2)
            {
                animationManager.SetExclusiveState(exclusiveState);
            }

            return(result);
        }
Пример #2
0
        public override void OnTrigger(RulebookEventContext context)
        {
            if (!Weapon.IsMelee)
            {
                return;
            }

            Result = Initiator.GetActiveCombatManeuverToggle();

            if (Result == CombatManeuver.Trip)
            {
                UnitState state = 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))
                {
                    Result = CombatManeuver.None;
                }
            }
            else if (Result == CombatManeuver.Disarm)
            {
                bool canBeDisarmed = false;
                // same checks as in RuleCombatManeuver. If the unit cannot be disarmed (further), don't attempt to disarm.
                ItemEntityWeapon maybeWeapon  = Target.Body.PrimaryHand.MaybeWeapon;
                ItemEntityWeapon maybeWeapon2 = Target.Body.SecondaryHand.MaybeWeapon;

                if (maybeWeapon != null && !maybeWeapon.Blueprint.IsUnarmed && !maybeWeapon.Blueprint.IsNatural && !Target.Descriptor.Buffs.HasFact(BlueprintRoot.Instance.SystemMechanics.DisarmMainHandBuff))
                {
                    canBeDisarmed = true;
                }
                else if (maybeWeapon2 != null && !maybeWeapon2.Blueprint.IsUnarmed && !maybeWeapon2.Blueprint.IsNatural && !Target.Descriptor.Buffs.HasFact(BlueprintRoot.Instance.SystemMechanics.DisarmOffHandBuff))
                {
                    canBeDisarmed = true;
                }

                if (!canBeDisarmed)
                {
                    Result = CombatManeuver.None;
                }
            }
            else if (Result == CombatManeuver.SunderArmor)
            {
                if (Target.Descriptor.Buffs.HasFact(BlueprintRoot.Instance.SystemMechanics.SunderArmorBuff))
                {
                    Result = CombatManeuver.None;
                }
            }

            if (ForceNormalAttack)
            {
                Result = CombatManeuver.None;
            }
        }
        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);
        }