Exemple #1
0
        internal static TierSuitability GetTierSuitability(
            IColonizationResearchScenario colonizationResearchScenario,
            TieredResource tieredResource,
            TechTier tier,
            TechTier partMaxTier,
            string body)
        {
            if (body == null && tieredResource.ResearchCategory.Type != ProductionRestriction.Space)
            {
                return(TierSuitability.BodyNotSelected);
            }

            if (tier > partMaxTier)
            {
                return(TierSuitability.PartDoesntSupportTier);
            }

            var maxTier = colonizationResearchScenario.GetMaxUnlockedTier(tieredResource, body);

            if (tier > maxTier)
            {
                return(TierSuitability.NotResearched);
            }

            bool subordinateTechIsCapping = false;

            for (TieredResource requiredResource = tieredResource.MadeFrom(tier); requiredResource != null; requiredResource = requiredResource.MadeFrom(tier))
            {
                if (requiredResource.ResearchCategory.Type != tieredResource.ResearchCategory.Type)
                {
                    // This would be a case where the made-from is produced in one situation (e.g. landed) and consumed
                    // in another (in space).  We don't know where the stuff is produced, so we'll just have to assume
                    // we can get the stuff from somewhere.
                    break;
                }

                var t = colonizationResearchScenario.GetMaxUnlockedTier(requiredResource, body);
                if (tier > t)
                {
                    return(TierSuitability.LacksSubordinateResearch);
                }
                else if (tier == t)
                {
                    subordinateTechIsCapping = true;
                }
            }

            TechTier maxScanningTier = string.IsNullOrEmpty(body) ? TechTier.Tier4 : colonizationResearchScenario.GetMaxUnlockedScanningTier(body);

            if (tier > maxScanningTier)
            {
                return(TierSuitability.LacksScanner);
            }

            if (tier < maxTier && !subordinateTechIsCapping && (string.IsNullOrEmpty(body) || tier < maxScanningTier))
            {
                return(TierSuitability.UnderTier);
            }

            return(TierSuitability.Ideal);
        }
Exemple #2
0
        internal static IEnumerable <WarningMessage> CheckTieredProduction(IColonizationResearchScenario colonizationResearch, List <ITieredProducer> producers, Dictionary <string, double> amountAvailable, Dictionary <string, double> storageAvailable)
        {
            List <ITieredProducer> noScannerParts     = new List <ITieredProducer>();
            List <ITieredProducer> noSubResearchParts = new List <ITieredProducer>();
            List <ITieredProducer> underTier          = new List <ITieredProducer>();

            foreach (var producer in producers)
            {
                var suitability = StaticAnalysis.GetTierSuitability(colonizationResearch, producer.Output, producer.Tier, producer.MaximumTier, producer.Body);
                switch (suitability)
                {
                case TierSuitability.LacksScanner:
                    noScannerParts.Add(producer);
                    break;

                case TierSuitability.LacksSubordinateResearch:
                    noSubResearchParts.Add(producer);
                    break;

                case TierSuitability.UnderTier:
                    underTier.Add(producer);
                    break;

                default:
                    break;
                }
            }

            if (noScannerParts.Any())
            {
                var examplePart = noScannerParts[0];
                yield return(new WarningMessage
                {
                    Message = $"Scanning technology at {examplePart.Body} has not kept up with production technologies - {examplePart.Tier.DisplayName()} parts will not function until you deploy an equal-tier scanner to orbit around {examplePart.Body}.",
                    IsClearlyBroken = true,
                    FixIt = () => SetToIdealTier(colonizationResearch, noScannerParts)
                });
            }

            if (noSubResearchParts.Any())
            {
                var examplePart = noSubResearchParts[0];
                yield return(new WarningMessage
                {
                    Message = $"Not all the products in the production chain for {examplePart.Output.DisplayName} have advanced to {examplePart.Tier}.",
                    IsClearlyBroken = true,
                    FixIt = () => SetToIdealTier(colonizationResearch, noSubResearchParts)
                });
            }

            if (underTier.Any())
            {
                var examplePart = underTier[0];
                yield return(new WarningMessage
                {
                    Message = $"This base is not taking advantage of the latest tech for producing {examplePart.Output.DisplayName}",
                    IsClearlyBroken = true,
                    FixIt = () => SetToIdealTier(colonizationResearch, underTier)
                });
            }

            var mostUsedBodyAndCount = producers
                                       .Where(c => c.Output.ProductionRestriction != ProductionRestriction.Space)
                                       .Where(c => c.Body != null)
                                       .GroupBy(c => c.Body)
                                       .Select(g => new { body = g.Key, count = g.Count() })
                                       .OrderByDescending(o => o.count)
                                       .ToArray();
            string targetBody = mostUsedBodyAndCount.Length > 0 ? mostUsedBodyAndCount[0].body : null;

            foreach (var pair in producers.GroupBy(producer => producer.Output))
            {
                TieredResource output = pair.Key;
                IEnumerable <ITieredProducer> parts = pair;

                // Parts should be set consistently
                TechTier minTier = parts.Min(p => p.Tier);
                TechTier maxTier = parts.Max(p => p.Tier);
                if (minTier != maxTier)
                {
                    yield return(new WarningMessage
                    {
                        Message = $"Not all of the parts producing {output.BaseName} are set at {maxTier}",
                        IsClearlyBroken = false,
                        FixIt = () =>
                        {
                            foreach (var part in parts)
                            {
                                part.Tier = maxTier;
                            }
                        }
                    });

                    break;
                }

                // Supplier parts should be at least maxTier
                var            firstPart = parts.First();
                TieredResource input     = firstPart.Input;
                if (parts.First().Input == null && output.IsHarvestedLocally && targetBody != null)
                {
                    // then it depends on scanning
                    TechTier maxScanningTier = colonizationResearch.GetMaxUnlockedScanningTier(targetBody);
                    if (maxTier > maxScanningTier)
                    {
                    }
                }
                else if (input != null)
                {
                    // Ensure that the suppliers are all at least the same tier.
                    if (producers.Any(producer => producer.Output == input && producer.Tier < maxTier))
                    {
                        yield return(new WarningMessage
                        {
                            Message = $"There are {maxTier.DisplayName()} producers of {output.BaseName}, but it requires equal-tier {input.BaseName} production in order to work.",
                            IsClearlyBroken = true,
                            FixIt = null
                        });
                    }
                }
            }
        }