New 7.0 actions and updates
This commit is contained in:
@@ -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)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace Craftimizer.Simulator.Actions;
|
|
||||||
|
|
||||||
internal sealed class FocusedTouchCombo() : BaseComboAction<Observe, FocusedTouch>(
|
|
||||||
ActionType.Observe, ActionType.FocusedTouch
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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";
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Craftimizer.Simulator.Actions;
|
||||||
|
|
||||||
|
internal sealed class RefinedTouchCombo() : BaseComboAction<BasicTouch, RefinedTouch>(
|
||||||
|
ActionType.BasicTouch, ActionType.RefinedTouch
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -12,4 +12,6 @@ public enum EffectType
|
|||||||
MuscleMemory,
|
MuscleMemory,
|
||||||
Manipulation,
|
Manipulation,
|
||||||
HeartAndSoul,
|
HeartAndSoul,
|
||||||
|
Expedience,
|
||||||
|
TrainedPerfection
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
Reference in New Issue
Block a user