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);
     }
 }
Ejemplo n.º 3
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;
        }
Ejemplo n.º 4
0
 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));
     }
 }
Ejemplo n.º 5
0
        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));
            }
        }
Ejemplo n.º 7
0
        private bool check(RuleAttackWithWeapon evt)
        {
            if (!evt.IsAttackOfOpportunity)
            {
                return(true);
            }

            if (!weapon_categories.Contains(evt.Weapon.Blueprint.Category))
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 8
0
        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;
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 12
0
 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);
         }
     }
 }
Ejemplo n.º 13
0
 static bool Prefix(ManeuverOnAttack __instance, RuleAttackWithWeapon evt)
 {
     CombatManeuverProvokeAttack.DoNotTriggerAoOForNextCombatManeuver(evt.Initiator);
     return(true);
 }
Ejemplo n.º 14
0
 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);
        }
Ejemplo n.º 19
0
        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;
        }
Ejemplo n.º 20
0
        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;
        }