Skip to content

Commit

Permalink
Fix handling of disabled recipes (#130)
Browse files Browse the repository at this point in the history
Always show empty boxes for both the ingredients and products of disabled recipes. 
That is, they'll always look like this:

![image](https://github.com/have-fun-was-taken/yafc-ce/assets/21223975/d60eeefa-f56d-4d9c-afc7-7dcd8759f784)

I also discovered the code that cleans up old links removes links if the
item/fluid does not appear in any _enabled_ recipes. I wanted the links
to stay put when disabling and enabling recipes, and I couldn't
concentrate on #122 with that behavior, so I changed the code to
consider all recipes. If that change (f28d35f) should be discussed more,
I can remove it from this PR.
  • Loading branch information
shpaass committed May 15, 2024
2 parents 6a28abf + ee341cb commit c687398
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 6 deletions.
29 changes: 28 additions & 1 deletion Yafc.Model/Model/ProductionTable.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -130,6 +131,24 @@ public bool Search(SearchQuery query) {
return false;
}

/// <summary>
/// Get all <see cref="RecipeRow"/>s contained in this <see cref="ProductionTable"/>, in a depth-first ordering. (The same as in the UI when all nested tables are expanded.)
/// </summary>
public IEnumerable<RecipeRow> GetAllRecipes() {
return flatten(recipes);

static IEnumerable<RecipeRow> flatten(IEnumerable<RecipeRow> 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<Goods, (double prod, double cons)> summer) {
foreach (var product in recipe.recipe.products) {
_ = summer.TryGetValue(product.goods, out var prev);
Expand Down Expand Up @@ -316,7 +335,7 @@ public override async Task<string> 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);
}

Expand Down Expand Up @@ -448,6 +467,14 @@ public override async Task<string> Solve(ProjectPage page) {
return builtCountExceeded ? "This model requires more buildings than are currently built" : null;
}

/// <summary>
/// Search the disabled recipes in this table and see if any of them produce or consume <paramref name="goods"/>. If they do, the corresponding <see cref="ProductionLink"/> should not be deleted.
/// </summary>
/// <param name="goods">The <see cref="Goods"/> that might have its link removed.</param>
/// <returns><see langword="true"/> if the link should be preserved, or <see langword="false"/> if it is ok to delete the link.</returns>
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++) {
Expand Down
7 changes: 7 additions & 0 deletions Yafc.Model/Model/ProductionTableContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,14 @@ public class RecipeRow : ModelObject<ProductionTable>, IModuleFiller, IGroupedEl
public RecipeLinks links { get; internal set; }
public float fixedBuildings { get; set; }
public int? builtBuildings { get; set; }
/// <summary>
/// If <see langword="true"/>, the enabled checkbox for this recipe is checked.
/// </summary>
public bool enabled { get; set; } = true;
/// <summary>
/// If <see langword="true"/>, the enabled checkboxes for this recipe and all its parent recipies are checked.
/// If <see langword="false"/>, at least one enabled checkbox for this recipe or its ancestors is unchecked.
/// </summary>
public bool hierarchyEnabled { get; internal set; }
public int tag { get; set; }

Expand Down
12 changes: 7 additions & 5 deletions Yafc/Workspace/ProductionTable/ProductionTableView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
}
}
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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);
}
}
Expand Down

0 comments on commit c687398

Please sign in to comment.