diff --git a/Yafc/Workspace/ProductionTable/ProductionLinkSummaryScreen.cs b/Yafc/Workspace/ProductionTable/ProductionLinkSummaryScreen.cs index 4eb1274e..f42234c9 100644 --- a/Yafc/Workspace/ProductionTable/ProductionLinkSummaryScreen.cs +++ b/Yafc/Workspace/ProductionTable/ProductionLinkSummaryScreen.cs @@ -44,17 +44,23 @@ private void BuildScrollArea(ImGui gui) { private void ShowRelatedLinks(ImGui gui) { ModelObject o = link; + List parents = []; while (o.ownerObject is not ProjectPage) { var t = o.ownerObject; if (t is null) { break; } o = t; + if (t == o.ownerObject) continue; + parents.Add(t); } - if (o is ProductionTable p) { - Dictionary> related = []; + if (o is ProductionTable page) { + Dictionary> childLinks = [], parentLinks = [], otherLinks = []; List<(RecipeRow row, float flow)> unlinked = [], table; - foreach (var r in GetAllRecipes(p)) { + foreach (var (r, relationLinks) in + GetAllRecipes(page, link.owner) + .Select(e => (e, IsParrent(e, parents) ? parentLinks : otherLinks)) + .Concat(GetAllRecipes(link.owner).Select(e => (e, childLinks)))) { if (link.capturedRecipes.Any(e => e == r) || (!r.Ingredients.Any(e => e.Goods == link.goods) && !r.Products.Any(e => e.Goods == link.goods) @@ -64,10 +70,10 @@ private void ShowRelatedLinks(ImGui gui) { float localFlow = DetermineFlow(link.goods, r); if ((r.FindLink(link.goods, out var otherLink) && otherLink != link)) { - if (!related.ContainsKey(otherLink)) { - related.Add(otherLink, []); + if (!relationLinks.ContainsKey(otherLink)) { + relationLinks.Add(otherLink, []); } - table = related[otherLink]; + table = relationLinks[otherLink]; } else { table = unlinked; @@ -83,24 +89,41 @@ private void ShowRelatedLinks(ImGui gui) { table.Add((r, 0)); } } - if (related.Values.Any(e => e.Any())) { - gui.BuildText("Related links: "); - var color = 1; - foreach (var relTable in related.Values) { + var color = 1; + if (childLinks.Values.Any(e => e.Any())) { + gui.BuildText("Child links: ", Font.subheader); + foreach (var relTable in childLinks.Values) { + BuildFlow(gui, relTable, relTable.Sum(e => Math.Abs(e.flow)), false, color++); + } + } + if (parentLinks.Values.Any(e => e.Any())) { + gui.BuildText("Parent links: ", Font.subheader); + foreach (var relTable in parentLinks.Values) { + BuildFlow(gui, relTable, relTable.Sum(e => Math.Abs(e.flow)), false, color++); + } + } + if (otherLinks.Values.Any(e => e.Any())) { + gui.BuildText("Unrelated links: ", Font.subheader); + foreach (var relTable in otherLinks.Values) { BuildFlow(gui, relTable, relTable.Sum(e => Math.Abs(e.flow)), false, color++); } } if (unlinked.Any()) { - gui.BuildText("Unlinked: "); + gui.BuildText("Unlinked: ", Font.subheader); BuildFlow(gui, unlinked, 0, false); } } } - private static List GetAllRecipes(ProductionTable p) => [..p.recipes, ..p.recipes + private bool IsParrent(RecipeRow row, List parents) => row.Ingredients.Select(e => e.Link).Concat(row.Products.Select(e => e.Link)).Append(row.FuelInformation.Link) + .Where(e => e?.ownerObject is not null) + .Where(e => e!.goods == link.goods) + .Any(e => parents.Contains(e!.ownerObject!)); + + private static List GetAllRecipes(ProductionTable p, ProductionTable? skip = null) => p == skip ? [] : [..p.recipes, ..p.recipes .Select(e => e.subgroup) .Where(e => e is not null) - .SelectMany(e => GetAllRecipes(e!))]; + .SelectMany(e => GetAllRecipes(e!, skip))]; public override void Build(ImGui gui) { BuildHeader(gui, "Link summary"); @@ -139,13 +162,12 @@ private void BuildFlow(ImGui gui, List<(RecipeRow row, float flow)> list, float links.Remove(link.goods); // except the current one, only applicable for recipes like kovarex that have catalysts. // Jump to the only link, or offer a selection of links to inspect next. - if (links.Count == 1) { - changeLinkView(links.First().Value); - } - else if (row.FindLink(link.goods, out var otherLink) && otherLink != link) { changeLinkView(otherLink); } + else if (links.Count == 1) { + changeLinkView(links.First().Value); + } else { gui.ShowDropDown(drawLinks); } @@ -256,7 +278,7 @@ private void CalculateFlow(ProductionLink link) { scrollArea.RebuildContents(); } - private static float DetermineFlow(Goods goods, RecipeRow recipe) { + private static float DetermineFlow(IObjectWithQuality goods, RecipeRow recipe) { float production = recipe.GetProductionForRow(goods); float consumption = recipe.GetConsumptionForRow(goods); float fuelUsage = recipe.fuel == goods ? recipe.FuelInformation.Amount : 0;