Convert Simulation into data-oriented SimualtionState
This commit is contained in:
@@ -11,7 +11,7 @@ namespace Craftimizer.Plugin;
|
|||||||
|
|
||||||
public class SimulatorWindow : Window
|
public class SimulatorWindow : Window
|
||||||
{
|
{
|
||||||
public Simulation Simulation { get; }
|
public SimulationState Simulation { get; }
|
||||||
|
|
||||||
private bool showOnlyGuaranteedActions = true;
|
private bool showOnlyGuaranteedActions = true;
|
||||||
|
|
||||||
@@ -23,7 +23,11 @@ public class SimulatorWindow : Window
|
|||||||
MaximumSize = new Vector2(float.MaxValue, float.MaxValue)
|
MaximumSize = new Vector2(float.MaxValue, float.MaxValue)
|
||||||
};
|
};
|
||||||
|
|
||||||
Simulation = new(new CharacterStats { Craftsmanship = 4041, Control = 3905, CP = 609, Level = 90 }, LuminaSheets.RecipeSheet.GetRow(35499)!);
|
Simulation = new(new()
|
||||||
|
{
|
||||||
|
Stats = new CharacterStats { Craftsmanship = 4041, Control = 3905, CP = 609, Level = 90 },
|
||||||
|
Recipe = LuminaSheets.RecipeSheet.GetRow(35499)!
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw()
|
public override void Draw()
|
||||||
@@ -62,19 +66,19 @@ public class SimulatorWindow : Window
|
|||||||
ImGui.Text($"Step {Simulation.StepCount + 1}");
|
ImGui.Text($"Step {Simulation.StepCount + 1}");
|
||||||
ImGui.Text(Simulation.Condition.Name());
|
ImGui.Text(Simulation.Condition.Name());
|
||||||
if (ImGui.IsItemHovered())
|
if (ImGui.IsItemHovered())
|
||||||
ImGui.SetTooltip(Simulation.Condition.Description(Simulation.Stats.HasRelic));
|
ImGui.SetTooltip(Simulation.Condition.Description(Simulation.Input.Stats.HasRelic));
|
||||||
ImGui.Text($"{Simulation.HQPercent}%% HQ");
|
ImGui.Text($"{Simulation.HQPercent}%% HQ");
|
||||||
ImGui.PushStyleColor(ImGuiCol.PlotHistogram, new Vector4(.2f, 1f, .2f, 1f));
|
ImGui.PushStyleColor(ImGuiCol.PlotHistogram, new Vector4(.2f, 1f, .2f, 1f));
|
||||||
ImGui.ProgressBar(Math.Min((float)Simulation.Progress / Simulation.MaxProgress, 1f), new Vector2(200, 20), $"{Simulation.Progress} / {Simulation.MaxProgress}");
|
ImGui.ProgressBar(Math.Min((float)Simulation.Progress / Simulation.Input.MaxProgress, 1f), new Vector2(200, 20), $"{Simulation.Progress} / {Simulation.Input.MaxProgress}");
|
||||||
ImGui.PopStyleColor();
|
ImGui.PopStyleColor();
|
||||||
ImGui.PushStyleColor(ImGuiCol.PlotHistogram, new Vector4(.2f, .2f, 1f, 1f));
|
ImGui.PushStyleColor(ImGuiCol.PlotHistogram, new Vector4(.2f, .2f, 1f, 1f));
|
||||||
ImGui.ProgressBar(Math.Min((float)Simulation.Quality / Simulation.MaxQuality, 1f), new Vector2(200, 20), $"{Simulation.Quality} / {Simulation.MaxQuality}");
|
ImGui.ProgressBar(Math.Min((float)Simulation.Quality / Simulation.Input.MaxQuality, 1f), new Vector2(200, 20), $"{Simulation.Quality} / {Simulation.Input.MaxQuality}");
|
||||||
ImGui.PopStyleColor();
|
ImGui.PopStyleColor();
|
||||||
ImGui.PushStyleColor(ImGuiCol.PlotHistogram, new Vector4(1f, 1f, .2f, 1f));
|
ImGui.PushStyleColor(ImGuiCol.PlotHistogram, new Vector4(1f, 1f, .2f, 1f));
|
||||||
ImGui.ProgressBar(Math.Clamp((float)Simulation.Durability / Simulation.MaxDurability, 0f, 1f), new Vector2(200, 20), $"{Simulation.Durability} / {Simulation.MaxDurability}");
|
ImGui.ProgressBar(Math.Clamp((float)Simulation.Durability / Simulation.Input.MaxDurability, 0f, 1f), new Vector2(200, 20), $"{Simulation.Durability} / {Simulation.Input.MaxDurability}");
|
||||||
ImGui.PopStyleColor();
|
ImGui.PopStyleColor();
|
||||||
ImGui.PushStyleColor(ImGuiCol.PlotHistogram, new Vector4(1f, .2f, 1f, 1f));
|
ImGui.PushStyleColor(ImGuiCol.PlotHistogram, new Vector4(1f, .2f, 1f, 1f));
|
||||||
ImGui.ProgressBar(Math.Clamp((float)Simulation.CP / Simulation.Stats.CP, 0f, 1f), new Vector2(200, 20), $"{Simulation.CP} / {Simulation.Stats.CP}");
|
ImGui.ProgressBar(Math.Clamp((float)Simulation.CP / Simulation.Input.Stats.CP, 0f, 1f), new Vector2(200, 20), $"{Simulation.CP} / {Simulation.Input.Stats.CP}");
|
||||||
ImGui.PopStyleColor();
|
ImGui.PopStyleColor();
|
||||||
ImGuiHelpers.ScaledDummy(5);
|
ImGuiHelpers.ScaledDummy(5);
|
||||||
ImGui.Text($"Effects:");
|
ImGui.Text($"Effects:");
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ internal static class ActionUtils
|
|||||||
|
|
||||||
private static BaseAction Action(this ActionType me) => Actions[(int)me];
|
private static BaseAction Action(this ActionType me) => Actions[(int)me];
|
||||||
|
|
||||||
public static BaseAction With(this ActionType me, Simulation simulation)
|
public static BaseAction With(this ActionType me, SimulationState simulation)
|
||||||
{
|
{
|
||||||
BaseAction.TLSSimulation.Value = simulation;
|
BaseAction.TLSSimulation.Value = simulation;
|
||||||
return Action(me);
|
return Action(me);
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ namespace Craftimizer.Simulator.Actions;
|
|||||||
|
|
||||||
internal abstract class BaseAction
|
internal abstract class BaseAction
|
||||||
{
|
{
|
||||||
internal static readonly ThreadLocal<Simulation> TLSSimulation = new(false);
|
internal static readonly ThreadLocal<SimulationState?> TLSSimulation = new(false);
|
||||||
protected static Simulation Simulation => TLSSimulation.Value ?? throw new NullReferenceException();
|
protected static SimulationState Simulation => TLSSimulation.Value ?? throw new NullReferenceException();
|
||||||
|
|
||||||
public BaseAction() { }
|
public BaseAction() { }
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ internal abstract class BaseAction
|
|||||||
public virtual bool IsGuaranteedAction => SuccessRate == 1f;
|
public virtual bool IsGuaranteedAction => SuccessRate == 1f;
|
||||||
|
|
||||||
public virtual bool CanUse =>
|
public virtual bool CanUse =>
|
||||||
Simulation.Stats.Level >= Level && Simulation.CP >= CPCost;
|
Simulation.Input.Stats.Level >= Level && Simulation.CP >= CPCost;
|
||||||
|
|
||||||
public virtual void Use()
|
public virtual void Use()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ internal class BasicSynthesis : BaseAction
|
|||||||
|
|
||||||
public override int CPCost => 0;
|
public override int CPCost => 0;
|
||||||
// Basic Synthesis Mastery Trait
|
// Basic Synthesis Mastery Trait
|
||||||
public override float Efficiency => Simulation.Stats.Level >= 31 ? 1.20f : 1.00f;
|
public override float Efficiency => Simulation.Input.Stats.Level >= 31 ? 1.20f : 1.00f;
|
||||||
public override bool IncreasesProgress => true;
|
public override bool IncreasesProgress => true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ internal class CarefulObservation : BaseAction
|
|||||||
public override int DurabilityCost => 0;
|
public override int DurabilityCost => 0;
|
||||||
public override bool IncreasesStepCount => false;
|
public override bool IncreasesStepCount => false;
|
||||||
|
|
||||||
public override bool CanUse => Simulation.Stats.IsSpecialist && Simulation.CountPreviousAction(ActionType.CarefulObservation) < 3;
|
public override bool CanUse => Simulation.Input.Stats.IsSpecialist && Simulation.CountPreviousAction(ActionType.CarefulObservation) < 3;
|
||||||
|
|
||||||
public override void UseSuccess() =>
|
public override void UseSuccess() =>
|
||||||
Simulation.StepCondition();
|
Simulation.StepCondition();
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ internal class CarefulSynthesis : BaseAction
|
|||||||
|
|
||||||
public override int CPCost => 7;
|
public override int CPCost => 7;
|
||||||
// Careful Synthesis Mastery Trait
|
// Careful Synthesis Mastery Trait
|
||||||
public override float Efficiency => Simulation.Stats.Level >= 82 ? 1.80f : 1.50f;
|
public override float Efficiency => Simulation.Input.Stats.Level >= 82 ? 1.80f : 1.50f;
|
||||||
public override bool IncreasesProgress => true;
|
public override bool IncreasesProgress => true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ internal class Groundwork : BaseAction
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var ret = Simulation.Stats.Level >= 86 ? 3.60f : 3.00f;
|
var ret = Simulation.Input.Stats.Level >= 86 ? 3.60f : 3.00f;
|
||||||
// TODO: does not account for waste not
|
// TODO: does not account for waste not
|
||||||
return Simulation.Durability < DurabilityCost ? ret / 2 : ret;
|
return Simulation.Durability < DurabilityCost ? ret / 2 : ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ internal class HeartAndSoul : BaseBuffAction
|
|||||||
|
|
||||||
public override Effect Effect => new() { Type = EffectType.HeartAndSoul };
|
public override Effect Effect => new() { Type = EffectType.HeartAndSoul };
|
||||||
|
|
||||||
public override bool CanUse => Simulation.Stats.IsSpecialist && Simulation.CountPreviousAction(ActionType.HeartAndSoul) == 0;
|
public override bool CanUse => Simulation.Input.Stats.IsSpecialist && Simulation.CountPreviousAction(ActionType.HeartAndSoul) == 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ internal class RapidSynthesis : BaseAction
|
|||||||
|
|
||||||
public override int CPCost => 0;
|
public override int CPCost => 0;
|
||||||
// Rapid Synthesis Mastery Trait
|
// Rapid Synthesis Mastery Trait
|
||||||
public override float Efficiency => Simulation.Stats.Level >= 63 ? 5.00f : 2.50f;
|
public override float Efficiency => Simulation.Input.Stats.Level >= 63 ? 5.00f : 2.50f;
|
||||||
public override bool IncreasesProgress => true;
|
public override bool IncreasesProgress => true;
|
||||||
public override float SuccessRate => 0.50f;
|
public override float SuccessRate => 0.50f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ internal class TrainedEye : BaseAction
|
|||||||
public override bool CanUse => Simulation.IsFirstStep && base.CanUse;
|
public override bool CanUse => Simulation.IsFirstStep && base.CanUse;
|
||||||
|
|
||||||
public override void UseSuccess() =>
|
public override void UseSuccess() =>
|
||||||
Simulation.IncreaseQualityRaw(Simulation.MaxQuality - Simulation.Quality);
|
Simulation.IncreaseQualityRaw(Simulation.Input.MaxQuality - Simulation.Quality);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using Lumina.Excel.GeneratedSheets;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Craftimizer.Simulator;
|
||||||
|
|
||||||
|
public readonly record struct SimulationInput
|
||||||
|
{
|
||||||
|
public CharacterStats Stats { get; init; }
|
||||||
|
public Recipe Recipe { get; init; }
|
||||||
|
public Random Random { get; init; }
|
||||||
|
|
||||||
|
public RecipeLevelTable RecipeTable => Recipe.RecipeLevelTable.Value!;
|
||||||
|
public int RLvl => (int)RecipeTable.RowId;
|
||||||
|
public Condition[] AvailableConditions => ConditionUtils.GetPossibleConditions(RecipeTable.ConditionsFlag);
|
||||||
|
|
||||||
|
public int MaxDurability => RecipeTable.Durability * Recipe.DurabilityFactor / 100;
|
||||||
|
public int MaxQuality => (int)RecipeTable.Quality * Recipe.QualityFactor / 100;
|
||||||
|
public int MaxProgress => RecipeTable.Difficulty * Recipe.DifficultyFactor / 100;
|
||||||
|
}
|
||||||
@@ -1,23 +1,13 @@
|
|||||||
using Craftimizer.Simulator.Actions;
|
using Craftimizer.Simulator.Actions;
|
||||||
using Dalamud.Logging;
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Craftimizer.Simulator;
|
namespace Craftimizer.Simulator;
|
||||||
|
|
||||||
public class Simulation
|
public record struct SimulationState
|
||||||
{
|
{
|
||||||
public CharacterStats Stats { get; }
|
public readonly SimulationInput Input { get; }
|
||||||
public Recipe Recipe { get; }
|
|
||||||
public RecipeLevelTable RecipeTable => Recipe.RecipeLevelTable.Value!;
|
|
||||||
public int RLvl => (int)RecipeTable.RowId;
|
|
||||||
public readonly Condition[] AvailableConditions;
|
|
||||||
|
|
||||||
public int MaxDurability => RecipeTable.Durability * Recipe.DurabilityFactor / 100;
|
|
||||||
public int MaxQuality => (int)RecipeTable.Quality * Recipe.QualityFactor / 100;
|
|
||||||
public int MaxProgress => RecipeTable.Difficulty * Recipe.DifficultyFactor / 100;
|
|
||||||
|
|
||||||
public bool IsComplete { get; private set; }
|
public bool IsComplete { get; private set; }
|
||||||
public int StepCount { get; private set; }
|
public int StepCount { get; private set; }
|
||||||
@@ -26,8 +16,8 @@ public class Simulation
|
|||||||
public int Durability { get; private set; }
|
public int Durability { get; private set; }
|
||||||
public int CP { get; private set; }
|
public int CP { get; private set; }
|
||||||
public Condition Condition { get; private set; }
|
public Condition Condition { get; private set; }
|
||||||
public List<Effect> ActiveEffects { get; } = new();
|
public List<Effect> ActiveEffects { get; }
|
||||||
public List<ActionType> ActionHistory { get; } = new();
|
public List<ActionType> ActionHistory { get; }
|
||||||
|
|
||||||
// https://github.com/ffxiv-teamcraft/simulator/blob/0682dfa76043ff4ccb38832c184d046ceaff0733/src/model/tables.ts#L2
|
// https://github.com/ffxiv-teamcraft/simulator/blob/0682dfa76043ff4ccb38832c184d046ceaff0733/src/model/tables.ts#L2
|
||||||
private static readonly int[] HQPercentTable = {
|
private static readonly int[] HQPercentTable = {
|
||||||
@@ -36,27 +26,33 @@ public class Simulation
|
|||||||
17, 18, 18, 18, 19, 19, 20, 20, 21, 22, 23, 24, 26, 28, 31, 34, 38, 42, 47, 52, 58, 64, 68, 71,
|
17, 18, 18, 18, 19, 19, 20, 20, 21, 22, 23, 24, 26, 28, 31, 34, 38, 42, 47, 52, 58, 64, 68, 71,
|
||||||
74, 76, 78, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 94, 96, 98, 100
|
74, 76, 78, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 94, 96, 98, 100
|
||||||
};
|
};
|
||||||
public int HQPercent => HQPercentTable[(int)Math.Clamp((float)Quality / MaxQuality * 100, 0, 100)];
|
public int HQPercent => HQPercentTable[(int)Math.Clamp((float)Quality / Input.MaxQuality * 100, 0, 100)];
|
||||||
|
|
||||||
public bool IsFirstStep => StepCount == 0;
|
public bool IsFirstStep => StepCount == 0;
|
||||||
|
|
||||||
private Random Random { get; } = new();
|
public SimulationState(SimulationInput input)
|
||||||
|
|
||||||
public Simulation(CharacterStats stats, Recipe recipe)
|
|
||||||
{
|
{
|
||||||
Stats = stats;
|
Input = input;
|
||||||
Recipe = recipe;
|
|
||||||
IsComplete = false;
|
IsComplete = false;
|
||||||
StepCount = 0;
|
StepCount = 0;
|
||||||
Progress = 0;
|
Progress = 0;
|
||||||
Quality = 0;
|
Quality = 0;
|
||||||
Durability = MaxDurability;
|
Durability = Input.MaxDurability;
|
||||||
CP = Stats.CP;
|
CP = Input.Stats.CP;
|
||||||
Condition = Condition.Normal;
|
Condition = Condition.Normal;
|
||||||
AvailableConditions = ConditionUtils.GetPossibleConditions(RecipeTable.ConditionsFlag);
|
ActiveEffects = new();
|
||||||
|
ActionHistory = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResponse Execute(ActionType action)
|
public (ActionResponse Response, SimulationState NewState) Execute(ActionType action)
|
||||||
|
{
|
||||||
|
var newState = this;
|
||||||
|
var response = newState.ExecuteSelf(action);
|
||||||
|
return (response, newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionResponse ExecuteSelf(ActionType action)
|
||||||
{
|
{
|
||||||
if (IsComplete)
|
if (IsComplete)
|
||||||
return ActionResponse.SimulationComplete;
|
return ActionResponse.SimulationComplete;
|
||||||
@@ -64,7 +60,7 @@ public class Simulation
|
|||||||
var baseAction = action.With(this);
|
var baseAction = action.With(this);
|
||||||
if (!baseAction.CanUse)
|
if (!baseAction.CanUse)
|
||||||
{
|
{
|
||||||
if (baseAction.Level > Stats.Level)
|
if (baseAction.Level > Input.Stats.Level)
|
||||||
return ActionResponse.ActionNotUnlocked;
|
return ActionResponse.ActionNotUnlocked;
|
||||||
if (baseAction.CPCost > CP)
|
if (baseAction.CPCost > CP)
|
||||||
return ActionResponse.NotEnoughCP;
|
return ActionResponse.NotEnoughCP;
|
||||||
@@ -85,7 +81,7 @@ public class Simulation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Progress >= MaxProgress)
|
if (Progress >= Input.MaxProgress)
|
||||||
{
|
{
|
||||||
IsComplete = true;
|
IsComplete = true;
|
||||||
return ActionResponse.ProgressComplete;
|
return ActionResponse.ProgressComplete;
|
||||||
@@ -112,7 +108,8 @@ public class Simulation
|
|||||||
duration++;
|
duration++;
|
||||||
|
|
||||||
var currentEffect = GetEffect(effect);
|
var currentEffect = GetEffect(effect);
|
||||||
if (currentEffect != null) {
|
if (currentEffect != null)
|
||||||
|
{
|
||||||
currentEffect.Duration = duration;
|
currentEffect.Duration = duration;
|
||||||
currentEffect.Strength = strength;
|
currentEffect.Strength = strength;
|
||||||
}
|
}
|
||||||
@@ -148,7 +145,7 @@ public class Simulation
|
|||||||
ActionHistory.Count(a => a == action);
|
ActionHistory.Count(a => a == action);
|
||||||
|
|
||||||
public bool RollSuccessRaw(float successRate) =>
|
public bool RollSuccessRaw(float successRate) =>
|
||||||
successRate >= Random.NextSingle();
|
successRate >= Input.Random.NextSingle();
|
||||||
|
|
||||||
public bool RollSuccess(float successRate) =>
|
public bool RollSuccess(float successRate) =>
|
||||||
RollSuccessRaw(CalculateSuccessRate(successRate));
|
RollSuccessRaw(CalculateSuccessRate(successRate));
|
||||||
@@ -159,10 +156,10 @@ public class Simulation
|
|||||||
StepCondition();
|
StepCondition();
|
||||||
}
|
}
|
||||||
|
|
||||||
private float GetConditionChance(Condition condition) =>
|
private static float GetConditionChance(SimulationInput input, Condition condition) =>
|
||||||
condition switch
|
condition switch
|
||||||
{
|
{
|
||||||
Condition.Good => Recipe.IsExpert ? 0.12f : (Stats.Level >= 63 ? 0.15f : 0.18f),
|
Condition.Good => input.Recipe.IsExpert ? 0.12f : (input.Stats.Level >= 63 ? 0.15f : 0.18f),
|
||||||
Condition.Excellent => 0.04f,
|
Condition.Excellent => 0.04f,
|
||||||
Condition.Centered => 0.15f,
|
Condition.Centered => 0.15f,
|
||||||
Condition.Sturdy => 0.15f,
|
Condition.Sturdy => 0.15f,
|
||||||
@@ -173,16 +170,26 @@ public class Simulation
|
|||||||
_ => 0.00f
|
_ => 0.00f
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private Condition GetNextRandomCondition()
|
||||||
|
{
|
||||||
|
var conditionChance = Input.Random.NextSingle();
|
||||||
|
|
||||||
|
foreach (var condition in Input.AvailableConditions)
|
||||||
|
if ((conditionChance -= GetConditionChance(Input, condition)) < 0)
|
||||||
|
return condition;
|
||||||
|
|
||||||
|
return Condition.Normal;
|
||||||
|
}
|
||||||
|
|
||||||
public void StepCondition()
|
public void StepCondition()
|
||||||
{
|
{
|
||||||
var conditionChance = Random.NextSingle();
|
Condition = Condition switch
|
||||||
|
{
|
||||||
Condition = Condition switch {
|
|
||||||
Condition.Poor => Condition.Normal,
|
Condition.Poor => Condition.Normal,
|
||||||
Condition.Good => Condition.Normal,
|
Condition.Good => Condition.Normal,
|
||||||
Condition.Excellent => Condition.Poor,
|
Condition.Excellent => Condition.Poor,
|
||||||
Condition.GoodOmen => Condition.Good,
|
Condition.GoodOmen => Condition.Good,
|
||||||
_ => AvailableConditions.FirstOrDefault(c => (conditionChance -= GetConditionChance(c)) < 0, Condition.Normal)
|
_ => GetNextRandomCondition()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,16 +197,16 @@ public class Simulation
|
|||||||
{
|
{
|
||||||
Durability += amount;
|
Durability += amount;
|
||||||
|
|
||||||
if (Durability > MaxDurability)
|
if (Durability > Input.MaxDurability)
|
||||||
Durability = MaxDurability;
|
Durability = Input.MaxDurability;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RestoreCP(int amount)
|
public void RestoreCP(int amount)
|
||||||
{
|
{
|
||||||
CP += amount;
|
CP += amount;
|
||||||
|
|
||||||
if (CP > Stats.CP)
|
if (CP > Input.Stats.CP)
|
||||||
CP = Stats.CP;
|
CP = Input.Stats.CP;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float CalculateSuccessRate(float successRate)
|
public float CalculateSuccessRate(float successRate)
|
||||||
@@ -246,9 +253,9 @@ public class Simulation
|
|||||||
};
|
};
|
||||||
|
|
||||||
// https://github.com/NotRanged/NotRanged.github.io/blob/0f4aee074f969fb05aad34feaba605057c08ffd1/app/js/ffxivcraftmodel.js#L88
|
// https://github.com/NotRanged/NotRanged.github.io/blob/0f4aee074f969fb05aad34feaba605057c08ffd1/app/js/ffxivcraftmodel.js#L88
|
||||||
var baseIncrease = (Stats.Craftsmanship * 10f / RecipeTable.ProgressDivider) + 2;
|
var baseIncrease = (Input.Stats.Craftsmanship * 10f / Input.RecipeTable.ProgressDivider) + 2;
|
||||||
if (Stats.CLvl <= RLvl)
|
if (Input.Stats.CLvl <= Input.RLvl)
|
||||||
baseIncrease *= RecipeTable.ProgressModifier / 100f;
|
baseIncrease *= Input.RecipeTable.ProgressModifier / 100f;
|
||||||
baseIncrease = MathF.Floor(baseIncrease);
|
baseIncrease = MathF.Floor(baseIncrease);
|
||||||
|
|
||||||
var progressGain = (int)(baseIncrease * efficiency * conditionModifier * buffModifier);
|
var progressGain = (int)(baseIncrease * efficiency * conditionModifier * buffModifier);
|
||||||
@@ -272,14 +279,14 @@ public class Simulation
|
|||||||
var conditionModifier = Condition switch
|
var conditionModifier = Condition switch
|
||||||
{
|
{
|
||||||
Condition.Poor => 0.50f,
|
Condition.Poor => 0.50f,
|
||||||
Condition.Good => Stats.HasRelic ? 1.75f : 1.50f,
|
Condition.Good => Input.Stats.HasRelic ? 1.75f : 1.50f,
|
||||||
Condition.Excellent => 4.00f,
|
Condition.Excellent => 4.00f,
|
||||||
_ => 1.00f,
|
_ => 1.00f,
|
||||||
};
|
};
|
||||||
|
|
||||||
var baseIncrease = (Stats.Control * 10f / RecipeTable.QualityDivider) + 35;
|
var baseIncrease = (Input.Stats.Control * 10f / Input.RecipeTable.QualityDivider) + 35;
|
||||||
if (Stats.CLvl <= RLvl)
|
if (Input.Stats.CLvl <= Input.RLvl)
|
||||||
baseIncrease *= RecipeTable.QualityModifier / 100f;
|
baseIncrease *= Input.RecipeTable.QualityModifier / 100f;
|
||||||
baseIncrease = MathF.Floor(baseIncrease);
|
baseIncrease = MathF.Floor(baseIncrease);
|
||||||
|
|
||||||
var qualityGain = (int)(baseIncrease * efficiency * conditionModifier * buffModifier);
|
var qualityGain = (int)(baseIncrease * efficiency * conditionModifier * buffModifier);
|
||||||
@@ -296,9 +303,9 @@ public class Simulation
|
|||||||
{
|
{
|
||||||
Progress += progressGain;
|
Progress += progressGain;
|
||||||
|
|
||||||
if (HasEffect(EffectType.FinalAppraisal) && Progress >= MaxProgress)
|
if (HasEffect(EffectType.FinalAppraisal) && Progress >= Input.MaxProgress)
|
||||||
{
|
{
|
||||||
Progress = MaxProgress - 1;
|
Progress = Input.MaxProgress - 1;
|
||||||
RemoveEffect(EffectType.FinalAppraisal);
|
RemoveEffect(EffectType.FinalAppraisal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -307,7 +314,7 @@ public class Simulation
|
|||||||
{
|
{
|
||||||
Quality += qualityGain;
|
Quality += qualityGain;
|
||||||
|
|
||||||
if (Stats.Level >= 11)
|
if (Input.Stats.Level >= 11)
|
||||||
StrengthenEffect(EffectType.InnerQuiet);
|
StrengthenEffect(EffectType.InnerQuiet);
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user