static bool Prefix(UnitCombatState __instance, UnitCommand.CommandType commandType, ref bool __result)
            {
                if (IsInCombat() && __instance.Unit.IsInCombat)
                {
                    switch (commandType)
                    {
                    case UnitCommand.CommandType.Free:
                        __result = false;
                        break;

                    case UnitCommand.CommandType.Move:
                        __result = !__instance.Unit.HasMoveAction();
                        break;

                    case UnitCommand.CommandType.Standard:
                        UnitCommand moveCommand = __instance.Unit.Commands.GetCommand(UnitCommand.CommandType.Move);
                        __result = (moveCommand != null && moveCommand.IsRunning) || !__instance.Unit.HasStandardAction();
                        break;

                    case UnitCommand.CommandType.Swift:
                        __result = __instance.Cooldown.SwiftAction > 0f;
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                    return(false);
                }
                return(true);
            }
Example #2
0
 static void Postfix(UnitCombatState __instance, ref bool?__state)
 {
     if (__state.HasValue)
     {
         SettingsRoot.Instance.PauseOnEngagement.CurrentValue = __state.Value;
     }
 }
 static void Postfix(UnitCombatState __instance, ref UnitReference?__state)
 {
     if (__state.HasValue)
     {
         __instance.LastTarget = __state.Value;
     }
 }
Example #4
0
 static void Prefix(UnitCombatState __instance, bool inCombat, ref bool?__state)
 {
     if (IsEnabled() && DoNotPauseOnCombatStart && inCombat)
     {
         __state = SettingsRoot.Instance.PauseOnEngagement.CurrentValue;
         SettingsRoot.Instance.PauseOnEngagement.CurrentValue = false;
     }
 }
Example #5
0
 static bool Prefix(UnitCombatState __instance, ref bool __result)
 {
     if (IsInCombat() && __instance.Unit.IsInCombat && FlankingCountAllNearbyOpponents)
     {
         __result = __instance.EngagedBy.Count > 1 && !__instance.Unit.Descriptor.State.Features.CannotBeFlanked;
         return(false);
     }
     return(true);
 }
 static bool Prefix(UnitCombatState __instance, ref bool __result)
 {
     if (IsInCombat() && __instance.Unit.IsInCombat)
     {
         __result = __instance.Unit.UsedOneMoveAction() || (__instance.Unit.IsCurrentUnit() && !CurrentTurn().EnabledFullAttack);
         return(false);
     }
     return(true);
 }
 static bool Prefix(UnitCombatState __instance, ref bool __result)
 {
     if ((__instance.Unit.Get <UnitPartAlwaysFlanked>()?.active()).GetValueOrDefault() &&
         !__instance.Unit.Descriptor.State.Features.CannotBeFlanked)
     {
         __result = true;
         return(false);
     }
     return(false);
 }
 static bool Prefix(UnitCombatState __instance, UnitCommand command, ref bool __result)
 {
     if (IsInCombat() && __instance.Unit.IsInCombat)
     {
         __result = !command.IsIgnoreCooldown &&
                    (ShouldRestrictCommand(__instance.Unit, command) || __instance.HasCooldownForCommand(command.Type));
         return(false);
     }
     return(true);
 }
Example #9
0
 public static void Postfix(ref bool __result, UnitCombatState __instance)
 {
     if (settings.toggleInstantCooldown && __instance.Unit.IsDirectlyControllable)
     {
         __result = false;
     }
     if (CombatController.IsInTurnBasedCombat() && settings.toggleUnlimitedActionsPerTurn)
     {
         __result = false;
     }
 }
Example #10
0
        static bool Prefix(UnitCombatState __instance, UnitEntityData target, ref bool __result)
        {//prevent attack of opportunity if target has cover
            var        weapon      = __instance?.Unit?.GetFirstWeapon();
            AttackType attack_type = weapon == null ? AttackType.Melee : weapon.Blueprint.AttackType;

            if (target.hasCoverFrom(__instance.Unit, __instance.Unit.GetFirstWeapon().Blueprint.AttackType) != Cover.CoverType.None)
            {
                __result = false;
                return(false);
            }
            return(true);
        }
Example #11
0
 static bool HasCooldown(UnitCombatState combatState)
 {
     if (Mod.Enabled && FixActionTypeOfSwappingWeapon)
     {
         return
             (combatState.HasCooldownForCommand(UnitCommand.CommandType.Standard) &&
              combatState.HasCooldownForCommand(UnitCommand.CommandType.Move));
     }
     else
     {
         return(combatState.HasCooldownForCommand(UnitCommand.CommandType.Standard));
     }
 }
Example #12
0
 static void Postfix(UnitCombatState __instance, UnitEntityData target, ref bool __result)
 {
     if (Mod.Enabled && FixAcrobaticsMobility && __result)
     {
         if (target.Descriptor.State.HasCondition(UnitCondition.UseMobilityToNegateAttackOfOpportunity))
         {
             if (Rulebook.Trigger(new RuleSkillCheck(target, StatType.SkillMobility,
                                                     Rulebook.Trigger(new RuleCalculateCMD(target, __instance.Unit, CombatManeuver.None)).Result)).IsPassed)
             {
                 __result = false;
             }
         }
     }
 }
            static bool Prefix(UnitCombatState __instance, UnitEntityData target, ref bool __result, ref UnitReference?__state)
            {
                if (IsInCombat())
                {
                    __state = __instance.LastTarget;
                    __instance.LastTarget = target;

                    if (target.IsCurrentUnit() && CurrentTurn().ImmuneAttackOfOpportunityOnDisengage)
                    {
                        __result = false;
                        return(false);
                    }
                }
                return(true);
            }
Example #14
0
        protected void mod_TickOnUnit(UnitEntityData unit)
        {
            if (!KingmakerPatchSettings.Cheats.InstantCooldowns)
            {
                this.source_TickOnUnit(unit);
            }

            if (unit.IsDirectlyControllable)
            {
                UnitCombatState combatState = unit.CombatState;
                UnitCooldownsHelper.Reset(combatState.Cooldown);
                combatState.OnNewRound();
                EventBus.RaiseEvent((IUnitNewCombatRoundHandler h) => h.HandleNewCombatRound(unit));
                return;
            }

            this.source_TickOnUnit(unit);
        }
Example #15
0
 static void UpdateCooldown(UnitCombatState combatState)
 {
     if (Mod.Enabled && FixActionTypeOfSwappingWeapon)
     {
         if (combatState.HasCooldownForCommand(UnitCommand.CommandType.Move))
         {
             combatState.Cooldown.StandardAction = 6.0f;
         }
         else
         {
             combatState.Cooldown.MoveAction += 3.0f;
         }
     }
     else
     {
         combatState.Cooldown.StandardAction = 6.0f;
     }
 }
Example #16
0
        static bool Prefix(UnitCombatState __instance, ref bool __result)
        {
            __result = false;

            // Without flanking parameters, this won't work, so the result is always false. This means all methods that call IsFlanked need
            // to be made compatible, however the alternative would be to defer to the base IsFlanked behaviour, which would result in
            // unpredictable behaviour.
            if (flankingParameters.Count <= 0)
            {
                return(false);
            }

            FlankingParameters currentParameters = flankingParameters.Pop();

            // Nonsensical parameters => false
            if (currentParameters.FlankedBy == null && !currentParameters.FlankedByAnyone || currentParameters.FlankedBy != null && currentParameters.FlankedByAnyone)
            {
                return(false);
            }

            // Check if a specific unit is flanking the target (with a possible extra preconditions test)
            if (currentParameters.FlankedBy != null && !currentParameters.FlankedByAnyone)
            {
                __result = __instance.Unit.IsFlankedByUnit(currentParameters.FlankedBy, currentParameters.FlankingPreconditions);
            }
            // Check if the target is by any two attackers (adhering to possible preconditions)
            else if (currentParameters.FlankedByAnyone)
            {
                foreach (UnitEntityData unitEntityData in __instance.EngagedBy)
                {
                    // Ignore the ExceptFlankedBy unit (if it is not null) for the flanking test
                    if (currentParameters.ExceptFlankedBy == null || unitEntityData != currentParameters.ExceptFlankedBy)
                    {
                        if (__instance.Unit.IsFlankedByUnit(unitEntityData, currentParameters.FlankingPreconditions))
                        {
                            __result = true;
                            break;
                        }
                    }
                }
            }

            return(false);
        }
            static bool Prefix(UnitEntityData unit)
            {
                if (IsInCombat())
                {
                    if (unit.IsInCombat)
                    {
                        if (IsPassing())
                        {
                            UnitCombatState           combatState = unit.CombatState;
                            UnitCombatState.Cooldowns cooldown    = combatState.Cooldown;
                            float gameDeltaTime = Game.Instance.TimeController.GameDeltaTime;

                            if (cooldown.Initiative > 0f)
                            {
                                if (gameDeltaTime >= cooldown.Initiative)
                                {
                                    gameDeltaTime      -= cooldown.Initiative;
                                    cooldown.Initiative = 0f;
                                }
                                else
                                {
                                    cooldown.Initiative -= gameDeltaTime;
                                    gameDeltaTime        = 0f;
                                }
                            }

                            if (gameDeltaTime > 0f)
                            {
                                cooldown.StandardAction      = Math.Max(0f, cooldown.StandardAction - gameDeltaTime);
                                cooldown.MoveAction          = Math.Max(0f, cooldown.MoveAction - gameDeltaTime);
                                cooldown.SwiftAction         = Math.Max(0f, cooldown.SwiftAction - gameDeltaTime);
                                cooldown.AttackOfOpportunity = Math.Max(0f, cooldown.AttackOfOpportunity - gameDeltaTime);
                            }
                        }
                        return(false);
                    }
                    else
                    {
                        return(IsPassing());
                    }
                }
                return(true);
            }
Example #18
0
 public static bool Prefix(UnitCombatState __instance)
 {
     if (__instance.Unit.IsDirectlyControllable && settings.toggleInstantCooldown)
     {
         __instance.Cooldown.Initiative          = 0f;
         __instance.Cooldown.StandardAction      = 0f;
         __instance.Cooldown.MoveAction          = 0f;
         __instance.Cooldown.SwiftAction         = 0f;
         __instance.Cooldown.AttackOfOpportunity = 0f;
     }
     if (CombatController.IsInTurnBasedCombat() && settings.toggleUnlimitedActionsPerTurn)
     {
         __instance.Cooldown.Initiative          = 0f;
         __instance.Cooldown.StandardAction      = 0f;
         __instance.Cooldown.MoveAction          = 0f;
         __instance.Cooldown.SwiftAction         = 0f;
         __instance.Cooldown.AttackOfOpportunity = 0f;
     }
     return(true);
 }
Example #19
0
 public void Act()
 {
     Debug.Log("UnitAct");
     if (State == UnitCombatState.recuperation)
     {
         if (WaitingList.Count != 0)
         {
             WaitingList[0]?.Declare();
             State = UnitCombatState.preparation;
         }
         else
         {
             Controller.OnMovePicked += Declare;
             Controller.PickAction(this);
         }
     }
     else if (State == UnitCombatState.preparation)
     {
         WaitingList[0]?.Execute();
         State = UnitCombatState.recuperation;
     }
 }
Example #20
0
 public void Declare(MoveBehaviour move)
 {
     Debug.Log("UnitAct");
     State = UnitCombatState.preparation;
     Controller.OnMovePicked -= Declare;
 }
        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);
        }
 static bool Prefix(UnitCombatState __instance, Dictionary <UnitEntityData, TimeSpan> ___m_EngagedBy, ref Dictionary <UnitEntityData, TimeSpan> .KeyCollection __result)
 {
     __result = ___m_EngagedBy.Where(kv => !kv.Key.IsAlly(__instance.Unit)).ToDictionary(d => d.Key, d => d.Value).Keys;
     return(false);
 }
 static bool Prefix(UnitCombatState __instance, UnitEntityData target)
 {
     return(__instance.Unit?.Get <UnitPartDoesNotEngage>() == null);
 }
        static bool Prefix(UnitCombatState __instance, UnitEntityData target, ref bool __result)
        {
            __result = target?.Get <UnitPartNoAooOnDisengage>() == null;

            return(__result);
        }