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); }
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; } }
static void Prefix(UnitCombatState __instance, bool inCombat, ref bool?__state) { if (IsEnabled() && DoNotPauseOnCombatStart && inCombat) { __state = SettingsRoot.Instance.PauseOnEngagement.CurrentValue; SettingsRoot.Instance.PauseOnEngagement.CurrentValue = false; } }
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); }
public static void Postfix(ref bool __result, UnitCombatState __instance) { if (settings.toggleInstantCooldown && __instance.Unit.IsDirectlyControllable) { __result = false; } if (CombatController.IsInTurnBasedCombat() && settings.toggleUnlimitedActionsPerTurn) { __result = false; } }
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); }
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)); } }
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); }
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); }
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; } }
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); }
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); }
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; } }
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); }