From a5ad55865277f5f56abf45a1d2483be947caa918 Mon Sep 17 00:00:00 2001 From: Jeremy Saklad Date: Sun, 23 May 2021 14:53:50 -0500 Subject: [PATCH 1/5] Add builtBuildings variable to RecipeRow This variable, which defaults to null, can be used to track the number of buildings that have actually been built. This number has no impact on the model. --- YAFCmodel/Model/ProductionTableContent.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/YAFCmodel/Model/ProductionTableContent.cs b/YAFCmodel/Model/ProductionTableContent.cs index 4e34e103..2897ccf5 100644 --- a/YAFCmodel/Model/ProductionTableContent.cs +++ b/YAFCmodel/Model/ProductionTableContent.cs @@ -164,6 +164,7 @@ public class RecipeRow : ModelObject, IModuleFiller public Goods fuel { get; set; } public RecipeLinks links { get; internal set; } public float fixedBuildings { get; set; } + public int? builtBuildings { get; set; } public bool enabled { get; set; } = true; public bool hierarchyEnabled { get; internal set; } public int tag { get; set; } From 7478a67180d60ae29bb5a105556d61cd7a5a1eba Mon Sep 17 00:00:00 2001 From: Jeremy Saklad Date: Sun, 23 May 2021 15:44:16 -0500 Subject: [PATCH 2/5] Add dropdown menu items for changing builtBuildings Dropdown menu items for setting or clearing the builtBuildings value have been added for each recipe row. These items mirror the behavior and implementation of those for fixedBuildings, for the most part. The initial value is buildingCount rounded up, or 0 if buildingCount is negative. As 0 is a valid value, clearing builtBuildings returns it to null. Shopping lists now use the builtBuildings value instead of buildingCount if the former is not null. --- .../ProductionTable/ProductionTableView.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/YAFC/Workspace/ProductionTable/ProductionTableView.cs b/YAFC/Workspace/ProductionTable/ProductionTableView.cs index a24da8fe..48276d60 100644 --- a/YAFC/Workspace/ProductionTable/ProductionTableView.cs +++ b/YAFC/Workspace/ProductionTable/ProductionTableView.cs @@ -340,6 +340,17 @@ private void ShowEntityDropPown(ImGui imgui, RecipeRow recipe) if (gui.BuildButton("Set fixed building count") && gui.CloseDropdown()) recipe.RecordUndo().fixedBuildings = recipe.buildingCount <= 0f ? 1f : recipe.buildingCount; } + + if (recipe.builtBuildings != null) + { + if (gui.BuildButton("Clear built building count") && gui.CloseDropdown()) + recipe.RecordUndo().builtBuildings = null; + } + else + { + if (gui.BuildButton("Set built building count") && gui.CloseDropdown()) + recipe.RecordUndo().builtBuildings = Math.Max(0, Convert.ToInt32(Math.Ceiling(recipe.buildingCount))); + } if (recipe.entity != null && gui.BuildButton("Create single building blueprint") && gui.CloseDropdown()) { @@ -512,7 +523,7 @@ private void BuildShoppngList(RecipeRow recipeRoot) if (recipe.entity != null) { shopList.TryGetValue(recipe.entity, out var prev); - var count = MathUtils.Ceil(recipe.buildingCount); + var count = MathUtils.Ceil(recipe.builtBuildings ?? recipe.buildingCount); shopList[recipe.entity] = prev + count; if (recipe.parameters.modules.modules != null) { From ef438657680f8e18e33426f2d39fc1e82be96dd5 Mon Sep 17 00:00:00 2001 From: Jeremy Saklad Date: Sun, 23 May 2021 18:12:16 -0500 Subject: [PATCH 3/5] Add text field for builtBuildings The text field is only visible if builtBuildings is not null, and is placed under the building count. It is colored grey to indicate that it is not playing a role in the model. --- .../ProductionTable/ProductionTableView.cs | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/YAFC/Workspace/ProductionTable/ProductionTableView.cs b/YAFC/Workspace/ProductionTable/ProductionTableView.cs index 48276d60..b9cb4466 100644 --- a/YAFC/Workspace/ProductionTable/ProductionTableView.cs +++ b/YAFC/Workspace/ProductionTable/ProductionTableView.cs @@ -270,15 +270,28 @@ private void BuildRecipeEntity(ImGui gui, RecipeRow recipe) if (recipe.isOverviewMode) return; bool clicked; - if (recipe.fixedBuildings > 0) + using (var group = gui.EnterGroup(default, RectAllocator.Stretch, spacing:0f)) { - var evt = gui.BuildFactorioObjectWithEditableAmount(recipe.entity, recipe.fixedBuildings, UnitOfMeasure.None, out var newAmount); - if (evt == GoodsWithAmountEvent.TextEditing) - recipe.RecordUndo().fixedBuildings = newAmount; - clicked = evt == GoodsWithAmountEvent.ButtonClick; + group.SetWidth(3f); + if (recipe.fixedBuildings > 0) + { + var evt = gui.BuildFactorioObjectWithEditableAmount(recipe.entity, recipe.fixedBuildings, UnitOfMeasure.None, out var newAmount); + if (evt == GoodsWithAmountEvent.TextEditing) + recipe.RecordUndo().fixedBuildings = newAmount; + clicked = evt == GoodsWithAmountEvent.ButtonClick; + } + else + clicked = gui.BuildFactorioObjectWithAmount(recipe.entity, recipe.buildingCount, UnitOfMeasure.None) && recipe.recipe.crafters.Length > 0; + + if (recipe.builtBuildings != null) + { + if (gui.BuildTextInput(DataUtils.FormatAmount(Convert.ToSingle(recipe.builtBuildings), UnitOfMeasure.None), out var newText, null, Icon.None, true, default, RectAlignment.Middle, SchemeColor.Grey)) + { + if (DataUtils.TryParseAmount(newText, out var newAmount, UnitOfMeasure.None)) + recipe.RecordUndo().builtBuildings = Convert.ToInt32(newAmount); + } + } } - else - clicked = gui.BuildFactorioObjectWithAmount(recipe.entity, recipe.buildingCount, UnitOfMeasure.None) && recipe.recipe.crafters.Length > 0; if (clicked) From d66426f8a258d79f7f8feab61bb73e6178a6ae2e Mon Sep 17 00:00:00 2001 From: Jeremy Saklad Date: Sun, 23 May 2021 19:00:10 -0500 Subject: [PATCH 4/5] Treat buildingCount above builtBuildings as error If the number of buildings needed for the model's solution is greater than the specified number of built buildings, the recipe will now be flagged accordingly. This makes it substantially easier to determine which recipes need to be revisited if a change is made. --- YAFC/Workspace/ProductionTable/ProductionTableView.cs | 3 ++- YAFCmodel/Model/ProductionTable.cs | 3 +++ YAFCmodel/Model/RecipeParameters.cs | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/YAFC/Workspace/ProductionTable/ProductionTableView.cs b/YAFC/Workspace/ProductionTable/ProductionTableView.cs index b9cb4466..71ec882f 100644 --- a/YAFC/Workspace/ProductionTable/ProductionTableView.cs +++ b/YAFC/Workspace/ProductionTable/ProductionTableView.cs @@ -888,7 +888,8 @@ protected override void BuildPageTooltip(ImGui gui, ProductionTable contents) {WarningFlags.TemperatureForIngredientNotMatch, "This recipe does care about ingridient temperature, and the temperature range does not match"}, {WarningFlags.ReactorsNeighboursFromPrefs, "Assumes reactor formation from preferences"}, {WarningFlags.AssumesNauvisSolarRatio, "Energy production values assumes Nauvis solar ration (70% power output). Don't forget accumulators."}, - {WarningFlags.RecipeTickLimit, "Production is limited to 60 recipes per second (1/tick). This interacts weirdly with productivity bonus - actual productivity may be imprecise and may depend on your setup - test your setup before commiting to it."} + {WarningFlags.RecipeTickLimit, "Production is limited to 60 recipes per second (1/tick). This interacts weirdly with productivity bonus - actual productivity may be imprecise and may depend on your setup - test your setup before commiting to it."}, + {WarningFlags.ExceedsBuiltCount, "This recipe requires more buildings than are currently built."} }; private void BuildRecipePad(ImGui gui, RecipeRow row) diff --git a/YAFCmodel/Model/ProductionTable.cs b/YAFCmodel/Model/ProductionTable.cs index cb403d8b..d6ea944f 100644 --- a/YAFCmodel/Model/ProductionTable.cs +++ b/YAFCmodel/Model/ProductionTable.cs @@ -464,6 +464,9 @@ public override async Task Solve(ProjectPage page) { var recipe = allRecipes[i]; recipe.recipesPerSecond = vars[i].SolutionValue(); + + if (recipe.buildingCount > recipe.builtBuildings) + recipe.parameters.warningFlags |= WarningFlags.ExceedsBuiltCount; } CalculateFlow(null); diff --git a/YAFCmodel/Model/RecipeParameters.cs b/YAFCmodel/Model/RecipeParameters.cs index d9045869..c487c841 100644 --- a/YAFCmodel/Model/RecipeParameters.cs +++ b/YAFCmodel/Model/RecipeParameters.cs @@ -21,6 +21,7 @@ public enum WarningFlags // Solution errors DeadlockCandidate = 1 << 16, OverproductionRequired = 1 << 17, + ExceedsBuiltCount = 1 << 18, // Not implemented warnings TemperatureForIngredientNotMatch = 1 << 24, From b8c720d39aad296137ebc0861ad10f00882bf8b4 Mon Sep 17 00:00:00 2001 From: Jeremy Saklad Date: Sun, 23 May 2021 23:40:32 -0500 Subject: [PATCH 5/5] Add page-wide error for builtCountExceeded To make issues more apparent, the entire page now displays an error message (like with deadlocks) if a recipe needs more machines than it currenty has built. --- YAFCmodel/Model/ProductionTable.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/YAFCmodel/Model/ProductionTable.cs b/YAFCmodel/Model/ProductionTable.cs index d6ea944f..79484ade 100644 --- a/YAFCmodel/Model/ProductionTable.cs +++ b/YAFCmodel/Model/ProductionTable.cs @@ -460,18 +460,22 @@ public override async Task Solve(ProjectPage page) } + var builtCountExceeded = false; for (var i = 0; i < allRecipes.Count; i++) { var recipe = allRecipes[i]; recipe.recipesPerSecond = vars[i].SolutionValue(); if (recipe.buildingCount > recipe.builtBuildings) + { recipe.parameters.warningFlags |= WarningFlags.ExceedsBuiltCount; + builtCountExceeded = true; + } } CalculateFlow(null); solver.Dispose(); - return null; + return builtCountExceeded ? "This model requires more buildings than are currently built" : null; } private void FindAllRecipeLinks(RecipeRow recipe, List sources, List targets)