diff --git a/Yafc.Model/Model/ProductionTable.cs b/Yafc.Model/Model/ProductionTable.cs
index 56a2b264..568e8bea 100644
--- a/Yafc.Model/Model/ProductionTable.cs
+++ b/Yafc.Model/Model/ProductionTable.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Google.OrTools.LinearSolver;
@@ -130,6 +131,24 @@ public bool Search(SearchQuery query) {
return false;
}
+ ///
+ /// Get all s contained in this , in a depth-first ordering. (The same as in the UI when all nested tables are expanded.)
+ ///
+ public IEnumerable GetAllRecipes() {
+ return flatten(recipes);
+
+ static IEnumerable flatten(IEnumerable rows) {
+ foreach (var row in rows) {
+ yield return row;
+ if (row.subgroup is not null) {
+ foreach (var row2 in flatten(row.subgroup.GetAllRecipes())) {
+ yield return row2;
+ }
+ }
+ }
+ }
+ }
+
private static void AddFlow(RecipeRow recipe, Dictionary summer) {
foreach (var product in recipe.recipe.products) {
_ = summer.TryGetValue(product.goods, out var prev);
@@ -316,7 +335,7 @@ public override async Task Solve(ProjectPage page) {
foreach (var link in allLinks) {
link.notMatchedFlow = 0f;
if (!link.flags.HasFlags(ProductionLink.Flags.HasProductionAndConsumption)) {
- if (!link.flags.HasFlagAny(ProductionLink.Flags.HasProductionAndConsumption)) {
+ if (!link.flags.HasFlagAny(ProductionLink.Flags.HasProductionAndConsumption) && !link.owner.HasDisabledRecipeReferencing(link.goods)) {
_ = link.owner.RecordUndo(true).links.Remove(link);
}
@@ -448,6 +467,14 @@ public override async Task Solve(ProjectPage page) {
return builtCountExceeded ? "This model requires more buildings than are currently built" : null;
}
+ ///
+ /// Search the disabled recipes in this table and see if any of them produce or consume . If they do, the corresponding should not be deleted.
+ ///
+ /// The that might have its link removed.
+ /// if the link should be preserved, or if it is ok to delete the link.
+ private bool HasDisabledRecipeReferencing(Goods goods)
+ => GetAllRecipes().Any(row => !row.hierarchyEnabled && row.recipe.ingredients.Any(i => i.goods == goods) || row.recipe.products.Any(p => p.goods == goods) || row.fuel == goods);
+
private bool CheckBuiltCountExceeded() {
bool builtCountExceeded = false;
for (int i = 0; i < recipes.Count; i++) {
diff --git a/Yafc.Model/Model/ProductionTableContent.cs b/Yafc.Model/Model/ProductionTableContent.cs
index 4fd57baf..e175c8fc 100644
--- a/Yafc.Model/Model/ProductionTableContent.cs
+++ b/Yafc.Model/Model/ProductionTableContent.cs
@@ -177,7 +177,14 @@ public class RecipeRow : ModelObject, IModuleFiller, IGroupedEl
public RecipeLinks links { get; internal set; }
public float fixedBuildings { get; set; }
public int? builtBuildings { get; set; }
+ ///
+ /// If , the enabled checkbox for this recipe is checked.
+ ///
public bool enabled { get; set; } = true;
+ ///
+ /// If , the enabled checkboxes for this recipe and all its parent recipies are checked.
+ /// If , at least one enabled checkbox for this recipe or its ancestors is unchecked.
+ ///
public bool hierarchyEnabled { get; internal set; }
public int tag { get; set; }
diff --git a/Yafc/Workspace/ProductionTable/ProductionTableView.cs b/Yafc/Workspace/ProductionTable/ProductionTableView.cs
index 92f8bf8c..536223d8 100644
--- a/Yafc/Workspace/ProductionTable/ProductionTableView.cs
+++ b/Yafc/Workspace/ProductionTable/ProductionTableView.cs
@@ -401,8 +401,8 @@ public override void BuildElement(ImGui gui, RecipeRow recipe) {
else {
for (int i = 0; i < recipe.recipe.ingredients.Length; i++) {
var ingredient = recipe.recipe.ingredients[i];
- var link = recipe.links.ingredients[i];
- var goods = recipe.links.ingredientGoods[i];
+ var link = recipe.hierarchyEnabled ? recipe.links.ingredients[i] : null;
+ var goods = recipe.hierarchyEnabled ? ingredient.goods : null;
grid.Next();
view.BuildGoodsIcon(gui, goods, link, (float)(ingredient.amount * recipe.recipesPerSecond), ProductDropdownType.Ingredient, recipe, recipe.linkRoot, ingredient.variants);
}
@@ -420,8 +420,10 @@ public override void BuildElement(ImGui gui, RecipeRow recipe) {
else {
for (int i = 0; i < recipe.recipe.products.Length; i++) {
var product = recipe.recipe.products[i];
+ var link = recipe.hierarchyEnabled ? recipe.links.products[i] : null;
+ var goods = recipe.hierarchyEnabled ? product.goods : null;
grid.Next();
- view.BuildGoodsIcon(gui, product.goods, recipe.links.products[i], (float)(recipe.recipesPerSecond * product.GetAmount(recipe.parameters.productivity)), ProductDropdownType.Product,
+ view.BuildGoodsIcon(gui, goods, link, (float)(recipe.recipesPerSecond * product.GetAmount(recipe.parameters.productivity)), ProductDropdownType.Product,
recipe, recipe.linkRoot);
}
}
@@ -459,7 +461,7 @@ public override void BuildElement(ImGui gui, RecipeRow recipe) {
using var grid = gui.EnterInlineGrid(3f);
if (recipe.parameters.modules.modules == null || recipe.parameters.modules.modules.Length == 0) {
grid.Next();
- if (gui.BuildFactorioObjectWithAmount(null, 0, UnitOfMeasure.None)) {
+ if (gui.BuildFactorioObjectWithAmount(null, 0, UnitOfMeasure.None) && recipe.hierarchyEnabled) {
ShowModuleDropDown(gui, recipe);
}
}
@@ -886,7 +888,7 @@ private void BuildGoodsIcon(ImGui gui, Goods goods, ProductionLink link, float a
textColor = SchemeColor.BackgroundTextFaint;
}
- if (gui.BuildFactorioObjectWithAmount(goods, amount, goods?.flowUnitOfMeasure ?? UnitOfMeasure.None, iconColor, textColor)) {
+ if (gui.BuildFactorioObjectWithAmount(goods, amount, goods?.flowUnitOfMeasure ?? UnitOfMeasure.None, iconColor, textColor) && goods is not null) {
OpenProductDropdown(gui, gui.lastRect, goods, amount, link, dropdownType, recipe, context, variants);
}
}