diff --git a/YAFC/Workspace/ProductionTable/ProductionTableView.cs b/YAFC/Workspace/ProductionTable/ProductionTableView.cs index c0bba294..f88ca771 100644 --- a/YAFC/Workspace/ProductionTable/ProductionTableView.cs +++ b/YAFC/Workspace/ProductionTable/ProductionTableView.cs @@ -255,16 +255,28 @@ public override void BuildElement(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) { @@ -326,6 +338,17 @@ private void ShowEntityDropPown(ImGui imgui, RecipeRow recipe) 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()) { var entity = new BlueprintEntity {index = 1, name = recipe.entity.name}; @@ -907,7 +930,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) { @@ -1061,7 +1084,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 63b16fc7..4b8b5b52 100644 --- a/YAFCmodel/Model/ProductionTable.cs +++ b/YAFCmodel/Model/ProductionTable.cs @@ -460,16 +460,38 @@ public override async Task Solve(ProjectPage page) } } - + for (var i = 0; i < allRecipes.Count; i++) { var recipe = allRecipes[i]; recipe.recipesPerSecond = vars[i].SolutionValue(); } + var builtCountExceeded = CheckBuiltCountExceeded(); + CalculateFlow(null); solver.Dispose(); - return null; + return builtCountExceeded ? "This model requires more buildings than are currently built" : null; + } + + private bool CheckBuiltCountExceeded() { + var builtCountExceeded = false; + for (var i = 0; i < recipes.Count; i++) + { + var recipe = recipes[i]; + if (recipe.buildingCount > recipe.builtBuildings) + { + recipe.parameters.warningFlags |= WarningFlags.ExceedsBuiltCount; + builtCountExceeded = true; + } else if (recipe.subgroup != null) { + if (recipe.subgroup.CheckBuiltCountExceeded()) { + recipe.parameters.warningFlags |= WarningFlags.ExceedsBuiltCount; + builtCountExceeded = true; + } + } + } + + return builtCountExceeded; } private void FindAllRecipeLinks(RecipeRow recipe, List sources, List targets) diff --git a/YAFCmodel/Model/ProductionTableContent.cs b/YAFCmodel/Model/ProductionTableContent.cs index 04419ad4..2fa18325 100644 --- a/YAFCmodel/Model/ProductionTableContent.cs +++ b/YAFCmodel/Model/ProductionTableContent.cs @@ -178,6 +178,7 @@ public class RecipeRow : ModelObject, IModuleFiller, IGroupedEl 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; } diff --git a/YAFCmodel/Model/RecipeParameters.cs b/YAFCmodel/Model/RecipeParameters.cs index dd4d4005..8764b9e9 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,