Example #1
0
 public static void EditWeightedList(string label, bool show, WeightedList list)
 {
     DrawList(list.ToList())
     .Header(label)
     .Fold(show)
     .Item((item) =>
     {
         item.Object = EditorGUILayout.ObjectField(item.Object, typeof(UnityEngine.Object), true);
         item.Weight = EditorGUILayout.FloatField(item.Weight);
         return(item);
     })
     .Render();
 }
Example #2
0
        private static IEnumerator StartGeneratePotentialContractsRoutine(SimGameState __instance, bool clearExistingContracts, Action onContractGenComplete, StarSystem systemOverride, bool useWait)
        {
            int  debugCount       = 0;
            bool usingBreadcrumbs = systemOverride != null;

            if (useWait)
            {
                yield return(new WaitForSeconds(0.2f));
            }
            StarSystem      system;
            List <Contract> contractList;
            int             maxContracts;

            if (usingBreadcrumbs)
            {
                system       = systemOverride;
                contractList = __instance.CurSystem.SystemBreadcrumbs;
                maxContracts = __instance.CurSystem.CurMaxBreadcrumbs;
            }
            else
            {
                system       = __instance.CurSystem;
                contractList = __instance.CurSystem.SystemContracts;
                maxContracts = Mathf.CeilToInt(system.CurMaxContracts);
            }
            if (clearExistingContracts)
            {
                contractList.Clear();
            }
            List <StarSystem> AllSystems = new List <StarSystem>();

            foreach (StarSystem addsystem in __instance.StarSystems)
            {
                if (addsystem.OwnerValue.Name != FactionEnumeration.GetNoFactionValue().Name)
                {
                    AllSystems.Add(addsystem);
                }
            }
            while (contractList.Count < maxContracts && debugCount < 1000)
            {
                try {
                    if (usingBreadcrumbs)
                    {
                        List <StarSystem> listsys = AllSystems;
                        listsys.Shuffle();
                        if (Fields.currBorderCons < maxContracts * Fields.settings.percentageOfTravelOnBorder)
                        {
                            int sysNr = 0;
                            if (Fields.settings.warBorders)
                            {
                                while (!Helper.IsWarBorder(listsys[sysNr], __instance))
                                {
                                    sysNr++;
                                }
                            }
                            else
                            {
                                while (!Helper.IsBorder(listsys[sysNr], __instance))
                                {
                                    sysNr++;
                                }
                            }
                            system = listsys[sysNr];
                            Fields.currBorderCons++;
                        }
                        else
                        {
                            system = listsys[0];
                        }
                    }
                }
                catch (Exception e)
                {
                    Logger.LogError(e);
                    yield break;
                }
                var difficultyRange = AccessTools.Method(typeof(SimGameState), "GetContractRangeDifficultyRange").Invoke(__instance, new object[] { system, __instance.SimGameMode, __instance.GlobalDifficulty });
                Dictionary <int, List <ContractOverride> > potentialContracts = (Dictionary <int, List <ContractOverride> >)AccessTools.Method(typeof(SimGameState), "GetSinglePlayerProceduralContractOverrides").Invoke(__instance, new object[] { difficultyRange });
                WeightedList <MapAndEncounters>            playableMaps       = MetadataDatabase.Instance.GetReleasedMapsAndEncountersBySinglePlayerProceduralContractTypeAndTags(system.Def.MapRequiredTags, system.Def.MapExcludedTags, system.Def.SupportedBiomes, true).ToWeightedList(WeightedListType.SimpleRandom);
                var validParticipants = AccessTools.Method(typeof(SimGameState), "GetValidParticipants").Invoke(__instance, new object[] { system });
                if (!(bool)AccessTools.Method(typeof(SimGameState), "HasValidMaps").Invoke(__instance, new object[] { system, playableMaps }) ||
                    !(bool)AccessTools.Method(typeof(SimGameState), "HasValidContracts").Invoke(__instance, new object[] { difficultyRange, potentialContracts }) ||
                    !(bool)AccessTools.Method(typeof(SimGameState), "HasValidParticipants").Invoke(__instance, new object[] { system, validParticipants }))
                {
                    if (onContractGenComplete != null)
                    {
                        onContractGenComplete();
                    }
                    yield break;
                }
                AccessTools.Method(typeof(SimGameState), "ClearUsedBiomeFromDiscardPile").Invoke(__instance, new object[] { playableMaps });
                debugCount++;
                IEnumerable <int> mapWeights = from map in playableMaps
                                               select map.Map.Weight;
                WeightedList <MapAndEncounters> activeMaps = new WeightedList <MapAndEncounters>(WeightedListType.WeightedRandom, playableMaps.ToList(), mapWeights.ToList <int>(), 0);
                AccessTools.Method(typeof(SimGameState), "FilterActiveMaps").Invoke(__instance, new object[] { activeMaps, contractList });
                activeMaps.Reset(false);
                MapAndEncounters level        = activeMaps.GetNext(false);
                var  MapEncounterContractData = AccessTools.Method(typeof(SimGameState), "FillMapEncounterContractData").Invoke(__instance, new object[] { system, difficultyRange, potentialContracts, validParticipants, level });
                bool HasContracts             = Traverse.Create(MapEncounterContractData).Property("HasContracts").GetValue <bool>();
                while (!HasContracts && activeMaps.ActiveListCount > 0)
                {
                    level = activeMaps.GetNext(false);
                    MapEncounterContractData = AccessTools.Method(typeof(SimGameState), "FillMapEncounterContractData").Invoke(__instance, new object[] { system, difficultyRange, potentialContracts, validParticipants, level });
                }
                system.SetCurrentContractFactions(FactionEnumeration.GetInvalidUnsetFactionValue(), FactionEnumeration.GetInvalidUnsetFactionValue());
                HashSet <int> Contracts = Traverse.Create(MapEncounterContractData).Field("Contracts").GetValue <HashSet <int> >();

                if (MapEncounterContractData == null || Contracts.Count == 0)
                {
                    List <string> mapDiscardPile = Traverse.Create(__instance).Field("mapDiscardPile").GetValue <List <string> >();
                    if (mapDiscardPile.Count > 0)
                    {
                        mapDiscardPile.Clear();
                    }
                    else
                    {
                        debugCount = 1000;
                        SimGameState.logger.LogError(string.Format("[CONTRACT] Unable to find any valid contracts for available map pool. Alert designers.", new object[0]));
                    }
                }
                GameContext gameContext = new GameContext(__instance.Context);
                gameContext.SetObject(GameContextObjectTagEnum.TargetStarSystem, system);
                Contract con = (Contract)AccessTools.Method(typeof(SimGameState), "CreateProceduralContract").Invoke(__instance, new object[] { system, usingBreadcrumbs, level, MapEncounterContractData, gameContext });
                contractList.Add(con);
                if (useWait)
                {
                    yield return(new WaitForSeconds(0.2f));
                }
            }
            if (debugCount >= 1000)
            {
                SimGameState.logger.LogError("Unable to fill contract list. Please inform AJ Immediately");
            }
            if (onContractGenComplete != null)
            {
                onContractGenComplete();
            }
            yield break;
        }
        private static void HandleLackOfContractsSituation(SimGameState simGameState, WeightedList <MapAndEncounters> activeMaps, List <Contract> currentContracts)
        {
            // If there are no more active maps, reset the biomes/maps list
            Main.Logger.LogWarning($"[FilterOnMapsWithEncountersWithValidContractRequirements] No valid map/encounter combinations. Handling lack of map/encounter situation.");
            StarSystem    system         = MissionControl.Instance.System;
            List <string> mapDiscardPile = (List <string>)AccessTools.Field(typeof(SimGameState), "mapDiscardPile").GetValue(simGameState);

            mapDiscardPile.Clear();

            WeightedList <MapAndEncounters> playableMaps = (WeightedList <MapAndEncounters>)AccessTools.Method(typeof(SimGameState), "GetSinglePlayerProceduralPlayableMaps").Invoke(null, new object[] { system });
            IEnumerable <int> source = from map in playableMaps select map.Map.Weight;
            WeightedList <MapAndEncounters> weightedList = new WeightedList <MapAndEncounters>(WeightedListType.WeightedRandom, playableMaps.ToList(), source.ToList <int>(), 0);

            activeMaps.AddRange(weightedList);

            Main.Logger.LogWarning($"[FilterOnMapsWithEncountersWithValidContractRequirements] Running fresh map list over post processing to ensure no contracts screen freezes");
            HandleContractRepeats(simGameState, activeMaps);
            FilterOnMapsWithEncountersWithValidContractRequirements(simGameState, activeMaps, currentContracts);
            FixActiveMapWeights(activeMaps);
        }
Example #4
0
        public static Contract getNewProceduralContract(StarSystem system, FactionValue employer, FactionValue target)
        {
            // In order to force a given employer and target, we have to temoporarily munge the system we're in, such that
            // our employer/target are the only valid ones. We undo this at the end of getNewProceduralContract.
            var oldEmployers = (List <string>)_fieldSetContractEmployers.GetValue(system.Def);
            var oldTargets   = (List <string>)_fieldSetContractTargets.GetValue(system.Def);

            _fieldSetContractEmployers.SetValue(system.Def, new List <string>()
            {
                employer.Name
            });
            _fieldSetContractTargets.SetValue(system.Def, new List <string>()
            {
                target.Name
            });

            // In addition, we have to make sure that our target is a valid enemy for the employer - otherwise the base game's
            // `GenerateContractParticipants` will return an empty list and the contract will fail to generate.
            string[]      oldEnemies = employer.FactionDef.Enemies;
            List <string> enemies    = oldEnemies.ToList();

            enemies.Add(target.Name);
            Traverse.Create(employer.FactionDef).Property("Enemies").SetValue(enemies.ToArray());

            WIIC.modLog.Debug?.Write($"getNewProceduralContract: SimGameMode {WIIC.sim.SimGameMode}, GlobalDifficulty {WIIC.sim.GlobalDifficulty}");
            var difficultyRange = _getContractRangeDifficultyRange.Invoke(WIIC.sim, new object[] { system, WIIC.sim.SimGameMode, WIIC.sim.GlobalDifficulty });

            Type Diff       = difficultyRange.GetType();
            int  min        = (int)AccessTools.Field(Diff, "MinDifficulty").GetValue(difficultyRange);
            int  max        = (int)AccessTools.Field(Diff, "MaxDifficulty").GetValue(difficultyRange);
            int  minClamped = (int)AccessTools.Field(Diff, "MinDifficultyClamped").GetValue(difficultyRange);
            int  maxClamped = (int)AccessTools.Field(Diff, "MaxDifficultyClamped").GetValue(difficultyRange);

            WIIC.modLog.Debug?.Write($"difficultyRange: MinDifficulty {min}, MaxDifficulty {max}, MinClamped {minClamped}, MaxClamped {maxClamped}");

            var validTypes = contractTypes.AddRangeToArray(WIIC.settings.customContractEnums.ToArray());

            var potentialContracts = (Dictionary <int, List <ContractOverride> >)_getContractOverrides.Invoke(WIIC.sim, new object[] { difficultyRange, validTypes });

            WeightedList <MapAndEncounters> playableMaps =
                MetadataDatabase.Instance.GetReleasedMapsAndEncountersBySinglePlayerProceduralContractTypeAndTags(
                    system.Def.MapRequiredTags, system.Def.MapExcludedTags, system.Def.SupportedBiomes, true)
                .ToWeightedList(WeightedListType.SimpleRandom);

            var validParticipants = _getValidParticipants.Invoke(WIIC.sim, new object[] { system });

            if (!(bool)_hasValidMaps.Invoke(WIIC.sim, new object[] { system, playableMaps }) ||
                !(bool)_hasValidContracts.Invoke(WIIC.sim, new object[] { difficultyRange, potentialContracts }) ||
                !(bool)_hasValidParticipants.Invoke(WIIC.sim, new object[] { system, validParticipants }))
            {
                return(null);
            }

            _clearUsedBiomeFromDiscardPile.Invoke(WIIC.sim, new object[] { playableMaps });
            IEnumerable <int> mapWeights = from map in playableMaps
                                           select map.Map.Weight;

            var activeMaps = new WeightedList <MapAndEncounters>(WeightedListType.WeightedRandom, playableMaps.ToList(), mapWeights.ToList <int>(), 0);

            _filterActiveMaps.Invoke(WIIC.sim, new object[] { activeMaps, WIIC.sim.GlobalContracts });
            activeMaps.Reset(false);
            MapAndEncounters level = activeMaps.GetNext(false);

            var  MapEncounterContractData = _fillMapEncounterContractData.Invoke(WIIC.sim, new object[] { system, difficultyRange, potentialContracts, validParticipants, level });
            bool HasContracts             = Traverse.Create(MapEncounterContractData).Property("HasContracts").GetValue <bool>();

            while (!HasContracts && activeMaps.ActiveListCount > 0)
            {
                level = activeMaps.GetNext(false);
                MapEncounterContractData = _fillMapEncounterContractData.Invoke(WIIC.sim, new object[] { system, difficultyRange, potentialContracts, validParticipants, level });
            }
            system.SetCurrentContractFactions(FactionEnumeration.GetInvalidUnsetFactionValue(), FactionEnumeration.GetInvalidUnsetFactionValue());
            HashSet <int> Contracts = Traverse.Create(MapEncounterContractData).Field("Contracts").GetValue <HashSet <int> >();

            if (MapEncounterContractData == null || Contracts.Count == 0)
            {
                List <string> mapDiscardPile = Traverse.Create(WIIC.sim).Field("mapDiscardPile").GetValue <List <string> >();
                if (mapDiscardPile.Count > 0)
                {
                    mapDiscardPile.Clear();
                }
                else
                {
                    WIIC.modLog.Error?.Write($"Unable to find any valid contracts for available map pool.");
                }
            }
            GameContext gameContext = new GameContext(WIIC.sim.Context);

            gameContext.SetObject(GameContextObjectTagEnum.TargetStarSystem, system);

            Contract contract = (Contract)_createProceduralContract.Invoke(WIIC.sim, new object[] { system, true, level, MapEncounterContractData, gameContext });

            // Restore system and faction to previous values, now that we've forced the game to generate our desired contract.
            _fieldSetContractEmployers.SetValue(system.Def, oldEmployers);
            _fieldSetContractTargets.SetValue(system.Def, oldTargets);
            Traverse.Create(employer.FactionDef).Property("Enemies").SetValue(oldEnemies);
            return(contract);
        }
Example #5
0
        public static Contract GetNewWarContract(SimGameState Sim, int Difficulty, Faction emp, Faction targ, StarSystem system)
        {
            if (Difficulty <= 1)
            {
                Difficulty = 2;
            }
            else if (Difficulty > 9)
            {
                Difficulty = 9;
            }

            ContractDifficulty minDiffClamped = (ContractDifficulty)AccessTools.Method(typeof(SimGameState), "GetDifficultyEnumFromValue").Invoke(Sim, new object[] { Difficulty });
            ContractDifficulty maxDiffClamped = (ContractDifficulty)AccessTools.Method(typeof(SimGameState), "GetDifficultyEnumFromValue").Invoke(Sim, new object[] { Difficulty });
            List <Contract>    contractList   = new List <Contract>();
            int maxContracts = 1;
            int debugCount   = 0;

            while (contractList.Count < maxContracts && debugCount < 1000)
            {
                WeightedList <MapAndEncounters> contractMaps  = new WeightedList <MapAndEncounters>(WeightedListType.SimpleRandom, null, null, 0);
                List <ContractType>             contractTypes = new List <ContractType>();
                Dictionary <ContractType, List <ContractOverride> > potentialOverrides = new Dictionary <ContractType, List <ContractOverride> >();
                AccessTools.Field(typeof(SimGameState), "singlePlayerTypes");
                ContractType[] singlePlayerTypes = (ContractType[])AccessTools.Field(typeof(SimGameState), "singlePlayerTypes").GetValue(Sim);
                using (MetadataDatabase metadataDatabase = new MetadataDatabase()) {
                    foreach (Contract_MDD contract_MDD in metadataDatabase.GetContractsByDifficultyRange(Difficulty - 1, Difficulty + 1))
                    {
                        ContractType contractType = contract_MDD.ContractTypeEntry.ContractType;
                        if (singlePlayerTypes.Contains(contractType))
                        {
                            if (!contractTypes.Contains(contractType))
                            {
                                contractTypes.Add(contractType);
                            }
                            if (!potentialOverrides.ContainsKey(contractType))
                            {
                                potentialOverrides.Add(contractType, new List <ContractOverride>());
                            }
                            ContractOverride item = Sim.DataManager.ContractOverrides.Get(contract_MDD.ContractID);
                            potentialOverrides[contractType].Add(item);
                        }
                    }
                    foreach (MapAndEncounters element in metadataDatabase.GetReleasedMapsAndEncountersByContractTypeAndTags(singlePlayerTypes, system.Def.MapRequiredTags, system.Def.MapExcludedTags, system.Def.SupportedBiomes))
                    {
                        if (!contractMaps.Contains(element))
                        {
                            contractMaps.Add(element, 0);
                        }
                    }
                }
                if (contractMaps.Count == 0)
                {
                    Logger.LogLine("Maps0 break");
                    break;
                }
                if (potentialOverrides.Count == 0)
                {
                    Logger.LogLine("Overrides0 break");
                    break;
                }
                contractMaps.Reset(false);
                WeightedList <Faction> validEmployers = new WeightedList <Faction>(WeightedListType.SimpleRandom, null, null, 0);
                Dictionary <Faction, WeightedList <Faction> > validTargets = new Dictionary <Faction, WeightedList <Faction> >();

                int i = debugCount;
                debugCount = i + 1;
                WeightedList <MapAndEncounters> activeMaps    = new WeightedList <MapAndEncounters>(WeightedListType.SimpleRandom, contractMaps.ToList(), null, 0);
                List <MapAndEncounters>         discardedMaps = new List <MapAndEncounters>();


                List <string> mapDiscardPile = (List <string>)AccessTools.Field(typeof(SimGameState), "mapDiscardPile").GetValue(Sim);

                for (int j = activeMaps.Count - 1; j >= 0; j--)
                {
                    if (mapDiscardPile.Contains(activeMaps[j].Map.MapID))
                    {
                        discardedMaps.Add(activeMaps[j]);
                        activeMaps.RemoveAt(j);
                    }
                }
                if (activeMaps.Count == 0)
                {
                    mapDiscardPile.Clear();
                    foreach (MapAndEncounters element2 in discardedMaps)
                    {
                        activeMaps.Add(element2, 0);
                    }
                }
                activeMaps.Reset(false);
                MapAndEncounters          level           = null;
                List <EncounterLayer_MDD> validEncounters = new List <EncounterLayer_MDD>();


                Dictionary <ContractType, WeightedList <PotentialContract> > validContracts = new Dictionary <ContractType, WeightedList <PotentialContract> >();
                WeightedList <PotentialContract> flatValidContracts = null;
                do
                {
                    level = activeMaps.GetNext(false);
                    if (level == null)
                    {
                        break;
                    }
                    validEncounters.Clear();
                    validContracts.Clear();
                    flatValidContracts = new WeightedList <PotentialContract>(WeightedListType.WeightedRandom, null, null, 0);
                    foreach (EncounterLayer_MDD encounterLayer_MDD in level.Encounters)
                    {
                        ContractType contractType2 = encounterLayer_MDD.ContractTypeEntry.ContractType;
                        if (contractTypes.Contains(contractType2))
                        {
                            if (validContracts.ContainsKey(contractType2))
                            {
                                validEncounters.Add(encounterLayer_MDD);
                            }
                            else
                            {
                                foreach (ContractOverride contractOverride2 in potentialOverrides[contractType2])
                                {
                                    bool flag = true;
                                    ContractDifficulty difficultyEnumFromValue = (ContractDifficulty)AccessTools.Method(typeof(SimGameState), "GetDifficultyEnumFromValue").Invoke(Sim, new object[] { contractOverride2.difficulty });
                                    Faction            employer2 = Faction.INVALID_UNSET;
                                    Faction            target2   = Faction.INVALID_UNSET;
                                    if (difficultyEnumFromValue >= minDiffClamped && difficultyEnumFromValue <= maxDiffClamped)
                                    {
                                        employer2 = emp;
                                        target2   = targ;
                                        int difficulty = Sim.NetworkRandom.Int(Difficulty, Difficulty + 1);
                                        system.SetCurrentContractFactions(employer2, target2);
                                        int k = 0;
                                        while (k < contractOverride2.requirementList.Count)
                                        {
                                            RequirementDef requirementDef = new RequirementDef(contractOverride2.requirementList[k]);
                                            EventScope     scope          = requirementDef.Scope;
                                            TagSet         curTags;
                                            StatCollection stats;
                                            switch (scope)
                                            {
                                            case EventScope.Company:
                                                curTags = Sim.CompanyTags;
                                                stats   = Sim.CompanyStats;
                                                break;

                                            case EventScope.MechWarrior:
                                            case EventScope.Mech:
                                                goto IL_88B;

                                            case EventScope.Commander:
                                                goto IL_8E9;

                                            case EventScope.StarSystem:
                                                curTags = system.Tags;
                                                stats   = system.Stats;
                                                break;

                                            default:
                                                goto IL_88B;
                                            }
IL_803:
                                            for (int l = requirementDef.RequirementComparisons.Count - 1; l >= 0; l--)
                                            {
                                                ComparisonDef item2 = requirementDef.RequirementComparisons[l];
                                                if (item2.obj.StartsWith("Target") || item2.obj.StartsWith("Employer"))
                                                {
                                                    requirementDef.RequirementComparisons.Remove(item2);
                                                }
                                            }
                                            if (!SimGameState.MeetsRequirements(requirementDef, curTags, stats, null))
                                            {
                                                flag = false;
                                                break;
                                            }
                                            k++;
                                            continue;
IL_88B:
                                            if (scope != EventScope.Map)
                                            {
                                                throw new Exception("Contracts cannot use the scope of: " + requirementDef.Scope);
                                            }
                                            using (MetadataDatabase metadataDatabase2 = new MetadataDatabase()) {
                                                curTags = metadataDatabase2.GetTagSetForTagSetEntry(level.Map.TagSetID);
                                                stats   = new StatCollection();
                                                goto IL_803;
                                            }
IL_8E9:
                                            curTags = Sim.CommanderTags;
                                            stats   = Sim.CommanderStats;
                                            goto IL_803;
                                        }
                                        if (flag)
                                        {
                                            PotentialContract element3 = default(PotentialContract);
                                            element3.contractOverride = contractOverride2;
                                            element3.difficulty       = difficulty;
                                            element3.employer         = employer2;
                                            element3.target           = target2;
                                            validEncounters.Add(encounterLayer_MDD);
                                            if (!validContracts.ContainsKey(contractType2))
                                            {
                                                validContracts.Add(contractType2, new WeightedList <PotentialContract>(WeightedListType.WeightedRandom, null, null, 0));
                                            }
                                            validContracts[contractType2].Add(element3, contractOverride2.weight);
                                            flatValidContracts.Add(element3, contractOverride2.weight);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }while (validContracts.Count == 0 && level != null);
                system.SetCurrentContractFactions(Faction.INVALID_UNSET, Faction.INVALID_UNSET);
                if (validContracts.Count == 0)
                {
                    if (mapDiscardPile.Count > 0)
                    {
                        mapDiscardPile.Clear();
                    }
                    else
                    {
                        debugCount = 1000;
                        Logger.LogLine(string.Format("[CONTRACT] Unable to find any valid contracts for available map pool. Alert designers.", new object[0]));
                    }
                }
                else
                {
                    GameContext gameContext = new GameContext(Sim.Context);
                    gameContext.SetObject(GameContextObjectTagEnum.TargetStarSystem, system);
                    Dictionary <ContractType, List <EncounterLayer_MDD> > finalEncounters = new Dictionary <ContractType, List <EncounterLayer_MDD> >();
                    foreach (EncounterLayer_MDD encounterLayer_MDD2 in validEncounters)
                    {
                        ContractType contractType3 = encounterLayer_MDD2.ContractTypeEntry.ContractType;
                        if (!finalEncounters.ContainsKey(contractType3))
                        {
                            finalEncounters.Add(contractType3, new List <EncounterLayer_MDD>());
                        }
                        finalEncounters[contractType3].Add(encounterLayer_MDD2);
                    }
                    List <PotentialContract> discardedContracts = new List <PotentialContract>();

                    List <string> contractDiscardPile = (List <string>)AccessTools.Field(typeof(SimGameState), "contractDiscardPile").GetValue(Sim);
                    for (int m = flatValidContracts.Count - 1; m >= 0; m--)
                    {
                        if (contractDiscardPile.Contains(flatValidContracts[m].contractOverride.ID))
                        {
                            discardedContracts.Add(flatValidContracts[m]);
                            flatValidContracts.RemoveAt(m);
                        }
                    }
                    if ((float)discardedContracts.Count >= (float)flatValidContracts.Count * Sim.Constants.Story.DiscardPileToActiveRatio || flatValidContracts.Count == 0)
                    {
                        contractDiscardPile.Clear();
                        foreach (PotentialContract element4 in discardedContracts)
                        {
                            flatValidContracts.Add(element4, 0);
                        }
                    }
                    PotentialContract next = flatValidContracts.GetNext(true);
                    ContractType      finalContractType = next.contractOverride.contractType;
                    finalEncounters[finalContractType].Shuffle <EncounterLayer_MDD>();
                    string           encounterGuid     = finalEncounters[finalContractType][0].EncounterLayerGUID;
                    ContractOverride contractOverride3 = next.contractOverride;
                    Faction          employer3         = next.employer;
                    Faction          target3           = next.target;
                    int targetDifficulty = next.difficulty;

                    Contract con = (Contract)AccessTools.Method(typeof(SimGameState), "CreateTravelContract").Invoke(Sim, new object[] { level.Map.MapName, level.Map.MapPath, encounterGuid, finalContractType, contractOverride3, gameContext, employer3, target3, employer3, false, targetDifficulty });
                    mapDiscardPile.Add(level.Map.MapID);
                    contractDiscardPile.Add(contractOverride3.ID);
                    Sim.PrepContract(con, employer3, target3, target3, level.Map.BiomeSkinEntry.BiomeSkin, con.Override.travelSeed, system);
                    contractList.Add(con);
                }
            }
            if (debugCount >= 1000)
            {
                Logger.LogLine("Unable to fill contract list. Please inform AJ Immediately");
            }
            return(contractList[0]);
        }
Example #6
0
        private static IEnumerator StartGeneratePotentialContractsRoutine(SimGameState instance, bool clearExistingContracts, Action onContractGenComplete, StarSystem systemOverride, bool useCoroutine)
        {
            if (useCoroutine)
            {
                yield return(new WaitForSeconds(0.2f));
            }
            bool            usingBreadcrumbs = systemOverride != null;
            StarSystem      system;
            List <Contract> contractList;

            if (systemOverride != null)
            {
                system       = systemOverride;
                contractList = instance.CurSystem.SystemBreadcrumbs;
            }
            else
            {
                system       = instance.CurSystem;
                contractList = instance.CurSystem.SystemContracts;
            }
            if (clearExistingContracts)
            {
                contractList.Clear();
            }
            int maxContracts;

            if (systemOverride != null)
            {
                maxContracts = instance.CurSystem.CurMaxBreadcrumbs;
            }
            else
            {
                maxContracts = Mathf.CeilToInt(system.CurMaxContracts);
            }

            int debugCount = 0;

            while (contractList.Count < maxContracts && debugCount < 1000)
            {
                if (usingBreadcrumbs)
                {
                    List <StarSystem> listsys = instance.StarSystems;
                    listsys.Shuffle <StarSystem>();
                    system = listsys[0];
                }
                int globalDifficulty = system.Def.Difficulty + Mathf.FloorToInt(instance.GlobalDifficulty);
                int minDiff;
                int maxDiff;

                int contractDifficultyVariance = instance.Constants.Story.ContractDifficultyVariance;
                minDiff = Mathf.Max(1, globalDifficulty - contractDifficultyVariance);
                maxDiff = Mathf.Max(1, globalDifficulty + contractDifficultyVariance);

                ContractDifficulty minDiffClamped             = (ContractDifficulty)ReflectionHelper.InvokePrivateMethode(instance, "GetDifficultyEnumFromValue", new object[] { minDiff });
                ContractDifficulty maxDiffClamped             = (ContractDifficulty)ReflectionHelper.InvokePrivateMethode(instance, "GetDifficultyEnumFromValue", new object[] { maxDiff });
                WeightedList <MapAndEncounters> contractMaps  = new WeightedList <MapAndEncounters>(WeightedListType.SimpleRandom, null, null, 0);
                List <ContractType>             contractTypes = new List <ContractType>();
                Dictionary <ContractType, List <ContractOverride> > potentialOverrides = new Dictionary <ContractType, List <ContractOverride> >();
                ContractType[] singlePlayerTypes = (ContractType[])ReflectionHelper.GetPrivateStaticField(typeof(SimGameState), "singlePlayerTypes");
                using (MetadataDatabase metadataDatabase = new MetadataDatabase()) {
                    foreach (Contract_MDD contract_MDD in metadataDatabase.GetContractsByDifficultyRangeAndScope((int)minDiffClamped, (int)maxDiffClamped, instance.ContractScope))
                    {
                        ContractType contractType = contract_MDD.ContractTypeEntry.ContractType;

                        if (singlePlayerTypes.Contains(contractType))
                        {
                            if (!contractTypes.Contains(contractType))
                            {
                                contractTypes.Add(contractType);
                            }
                            if (!potentialOverrides.ContainsKey(contractType))
                            {
                                potentialOverrides.Add(contractType, new List <ContractOverride>());
                            }
                            ContractOverride item = instance.DataManager.ContractOverrides.Get(contract_MDD.ContractID);
                            potentialOverrides[contractType].Add(item);
                        }
                    }
                    foreach (MapAndEncounters element in metadataDatabase.GetReleasedMapsAndEncountersByContractTypeAndTags(singlePlayerTypes, system.Def.MapRequiredTags, system.Def.MapExcludedTags, system.Def.SupportedBiomes))
                    {
                        if (!contractMaps.Contains(element))
                        {
                            contractMaps.Add(element, 0);
                        }
                    }
                }
                if (contractMaps.Count == 0)
                {
                    Debug.LogError(string.Format("No valid map for System {0}", system.Name));
                    if (onContractGenComplete != null)
                    {
                        onContractGenComplete();
                    }
                    yield break;
                }
                if (potentialOverrides.Count == 0)
                {
                    Debug.LogError(string.Format("No valid contracts queried for difficulties between {0} and {1}, with a SCOPE of {2}", minDiffClamped, maxDiffClamped, instance.ContractScope));
                    if (onContractGenComplete != null)
                    {
                        onContractGenComplete();
                    }
                    yield break;
                }
                contractMaps.Reset(false);
                WeightedList <Faction> validEmployers = new WeightedList <Faction>(WeightedListType.SimpleRandom, null, null, 0);
                Dictionary <Faction, WeightedList <Faction> > validTargets = new Dictionary <Faction, WeightedList <Faction> >();

                Dictionary <Faction, FactionDef> factions = (Dictionary <Faction, FactionDef>)ReflectionHelper.GetPrivateField(instance, "factions");

                foreach (Faction faction in system.Def.ContractEmployers)
                {
                    foreach (Faction faction2 in factions[faction].Enemies)
                    {
                        if (system.Def.ContractTargets.Contains(faction2))
                        {
                            if (!validTargets.ContainsKey(faction))
                            {
                                validTargets.Add(faction, new WeightedList <Faction>(WeightedListType.PureRandom, null, null, 0));
                            }
                            validTargets[faction].Add(faction2, 0);
                        }
                    }
                    if (validTargets.ContainsKey(faction))
                    {
                        validTargets[faction].Reset(false);
                        validEmployers.Add(faction, 0);
                    }
                }
                validEmployers.Reset(false);

                if (validEmployers.Count <= 0 || validTargets.Count <= 0)
                {
                    Debug.LogError(string.Format("Cannot find any valid employers or targets for system {0}", system));
                }
                if (validTargets.Count == 0 || validEmployers.Count == 0)
                {
                    SimGameState.logger.LogError(string.Format("There are no valid employers or employers for the system of {0}. Num valid employers: {1}", system.Name, validEmployers.Count));
                    foreach (Faction faction3 in validTargets.Keys)
                    {
                        SimGameState.logger.LogError(string.Format("--- Targets for {0}: {1}", faction3, validTargets[faction3].Count));
                    }
                    if (onContractGenComplete != null)
                    {
                        onContractGenComplete();
                    }
                    yield break;
                }

                int i = debugCount;
                debugCount = i + 1;
                WeightedList <MapAndEncounters> activeMaps    = new WeightedList <MapAndEncounters>(WeightedListType.SimpleRandom, contractMaps.ToList(), null, 0);
                List <MapAndEncounters>         discardedMaps = new List <MapAndEncounters>();

                List <string> mapDiscardPile = (List <string>)ReflectionHelper.GetPrivateField(instance, "mapDiscardPile");

                for (int j = activeMaps.Count - 1; j >= 0; j--)
                {
                    if (mapDiscardPile.Contains(activeMaps[j].Map.MapID))
                    {
                        discardedMaps.Add(activeMaps[j]);
                        activeMaps.RemoveAt(j);
                    }
                }
                if (activeMaps.Count == 0)
                {
                    mapDiscardPile.Clear();
                    foreach (MapAndEncounters element2 in discardedMaps)
                    {
                        activeMaps.Add(element2, 0);
                    }
                }
                activeMaps.Reset(false);
                MapAndEncounters          level           = null;
                List <EncounterLayer_MDD> validEncounters = new List <EncounterLayer_MDD>();


                Dictionary <ContractType, WeightedList <PotentialContract> > validContracts = new Dictionary <ContractType, WeightedList <PotentialContract> >();
                WeightedList <PotentialContract> flatValidContracts = null;
                do
                {
                    level = activeMaps.GetNext(false);
                    if (level == null)
                    {
                        break;
                    }
                    validEncounters.Clear();
                    validContracts.Clear();
                    flatValidContracts = new WeightedList <PotentialContract>(WeightedListType.WeightedRandom, null, null, 0);
                    foreach (EncounterLayer_MDD encounterLayer_MDD in level.Encounters)
                    {
                        ContractType contractType2 = encounterLayer_MDD.ContractTypeEntry.ContractType;
                        if (contractTypes.Contains(contractType2))
                        {
                            if (validContracts.ContainsKey(contractType2))
                            {
                                validEncounters.Add(encounterLayer_MDD);
                            }
                            else
                            {
                                foreach (ContractOverride contractOverride2 in potentialOverrides[contractType2])
                                {
                                    bool flag = true;
                                    ContractDifficulty difficultyEnumFromValue = (ContractDifficulty)ReflectionHelper.InvokePrivateMethode(instance, "GetDifficultyEnumFromValue", new object[] { contractOverride2.difficulty });
                                    Faction            employer2 = Faction.INVALID_UNSET;
                                    Faction            target2   = Faction.INVALID_UNSET;
                                    object[]           args      = new object[] { system, validEmployers, validTargets, contractOverride2.requirementList, employer2, target2 };
                                    if (difficultyEnumFromValue >= minDiffClamped && difficultyEnumFromValue <= maxDiffClamped && (bool)ReflectionHelper.InvokePrivateMethode(instance, "GetValidFaction", args))
                                    {
                                        employer2 = (Faction)args[4];
                                        target2   = (Faction)args[5];
                                        int difficulty = instance.NetworkRandom.Int(minDiff, maxDiff + 1);
                                        system.SetCurrentContractFactions(employer2, target2);
                                        int k = 0;
                                        while (k < contractOverride2.requirementList.Count)
                                        {
                                            RequirementDef requirementDef = new RequirementDef(contractOverride2.requirementList[k]);
                                            EventScope     scope          = requirementDef.Scope;
                                            TagSet         curTags;
                                            StatCollection stats;
                                            switch (scope)
                                            {
                                            case EventScope.Company:
                                                curTags = instance.CompanyTags;
                                                stats   = instance.CompanyStats;
                                                break;

                                            case EventScope.MechWarrior:
                                            case EventScope.Mech:
                                                goto IL_88B;

                                            case EventScope.Commander:
                                                goto IL_8E9;

                                            case EventScope.StarSystem:
                                                curTags = system.Tags;
                                                stats   = system.Stats;
                                                break;

                                            default:
                                                goto IL_88B;
                                            }
IL_803:
                                            for (int l = requirementDef.RequirementComparisons.Count - 1; l >= 0; l--)
                                            {
                                                ComparisonDef item2 = requirementDef.RequirementComparisons[l];
                                                if (item2.obj.StartsWith("Target") || item2.obj.StartsWith("Employer"))
                                                {
                                                    requirementDef.RequirementComparisons.Remove(item2);
                                                }
                                            }
                                            if (!SimGameState.MeetsRequirements(requirementDef, curTags, stats, null))
                                            {
                                                flag = false;
                                                break;
                                            }
                                            k++;
                                            continue;
IL_88B:
                                            if (scope != EventScope.Map)
                                            {
                                                throw new Exception("Contracts cannot use the scope of: " + requirementDef.Scope);
                                            }
                                            using (MetadataDatabase metadataDatabase2 = new MetadataDatabase()) {
                                                curTags = metadataDatabase2.GetTagSetForTagSetEntry(level.Map.TagSetID);
                                                stats   = new StatCollection();
                                                goto IL_803;
                                            }
IL_8E9:
                                            curTags = instance.CommanderTags;
                                            stats   = instance.CommanderStats;
                                            goto IL_803;
                                        }
                                        if (flag)
                                        {
                                            PotentialContract element3 = default(PotentialContract);
                                            element3.contractOverride = contractOverride2;
                                            element3.difficulty       = difficulty;
                                            element3.employer         = employer2;
                                            element3.target           = target2;
                                            validEncounters.Add(encounterLayer_MDD);
                                            if (!validContracts.ContainsKey(contractType2))
                                            {
                                                validContracts.Add(contractType2, new WeightedList <PotentialContract>(WeightedListType.WeightedRandom, null, null, 0));
                                            }
                                            validContracts[contractType2].Add(element3, contractOverride2.weight);
                                            flatValidContracts.Add(element3, contractOverride2.weight);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }while (validContracts.Count == 0 && level != null);
                system.SetCurrentContractFactions(Faction.INVALID_UNSET, Faction.INVALID_UNSET);
                if (validContracts.Count == 0)
                {
                    if (mapDiscardPile.Count > 0)
                    {
                        mapDiscardPile.Clear();
                    }
                    else
                    {
                        debugCount = 1000;
                        SimGameState.logger.LogError(string.Format("[CONTRACT] Unable to find any valid contracts for available map pool. Alert designers.", new object[0]));
                    }
                }
                else
                {
                    GameContext gameContext = new GameContext(instance.Context);
                    gameContext.SetObject(GameContextObjectTagEnum.TargetStarSystem, system);
                    Dictionary <ContractType, List <EncounterLayer_MDD> > finalEncounters = new Dictionary <ContractType, List <EncounterLayer_MDD> >();
                    foreach (EncounterLayer_MDD encounterLayer_MDD2 in validEncounters)
                    {
                        ContractType contractType3 = encounterLayer_MDD2.ContractTypeEntry.ContractType;
                        if (!finalEncounters.ContainsKey(contractType3))
                        {
                            finalEncounters.Add(contractType3, new List <EncounterLayer_MDD>());
                        }
                        finalEncounters[contractType3].Add(encounterLayer_MDD2);
                    }
                    List <PotentialContract> discardedContracts  = new List <PotentialContract>();
                    List <string>            contractDiscardPile = (List <string>)ReflectionHelper.GetPrivateField(instance, "contractDiscardPile");
                    for (int m = flatValidContracts.Count - 1; m >= 0; m--)
                    {
                        if (contractDiscardPile.Contains(flatValidContracts[m].contractOverride.ID))
                        {
                            discardedContracts.Add(flatValidContracts[m]);
                            flatValidContracts.RemoveAt(m);
                        }
                    }
                    if ((float)discardedContracts.Count >= (float)flatValidContracts.Count * instance.Constants.Story.DiscardPileToActiveRatio || flatValidContracts.Count == 0)
                    {
                        contractDiscardPile.Clear();
                        foreach (PotentialContract element4 in discardedContracts)
                        {
                            flatValidContracts.Add(element4, 0);
                        }
                    }
                    PotentialContract next = flatValidContracts.GetNext(true);
                    ContractType      finalContractType = next.contractOverride.contractType;
                    finalEncounters[finalContractType].Shuffle <EncounterLayer_MDD>();
                    string           encounterGuid     = finalEncounters[finalContractType][0].EncounterLayerGUID;
                    ContractOverride contractOverride3 = next.contractOverride;
                    Faction          employer3         = next.employer;
                    Faction          target3           = next.target;
                    int      targetDifficulty          = next.difficulty;
                    Contract con;
                    if (usingBreadcrumbs)
                    {
                        con = (Contract)ReflectionHelper.InvokePrivateMethode(instance, "CreateTravelContract", new object[] { level.Map.MapName, level.Map.MapPath, encounterGuid, finalContractType, contractOverride3, gameContext, employer3, target3, employer3, false, targetDifficulty });
                    }
                    else
                    {
                        con = new Contract(level.Map.MapName, level.Map.MapPath, encounterGuid, finalContractType, instance.BattleTechGame, contractOverride3, gameContext, true, targetDifficulty, 0, null);
                    }
                    mapDiscardPile.Add(level.Map.MapID);
                    contractDiscardPile.Add(contractOverride3.ID);
                    instance.PrepContract(con, employer3, target3, target3, level.Map.BiomeSkinEntry.BiomeSkin, con.Override.travelSeed, system);
                    contractList.Add(con);
                    if (useCoroutine)
                    {
                        yield return(new WaitForSeconds(0.2f));
                    }
                }
            }
            if (debugCount >= 1000)
            {
                SimGameState.logger.LogError("Unable to fill contract list. Please inform AJ Immediately");
            }
            if (onContractGenComplete != null)
            {
                onContractGenComplete();
            }
            yield break;
        }
Example #7
0
        public static Contract GetNewWarContract(SimGameState Sim, int Difficulty, Faction emp, Faction targ, Faction third, StarSystem system)
        {
            Fields.prioGen      = true;
            Fields.prioEmployer = emp;
            Fields.prioTarget   = targ;
            Fields.prioThird    = third;

            if (Difficulty <= 1)
            {
                Difficulty = 2;
            }
            else if (Difficulty > 9)
            {
                Difficulty = 9;
            }

            var difficultyRange = AccessTools.Method(typeof(SimGameState), "GetContractRangeDifficultyRange").Invoke(Sim, new object[] { system, Sim.SimGameMode, Sim.GlobalDifficulty });
            Dictionary <int, List <ContractOverride> > potentialContracts = (Dictionary <int, List <ContractOverride> >)AccessTools.Method(typeof(SimGameState), "GetContractOverrides").Invoke(Sim, new object[] { difficultyRange, prioTypes });
            WeightedList <MapAndEncounters>            playableMaps       =
                //MetadataDatabase.Instance.GetReleasedMapsAndEncountersByContractTypeAndTagsAndOwnership(potentialContracts.Keys.ToArray<ContractType>(),
                //      system.Def.MapRequiredTags, system.Def.MapExcludedTags, system.Def.SupportedBiomes).ToWeightedList(WeightedListType.SimpleRandom);
                // TODO: MORPH - please review!
                MetadataDatabase.Instance.GetReleasedMapsAndEncountersBySinglePlayerProceduralContractTypeAndTags(
                    system.Def.MapRequiredTags, system.Def.MapExcludedTags, system.Def.SupportedBiomes, true)
                .ToWeightedList(WeightedListType.SimpleRandom);
            var validParticipants = AccessTools.Method(typeof(SimGameState), "GetValidParticipants").Invoke(Sim, new object[] { system });

            if (!(bool)AccessTools.Method(typeof(SimGameState), "HasValidMaps").Invoke(Sim, new object[] { system, playableMaps }) ||
                !(bool)AccessTools.Method(typeof(SimGameState), "HasValidContracts").Invoke(Sim, new object[] { difficultyRange, potentialContracts }) ||
                !(bool)AccessTools.Method(typeof(SimGameState), "HasValidParticipants").Invoke(Sim, new object[] { system, validParticipants }))
            {
                return(null);
            }
            AccessTools.Method(typeof(SimGameState), "ClearUsedBiomeFromDiscardPile").Invoke(Sim, new object[] { playableMaps });
            IEnumerable <int> mapWeights = from map in playableMaps
                                           select map.Map.Weight;
            WeightedList <MapAndEncounters> activeMaps = new WeightedList <MapAndEncounters>(WeightedListType.WeightedRandom, playableMaps.ToList(), mapWeights.ToList <int>(), 0);

            AccessTools.Method(typeof(SimGameState), "FilterActiveMaps").Invoke(Sim, new object[] { activeMaps, Sim.GlobalContracts });
            activeMaps.Reset(false);
            MapAndEncounters level        = activeMaps.GetNext(false);
            var  MapEncounterContractData = AccessTools.Method(typeof(SimGameState), "FillMapEncounterContractData").Invoke(Sim, new object[] { system, difficultyRange, potentialContracts, validParticipants, level });
            bool HasContracts             = Traverse.Create(MapEncounterContractData).Property("HasContracts").GetValue <bool>();

            while (!HasContracts && activeMaps.ActiveListCount > 0)
            {
                level = activeMaps.GetNext(false);
                MapEncounterContractData = AccessTools.Method(typeof(SimGameState), "FillMapEncounterContractData").Invoke(Sim, new object[] { system, difficultyRange, potentialContracts, validParticipants, level });
            }
            system.SetCurrentContractFactions(Faction.INVALID_UNSET, Faction.INVALID_UNSET);
            HashSet <int> Contracts = Traverse.Create(MapEncounterContractData).Field("Contracts").GetValue <HashSet <int> >();

            if (MapEncounterContractData == null || Contracts.Count == 0)
            {
                List <string> mapDiscardPile = Traverse.Create(Sim).Field("mapDiscardPile").GetValue <List <string> >();
                if (mapDiscardPile.Count > 0)
                {
                    mapDiscardPile.Clear();
                }
                else
                {
                    PersistentMapClient.Logger.Log(string.Format("[CONTRACT] Unable to find any valid contracts for available map pool. Alert designers.", new object[0]));
                }
            }
            GameContext gameContext = new GameContext(Sim.Context);

            gameContext.SetObject(GameContextObjectTagEnum.TargetStarSystem, system);


            Contract contract = (Contract)AccessTools.Method(typeof(SimGameState), "CreateProceduralContract").Invoke(Sim, new object[] { system, true, level, MapEncounterContractData, gameContext });

            Fields.prioGen = false;
            return(contract);
        }
        private static void FilterOnMapsWithEncountersWithValidContractRequirements(SimGameState simGameState, WeightedList <MapAndEncounters> activeMaps, List <Contract> currentContracts)
        {
            List <MapAndEncounters> mapsToRemove = new List <MapAndEncounters>();

            StarSystem system                = MissionControl.Instance.System;
            var        validParticipants     = AccessTools.Method(typeof(SimGameState), "GetValidParticipants").Invoke(simGameState, new object[] { system });
            MethodInfo GetValidFactionMethod = AccessTools.Method(typeof(SimGameState), "GetValidFaction");
            MethodInfo DoesContractMeetRequirementsMethod = AccessTools.Method(typeof(SimGameState), "DoesContractMeetRequirements");

            for (int i = 0; i < activeMaps.Count; i++)
            {
                MapAndEncounters level     = activeMaps[i];
                bool             removeMap = true;

                foreach (EncounterLayer_MDD encounterLayerMDD in level.Encounters)
                {
                    int contractTypeId = (int)encounterLayerMDD.ContractTypeRow.ContractTypeID;

                    // If the encounter ContractTypeID exists in the potential contracts list, continue
                    if (MissionControl.Instance.PotentialContracts.ContainsKey(contractTypeId))
                    {
                        // If the contract overrides in the potential contracts by ContractTypeID has a `DoesContractMeetRequirements` sucess, mark remove = false
                        List <ContractOverride> contractOverrides = MissionControl.Instance.PotentialContracts[contractTypeId];
                        // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] '{contractTypeId}' - contractOverrides count is: {contractOverrides.Count}");
                        for (int j = contractOverrides.Count; j > 0; j--)
                        {
                            ContractOverride contractOverride = contractOverrides[j - 1];
                            // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] '{contractTypeId}' - contractOverride is: {contractOverride.ID}");
                            // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] '{contractTypeId}' - validParticipants is: {validParticipants}");
                            bool doesContractHaveValidFactions = (bool)GetValidFactionMethod.Invoke(simGameState, new object[] { system, validParticipants, contractOverride.requirementList, null });
                            // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] '{contractTypeId}' - Contract '{contractOverride.ID}' has valid fations?: {doesContractHaveValidFactions}");
                            if (!doesContractHaveValidFactions)
                            {
                                // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] '{contractTypeId}' - Removing Contract '{contractOverride.ID}' from potential list");
                                contractOverrides.RemoveAt(j - 1);
                                continue;
                            }

                            bool doesContractMeetReqs = (bool)DoesContractMeetRequirementsMethod.Invoke(simGameState, new object[] { system, level, contractOverride });
                            if (doesContractMeetReqs)
                            {
                                // At least one contract override meets the requirements to prevent the infinite spinner so ignore this logic now and continue to the next map/encounter combo
                                // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] '{contractTypeId}' - Level '{level.Map.MapName}.{encounterLayerMDD.Name}' has at least one valid contract override");
                                removeMap = false;
                                break;
                            }
                        }
                    }
                }

                if (removeMap)
                {
                    // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] Level '{level.Map.MapName}' had no encounters with any valid contract overrides. Removing map.");
                    mapsToRemove.Add(level);
                }
            }

            // Remove maps that have no valid contracts due to failing requirements
            foreach (MapAndEncounters level in mapsToRemove)
            {
                // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] Attempting to remove Level '{level.Map.MapName}'");
                activeMaps.Remove(level);
            }

            // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] There are '{activeMaps.Count}' active maps/encounter combos to use. These are:");

            /*
             * for (int k = 0; k < activeMaps.Count; k++) {
             * MapAndEncounters level = activeMaps[k];
             * Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] - '{level.Map.MapName}' with '{level.Encounters.Length}' encounters");
             * foreach (EncounterLayer_MDD encounterLayerMDD in level.Encounters) {
             *  Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements]   - Encounter '{encounterLayerMDD.Name}'");
             * }
             * }
             */

            // If there are no more active maps, reset the biomes/maps list
            if (activeMaps.Count <= 0)
            {
                Main.Logger.LogWarning($"[FilterOnMapsWithEncountersWithValidContractRequirements] No valid map/encounter combinations. Clearing map discard pile. WARNING: MapEncounters unfiltered by MC being used. Potential for infinite loading issue. If you see this from an infinite load freeze - inform CWolf from Mission Control");
                List <string> mapDiscardPile = (List <string>)AccessTools.Field(typeof(SimGameState), "mapDiscardPile").GetValue(simGameState);
                mapDiscardPile.Clear();

                WeightedList <MapAndEncounters> playableMaps = (WeightedList <MapAndEncounters>)AccessTools.Method(typeof(SimGameState), "GetSinglePlayerProceduralPlayableMaps").Invoke(null, new object[] { system });
                IEnumerable <int> source = from map in playableMaps select map.Map.Weight;
                WeightedList <MapAndEncounters> weightedList = new WeightedList <MapAndEncounters>(WeightedListType.WeightedRandom, playableMaps.ToList(), source.ToList <int>(), 0);

                activeMaps.AddRange(weightedList);
            }
        }