diff --git a/Simulator/ActionStates.cs b/Simulator/ActionStates.cs index 4c08f1b..cf1298b 100644 --- a/Simulator/ActionStates.cs +++ b/Simulator/ActionStates.cs @@ -1,4 +1,5 @@ using Craftimizer.Simulator.Actions; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Craftimizer.Simulator; @@ -11,22 +12,23 @@ public struct ActionStates public bool UsedHeartAndSoul; public bool Observed; - public void MutateState(ActionType action) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void MutateState(BaseAction baseAction) { - if (action == ActionType.BasicTouch) + if (baseAction is BasicTouch) TouchComboIdx = 1; - else if (TouchComboIdx == 1 && action == ActionType.StandardTouch) + else if (TouchComboIdx == 1 && baseAction is StandardTouch) TouchComboIdx = 2; else TouchComboIdx = 0; - if (action == ActionType.CarefulObservation) + if (baseAction is CarefulObservation) CarefulObservationCount++; - if (action == ActionType.HeartAndSoul) + if (baseAction is HeartAndSoul) UsedHeartAndSoul = true; - Observed = action == ActionType.Observe; + Observed = baseAction is Observe; } public override readonly string ToString() => diff --git a/Simulator/Actions/AdvancedTouchCombo.cs b/Simulator/Actions/AdvancedTouchCombo.cs index cb51547..6a147a0 100644 --- a/Simulator/Actions/AdvancedTouchCombo.cs +++ b/Simulator/Actions/AdvancedTouchCombo.cs @@ -1,30 +1,7 @@ namespace Craftimizer.Simulator.Actions; -// Basic Touch -> Standard Touch -> Advanced Touch -internal sealed class AdvancedTouchCombo : BaseAction +internal sealed class AdvancedTouchCombo : BaseComboAction { - public override ActionCategory Category => ActionCategory.Combo; - public override int Level => 84; - public override uint ActionId => 100411; - - public override bool IncreasesQuality => true; - - public override int CPCost(Simulator s) => 18 + 18 + 18; - - public override bool CanUse(Simulator s) => - // BasicTouch.DurabilityCost vv vv StandardTouch.DurabilityCost - base.CanUse(s) && VerifyDurability3(s, 10, 10); - - private static readonly BasicTouch ActionA = new(); - private static readonly StandardTouch ActionB = new(); - private static readonly AdvancedTouch ActionC = new(); - public override void Use(Simulator s) - { - s.ExecuteForced(ActionType.BasicTouch, ActionA); - s.ExecuteForced(ActionType.StandardTouch, ActionB); - ActionC.Use(s); - } - - public override string GetTooltip(Simulator s, bool addUsability) => - $"{ActionA.GetTooltip(s, addUsability)}\n{ActionB.GetTooltip(s, addUsability)}\n{ActionC.GetTooltip(s, addUsability)}"; + public override ActionType ActionTypeA => ActionType.StandardTouchCombo; + public override ActionType ActionTypeB => ActionType.AdvancedTouch; } diff --git a/Simulator/Actions/BaseAction.cs b/Simulator/Actions/BaseAction.cs index 1470989..47e736f 100644 --- a/Simulator/Actions/BaseAction.cs +++ b/Simulator/Actions/BaseAction.cs @@ -44,6 +44,11 @@ public abstract class BaseAction if (IncreasesStepCount) s.IncreaseStepCount(); + + s.ActionStates.MutateState(this); + s.ActionCount++; + + s.ActiveEffects.DecrementDuration(); } public virtual void UseSuccess(Simulator s) @@ -80,54 +85,4 @@ public abstract class BaseAction builder.AppendLine($"{s.CalculateSuccessRate(SuccessRate(s)) * 100:##}%% Success Rate"); return builder.ToString(); } - - private static bool VerifyDurability2(int durabilityA, int durability, Effects effects) - { - var wasteNots = effects.HasEffect(EffectType.WasteNot) || effects.HasEffect(EffectType.WasteNot2); - // -A - durability -= (int)MathF.Ceiling(durabilityA * (wasteNots ? .5f : 1f)); - if (durability <= 0) - return false; - - // If we can do the first action and still have durability left to survive to the next - // step (even before the Manipulation modifier), we can certainly do the next action. - return true; - } - - public static bool VerifyDurability2(SimulationState s, int durabilityA) => - VerifyDurability2(durabilityA, s.Durability, s.ActiveEffects); - - public static bool VerifyDurability2(Simulator s, int durabilityA) => - VerifyDurability2(durabilityA, s.Durability, s.ActiveEffects); - - public static bool VerifyDurability3(int durabilityA, int durabilityB, int durability, Effects effects) - { - var wasteNots = Math.Max(effects.GetDuration(EffectType.WasteNot), effects.GetDuration(EffectType.WasteNot2)); - var manips = effects.HasEffect(EffectType.Manipulation); - - durability -= (int)MathF.Ceiling(durabilityA * wasteNots > 0 ? .5f : 1f); - if (durability <= 0) - return false; - - if (manips) - durability += 5; - - if (wasteNots > 0) - wasteNots--; - - durability -= (int)MathF.Ceiling(durabilityB * wasteNots > 0 ? .5f : 1f); - - if (durability <= 0) - return false; - - // If we can do the second action and still have durability left to survive to the next - // step (even before the Manipulation modifier), we can certainly do the next action. - return true; - } - - public static bool VerifyDurability3(Simulator s, int durabilityA, int durabilityB) => - VerifyDurability3(durabilityA, durabilityB, s.Durability, s.ActiveEffects); - - public static bool VerifyDurability3(SimulationState s, int durabilityA, int durabilityB) => - VerifyDurability3(durabilityA, durabilityB, s.Durability, s.ActiveEffects); } diff --git a/Simulator/Actions/BaseComboAction.cs b/Simulator/Actions/BaseComboAction.cs new file mode 100644 index 0000000..80d11f7 --- /dev/null +++ b/Simulator/Actions/BaseComboAction.cs @@ -0,0 +1,62 @@ +namespace Craftimizer.Simulator.Actions; + +public abstract class BaseComboAction : BaseAction +{ + public abstract ActionType ActionTypeA { get; } + public abstract ActionType ActionTypeB { get; } + + public sealed override ActionCategory Category => ActionCategory.Combo; + + protected bool BaseCanUse(Simulator s) => + base.CanUse(s); + + private static bool VerifyDurability2(int durabilityA, int durability, Effects effects) + { + var wasteNots = effects.HasEffect(EffectType.WasteNot) || effects.HasEffect(EffectType.WasteNot2); + // -A + durability -= (int)MathF.Ceiling(durabilityA * (wasteNots ? .5f : 1f)); + if (durability <= 0) + return false; + + // If we can do the first action and still have durability left to survive to the next + // step (even before the Manipulation modifier), we can certainly do the next action. + return true; + } + + public static bool VerifyDurability2(SimulationState s, int durabilityA) => + VerifyDurability2(durabilityA, s.Durability, s.ActiveEffects); + + public static bool VerifyDurability2(Simulator s, int durabilityA) => + VerifyDurability2(durabilityA, s.Durability, s.ActiveEffects); + + public static bool VerifyDurability3(int durabilityA, int durabilityB, int durability, Effects effects) + { + var wasteNots = Math.Max(effects.GetDuration(EffectType.WasteNot), effects.GetDuration(EffectType.WasteNot2)); + var manips = effects.HasEffect(EffectType.Manipulation); + + durability -= (int)MathF.Ceiling(durabilityA * wasteNots > 0 ? .5f : 1f); + if (durability <= 0) + return false; + + if (manips) + durability += 5; + + if (wasteNots > 0) + wasteNots--; + + durability -= (int)MathF.Ceiling(durabilityB * wasteNots > 0 ? .5f : 1f); + + if (durability <= 0) + return false; + + // If we can do the second action and still have durability left to survive to the next + // step (even before the Manipulation modifier), we can certainly do the next action. + return true; + } + + public static bool VerifyDurability3(Simulator s, int durabilityA, int durabilityB) => + VerifyDurability3(durabilityA, durabilityB, s.Durability, s.ActiveEffects); + + public static bool VerifyDurability3(SimulationState s, int durabilityA, int durabilityB) => + VerifyDurability3(durabilityA, durabilityB, s.Durability, s.ActiveEffects); +} diff --git a/Simulator/Actions/BaseComboActionImpl.cs b/Simulator/Actions/BaseComboActionImpl.cs new file mode 100644 index 0000000..f330329 --- /dev/null +++ b/Simulator/Actions/BaseComboActionImpl.cs @@ -0,0 +1,27 @@ +namespace Craftimizer.Simulator.Actions; + +internal abstract class BaseComboAction : BaseComboAction where A : BaseAction, new() where B : BaseAction, new() +{ + protected static readonly A ActionA = new(); + protected static readonly B ActionB = new(); + + public override int Level => ActionB.Level; + public override uint ActionId => ActionB.ActionId; + + public override bool IncreasesProgress => ActionA.IncreasesProgress || ActionB.IncreasesProgress; + public override bool IncreasesQuality => ActionA.IncreasesQuality || ActionB.IncreasesQuality; + + 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 void Use(Simulator s) + { + ActionA.Use(s); + ActionB.Use(s); + } + + public override string GetTooltip(Simulator s, bool addUsability) => + $"{ActionA.GetTooltip(s, addUsability)}\n{ActionB.GetTooltip(s, addUsability)}"; +} diff --git a/Simulator/Actions/FocusedSynthesisCombo.cs b/Simulator/Actions/FocusedSynthesisCombo.cs index 4c5bc4f..819b586 100644 --- a/Simulator/Actions/FocusedSynthesisCombo.cs +++ b/Simulator/Actions/FocusedSynthesisCombo.cs @@ -1,28 +1,7 @@ namespace Craftimizer.Simulator.Actions; -// Observe -> Focused Synthesis -internal sealed class FocusedSynthesisCombo : BaseAction +internal sealed class FocusedSynthesisCombo : BaseComboAction { - public override ActionCategory Category => ActionCategory.Combo; - public override int Level => 67; - public override uint ActionId => 100235; - - public override bool IncreasesProgress => true; - - public override int CPCost(Simulator s) => 7 + 5; - - public override bool CanUse(Simulator s) => - // Observe.DurabilityCost v - base.CanUse(s) && VerifyDurability2(s, 0); - - private static readonly Observe ActionA = new(); - private static readonly FocusedSynthesis ActionB = new(); - public override void Use(Simulator s) - { - s.ExecuteForced(ActionType.Observe, ActionA); - ActionB.Use(s); - } - - public override string GetTooltip(Simulator s, bool addUsability) => - $"{ActionA.GetTooltip(s, addUsability)}\n{ActionB.GetTooltip(s, addUsability)}"; + public override ActionType ActionTypeA => ActionType.Observe; + public override ActionType ActionTypeB => ActionType.FocusedSynthesis; } diff --git a/Simulator/Actions/FocusedTouchCombo.cs b/Simulator/Actions/FocusedTouchCombo.cs index 98e9767..98f7a15 100644 --- a/Simulator/Actions/FocusedTouchCombo.cs +++ b/Simulator/Actions/FocusedTouchCombo.cs @@ -1,28 +1,7 @@ namespace Craftimizer.Simulator.Actions; -// Observe -> Focused Touch -internal sealed class FocusedTouchCombo : BaseAction +internal sealed class FocusedTouchCombo : BaseComboAction { - public override ActionCategory Category => ActionCategory.Combo; - public override int Level => 68; - public override uint ActionId => 100243; - - public override bool IncreasesQuality => true; - - public override int CPCost(Simulator s) => 7 + 18; - - public override bool CanUse(Simulator s) => - // Observe.DurabilityCost v - base.CanUse(s) && VerifyDurability2(s, 0); - - private static readonly Observe ActionA = new(); - private static readonly FocusedTouch ActionB = new(); - public override void Use(Simulator s) - { - s.ExecuteForced(ActionType.Observe, ActionA); - ActionB.Use(s); - } - - public override string GetTooltip(Simulator s, bool addUsability) => - $"{ActionA.GetTooltip(s, addUsability)}\n{ActionB.GetTooltip(s, addUsability)}"; + public override ActionType ActionTypeA => ActionType.Observe; + public override ActionType ActionTypeB => ActionType.FocusedTouch; } diff --git a/Simulator/Actions/StandardTouchCombo.cs b/Simulator/Actions/StandardTouchCombo.cs index ded0665..5fcea98 100644 --- a/Simulator/Actions/StandardTouchCombo.cs +++ b/Simulator/Actions/StandardTouchCombo.cs @@ -1,28 +1,7 @@ namespace Craftimizer.Simulator.Actions; -// Basic Touch -> Standard Touch -internal sealed class StandardTouchCombo : BaseAction +internal sealed class StandardTouchCombo : BaseComboAction { - public override ActionCategory Category => ActionCategory.Combo; - public override int Level => 18; - public override uint ActionId => 100004; - - public override bool IncreasesQuality => true; - - public override int CPCost(Simulator s) => 18 + 18; - - public override bool CanUse(Simulator s) => - // BasicTouch.DurabilityCost vv - base.CanUse(s) && VerifyDurability2(s, 10); - - private static readonly BasicTouch ActionA = new(); - private static readonly StandardTouch ActionB = new(); - public override void Use(Simulator s) - { - s.ExecuteForced(ActionType.BasicTouch, ActionA); - ActionB.Use(s); - } - - public override string GetTooltip(Simulator s, bool addUsability) => - $"{ActionA.GetTooltip(s, addUsability)}\n{ActionB.GetTooltip(s, addUsability)}"; + public override ActionType ActionTypeA => ActionType.BasicTouch; + public override ActionType ActionTypeB => ActionType.StandardTouch; } diff --git a/Simulator/Simulator.cs b/Simulator/Simulator.cs index c0400a3..1986844 100644 --- a/Simulator/Simulator.cs +++ b/Simulator/Simulator.cs @@ -59,21 +59,11 @@ public class Simulator return ActionResponse.CannotUseAction; } - ExecuteForced(action, baseAction); + baseAction.Use(this); return ActionResponse.UsedAction; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ExecuteForced(ActionType action, BaseAction baseAction) - { - baseAction.Use(this); - ActionStates.MutateState(action); - ActionCount++; - - ActiveEffects.DecrementDuration(); - } - [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] public int GetEffectStrength(EffectType effect) => diff --git a/Solver/Crafty/SimulationNode.cs b/Solver/Crafty/SimulationNode.cs index 35b9543..672ce13 100644 --- a/Solver/Crafty/SimulationNode.cs +++ b/Solver/Crafty/SimulationNode.cs @@ -38,7 +38,7 @@ public struct SimulationNode if (state.ActiveEffects.InnerQuiet == 0) return false; - return BaseAction.VerifyDurability2(state, 10); + return BaseComboAction.VerifyDurability2(state, 10); } public static float? CalculateScoreForState(SimulationState state, CompletionState completionState, SolverConfig config)