diff --git a/Test/Simulator/Simulator.cs b/Test/Simulator/Simulator.cs index d71e024..7ec6e9a 100644 --- a/Test/Simulator/Simulator.cs +++ b/Test/Simulator/Simulator.cs @@ -5,40 +5,23 @@ public class SimulatorTests { // https://craftingway.app/rotation/loud-namazu-jVe9Y // Chondrite Saw - private static SimulationInput Input1 { get; } = - new(new() - { - Craftsmanship = 3304, - Control = 3374, - CP = 575, - Level = 90, - CanUseManipulation = true, - HasSplendorousBuff = false, - IsSpecialist = false, - }, - new() - { - IsExpert = false, - ClassJobLevel = 90, - ConditionsFlag = 0b1111, - MaxDurability = 80, - MaxQuality = 7200, - MaxProgress = 3500, - QualityModifier = 80, - QualityDivider = 115, - ProgressModifier = 90, - ProgressDivider = 130 - }); + private static SimulationInput Input1 { get; } = CreateInput(3304, 3374, 575, 90, 80, 7200, 3500, 80, 115, 90, 130); // https://craftingway.app/rotation/sandy-fafnir-doVCs // Classical Longsword - private static SimulationInput Input2 { get; } = - new(new() + private static SimulationInput Input2 { get; } = CreateInput(3290, 3541, 649, 90, 70, 10920, 3900, 70, 115, 80, 130); + + private static SimulationInput CreateInput( + int craftsmanship, int control, int cp, + int level, int durability, int quality, int progress, + int qualityModifier, int qualityDivider, int progressModifier, int progressDivider) + { + return new(new() { - Craftsmanship = 3290, - Control = 3541, - CP = 649, - Level = 90, + Craftsmanship = craftsmanship, + Control = control, + CP = cp, + Level = level, CanUseManipulation = true, HasSplendorousBuff = false, IsSpecialist = false, @@ -46,18 +29,18 @@ public class SimulatorTests new() { IsExpert = false, - ClassJobLevel = 90, - ConditionsFlag = 0b1111, - MaxDurability = 70, - MaxQuality = 10920, - MaxProgress = 3900, - QualityModifier = 70, - QualityDivider = 115, - ProgressModifier = 80, - ProgressDivider = 130 + ClassJobLevel = level, + MaxDurability = durability, + MaxQuality = quality, + MaxProgress = progress, + QualityModifier = qualityModifier, + QualityDivider = qualityDivider, + ProgressModifier = progressModifier, + ProgressDivider = progressDivider }); + } - private static SimulationState AssertCraft(SimulationInput input, IEnumerable actions, + private static SimulationState AssertCraft(SimulationInput input, ActionType[] actions, int progress, int quality, int durability, int cp) { @@ -71,68 +54,59 @@ public class SimulatorTests } [TestMethod] - public void BasicActions() - { + public void BasicActions() => AssertCraft( Input1, - new[] { + [ ActionType.BasicTouch, ActionType.BasicSynthesis, ActionType.MastersMend - }, + ], 276, 262, 80, 469); - } [TestMethod] - public void BasicTouchCombo() - { + public void BasicTouchCombo() => AssertCraft( Input1, - new[] { + [ ActionType.Innovation, ActionType.BasicTouch, ActionType.StandardTouch, ActionType.AdvancedTouch, ActionType.StandardTouch, ActionType.AdvancedTouch - }, + ], 0, 2828, 30, 425); - } [TestMethod] - public void WithBuffs1() - { + public void WithBuffs1() => AssertCraft( Input1, - new[] { + [ ActionType.Reflect, ActionType.Manipulation, ActionType.PreparatoryTouch, ActionType.WasteNot2 - }, + ], 0, 1414, 60, 335); - } [TestMethod] - public void WithBuffs2() - { + public void WithBuffs2() => AssertCraft( Input1, - new[] { + [ ActionType.MuscleMemory, ActionType.GreatStrides, ActionType.PrudentTouch, ActionType.DelicateSynthesis - }, + ], 1150, 812, 55, 480); - } [TestMethod] - public void WithBuffs3() - { + public void WithBuffs3() => AssertCraft( Input1, - new[] { + [ ActionType.MuscleMemory, ActionType.Manipulation, ActionType.MastersMend, @@ -142,16 +116,15 @@ public class SimulatorTests ActionType.BasicTouch, ActionType.GreatStrides, ActionType.ByregotsBlessing - }, + ], 1150, 1925, 80, 163); - } [TestMethod] public void TrainedFinesseProcs() { var state = AssertCraft( Input1, - new[] { + [ ActionType.Reflect, ActionType.WasteNot, ActionType.PreparatoryTouch, @@ -160,18 +133,17 @@ public class SimulatorTests ActionType.StandardTouch, ActionType.PrudentTouch, ActionType.PreparatoryTouch - }, + ], 0, 4588, 15, 332); Assert.AreEqual(10, state.ActiveEffects.InnerQuiet); Assert.IsTrue(ActionType.TrainedFinesse.Base().CanUse(new SimulatorNoRandom() { State = state })); } [TestMethod] - public void TestCompletedCraft1() - { + public void TestCompletedCraft1() => AssertCraft( Input1, - new[] { + [ ActionType.Reflect, ActionType.Manipulation, ActionType.PreparatoryTouch, @@ -186,16 +158,14 @@ public class SimulatorTests ActionType.Groundwork, ActionType.Groundwork, ActionType.Groundwork, - }, + ], 3726, 8748, 5, 69); - } [TestMethod] - public void TestCompletedCraft2() - { + public void TestCompletedCraft2() => AssertCraft( Input2, - new[] { + [ ActionType.MuscleMemory, ActionType.Manipulation, ActionType.Veneration, @@ -214,9 +184,125 @@ public class SimulatorTests ActionType.TrainedFinesse, ActionType.GreatStrides, ActionType.ByregotsBlessing - }, + ], // TC https://ffxivteamcraft.com/simulator/35020/34800/4PTlwTV6w1aGCUdO2BRl // Craftingway https://craftingway.app/rotation/sandy-fafnir-doVCs 3549, 10932, 5, 7); + + // Should handle Reflect properly + [TestMethod] + public void TestTeamcraft1() + { + var state = AssertCraft( + CreateInput(2278, 2348, 532, 80, 80, 866, 31, 100, 30, 100, 50), + [ + ActionType.Reflect, + ActionType.BasicTouch, + ActionType.CarefulSynthesis, + ], + 685, 3431, 50, 501); + + Assert.AreEqual(3, state.ActiveEffects.InnerQuiet); } + + // Should provide same result as ingame for a low level rotation + [TestMethod] + public void TestTeamcraft2() => + AssertCraft( + CreateInput(2278, 2348, 532, 80, 80, 866, 31, 100, 30, 100, 50), + [ + ActionType.Reflect, + ActionType.BasicTouch, + ActionType.ByregotsBlessing, + ActionType.CarefulSynthesis, + ], + 685, 5130, 40, 477); + + // Should handle new Innovation interactions properly + [TestMethod] + public void TestTeamcraft3() => + AssertCraft( + CreateInput(2763, 2780, 545, 80, 80, 5200, 2000, 100, 105, 100, 121), + [ + ActionType.Reflect, + ActionType.DelicateSynthesis, + ActionType.DelicateSynthesis, + ActionType.WasteNot, + ActionType.Groundwork, + ActionType.Innovation, + ActionType.PreparatoryTouch, + ActionType.PreparatoryTouch, + ActionType.MastersMend, + ActionType.PreparatoryTouch, + ], + 1150, 5947, 30, 175); + + // Should compute flooring accurately + [TestMethod] + public void TestTeamcraft4A() => + AssertCraft( + CreateInput(1645, 1532, 400, 80, 80, 5200, 2000, 100, 105, 100, 121), + [ + ActionType.BasicTouch, + ActionType.BasicTouch, + ActionType.BasicTouch, + ActionType.BasicTouch, + ], + 0, 828, 40, 328); + + [TestMethod] + public void TestTeamcraft4B() => + AssertCraft( + CreateInput(3289, 3420, 400, 90, 80, 10920, 3900, 70, 115, 80, 130), + [ + ActionType.MuscleMemory, + ActionType.Veneration, + ActionType.Groundwork, + ActionType.Groundwork, + ActionType.Observe, + ActionType.Observe, + ActionType.CarefulSynthesis, + ], + 3897, 0, 20, 319); + + // Should compute flooring accurately using DT rotation + [TestMethod] + public void TestTeamcraft5A() => + AssertCraft( + CreateInput(3957, 3896, 563, 94, 80, 11400, 6300, 100, 147, 100, 167), + [ + ActionType.Reflect, + ActionType.Innovation, + ActionType.PreparatoryTouch, + ActionType.PrudentTouch, + ], + 0, 2610, 45, 474); + + [TestMethod] + public void TestTeamcraft5B() => + AssertCraft( + CreateInput(4045, 3902, 601, 100, 80, 11400, 6300, 100, 147, 100, 167), + [ + ActionType.Reflect, + ActionType.Innovation, + ActionType.PreparatoryTouch, + ActionType.PrudentTouch, + ActionType.GreatStrides, + ActionType.PreparatoryTouch, + ActionType.GreatStrides, + ActionType.Innovation, + ActionType.PreparatoryTouch, + ActionType.ImmaculateMend, + ActionType.GreatStrides, + ActionType.ByregotsBlessing, + ActionType.WasteNot, + ActionType.Veneration, + ActionType.Groundwork, + ActionType.Groundwork, + ActionType.Groundwork, + ActionType.Groundwork, + ActionType.Veneration, + ActionType.Groundwork, + ], + 6585, 11400, 0, 0); }