From 6f094c58ae043532a337f86922883fdcc4d0547c Mon Sep 17 00:00:00 2001 From: Asriel Camora Date: Sun, 3 Mar 2024 18:58:57 -0800 Subject: [PATCH] Split CanUse into CouldUse & IsPossible --- Simulator/Actions/BaseAction.cs | 15 +++++++++++++-- Simulator/Actions/BaseComboAction.cs | 4 ++-- Simulator/Actions/BaseComboActionImpl.cs | 6 ++++-- Simulator/Actions/ByregotsBlessing.cs | 2 +- Simulator/Actions/CarefulObservation.cs | 7 +++++-- Simulator/Actions/HeartAndSoul.cs | 7 +++++-- Simulator/Actions/IntensiveSynthesis.cs | 4 ++-- Simulator/Actions/Manipulation.cs | 4 +++- Simulator/Actions/MuscleMemory.cs | 4 +++- Simulator/Actions/PreciseTouch.cs | 4 ++-- Simulator/Actions/PrudentSynthesis.cs | 4 ++-- Simulator/Actions/PrudentTouch.cs | 4 ++-- Simulator/Actions/Reflect.cs | 4 +++- Simulator/Actions/TrainedEye.cs | 7 ++++--- Simulator/Actions/TrainedFinesse.cs | 4 ++-- Simulator/Actions/TricksOfTheTrade.cs | 4 ++-- Simulator/Simulator.cs | 11 ++++++++++- 17 files changed, 65 insertions(+), 30 deletions(-) diff --git a/Simulator/Actions/BaseAction.cs b/Simulator/Actions/BaseAction.cs index 07c4cee..e650a00 100644 --- a/Simulator/Actions/BaseAction.cs +++ b/Simulator/Actions/BaseAction.cs @@ -25,8 +25,19 @@ public abstract class BaseAction public virtual int Efficiency(Simulator s) => 0; public virtual float SuccessRate(Simulator s) => 1f; - public virtual bool CanUse(Simulator s) => - s.Input.Stats.Level >= Level && s.CP >= CPCost(s); + // Return true if it can be in the action pool now or in the future + // e.g. if Heart and Soul is already used, it is impossible to use it again + // or if it's a first step action and IsFirstStep is false + public virtual bool IsPossible(Simulator s) => + s.Input.Stats.Level >= Level; + + // Return true if it can be used now + // This already assumes that IsPossible returns true *at some point before* + public virtual bool CouldUse(Simulator s) => + s.CP >= CPCost(s); + + public bool CanUse(Simulator s) => + IsPossible(s) && CouldUse(s); public virtual void Use(Simulator s) { diff --git a/Simulator/Actions/BaseComboAction.cs b/Simulator/Actions/BaseComboAction.cs index 16876c5..5151f4b 100644 --- a/Simulator/Actions/BaseComboAction.cs +++ b/Simulator/Actions/BaseComboAction.cs @@ -7,8 +7,8 @@ public abstract class BaseComboAction : BaseAction public sealed override ActionCategory Category => ActionCategory.Combo; - protected bool BaseCanUse(Simulator s) => - base.CanUse(s); + protected bool BaseCouldUse(Simulator s) => + base.CouldUse(s); private static bool VerifyDurability2(int durabilityA, int durability, in Effects effects) { diff --git a/Simulator/Actions/BaseComboActionImpl.cs b/Simulator/Actions/BaseComboActionImpl.cs index 623fd53..6f87f35 100644 --- a/Simulator/Actions/BaseComboActionImpl.cs +++ b/Simulator/Actions/BaseComboActionImpl.cs @@ -13,8 +13,10 @@ internal abstract class BaseComboAction : BaseComboAction where A : BaseAc public override int CPCost(Simulator s) => ActionA.CPCost(s) + ActionB.CPCost(s); - public override bool CanUse(Simulator s) => - BaseCanUse(s) && VerifyDurability2(s, ActionA.DurabilityCost); + public override bool IsPossible(Simulator s) => ActionA.IsPossible(s) && ActionB.IsPossible(s); + + public override bool CouldUse(Simulator s) => + BaseCouldUse(s) && VerifyDurability2(s, ActionA.DurabilityCost); public override void Use(Simulator s) { diff --git a/Simulator/Actions/ByregotsBlessing.cs b/Simulator/Actions/ByregotsBlessing.cs index 257db8e..7e29798 100644 --- a/Simulator/Actions/ByregotsBlessing.cs +++ b/Simulator/Actions/ByregotsBlessing.cs @@ -11,7 +11,7 @@ internal sealed class ByregotsBlessing : BaseAction public override int CPCost(Simulator s) => 24; public override int Efficiency(Simulator s) => 100 + (20 * s.GetEffectStrength(EffectType.InnerQuiet)); - public override bool CanUse(Simulator s) => s.HasEffect(EffectType.InnerQuiet) && base.CanUse(s); + public override bool CouldUse(Simulator s) => s.HasEffect(EffectType.InnerQuiet) && base.CouldUse(s); public override void UseSuccess(Simulator s) { diff --git a/Simulator/Actions/CarefulObservation.cs b/Simulator/Actions/CarefulObservation.cs index ebee287..5ae64d8 100644 --- a/Simulator/Actions/CarefulObservation.cs +++ b/Simulator/Actions/CarefulObservation.cs @@ -12,10 +12,13 @@ internal sealed class CarefulObservation : BaseAction public override int CPCost(Simulator s) => 0; - public override bool CanUse(Simulator s) => s.Input.Stats.IsSpecialist && s.ActionStates.CarefulObservationCount < 3; + public override bool IsPossible(Simulator s) => + base.IsPossible(s) && s.Input.Stats.IsSpecialist && s.ActionStates.CarefulObservationCount < 3; + + public override bool CouldUse(Simulator s) => s.ActionStates.CarefulObservationCount < 3; public override void UseSuccess(Simulator s) => s.StepCondition(); public override string GetTooltip(Simulator s, bool addUsability) => - $"{base.GetTooltip(s, addUsability)}Specialist Only"; + $"{base.GetTooltip(s, addUsability)}Specialist Only\n"; } diff --git a/Simulator/Actions/HeartAndSoul.cs b/Simulator/Actions/HeartAndSoul.cs index 16e7b1a..06e183b 100644 --- a/Simulator/Actions/HeartAndSoul.cs +++ b/Simulator/Actions/HeartAndSoul.cs @@ -13,8 +13,11 @@ internal sealed class HeartAndSoul : BaseBuffAction public override int CPCost(Simulator s) => 0; - public override bool CanUse(Simulator s) => s.Input.Stats.IsSpecialist && !s.ActionStates.UsedHeartAndSoul; + public override bool IsPossible(Simulator s) => + base.IsPossible(s) && s.Input.Stats.IsSpecialist && !s.ActionStates.UsedHeartAndSoul; + + public override bool CouldUse(Simulator s) => !s.ActionStates.UsedHeartAndSoul; public override string GetTooltip(Simulator s, bool addUsability) => - $"{GetBaseTooltip(s, addUsability)}Specialist Only"; + $"{GetBaseTooltip(s, addUsability)}Specialist Only\n"; } diff --git a/Simulator/Actions/IntensiveSynthesis.cs b/Simulator/Actions/IntensiveSynthesis.cs index 54db7b0..e54f3d2 100644 --- a/Simulator/Actions/IntensiveSynthesis.cs +++ b/Simulator/Actions/IntensiveSynthesis.cs @@ -11,9 +11,9 @@ internal sealed class IntensiveSynthesis : BaseAction public override int CPCost(Simulator s) => 6; public override int Efficiency(Simulator s) => 400; - public override bool CanUse(Simulator s) => + public override bool CouldUse(Simulator s) => (s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul)) - && base.CanUse(s); + && base.CouldUse(s); public override void UseSuccess(Simulator s) { diff --git a/Simulator/Actions/Manipulation.cs b/Simulator/Actions/Manipulation.cs index 804ee65..56dfa30 100644 --- a/Simulator/Actions/Manipulation.cs +++ b/Simulator/Actions/Manipulation.cs @@ -10,7 +10,9 @@ internal sealed class Manipulation : BaseBuffAction public override byte Duration => 8; public override int CPCost(Simulator s) => 96; - public override bool CanUse(Simulator s) => s.Input.Stats.CanUseManipulation && base.CanUse(s); + + public override bool IsPossible(Simulator s) => + s.Input.Stats.CanUseManipulation && base.IsPossible(s); public override void Use(Simulator s) { diff --git a/Simulator/Actions/MuscleMemory.cs b/Simulator/Actions/MuscleMemory.cs index f6eb09d..bde7941 100644 --- a/Simulator/Actions/MuscleMemory.cs +++ b/Simulator/Actions/MuscleMemory.cs @@ -11,7 +11,9 @@ internal sealed class MuscleMemory : BaseAction public override int CPCost(Simulator s) => 6; public override int Efficiency(Simulator s) => 300; - public override bool CanUse(Simulator s) => s.IsFirstStep && base.CanUse(s); + public override bool IsPossible(Simulator s) => s.IsFirstStep && base.IsPossible(s); + + public override bool CouldUse(Simulator s) => s.IsFirstStep && base.CouldUse(s); public override void UseSuccess(Simulator s) { diff --git a/Simulator/Actions/PreciseTouch.cs b/Simulator/Actions/PreciseTouch.cs index 1be9c2d..1b4766e 100644 --- a/Simulator/Actions/PreciseTouch.cs +++ b/Simulator/Actions/PreciseTouch.cs @@ -11,9 +11,9 @@ internal sealed class PreciseTouch : BaseAction public override int CPCost(Simulator s) => 18; public override int Efficiency(Simulator s) => 150; - public override bool CanUse(Simulator s) => + public override bool CouldUse(Simulator s) => (s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul)) - && base.CanUse(s); + && base.CouldUse(s); public override void UseSuccess(Simulator s) { diff --git a/Simulator/Actions/PrudentSynthesis.cs b/Simulator/Actions/PrudentSynthesis.cs index 1ac3a22..a441fe9 100644 --- a/Simulator/Actions/PrudentSynthesis.cs +++ b/Simulator/Actions/PrudentSynthesis.cs @@ -12,7 +12,7 @@ internal sealed class PrudentSynthesis : BaseAction public override int CPCost(Simulator s) => 18; public override int Efficiency(Simulator s) => 180; - public override bool CanUse(Simulator s) => + public override bool CouldUse(Simulator s) => !(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2)) - && base.CanUse(s); + && base.CouldUse(s); } diff --git a/Simulator/Actions/PrudentTouch.cs b/Simulator/Actions/PrudentTouch.cs index f01f814..2298f10 100644 --- a/Simulator/Actions/PrudentTouch.cs +++ b/Simulator/Actions/PrudentTouch.cs @@ -12,7 +12,7 @@ internal sealed class PrudentTouch : BaseAction public override int CPCost(Simulator s) => 25; public override int Efficiency(Simulator s) => 100; - public override bool CanUse(Simulator s) => + public override bool CouldUse(Simulator s) => !(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2)) - && base.CanUse(s); + && base.CouldUse(s); } diff --git a/Simulator/Actions/Reflect.cs b/Simulator/Actions/Reflect.cs index 9a7dbdc..28fc811 100644 --- a/Simulator/Actions/Reflect.cs +++ b/Simulator/Actions/Reflect.cs @@ -11,7 +11,9 @@ internal sealed class Reflect : BaseAction public override int CPCost(Simulator s) => 6; public override int Efficiency(Simulator s) => 100; - public override bool CanUse(Simulator s) => s.IsFirstStep && base.CanUse(s); + public override bool IsPossible(Simulator s) => s.IsFirstStep && base.IsPossible(s); + + public override bool CouldUse(Simulator s) => s.IsFirstStep && base.CouldUse(s); public override void UseSuccess(Simulator s) { diff --git a/Simulator/Actions/TrainedEye.cs b/Simulator/Actions/TrainedEye.cs index 494fb0c..94c4990 100644 --- a/Simulator/Actions/TrainedEye.cs +++ b/Simulator/Actions/TrainedEye.cs @@ -10,11 +10,12 @@ internal sealed class TrainedEye : BaseAction public override int CPCost(Simulator s) => 250; - public override bool CanUse(Simulator s) => - s.IsFirstStep && + public override bool IsPossible(Simulator s) => s.IsFirstStep && !s.Input.Recipe.IsExpert && s.Input.Stats.Level >= (s.Input.Recipe.ClassJobLevel + 10) && - base.CanUse(s); + base.IsPossible(s); + + public override bool CouldUse(Simulator s) => s.IsFirstStep && base.CouldUse(s); public override void UseSuccess(Simulator s) => s.IncreaseQualityRaw(s.Input.Recipe.MaxQuality - s.Quality); diff --git a/Simulator/Actions/TrainedFinesse.cs b/Simulator/Actions/TrainedFinesse.cs index 28026c2..724d0aa 100644 --- a/Simulator/Actions/TrainedFinesse.cs +++ b/Simulator/Actions/TrainedFinesse.cs @@ -12,7 +12,7 @@ internal sealed class TrainedFinesse : BaseAction public override int CPCost(Simulator s) => 32; public override int Efficiency(Simulator s) => 100; - public override bool CanUse(Simulator s) => + public override bool CouldUse(Simulator s) => s.GetEffectStrength(EffectType.InnerQuiet) == 10 - && base.CanUse(s); + && base.CouldUse(s); } diff --git a/Simulator/Actions/TricksOfTheTrade.cs b/Simulator/Actions/TricksOfTheTrade.cs index ae9f5d2..22a375f 100644 --- a/Simulator/Actions/TricksOfTheTrade.cs +++ b/Simulator/Actions/TricksOfTheTrade.cs @@ -10,9 +10,9 @@ internal sealed class TricksOfTheTrade : BaseAction public override int CPCost(Simulator s) => 0; - public override bool CanUse(Simulator s) => + public override bool CouldUse(Simulator s) => (s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul)) - && base.CanUse(s); + && base.CouldUse(s); public override void UseSuccess(Simulator s) { diff --git a/Simulator/Simulator.cs b/Simulator/Simulator.cs index 75364f5..b984d9b 100644 --- a/Simulator/Simulator.cs +++ b/Simulator/Simulator.cs @@ -35,7 +35,12 @@ public class Simulator } public bool IsComplete => CompletionState != CompletionState.Incomplete; - public IEnumerable AvailableActions => ActionUtils.AvailableActions(this); + public SimulationState ExecuteUnchecked(in SimulationState state, ActionType action) + { + this.state = state; + ExecuteUnchecked(action); + return this.state; + } public (ActionResponse Response, SimulationState NewState) Execute(in SimulationState state, ActionType action) { @@ -43,6 +48,10 @@ public class Simulator return (Execute(action), this.state); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ExecuteUnchecked(ActionType action) => + action.Base().Use(this); + private ActionResponse Execute(ActionType action) { if (IsComplete)