Skip to content

Commit f4c51fc

Browse files
authored
Fix 444: nested table shows some intermediates as products due to precision errors (#516)
This fixes #444 by filtering the input and output information provided to the UI. It worked properly for me on a page where I was seeing this happen, even after reducing the total production to 0.1/h.
2 parents eab1f07 + 45d2a52 commit f4c51fc

File tree

5 files changed

+53
-33
lines changed

5 files changed

+53
-33
lines changed

Yafc.Model/Data/DataUtils.cs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -358,17 +358,6 @@ public static float GetProductionPerRecipe(this RecipeOrTechnology recipe, Goods
358358
return amount;
359359
}
360360

361-
public static float GetProductionForRow(this RecipeRow row, IObjectWithQuality<Goods> product) {
362-
float amount = 0f;
363-
364-
foreach (var p in row.Products) {
365-
if (p.Goods == product) {
366-
amount += p.Amount;
367-
}
368-
}
369-
return amount;
370-
}
371-
372361
public static float GetConsumptionPerRecipe(this RecipeOrTechnology recipe, Goods product) {
373362
float amount = 0f;
374363

@@ -380,17 +369,6 @@ public static float GetConsumptionPerRecipe(this RecipeOrTechnology recipe, Good
380369
return amount;
381370
}
382371

383-
public static float GetConsumptionForRow(this RecipeRow row, IObjectWithQuality<Goods> ingredient) {
384-
float amount = 0f;
385-
386-
foreach (var i in row.recipe.target.ingredients) {
387-
if (i.goods.With(row.recipe.quality) == ingredient || (ingredient.quality == Quality.Normal && i.ContainsVariant(ingredient.target))) {
388-
amount += i.amount * (float)row.recipesPerSecond;
389-
}
390-
}
391-
return amount;
392-
}
393-
394372
public static FactorioObjectComparer<Recipe> GetRecipeComparerFor(Goods goods) => new FactorioObjectComparer<Recipe>((x, y) => (x.Cost(true) / x.GetProductionPerRecipe(goods)).CompareTo(y.Cost(true) / y.GetProductionPerRecipe(goods)));
395373

396374
public static T? AutoSelect<T>(this IEnumerable<T> list, IComparer<T>? comparer = default) {

Yafc.Model/Model/ProductionTable.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,25 @@ private void CalculateFlow(RecipeRow? include) {
415415
}
416416

417417
Array.Sort(flowArr, 0, flowArr.Length, this);
418-
flow = flowArr;
418+
flow = [.. flowArr.Where(shouldBeReported)];
419+
420+
bool shouldBeReported(ProductionTableFlow flow) {
421+
// Check low-throughput (< 1/hr) goods to see if they have production or consumption outside this table.
422+
423+
if (MathF.Abs(flow.amount) > 1 / 3600f || !FindLink(flow.goods, out IProductionLink? l) || l is not ProductionLink link
424+
|| owner is not RecipeRow parent || link.flags != ProductionLink.Flags.HasProductionAndConsumption || link.amount != 0) {
425+
426+
return true;
427+
}
428+
429+
HashSet<RecipeRow> recipes = [.. GetAllRecipes(), parent];
430+
foreach (IRecipeRow iRec in link.capturedRecipes) {
431+
if (iRec is not RecipeRow recipe || (!recipes.Contains(recipe) && recipe.DetermineFlow(flow.goods) != 0)) {
432+
return true;
433+
}
434+
}
435+
return false;
436+
}
419437
}
420438

421439
/// <summary>

Yafc.Model/Model/ProductionTableContent.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,36 @@ public void AutoApplyModuleTemplate(List<ProjectModuleTemplate> moduleTemplates)
771771
}
772772
}
773773

774+
public float DetermineFlow(IObjectWithQuality<Goods> goods) {
775+
float production = getProduction(goods);
776+
float consumption = getConsumption(goods);
777+
float fuelUsage = fuel == goods ? FuelInformation.Amount : 0;
778+
float localFlow = production - consumption - fuelUsage;
779+
return localFlow;
780+
781+
float getProduction(IObjectWithQuality<Goods> product) {
782+
float amount = 0f;
783+
784+
foreach (var p in Products) {
785+
if (p.Goods == product) {
786+
amount += p.Amount;
787+
}
788+
}
789+
return amount;
790+
}
791+
792+
float getConsumption(IObjectWithQuality<Goods> ingredient) {
793+
float amount = 0f;
794+
795+
foreach (var i in recipe.target.ingredients) {
796+
if (i.goods.With(recipe.quality) == ingredient || (ingredient.quality == Quality.Normal && i.ContainsVariant(ingredient.target))) {
797+
amount += i.amount * (float)recipesPerSecond;
798+
}
799+
}
800+
return amount;
801+
}
802+
}
803+
774804
// To avoid leaking these variables/methods (or just the setter, for recipesPerSecond) into public context,
775805
// these explicit interface implementations connect to internal members, instead of using implicit implementation via public members
776806
RecipeParameters IRecipeRow.parameters { get => parameters; set => parameters = value; }

Yafc/Workspace/ProductionTable/ProductionLinkSummaryScreen.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ private void ShowRelatedLinks(ImGui gui) {
6464
|| isNotRelatedToCurrentLink(row)) {
6565
continue;
6666
}
67-
float localFlow = DetermineFlow(link.goods, row);
67+
float localFlow = row.DetermineFlow(link.goods);
6868

6969
if ((row.FindLink(link.goods, out var otherLink) && otherLink != link)) {
7070
if (!relationLinks.ContainsKey(otherLink)) {
@@ -264,7 +264,7 @@ private void CalculateFlow(ProductionLink link) {
264264
List<(RecipeRow row, float flow)> input = [], output = [];
265265
totalInput = totalOutput = 0;
266266
foreach (var recipe in link.capturedRecipes.OfType<RecipeRow>()) {
267-
float localFlow = DetermineFlow(link.goods, recipe);
267+
float localFlow = recipe.DetermineFlow(link.goods);
268268
if (localFlow > 0) {
269269
input.Add((recipe, localFlow));
270270
totalInput += localFlow;
@@ -285,13 +285,6 @@ private void CalculateFlow(ProductionLink link) {
285285
scrollArea.RebuildContents();
286286
}
287287

288-
private static float DetermineFlow(IObjectWithQuality<Goods> goods, RecipeRow recipe) {
289-
float production = recipe.GetProductionForRow(goods);
290-
float consumption = recipe.GetConsumptionForRow(goods);
291-
float fuelUsage = recipe.fuel == goods ? recipe.FuelInformation.Amount : 0;
292-
float localFlow = production - consumption - fuelUsage;
293-
return localFlow;
294-
}
295288

296289
public static void Show(ProductionLink link) => _ = MainScreen.Instance.ShowPseudoScreen(new ProductionLinkSummaryScreen(link));
297290

changelog.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// The purpose of the changelog is to provide a concise overview of what was changed.
1+
// The purpose of the changelog is to provide a concise overview of what was changed.
22
// The purpose of the changelog format is to make it more organized.
33
// If you want to add an entry to the changelog, then please add it to the section without a release date and version.
44
// If there is no such section, then copypaste the previous version, remove the info, and put the result below the commented section.
@@ -28,6 +28,7 @@ Date:
2828
- Fix icon rendering.
2929
- Hide fluid temperature options when not part of a recipe or not accepted by that recipe.
3030
- Modify text colors for highlighted rows in dark mode to improve readability.
31+
- Don't draw table intermediates as <1μ ingredients/products.
3132
Internal changes:
3233
- Enable mod-fixes for the data, data-updates, and data-final-fixes files.
3334
----------------------------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)