diff --git a/Yafc.Model/Analysis/DependencyNode.cs b/Yafc.Model/Analysis/DependencyNode.cs index 62fc8c95..20e2e637 100644 --- a/Yafc.Model/Analysis/DependencyNode.cs +++ b/Yafc.Model/Analysis/DependencyNode.cs @@ -119,6 +119,10 @@ internal static DependencyNode Create(IEnumerable dependencies) } realDependencies = realDependencies.Distinct().ToList(); + if (realDependencies.Count == 0) { + throw new ArgumentException($"Must not join zero nodes with an 'and'. Instead, create an empty DependencyList to explain what expected dependencies are missing."); + } + // Prevent single-child nodes, so the drawing and preceding unpacking code doesn't have to handle that. if (realDependencies.Count == 1) { return realDependencies[0]; @@ -175,6 +179,10 @@ internal static DependencyNode Create(IEnumerable dependencies) } realDependencies = realDependencies.Distinct().ToList(); + if (realDependencies.Count == 0) { + throw new ArgumentException($"Must not join zero nodes with an 'or'. Instead, create an empty DependencyList to explain what expected dependencies are missing."); + } + // Prevent single-child nodes, so the drawing and preceding unpacking code doesn't have to handle that. if (realDependencies.Count == 1) { return realDependencies[0]; @@ -186,7 +194,7 @@ internal static DependencyNode Create(IEnumerable dependencies) internal override IEnumerable Flatten() => dependencies.SelectMany(d => d.Flatten()); internal override bool IsAccessible(Func isAccessible) => dependencies.Any(d => d.IsAccessible(isAccessible)); - internal override Bits AggregateBits(Func getBits) => dependencies.Select(d => d.AggregateBits(getBits)).Min(); + internal override Bits AggregateBits(Func getBits) => dependencies.Min(d => d.AggregateBits(getBits)); internal override AutomationStatus IsAutomatable(Func isAutomatable, AutomationStatus automationState) => dependencies.Max(d => d.IsAutomatable(isAutomatable, automationState)); @@ -234,7 +242,7 @@ internal override Bits AggregateBits(Func getBits) { return bits; } else if (dependencies.elements.Length > 0) { - return bits | dependencies.elements.Select(getBits).Min(); + return bits | dependencies.elements.Min(getBits); } return bits; } diff --git a/Yafc.Model/Data/DataClasses.cs b/Yafc.Model/Data/DataClasses.cs index ab7dcb03..09635b5b 100644 --- a/Yafc.Model/Data/DataClasses.cs +++ b/Yafc.Model/Data/DataClasses.cs @@ -540,24 +540,32 @@ public float Power(Quality quality) internal Lazy? getSpoilResult; public sealed override DependencyNode GetDependencies() { - List collector = []; + List collector = []; if (energy != null) { - collector.Add(new(energy.fuels, DependencyList.Flags.Fuel)); + collector.Add(new DependencyList(energy.fuels, DependencyList.Flags.Fuel)); } - if (spawnLocations.Length != 0) { - collector.Add(new(spawnLocations, DependencyList.Flags.Location)); + if (mapGenerated) { + if (itemsToPlace.Length != 0) { + collector.Add(DependencyNode.RequireAny( + new DependencyList(spawnLocations, DependencyList.Flags.Location), + new DependencyList(itemsToPlace, DependencyList.Flags.ItemToPlace))); + } + else { + collector.Add(new DependencyList(spawnLocations, DependencyList.Flags.Location)); + } } if (sourceEntities.Count > 0) { // Asteroid chunks require locations OR bigger-asteroid - collector.Add(new(sourceEntities, DependencyList.Flags.Source)); + collector.Add(new DependencyList(sourceEntities, DependencyList.Flags.Source)); return DependencyNode.RequireAny(collector); } if (captureAmmo.Count == 0) { if (!mapGenerated) { - collector.Add(new(itemsToPlace, DependencyList.Flags.ItemToPlace)); + collector.Add(new DependencyList(itemsToPlace, DependencyList.Flags.ItemToPlace)); } + return DependencyNode.RequireAll(collector); } @@ -600,7 +608,12 @@ public sealed override DependencyNode GetDependencies() { nonFuel.Add(DependencyNode.Create(new(Array.Empty(), DependencyList.Flags.Source))); } - return DependencyNode.RequireAll(DependencyNode.Create(collector[0]), DependencyNode.RequireAny(nonFuel)); + if (energy != null) { + return DependencyNode.RequireAll(collector[0] /* fuel */, DependencyNode.RequireAny(nonFuel)); + } + else { // Doesn't require fuel + return DependencyNode.RequireAny(nonFuel); + } } private sealed class ListComparer : IEqualityComparer> { diff --git a/changelog.txt b/changelog.txt index dd6e5a7e..80f02189 100644 --- a/changelog.txt +++ b/changelog.txt @@ -15,6 +15,11 @@ // Internal changes: // Changes to the code that do not affect the behavior of the program. ---------------------------------------------------------------------------------------------------------------------- +Version: +Date: + Fixes: + - "Map generated" entities that don't generate in any locations could break automation analysis. +---------------------------------------------------------------------------------------------------------------------- Version: 2.4.0 Date: November 21st 2024 Features: