Example #1
0
        private static bool TryFindScrounger(TechTier scannerTier, Vessel candidate, TieredResource stuffResource, out TechTier highestScroungerTier)
        {
            highestScroungerTier = TechTier.Tier0;

            // Don't trust KSP to actually always have these things populated;
            if (candidate.protoVessel == null || candidate.protoVessel.protoPartSnapshots == null)
            {
                return(false);
            }

            bool hasScrounger = false;

            foreach (var protoPart in candidate.protoVessel.protoPartSnapshots)
            {
                if (protoPart.modules == null)
                {
                    continue;
                }

                // Unloaded vessels have modules, but they're not truly populated - that is, the class for
                // the module is created, but the members have their default values...  So we can find the
                // stuff that's coded in the part description (in this case) the "output" field here:
                if (protoPart.partPrefab.Modules.OfType <PksTieredResourceConverter>().Any(c => c.Output == stuffResource))
                {
                    hasScrounger = true;

                    // ...But to get hold of the this that are set in the VAB (like the tier), you have
                    // to parse it out of the config nodes.
                    foreach (var protoModule in protoPart.modules.Where(m => m.moduleName == nameof(PksTieredResourceConverter)))
                    {
                        TechTier tier = PksTieredResourceConverter.GetTechTierFromConfig(protoModule.moduleValues);
                        if (tier > scannerTier)
                        {
                            // There's no practical use of finding stuff near this base - even if it has lower
                            // tier scroungers somewhere, the higher tier ones should be taking priority.
                            return(false);
                        }
                        else if (tier > highestScroungerTier)
                        {
                            highestScroungerTier = tier;
                        }
                    }
                }
            }

            return(hasScrounger && stuffResource.MadeFrom(highestScroungerTier) != null);
        }
Example #2
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);
        }