public static bool BuildingPresent(ResearchProjectDef research) { // try get from cache bool result; if (_buildingPresentCache.TryGetValue(research, out result)) { return(result); } // do the work manually if (research.requiredResearchBuilding == null) { result = true; } else { result = Find.Maps.SelectMany(map => map.listerBuildings.allBuildingsColonist) .OfType <Building_ResearchBench>() .Any(b => research.CanBeResearchedAt(b, true)); } if (result) { result = research.GetPrerequisitesRecursive().All(BuildingPresent); } // update cache _buildingPresentCache.Add(research, result); return(result); }
public static List <ThingDef> MissingFacilities(ResearchProjectDef research) { // try get from cache List <ThingDef> missing; if (_missingFacilitiesCache.TryGetValue(research, out missing)) { return(missing); } // get list of all researches required before this List <ResearchProjectDef> thisAndPrerequisites = research.GetPrerequisitesRecursive().Where(rpd => !rpd.IsFinished).ToList(); thisAndPrerequisites.Add(research); // get list of all available research benches var availableBenches = Find.Maps.SelectMany(map => map.listerBuildings.allBuildingsColonist) .OfType <Building_ResearchBench>(); var availableBenchDefs = availableBenches.Select(b => b.def).Distinct(); missing = new List <ThingDef>(); // check each for prerequisites // TODO: We should really build this list recursively so we can re-use results for prerequisites. foreach (ResearchProjectDef rpd in thisAndPrerequisites) { if (rpd.requiredResearchBuilding == null) { continue; } if (!availableBenchDefs.Contains(rpd.requiredResearchBuilding)) { missing.Add(rpd.requiredResearchBuilding); } if (rpd.requiredResearchFacilities.NullOrEmpty()) { continue; } foreach (ThingDef facility in rpd.requiredResearchFacilities) { if (!availableBenches.Any(b => b.HasFacility(facility))) { missing.Add(facility); } } } // add to cache missing = missing.Distinct().ToList(); _missingFacilitiesCache.Add(research, missing); return(missing); }