New 7.0 actions and updates

This commit is contained in:
Asriel Camora
2024-06-28 16:24:56 -07:00
parent f4b2b7cfb5
commit 1c4fd0a499
28 changed files with 212 additions and 145 deletions
+2
View File
@@ -310,6 +310,8 @@ internal static class EffectUtils
EffectType.MuscleMemory => 2191, EffectType.MuscleMemory => 2191,
EffectType.Manipulation => 1164, EffectType.Manipulation => 1164,
EffectType.HeartAndSoul => 2665, EffectType.HeartAndSoul => 2665,
EffectType.Expedience => 3812,
EffectType.TrainedPerfection => 3813,
_ => throw new ArgumentOutOfRangeException(nameof(me)), _ => throw new ArgumentOutOfRangeException(nameof(me)),
}; };
+32 -25
View File
@@ -256,30 +256,33 @@ public sealed class CommunityMacros
"PrudentSynthesis" => ActionType.PrudentSynthesis, "PrudentSynthesis" => ActionType.PrudentSynthesis,
"RapidSynthesis" => ActionType.RapidSynthesis, "RapidSynthesis" => ActionType.RapidSynthesis,
"Groundwork" => ActionType.Groundwork, "Groundwork" => ActionType.Groundwork,
"FocusedSynthesis" => ActionType.FocusedSynthesis,
"MuscleMemory" => ActionType.MuscleMemory, "MuscleMemory" => ActionType.MuscleMemory,
"IntensiveSynthesis" => ActionType.IntensiveSynthesis, "IntensiveSynthesis" => ActionType.IntensiveSynthesis,
"BasicTouch" => ActionType.BasicTouch, "BasicTouch" => ActionType.BasicTouch,
"StandardTouch" => ActionType.StandardTouch, "StandardTouch" => ActionType.StandardTouch,
"AdvancedTouch" => ActionType.AdvancedTouch, "AdvancedTouch" => ActionType.AdvancedTouch,
"HastyTouch" => ActionType.HastyTouch, "HastyTouch" => ActionType.HastyTouch,
"DaringTouch" => ActionType.DaringTouch,
"ByregotsBlessing" => ActionType.ByregotsBlessing, "ByregotsBlessing" => ActionType.ByregotsBlessing,
"PreciseTouch" => ActionType.PreciseTouch, "PreciseTouch" => ActionType.PreciseTouch,
"FocusedTouch" => ActionType.FocusedTouch,
"PrudentTouch" => ActionType.PrudentTouch, "PrudentTouch" => ActionType.PrudentTouch,
"TrainedEye" => ActionType.TrainedEye, "TrainedEye" => ActionType.TrainedEye,
"PreparatoryTouch" => ActionType.PreparatoryTouch, "PreparatoryTouch" => ActionType.PreparatoryTouch,
"Reflect" => ActionType.Reflect, "Reflect" => ActionType.Reflect,
"TrainedFinesse" => ActionType.TrainedFinesse, "TrainedFinesse" => ActionType.TrainedFinesse,
"RefinedTouch" => ActionType.RefinedTouch,
"TrainedPerfection" => ActionType.TrainedPerfection,
"TricksOfTheTrade" => ActionType.TricksOfTheTrade, "TricksOfTheTrade" => ActionType.TricksOfTheTrade,
"MastersMend" => ActionType.MastersMend, "MastersMend" => ActionType.MastersMend,
"Manipulation" => ActionType.Manipulation, "Manipulation" => ActionType.Manipulation,
"ImmaculateMend" => ActionType.ImmaculateMend,
"WasteNot" => ActionType.WasteNot, "WasteNot" => ActionType.WasteNot,
"WasteNotII" => ActionType.WasteNot2, "WasteNotII" => ActionType.WasteNot2,
"GreatStrides" => ActionType.GreatStrides, "GreatStrides" => ActionType.GreatStrides,
"Innovation" => ActionType.Innovation, "Innovation" => ActionType.Innovation,
"Veneration" => ActionType.Veneration, "Veneration" => ActionType.Veneration,
"FinalAppraisal" => ActionType.FinalAppraisal, "FinalAppraisal" => ActionType.FinalAppraisal,
"QuickInnovation" => ActionType.QuickInnovation,
"Observe" => ActionType.Observe, "Observe" => ActionType.Observe,
"HeartAndSoul" => ActionType.HeartAndSoul, "HeartAndSoul" => ActionType.HeartAndSoul,
"CarefulObservation" => ActionType.CarefulObservation, "CarefulObservation" => ActionType.CarefulObservation,
@@ -311,42 +314,46 @@ public sealed class CommunityMacros
if (macro.Actions is not { } rotation) if (macro.Actions is not { } rotation)
throw new Exception($"Internal error; No actions were returned"); throw new Exception($"Internal error; No actions were returned");
// https://github.com/ffxiv-teamcraft/ffxiv-teamcraft/blob/67f453041c6b2b31d32fcf6e1fd53aa38ed7a12b/apps/client/src/app/model/other/crafting-rotation.ts#L49 Name = macro.Slug ?? "New Craftingway Rotation";
Name = macro.Slug ?? "New Craftinway Rotation";
var actions = new List<ActionType>(); var actions = new List<ActionType>();
foreach (var action in rotation.Split(',')) foreach (var action in rotation.Split(','))
{ {
ActionType? actionType = action switch ActionType? actionType = action switch
{ {
"BasicSynthesis" => ActionType.BasicSynthesis, "MuscleMemory" => ActionType.MuscleMemory,
"BasicTouch" => ActionType.BasicTouch, "Reflect" => ActionType.Reflect,
"MastersMend" => ActionType.MastersMend, "TrainedEye" => ActionType.TrainedEye,
"Observe" => ActionType.Observe,
"WasteNot" => ActionType.WasteNot,
"Veneration" => ActionType.Veneration, "Veneration" => ActionType.Veneration,
"StandardTouch" => ActionType.StandardTouch,
"GreatStrides" => ActionType.GreatStrides, "GreatStrides" => ActionType.GreatStrides,
"Innovation" => ActionType.Innovation, "Innovation" => ActionType.Innovation,
"QuickInnovation" => ActionType.QuickInnovation,
"BasicSynthesis" => ActionType.BasicSynthesis,
"BasicSynthesisTraited" => ActionType.BasicSynthesis, "BasicSynthesisTraited" => ActionType.BasicSynthesis,
"WasteNotII" => ActionType.WasteNot2,
"ByregotsBlessing" => ActionType.ByregotsBlessing,
"MuscleMemory" => ActionType.MuscleMemory,
"CarefulSynthesis" => ActionType.CarefulSynthesis, "CarefulSynthesis" => ActionType.CarefulSynthesis,
"Manipulation" => ActionType.Manipulation,
"PrudentTouch" => ActionType.PrudentTouch,
"FocusedSynthesis" => ActionType.FocusedSynthesis,
"FocusedTouch" => ActionType.FocusedTouch,
"Reflect" => ActionType.Reflect,
"PreparatoryTouch" => ActionType.PreparatoryTouch,
"Groundwork" => ActionType.Groundwork,
"DelicateSynthesis" => ActionType.DelicateSynthesis,
"TrainedEye" => ActionType.TrainedEye,
"CarefulSynthesisTraited" => ActionType.CarefulSynthesis, "CarefulSynthesisTraited" => ActionType.CarefulSynthesis,
"AdvancedTouch" => ActionType.AdvancedTouch,
"GroundworkTraited" => ActionType.Groundwork,
"PrudentSynthesis" => ActionType.PrudentSynthesis, "PrudentSynthesis" => ActionType.PrudentSynthesis,
"Groundwork" => ActionType.Groundwork,
"GroundworkTraited" => ActionType.Groundwork,
"BasicTouch" => ActionType.BasicTouch,
"StandardTouch" => ActionType.StandardTouch,
"AdvancedTouch" => ActionType.AdvancedTouch,
"ByregotsBlessing" => ActionType.ByregotsBlessing,
"PrudentTouch" => ActionType.PrudentTouch,
"PreparatoryTouch" => ActionType.PreparatoryTouch,
"TrainedFinesse" => ActionType.TrainedFinesse, "TrainedFinesse" => ActionType.TrainedFinesse,
{ } actionValue => throw new Exception($"Unknown action {actionValue}"), "RefinedTouch" => ActionType.RefinedTouch,
"MastersMend" => ActionType.MastersMend,
"ImmaculateMend" => ActionType.ImmaculateMend,
"WasteNot" => ActionType.WasteNot,
"WasteNotII" => ActionType.WasteNot2,
"Manipulation" => ActionType.Manipulation,
"TrainedPerfection" => ActionType.TrainedPerfection,
"Observe" => ActionType.Observe,
"DelicateSynthesis" => ActionType.DelicateSynthesis,
"DelicateSynthesisTraited" => ActionType.DelicateSynthesis,
// Old actions?
_ => null
}; };
if (actionType.HasValue) if (actionType.HasValue)
actions.Add(actionType.Value); actions.Add(actionType.Value);
+2 -2
View File
@@ -24,12 +24,12 @@ public static unsafe class Gearsets
static Gearsets() static Gearsets()
{ {
LevelToCLvlLUT = new int[90]; LevelToCLvlLUT = new int[100];
for (uint i = 0; i < 80; ++i) { for (uint i = 0; i < 80; ++i) {
var level = i + 1; var level = i + 1;
LevelToCLvlLUT[i] = LuminaSheets.ParamGrowSheet.GetRow(level)!.CraftingLevel; LevelToCLvlLUT[i] = LuminaSheets.ParamGrowSheet.GetRow(level)!.CraftingLevel;
} }
for (var i = 80; i < 90; ++i) for (var i = 80; i < 100; ++i)
{ {
var level = i + 1; var level = i + 1;
LevelToCLvlLUT[i] = (int)LuminaSheets.RecipeLevelTableSheet.First(r => r.ClassJobLevel == level).RowId; LevelToCLvlLUT[i] = (int)LuminaSheets.RecipeLevelTableSheet.First(r => r.ClassJobLevel == level).RowId;
+2
View File
@@ -568,6 +568,8 @@ public sealed unsafe class SynthHelper : Window, IDisposable
WasteNot2 = GetEffectStack((ushort)EffectType.WasteNot2.StatusId()), WasteNot2 = GetEffectStack((ushort)EffectType.WasteNot2.StatusId()),
MuscleMemory = GetEffectStack((ushort)EffectType.MuscleMemory.StatusId()), MuscleMemory = GetEffectStack((ushort)EffectType.MuscleMemory.StatusId()),
Manipulation = GetEffectStack((ushort)EffectType.Manipulation.StatusId()), Manipulation = GetEffectStack((ushort)EffectType.Manipulation.StatusId()),
Expedience = HasEffect((ushort)EffectType.Expedience.StatusId()),
TrainedPerfection = HasEffect((ushort)EffectType.TrainedPerfection.StatusId()),
HeartAndSoul = HasEffect((ushort)EffectType.HeartAndSoul.StatusId()), HeartAndSoul = HasEffect((ushort)EffectType.HeartAndSoul.StatusId()),
}, },
ActionStates = CurrentActionStates ActionStates = CurrentActionStates
+10 -2
View File
@@ -10,7 +10,9 @@ public record struct ActionStates
public byte TouchComboIdx; public byte TouchComboIdx;
public byte CarefulObservationCount; public byte CarefulObservationCount;
public bool UsedHeartAndSoul; public bool UsedHeartAndSoul;
public bool Observed; public bool UsedQuickInnovation;
public bool UsedTrainedPerfection;
public bool ObserveCombo;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void MutateState(BaseAction baseAction) public void MutateState(BaseAction baseAction)
@@ -28,6 +30,12 @@ public record struct ActionStates
if (baseAction is HeartAndSoul) if (baseAction is HeartAndSoul)
UsedHeartAndSoul = true; UsedHeartAndSoul = true;
Observed = baseAction is Observe; if (baseAction is QuickInnovation)
UsedQuickInnovation = true;
if (baseAction is TrainedPerfection)
UsedTrainedPerfection = true;
ObserveCombo = baseAction is Observe;
} }
} }
+7 -47
View File
@@ -11,14 +11,14 @@ public enum ActionType : byte
ByregotsBlessing, ByregotsBlessing,
CarefulObservation, CarefulObservation,
CarefulSynthesis, CarefulSynthesis,
DaringTouch,
DelicateSynthesis, DelicateSynthesis,
FinalAppraisal, FinalAppraisal,
FocusedSynthesis,
FocusedTouch,
GreatStrides, GreatStrides,
Groundwork, Groundwork,
HastyTouch, HastyTouch,
HeartAndSoul, HeartAndSoul,
ImmaculateMend,
Innovation, Innovation,
IntensiveSynthesis, IntensiveSynthesis,
Manipulation, Manipulation,
@@ -29,11 +29,14 @@ public enum ActionType : byte
PreparatoryTouch, PreparatoryTouch,
PrudentSynthesis, PrudentSynthesis,
PrudentTouch, PrudentTouch,
QuickInnovation,
RapidSynthesis, RapidSynthesis,
RefinedTouch,
Reflect, Reflect,
StandardTouch, StandardTouch,
TrainedEye, TrainedEye,
TrainedFinesse, TrainedFinesse,
TrainedPerfection,
TricksOfTheTrade, TricksOfTheTrade,
Veneration, Veneration,
WasteNot, WasteNot,
@@ -41,8 +44,8 @@ public enum ActionType : byte
StandardTouchCombo, StandardTouchCombo,
AdvancedTouchCombo, AdvancedTouchCombo,
FocusedSynthesisCombo, ObservedAdvancedTouchCombo,
FocusedTouchCombo, RefinedTouchCombo,
} }
public static class ActionUtils public static class ActionUtils
@@ -68,47 +71,4 @@ public static class ActionUtils
public static ActionCategory Category(this ActionType me) => public static ActionCategory Category(this ActionType me) =>
me.Base().Category; me.Base().Category;
public static string IntName(this ActionType me) =>
me switch
{
ActionType.AdvancedTouch => "Advanced Touch",
ActionType.BasicSynthesis => "Basic Synthesis",
ActionType.BasicTouch => "Basic Touch",
ActionType.ByregotsBlessing => "Byregot's Blessing",
ActionType.CarefulObservation => "Careful Observation",
ActionType.CarefulSynthesis => "Careful Synthesis",
ActionType.DelicateSynthesis => "Delicate Synthesis",
ActionType.FinalAppraisal => "Final Appraisal",
ActionType.FocusedSynthesis => "Focused Synthesis",
ActionType.FocusedTouch => "Focused Touch",
ActionType.GreatStrides => "Great Strides",
ActionType.Groundwork => "Groundwork",
ActionType.HastyTouch => "Hasty Touch",
ActionType.HeartAndSoul => "Heart And Soul",
ActionType.Innovation => "Innovation",
ActionType.IntensiveSynthesis => "Intensive Synthesis",
ActionType.Manipulation => "Manipulation",
ActionType.MastersMend => "Master's Mend",
ActionType.MuscleMemory => "Muscle Memory",
ActionType.Observe => "Observe",
ActionType.PreciseTouch => "Precise Touch",
ActionType.PreparatoryTouch => "Preparatory Touch",
ActionType.PrudentSynthesis => "Prudent Synthesis",
ActionType.PrudentTouch => "Prudent Touch",
ActionType.RapidSynthesis => "Rapid Synthesis",
ActionType.Reflect => "Reflect",
ActionType.StandardTouch => "Standard Touch",
ActionType.TrainedEye => "Trained Eye",
ActionType.TrainedFinesse => "Trained Finesse",
ActionType.TricksOfTheTrade => "Tricks Of The Trade",
ActionType.Veneration => "Veneration",
ActionType.WasteNot => "Waste Not",
ActionType.WasteNot2 => "Waste Not II",
ActionType.StandardTouchCombo => "Standard Touch Combo",
ActionType.AdvancedTouchCombo => "Advanced Touch Combo",
ActionType.FocusedSynthesisCombo => "Focused Synthesis Combo",
ActionType.FocusedTouchCombo => "Focused Touch Combo",
_ => me.ToString(),
};
} }
+2 -2
View File
@@ -1,10 +1,10 @@
namespace Craftimizer.Simulator.Actions; namespace Craftimizer.Simulator.Actions;
internal sealed class AdvancedTouch() : BaseAction( internal sealed class AdvancedTouch() : BaseAction(
ActionCategory.Quality, level: 84, actionId: 100411, ActionCategory.Quality, level: 68, actionId: 100411,
increasesQuality: true, increasesQuality: true,
defaultCPCost: 46, defaultEfficiency: 150) defaultCPCost: 46, defaultEfficiency: 150)
{ {
public override int CPCost(Simulator s) => public override int CPCost(Simulator s) =>
s.ActionStates.TouchComboIdx == 2 ? 18 : 46; (s.ActionStates.TouchComboIdx == 2 || s.ActionStates.ObserveCombo) ? 18 : 46;
} }
+2 -1
View File
@@ -67,7 +67,8 @@ public abstract class BaseAction(
UseSuccess(s); UseSuccess(s);
s.ReduceCP(CPCost(s)); s.ReduceCP(CPCost(s));
s.ReduceDurability(DurabilityCost); if (!s.HasEffect(EffectType.TrainedPerfection))
s.ReduceDurability(DurabilityCost);
if (IncreasesStepCount) if (IncreasesStepCount)
{ {
+15 -8
View File
@@ -18,11 +18,14 @@ public abstract class BaseComboAction(
private static bool VerifyDurability2(int durabilityA, int durability, in Effects effects) private static bool VerifyDurability2(int durabilityA, int durability, in Effects effects)
{ {
var wasteNots = effects.HasEffect(EffectType.WasteNot) || effects.HasEffect(EffectType.WasteNot2); if (!effects.HasEffect(EffectType.TrainedPerfection))
// -A {
durability -= (int)MathF.Ceiling(durabilityA * (wasteNots ? .5f : 1f)); var wasteNots = effects.HasEffect(EffectType.WasteNot) || effects.HasEffect(EffectType.WasteNot2);
if (durability <= 0) // -A
return false; 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 // 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. // step (even before the Manipulation modifier), we can certainly do the next action.
@@ -36,10 +39,14 @@ public abstract class BaseComboAction(
{ {
var wasteNots = Math.Max(effects.GetDuration(EffectType.WasteNot), effects.GetDuration(EffectType.WasteNot2)); var wasteNots = Math.Max(effects.GetDuration(EffectType.WasteNot), effects.GetDuration(EffectType.WasteNot2));
var manips = effects.HasEffect(EffectType.Manipulation); var manips = effects.HasEffect(EffectType.Manipulation);
var perfection = effects.HasEffect(EffectType.TrainedPerfection);
durability -= (int)MathF.Ceiling(durabilityA * wasteNots > 0 ? .5f : 1f); if (!perfection)
if (durability <= 0) {
return false; durability -= (int)MathF.Ceiling(durabilityA * wasteNots > 0 ? .5f : 1f);
if (durability <= 0)
return false;
}
if (manips) if (manips)
durability += 5; durability += 5;
+13
View File
@@ -0,0 +1,13 @@
namespace Craftimizer.Simulator.Actions;
internal sealed class DaringTouch() : BaseAction(
ActionCategory.Quality, 96, 100451,
increasesQuality: true,
defaultCPCost: 0,
defaultEfficiency: 150,
defaultSuccessRate: 60
)
{
public override bool CouldUse(Simulator s) =>
s.HasEffect(EffectType.Expedience) && base.CouldUse(s);
}
+7 -1
View File
@@ -7,5 +7,11 @@ internal sealed class DelicateSynthesis() : BaseAction(
defaultEfficiency: 100 defaultEfficiency: 100
) )
{ {
public override void UseSuccess(Simulator s)
{
// Delicate Synthesis Mastery Trait
var hasTrait = s.Input.Stats.Level >= 94;
s.IncreaseProgress(hasTrait ? 150 : 100);
s.IncreaseQuality(100);
}
} }
-13
View File
@@ -1,13 +0,0 @@
namespace Craftimizer.Simulator.Actions;
internal sealed class FocusedSynthesis() : BaseAction(
ActionCategory.Synthesis, 67, 100235,
increasesProgress: true,
defaultCPCost: 5,
defaultEfficiency: 200,
defaultSuccessRate: 50
)
{
public override int SuccessRate(Simulator s) =>
s.ActionStates.Observed ? 100 : 50;
}
@@ -1,8 +0,0 @@
namespace Craftimizer.Simulator.Actions;
internal sealed class FocusedSynthesisCombo() : BaseComboAction<Observe, FocusedSynthesis>(
ActionType.Observe, ActionType.FocusedSynthesis
)
{
}
-13
View File
@@ -1,13 +0,0 @@
namespace Craftimizer.Simulator.Actions;
internal sealed class FocusedTouch() : BaseAction(
ActionCategory.Quality, 68, 100243,
increasesQuality: true,
defaultCPCost: 18,
defaultEfficiency: 150,
defaultSuccessRate: 50
)
{
public override int SuccessRate(Simulator s) =>
s.ActionStates.Observed ? 100 : 50;
}
-8
View File
@@ -1,8 +0,0 @@
namespace Craftimizer.Simulator.Actions;
internal sealed class FocusedTouchCombo() : BaseComboAction<Observe, FocusedTouch>(
ActionType.Observe, ActionType.FocusedTouch
)
{
}
+12
View File
@@ -0,0 +1,12 @@
namespace Craftimizer.Simulator.Actions;
internal sealed class ImmaculateMend() : BaseAction(
ActionCategory.Durability, 98, 100467,
macroWaitTime: 2,
durabilityCost: 0,
defaultCPCost: 112
)
{
public override void UseSuccess(Simulator s) =>
s.RestoreAllDurability();
}
+1
View File
@@ -2,6 +2,7 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class MastersMend() : BaseAction( internal sealed class MastersMend() : BaseAction(
ActionCategory.Durability, 7, 100003, ActionCategory.Durability, 7, 100003,
macroWaitTime: 2,
durabilityCost: 0, durabilityCost: 0,
defaultCPCost: 88 defaultCPCost: 88
) )
@@ -0,0 +1,8 @@
namespace Craftimizer.Simulator.Actions;
internal sealed class ObservedAdvancedTouchCombo() : BaseComboAction<Observe, AdvancedTouch>(
ActionType.StandardTouchCombo, ActionType.AdvancedTouch, 7 + 18
)
{
}
+18
View File
@@ -0,0 +1,18 @@
namespace Craftimizer.Simulator.Actions;
internal sealed class QuickInnovation() : BaseBuffAction(
ActionCategory.Other, 96, 100459,
EffectType.Innovation, duration: 1,
macroWaitTime: 3,
increasesStepCount: false
)
{
public override bool IsPossible(Simulator s) =>
base.IsPossible(s) && s.Input.Stats.IsSpecialist && !s.ActionStates.UsedQuickInnovation;
public override bool CouldUse(Simulator s) =>
!s.ActionStates.UsedQuickInnovation;
public override string GetTooltip(Simulator s, bool addUsability) =>
$"{GetBaseTooltip(s, addUsability)}Specialist Only\n";
}
+16
View File
@@ -0,0 +1,16 @@
namespace Craftimizer.Simulator.Actions;
internal sealed class RefinedTouch() : BaseAction(
ActionCategory.Quality, 92, 100443,
increasesQuality: true,
defaultCPCost: 24,
defaultEfficiency: 100
)
{
public override void UseSuccess(Simulator s)
{
base.UseSuccess(s);
if (s.ActionStates.TouchComboIdx == 1)
s.StrengthenEffect(EffectType.InnerQuiet);
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace Craftimizer.Simulator.Actions;
internal sealed class RefinedTouchCombo() : BaseComboAction<BasicTouch, RefinedTouch>(
ActionType.BasicTouch, ActionType.RefinedTouch
)
{
}
+1 -1
View File
@@ -4,7 +4,7 @@ internal sealed class Reflect() : BaseAction(
ActionCategory.FirstTurn, 69, 100387, ActionCategory.FirstTurn, 69, 100387,
increasesQuality: true, increasesQuality: true,
defaultCPCost: 6, defaultCPCost: 6,
defaultEfficiency: 100 defaultEfficiency: 300
) )
{ {
public override bool IsPossible(Simulator s) => s.IsFirstStep && base.IsPossible(s); public override bool IsPossible(Simulator s) => s.IsFirstStep && base.IsPossible(s);
+13
View File
@@ -0,0 +1,13 @@
namespace Craftimizer.Simulator.Actions;
internal sealed class TrainedPerfection() : BaseBuffAction(
ActionCategory.Durability, 100, 100475,
EffectType.TrainedPerfection, duration: 1
)
{
public override bool IsPossible(Simulator s) =>
base.IsPossible(s) && !s.ActionStates.UsedTrainedPerfection;
public override bool CouldUse(Simulator s) =>
!s.ActionStates.UsedTrainedPerfection;
}
+2
View File
@@ -12,4 +12,6 @@ public enum EffectType
MuscleMemory, MuscleMemory,
Manipulation, Manipulation,
HeartAndSoul, HeartAndSoul,
Expedience,
TrainedPerfection
} }
+13
View File
@@ -16,6 +16,8 @@ public record struct Effects
public byte WasteNot2; public byte WasteNot2;
public byte MuscleMemory; public byte MuscleMemory;
public byte Manipulation; public byte Manipulation;
public bool Expedience;
public bool TrainedPerfection;
public bool HeartAndSoul; public bool HeartAndSoul;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -51,6 +53,12 @@ public record struct Effects
case EffectType.Manipulation: case EffectType.Manipulation:
Manipulation = duration; Manipulation = duration;
break; break;
case EffectType.Expedience:
Expedience = duration != 0;
break;
case EffectType.TrainedPerfection:
TrainedPerfection = duration != 0;
break;
case EffectType.HeartAndSoul: case EffectType.HeartAndSoul:
HeartAndSoul = duration != 0; HeartAndSoul = duration != 0;
break; break;
@@ -78,6 +86,8 @@ public record struct Effects
EffectType.WasteNot2 => WasteNot2, EffectType.WasteNot2 => WasteNot2,
EffectType.MuscleMemory => MuscleMemory, EffectType.MuscleMemory => MuscleMemory,
EffectType.Manipulation => Manipulation, EffectType.Manipulation => Manipulation,
EffectType.Expedience => (byte)(Expedience ? 1 : 0),
EffectType.TrainedPerfection => (byte)(TrainedPerfection ? 1 : 0),
EffectType.HeartAndSoul => (byte)(HeartAndSoul ? 1 : 0), EffectType.HeartAndSoul => (byte)(HeartAndSoul ? 1 : 0),
_ => 0 _ => 0
}; };
@@ -117,5 +127,8 @@ public record struct Effects
MuscleMemory--; MuscleMemory--;
if (Manipulation > 0) if (Manipulation > 0)
Manipulation--; Manipulation--;
Expedience = false;
TrainedPerfection = false;
} }
} }
+6
View File
@@ -181,6 +181,12 @@ public class Simulator
Durability = Input.Recipe.MaxDurability; Durability = Input.Recipe.MaxDurability;
} }
public void RestoreAllDurability()
{
Durability = Input.Recipe.MaxDurability;
}
public void RestoreCP(int amount) public void RestoreCP(int amount)
{ {
CP += amount; CP += amount;
+17 -11
View File
@@ -72,7 +72,6 @@ public readonly record struct SolverConfig
ActionType.BasicSynthesis, ActionType.BasicSynthesis,
ActionType.CarefulSynthesis, ActionType.CarefulSynthesis,
ActionType.FocusedSynthesis,
ActionType.Groundwork, ActionType.Groundwork,
ActionType.DelicateSynthesis, ActionType.DelicateSynthesis,
ActionType.PrudentSynthesis, ActionType.PrudentSynthesis,
@@ -81,26 +80,30 @@ public readonly record struct SolverConfig
ActionType.StandardTouch, ActionType.StandardTouch,
ActionType.ByregotsBlessing, ActionType.ByregotsBlessing,
ActionType.PrudentTouch, ActionType.PrudentTouch,
ActionType.FocusedTouch,
ActionType.PreparatoryTouch,
ActionType.AdvancedTouch, ActionType.AdvancedTouch,
ActionType.PreparatoryTouch,
ActionType.TrainedFinesse, ActionType.TrainedFinesse,
ActionType.RefinedTouch,
ActionType.MastersMend, ActionType.MastersMend,
ActionType.WasteNot, ActionType.WasteNot,
ActionType.WasteNot2, ActionType.WasteNot2,
ActionType.Manipulation, ActionType.Manipulation,
ActionType.ImmaculateMend,
ActionType.TrainedPerfection,
ActionType.Veneration, ActionType.Veneration,
ActionType.GreatStrides, ActionType.GreatStrides,
ActionType.Innovation, ActionType.Innovation,
ActionType.QuickInnovation,
ActionType.Observe, ActionType.Observe,
ActionType.HeartAndSoul,
ActionType.StandardTouchCombo, ActionType.StandardTouchCombo,
ActionType.AdvancedTouchCombo, ActionType.AdvancedTouchCombo,
ActionType.FocusedTouchCombo, ActionType.ObservedAdvancedTouchCombo,
ActionType.FocusedSynthesisCombo, ActionType.RefinedTouchCombo,
}); });
// Same as deterministic, but with condition-specific actions added // Same as deterministic, but with condition-specific actions added
@@ -112,7 +115,6 @@ public readonly record struct SolverConfig
ActionType.BasicSynthesis, ActionType.BasicSynthesis,
ActionType.CarefulSynthesis, ActionType.CarefulSynthesis,
ActionType.FocusedSynthesis,
ActionType.Groundwork, ActionType.Groundwork,
ActionType.DelicateSynthesis, ActionType.DelicateSynthesis,
ActionType.IntensiveSynthesis, ActionType.IntensiveSynthesis,
@@ -123,34 +125,37 @@ public readonly record struct SolverConfig
ActionType.ByregotsBlessing, ActionType.ByregotsBlessing,
ActionType.PreciseTouch, ActionType.PreciseTouch,
ActionType.PrudentTouch, ActionType.PrudentTouch,
ActionType.FocusedTouch,
ActionType.PreparatoryTouch,
ActionType.AdvancedTouch, ActionType.AdvancedTouch,
ActionType.PreparatoryTouch,
ActionType.TrainedFinesse, ActionType.TrainedFinesse,
ActionType.RefinedTouch,
ActionType.MastersMend, ActionType.MastersMend,
ActionType.WasteNot, ActionType.WasteNot,
ActionType.WasteNot2, ActionType.WasteNot2,
ActionType.Manipulation, ActionType.Manipulation,
ActionType.ImmaculateMend,
ActionType.TrainedPerfection,
ActionType.Veneration, ActionType.Veneration,
ActionType.GreatStrides, ActionType.GreatStrides,
ActionType.Innovation, ActionType.Innovation,
ActionType.QuickInnovation,
ActionType.Observe, ActionType.Observe,
ActionType.HeartAndSoul,
ActionType.TricksOfTheTrade, ActionType.TricksOfTheTrade,
ActionType.StandardTouchCombo, ActionType.StandardTouchCombo,
ActionType.AdvancedTouchCombo, ActionType.AdvancedTouchCombo,
ActionType.FocusedTouchCombo, ActionType.ObservedAdvancedTouchCombo,
ActionType.FocusedSynthesisCombo, ActionType.RefinedTouchCombo,
}); });
public static readonly FrozenSet<ActionType> InefficientActions = public static readonly FrozenSet<ActionType> InefficientActions =
new[] new[]
{ {
ActionType.CarefulObservation, ActionType.CarefulObservation,
ActionType.HeartAndSoul,
ActionType.FinalAppraisal ActionType.FinalAppraisal
}.ToFrozenSet(); }.ToFrozenSet();
@@ -159,6 +164,7 @@ public readonly record struct SolverConfig
{ {
ActionType.RapidSynthesis, ActionType.RapidSynthesis,
ActionType.HastyTouch, ActionType.HastyTouch,
ActionType.DaringTouch,
}.ToFrozenSet(); }.ToFrozenSet();
public static readonly SolverConfig RecipeNoteDefault = new SolverConfig() with public static readonly SolverConfig RecipeNoteDefault = new SolverConfig() with
+3 -3
View File
@@ -114,7 +114,7 @@ public class SimulatorTests
ActionType.PreparatoryTouch, ActionType.PreparatoryTouch,
ActionType.WasteNot2 ActionType.WasteNot2
}, },
0, 890, 60, 335); 0, 1414, 60, 335);
} }
[TestMethod] [TestMethod]
@@ -165,7 +165,7 @@ public class SimulatorTests
ActionType.PrudentTouch, ActionType.PrudentTouch,
ActionType.PreparatoryTouch ActionType.PreparatoryTouch
}, },
0, 4064, 15, 332); 0, 4588, 15, 332);
Assert.AreEqual(10, state.ActiveEffects.InnerQuiet); Assert.AreEqual(10, state.ActiveEffects.InnerQuiet);
Assert.IsTrue(ActionType.TrainedFinesse.Base().CanUse(new SimulatorNoRandom() { State = state })); Assert.IsTrue(ActionType.TrainedFinesse.Base().CanUse(new SimulatorNoRandom() { State = state }));
} }
@@ -191,7 +191,7 @@ public class SimulatorTests
ActionType.Groundwork, ActionType.Groundwork,
ActionType.Groundwork, ActionType.Groundwork,
}, },
3726, 8224, 5, 69); 3726, 8748, 5, 69);
} }
[TestMethod] [TestMethod]