internal static IEnumerable <WarningMessage> CheckCorrectCapacity(IColonizationResearchScenario colonizationResearch, List <ITieredProducer> producers, Dictionary <string, double> amountAvailable, Dictionary <string, double> storageAvailable) { var production = producers .GroupBy(p => p.Output) .ToDictionary(pair => pair.Key, pair => pair.Sum(p => p.ProductionRate)); var consumption = producers .Where(p => p.Input != null) .GroupBy(p => p.Input) .ToDictionary(pair => pair.Key, pair => pair.Sum(p => p.ProductionRate)); foreach (var inputPair in consumption) { TieredResource inputResource = inputPair.Key; double inputRequired = inputPair.Value; if (inputResource.IsHarvestedLocally) { // Crush-ins -- there are other things that ensure this works. } else if (!production.TryGetValue(inputPair.Key, out double outputAmount)) { // Okay, there's no producer for this - complain if there's no storage that either contains the // required tier or could contain it if it's gathered locally. TechTier requiredTier = producers.Where(p => p.Input == inputResource).Select(p => p.Tier).Min(); bool anyInStorage = Enumerable.Range((int)requiredTier, 1 + (int)TechTier.Tier4) .Any(i => amountAvailable.TryGetValue(inputResource.TieredName((TechTier)i), out var amount) && amount > 0); if (!inputResource.IsHarvestedLocally && !anyInStorage) { yield return(new WarningMessage() { Message = $"The ship needs {inputResource.BaseName} to produce {producers.First(p => p.Input == inputResource).Output.BaseName}", IsClearlyBroken = false, FixIt = null }); } } else if (outputAmount < inputRequired) { yield return(new WarningMessage() { Message = $"The ship needs at least {inputRequired} production of {inputResource.BaseName} but it is only producing {outputAmount}", IsClearlyBroken = false, FixIt = null }); } } }