Economy checks: ConsumerDemand tests recipes, not keys; pin upkeep reached through a chain
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8d23a378d6
commit
8e6fd43d23
2 changed files with 10 additions and 8 deletions
|
|
@ -417,20 +417,20 @@ public static class EconomyChecks
|
|||
{
|
||||
var recipes = AllRecipes(catalog).Where(p => catalog.Get(p.Recipe.Output) != null).ToDictionary(p => p.Recipe.Output.Key.Value, p => p.Recipe, StringComparer.Ordinal);
|
||||
var drawn = Drawn(catalog);
|
||||
bool IsCommodityKey(string key) => recipes.TryGetValue(key, out var r) && Recipes.IsCommodity(catalog.Get(r.Output));
|
||||
bool IsCommodityRecipe(RecipeData r) => Recipes.IsCommodity(catalog.Get(r.Output));
|
||||
var consumerRoles = new HashSet<string>(recipes.Values.Where(r => Recipes.IsConsumerGood(catalog, r))
|
||||
.SelectMany(r => Recipes.RolesOf(catalog.Get(r.Output))).Select(role => role.Name), StringComparer.Ordinal);
|
||||
var gearRoles = new HashSet<string>(recipes.Values.Where(r => !Recipes.IsCommodity(catalog.Get(r.Output)))
|
||||
.SelectMany(r => Recipes.RolesOf(catalog.Get(r.Output))).Select(role => role.Name), StringComparer.Ordinal);
|
||||
var upkeep = new HashSet<string>(recipes.Values.SelectMany(r => r.Upkeep).Select(c => c.Commodity.Key.Value), StringComparer.Ordinal);
|
||||
var takenBy = recipes.Values.Where(r => IsCommodityKey(r.Output.Key.Value))
|
||||
var takenBy = recipes.Values.Where(IsCommodityRecipe)
|
||||
.SelectMany(r => r.Inputs.Select(input => (Input: input.Commodity.Key.Value, Output: r.Output.Key.Value)))
|
||||
.ToLookup(edge => edge.Input, edge => edge.Output, StringComparer.Ordinal);
|
||||
var faults = new List<EconomyFault>();
|
||||
foreach (var key in recipes.Keys.OrderBy(k => k, StringComparer.Ordinal))
|
||||
{
|
||||
var recipe = recipes[key];
|
||||
if (!IsCommodityKey(key) || Recipes.IsRaw(catalog, recipe) || Recipes.IsConsumerGood(catalog, recipe)) continue;
|
||||
if (!IsCommodityRecipe(recipe) || Recipes.IsRaw(catalog, recipe) || Recipes.IsConsumerGood(catalog, recipe)) continue;
|
||||
var reached = new HashSet<string>(StringComparer.Ordinal) { key };
|
||||
var open = new Stack<string>(reached);
|
||||
while (open.Count > 0)
|
||||
|
|
|
|||
|
|
@ -377,14 +377,16 @@ public sealed class EconomyChecksTests
|
|||
using var f = new EconomyFixture();
|
||||
f.Good("ore");
|
||||
f.Good("coke", inputs: new[] { ("ore", 1) });
|
||||
f.Good("plate", inputs: new[] { ("ore", 1) }, fills: new[] { "Plate" }, upkeep: new[] { ("coke", 1) });
|
||||
f.Good("fuel", inputs: new[] { ("coke", 1) });
|
||||
f.Good("plate", inputs: new[] { ("ore", 1) }, fills: new[] { "Plate" }, upkeep: new[] { ("fuel", 1) });
|
||||
f.Hull("tug", HullType.Ship, new[] { ("Plate", 1) });
|
||||
var fault = Assert.Single(EconomyChecks.ConsumerDemand(f.Cache));
|
||||
Assert.Equal("recipe:commodity:coke", fault.Record);
|
||||
Assert.Contains("'coke' leads into upkeep but no use leads into a consumer good.", fault.Message);
|
||||
// Fuel is upkeep itself; coke is shared because a good it leads into is.
|
||||
var faults = EconomyChecks.ConsumerDemand(f.Cache);
|
||||
Assert.Equal(new[] { "recipe:commodity:coke", "recipe:commodity:fuel" }, faults.Select(x => x.Record));
|
||||
Assert.Contains("'fuel' leads into upkeep but no use leads into a consumer good.", faults[1].Message);
|
||||
|
||||
f.Good("pot", roles: new[] { ("Casing", 1) });
|
||||
f.EditRecipe("commodity:coke", r => r.Fills.Add("Casing"));
|
||||
f.EditRecipe("commodity:fuel", r => r.Fills.Add("Casing"));
|
||||
Assert.Empty(EconomyChecks.ConsumerDemand(f.Cache));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue