static bool Prefix(UnitAttack __instance, AttackHandInfo attack) { var combatManeuver = Rulebook.Trigger(new RuleCheckCombatManeuverReplaceAttack(__instance.Executor, __instance.Target, attack)).Result; if (combatManeuver == CombatManeuver.None) { return(true); } var lastAttackRule = new RuleAttackWithWeapon(__instance.Executor, __instance.Target, attack.Weapon, attack.AttackBonusPenalty) { IsRend = __instance.IsRend(__instance.PlannedAttack), IsFirstAttack = (attack.AttackNumber == 0), IsFullAttack = __instance.IsFullAttack, IsCharge = __instance.IsCharge, AttackNumber = attack.AttackNumber, AttacksCount = ((List <AttackHandInfo>)unitattack_get_m_AllAttacks(__instance)).Count }; unitattack_set_LastAttackRule(__instance, lastAttackRule); attack.Target = __instance.Target; attack.IsHit = __instance.Executor.TriggerAttackReplacementCombatManeuver(__instance.Target, attack.Weapon, attack.AttackBonusPenalty, combatManeuver); return(false); }
public void OnEventDidTrigger(RuleAttackWithWeapon evt) { if (evt.Weapon == Owner && evt.AttackRoll.IsCriticalConfirmed && !evt.AttackRoll.FortificationNegatesCriticalHit) { evt.Target.Descriptor.AddBuff(Buff, evt.Initiator, 1.Rounds().Seconds); } }
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(RuleAttackWithWeapon evt) { if (evt.Target.Descriptor.HasFact(FixFlying.air_mastery) && isFlying()) { evt.AddTemporaryModifier(evt.Initiator.Stats.AdditionalDamage.AddModifier(-1, FixFlying.flying_fact, null, ModifierDescriptor.UntypedStackable)); } }
static bool Prefix(RuleAttackWithWeapon __instance, BlueprintProjectile projectile, bool first) { if ((!first) && __instance.Weapon.Blueprint.Type.FighterGroup == WeaponFighterGroup.Bows && (bool)__instance.Initiator.Descriptor.State.Features.Manyshot && (__instance.IsFirstAttack && __instance.IsFullAttack)) { if (__instance.Initiator.Get <UnitPartManyshotNotAvailable>() != null && __instance.Initiator.Get <UnitPartManyshotNotAvailable>().active()) { return(false); } } return(true); }
static RuleAttackWithWeapon performAttackOrManeuver(RuleAttackWithWeapon attack_rule) { var attack_replacement_part = attack_rule.Initiator.Get <UnitPartAttackReplacementWithAction>(); if (attack_replacement_part != null && attack_replacement_part.maybeReplaceAttackWithAction(attack_rule)) { return(attack_rule); } else { return(Rulebook.Trigger <RuleAttackWithWeapon>(attack_rule)); } }
private bool check(RuleAttackWithWeapon evt) { if (!evt.IsAttackOfOpportunity) { return(true); } if (!weapon_categories.Contains(evt.Weapon.Blueprint.Category)) { return(false); } return(true); }
public void OnEventDidTrigger(RuleAttackWithWeapon evt) { if (unit == null) { return; } var unit_attack_roll = Rulebook.Trigger <RuleAttackRoll>(new RuleAttackRoll(evt.Initiator, unit, evt.WeaponStats, evt.AttackBonusPenalty)); if (unit_attack_roll.IsHit) { var damage_base = evt.Weapon.Blueprint.DamageType.CreateDamage(DiceFormula.Zero, 0);//we write 0 damage here, since bonus damage is added in OnEventAboutToTrigger(RuleCalculateDamage evt) RuleDealDamage rule = new RuleDealDamage(this.Owner.Unit, unit, new DamageBundle(damage_base)); Rulebook.Trigger <RuleDealDamage>(rule); } unit = null; }
public void OnEventAboutToTrigger(RuleAttackWithWeapon evt) { if (!evt.Weapon.Blueprint.IsMelee || !evt.Target.isFlankedByAttacker(evt.Initiator)) { unit = null; } foreach (var u in evt.Target.CombatState.EngagedBy) { if (u != evt.Initiator && u.Buffs.HasFact(wild_flanking_mark) && evt.Target.isFlankedByAttacker(u)) { unit = u; damage = getPowerAttackBonus(this.Owner.Unit, evt.Weapon); break; } } }
public bool maybeReplaceAttackWithAction(RuleAttackWithWeapon attack_rule) { if (buffs.Empty()) { return(false); } //Main.logger.Log("Checking For Attack Replacement"); foreach (var b in buffs) { if (b.Get <AttackReplacementWithActionLogic>().maybeReplaceAttackWithAction(attack_rule)) { //Main.logger.Log("Attack Replaced"); return(true); } } return(false); }
static bool Prefix(RuleAttackWithWeapon __instance, BlueprintProjectile[] projectiles) { var tr = Harmony12.Traverse.Create(__instance); foreach (BlueprintProjectile projectile in projectiles) { if (projectile != null) { tr.Method("LaunchProjectile", projectile, true).GetValue(); if (__instance.Weapon.Blueprint.Type.FighterGroup == WeaponFighterGroup.Bows && __instance.Initiator.Descriptor.State.Features.Manyshot && (__instance.IsFirstAttack && __instance.IsFullAttack && !__instance.IsAttackOfOpportunity) && (__instance.Initiator.Get <UnitPartManyshotNotAvailable>() == null || !__instance.Initiator.Get <UnitPartManyshotNotAvailable>().active()) ) { tr.Method("LaunchProjectile", projectile, false).GetValue(); } } } return(false); }
public override void RunAction() { foreach (UnitEntityData attacker in GameHelper.GetTargetsAround(this.Target.Unit.Position, distance.Meters, false, false)) { if (attacker.Descriptor.HasFact(this.fact) && attacker.Descriptor.State.CanAct && (no_fact == null || !attacker.Descriptor.HasFact(no_fact)) && (!attacker.CombatState.IsEngage(attacker) || allow_engaged) && attacker.CombatState.CanAttackOfOpportunity && attacker.CanAttack(this.Target.Unit) && (attacker?.Body.PrimaryHand?.MaybeWeapon?.Blueprint?.IsRanged).GetValueOrDefault() && (attacker.CombatState.Cooldown.SwiftAction == 0.0f || !require_swift_action) && (attacker != Context?.MaybeCaster || !except_caster) ) { if (require_swift_action) { attacker.CombatState.Cooldown.SwiftAction += 6.0f; } RuleAttackWithWeapon attackWithWeapon = new RuleAttackWithWeapon(attacker, this.Target.Unit, attacker?.Body.PrimaryHand?.MaybeWeapon, 0); attackWithWeapon.Reason = (RuleReason)this.Context; RuleAttackWithWeapon rule = attackWithWeapon; this.Context.TriggerRule <RuleAttackWithWeapon>(rule); } } }
static bool Prefix(ManeuverOnAttack __instance, RuleAttackWithWeapon evt) { CombatManeuverProvokeAttack.DoNotTriggerAoOForNextCombatManeuver(evt.Initiator); return(true); }
public void OnEventDidTrigger(RuleAttackWithWeapon evt) { }
public abstract bool maybeReplaceAttackWithAction(RuleAttackWithWeapon attack_rule);
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); }
public void OnEventAboutToTrigger(RuleAttackWithWeapon evt) { }
static bool Prefix(UnitCombatState __instance, UnitEntityData target, ref bool __result) { __result = false; if (__instance.PreventAttacksOfOpporunityNextFrame || target.CombatState.PreventAttacksOfOpporunityNextFrame || !__instance.CanActInCombat && !__instance.Unit.Descriptor.State.HasCondition(UnitCondition.AttackOfOpportunityBeforeInitiative) || (!__instance.CanAttackOfOpportunity || !__instance.Unit.Descriptor.State.CanAct)) { return(false); } UnitPartForceMove unitPartForceMove = target.Get <UnitPartForceMove>(); if (unitPartForceMove && !unitPartForceMove.ProvokeAttackOfOpportunity || (UnitCommand.CommandTargetUntargetable(__instance.Unit, target, null) || __instance.Unit.HasMotionThisTick) || (__instance.Unit.GetThreatHand() == null || __instance.AttackOfOpportunityCount <= 0 || (!target.Memory.Contains(__instance.Unit) || target.Descriptor.State.HasCondition(UnitCondition.ImmuneToAttackOfOpportunity)))) { return(false); } if (target.Descriptor.State.HasCondition(UnitCondition.UseMobilityToNegateAttackOfOpportunity)) { RuleCalculateCMD ruleCalculateCmd = Rulebook.Trigger(new RuleCalculateCMD(target, __instance.Unit, CombatManeuver.None)); if (Rulebook.Trigger(new RuleSkillCheck(target, StatType.SkillMobility, ruleCalculateCmd.Result)).IsPassed) { return(false); } } // Changed code: instantly trigger AoO check (from UnitAttackOfOpportunity.OnAction) // === Original Start === // __instance.Unit.Commands.Run((UnitCommand) new UnitAttackOfOpportunity(target)); // EventBus.RaiseEvent<IAttackOfOpportunityHandler>((Action<IAttackOfOpportunityHandler>)(h => h.HandleAttackOfOpportunity(__instance.Unit, target))); // === Original End === // === Changed Start === RuleAttackWithWeapon aoo = new RuleAttackWithWeapon(__instance.Unit, target, __instance.Unit.GetThreatHand().Weapon, 0) { IsAttackOfOpportunity = true }; var combatManeuver = Rulebook.Trigger(new RuleCheckCombatManeuverReplaceAttack(__instance.Unit, target, __instance.Unit.GetThreatHand().Weapon.Blueprint)).Result; if (!target.Descriptor.State.IsDead) { EventBus.RaiseEvent <IAttackOfOpportunityHandler>(h => h.HandleAttackOfOpportunity(__instance.Unit, target)); if (combatManeuver != CombatManeuver.None) { __instance.Unit.TriggerAttackReplacementCombatManeuver(target, __instance.Unit.GetThreatHand().Weapon, 0, combatManeuver); } else { Rulebook.Trigger(aoo); } } // === Changed End === if (__instance.AttackOfOpportunityCount == __instance.AttackOfOpportunityPerRound) { __instance.Cooldown.AttackOfOpportunity = 5.4f; } --__instance.AttackOfOpportunityCount; // === Added start === (from UnitAttack.TriggerAttackRule) if (combatManeuver == CombatManeuver.None && target.View != null && target.View.HitFxManager != null) { target.View.HitFxManager.HandleAttackHit(aoo); } // === Added end === __result = true; return(false); }
public override IEnumerator <AbilityDeliveryTarget> Deliver(AbilityExecutionContext context, TargetWrapper target) { UnitEntityData caster = context.MaybeCaster; bool flag = caster == null; if (flag) { UberDebug.LogError(this, "Caster is missing", Array.Empty <object>()); yield break; } WeaponSlot threatHand = caster.GetThreatHand(); bool flag2 = threatHand == null; if (flag2) { UberDebug.LogError("Caster can't attack", Array.Empty <object>()); yield break; } UnitEntityData targetUnit = target.Unit; bool flag3 = targetUnit == null; if (flag3) { UberDebug.LogError("Can't be applied to point", Array.Empty <object>()); yield break; } int attackPenalty = 0; AbilityEffectCoupDeGrace.EventHandlers handlers = new AbilityEffectCoupDeGrace.EventHandlers(); handlers.Add(new AbilityEffectCoupDeGrace.Coup(caster)); RuleAttackWithWeapon rule = new RuleAttackWithWeapon(caster, targetUnit, threatHand.Weapon, attackPenalty) { AutoHit = true, AutoCriticalConfirmation = true, AutoCriticalThreat = true }; using (handlers.Activate()) { context.TriggerRule <RuleAttackWithWeapon>(rule); } AbilityEffectCoupDeGrace.EventHandlers eventHandlers = null; yield return(new AbilityDeliveryTarget(target)); RuleSavingThrow rule3 = new RuleSavingThrow(targetUnit, SavingThrowType.Fortitude, AbilityEffectCoupDeGrace.m_coupDamage + 10); context.TriggerRule <RuleSavingThrow>(rule3); bool flag6 = !rule3.IsPassed; if (flag6) { targetUnit.Descriptor.State.MarkedForDeath = true; } using (context.GetDataScope(target)) { this.Actions.Run(); } ElementsContextData elementsContextData = null; rule3 = null; yield break; }
public override IEnumerator <AbilityDeliveryTarget> Deliver(AbilityExecutionContext context, TargetWrapper target) { if (target.Unit == null) { UberDebug.LogError("Target unit is missing", Array.Empty <object>()); yield break; } UnitAttack cmd = new UnitAttack(target.Unit) { IsSingleAttack = true }; cmd.Init(context.Caster); cmd.Start(); AttackHandInfo attackHandInfo = cmd.AllAttacks.FirstOrDefault <AttackHandInfo>(); ItemEntityWeapon weapon = (attackHandInfo != null) ? attackHandInfo.Weapon : null; if (weapon == null) { UberDebug.LogError("Has no weapon for attack", Array.Empty <object>()); cmd.Interrupt(); yield break; } bool hitHandled = false; bool isMelee = weapon.Blueprint.IsMelee; for (; ;) { if (cmd.IsFinished) { RuleAttackWithWeapon lastAttackRule = cmd.LastAttackRule; if (((lastAttackRule != null) ? lastAttackRule.Projectile : null) == null || cmd.LastAttackRule.Projectile.IsHit || cmd.LastAttackRule.Projectile.Cleared || cmd.LastAttackRule.Projectile.Destroyed) { break; } } bool wasActed = cmd.IsActed; if (!cmd.IsFinished) { cmd.Tick(); } RuleAttackWithWeapon lastAttackRule2 = cmd.LastAttackRule; if (!wasActed && cmd.IsActed && isMelee) { hitHandled = true; if (lastAttackRule2.AttackRoll.IsHit) { yield return(new AbilityDeliveryTarget(target)); } } yield return(null); } if (!hitHandled && !isMelee) { RuleAttackWithWeapon lastAttackRule3 = cmd.LastAttackRule; bool?flag3 = (lastAttackRule3 != null) ? new bool?(lastAttackRule3.AttackRoll.IsHit) : null; if (flag3 != null && flag3.Value) { yield return(new AbilityDeliveryTarget(target)); } } yield break; }