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); }
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); }