internal static Contract GenerateContract(StarSystem system, int minDiff, int maxDiff, string employer = null, List <string> opFor = null, bool usingBreadcrumbs = false, bool includeOwnershipCheck = false) { min = minDiff; max = maxDiff; actualDifficulty = Globals.Rng.Next(min, max + 1); var difficultyRange = new SimGameState.ContractDifficultyRange(actualDifficulty, actualDifficulty, ContractDifficulty.Easy, ContractDifficulty.Easy); var potentialContracts = GetSinglePlayerProceduralContractOverrides(difficultyRange).ToDictionary(k => k.Key, v => v.Value); var playableMaps = GetSinglePlayerProceduralPlayableMaps(system, includeOwnershipCheck); var validParticipants = GetValidParticipants(system, employer, opFor); var source = playableMaps.Select(map => map.Map.Weight); var activeMaps = new WeightedList <MapAndEncounters>(WeightedListType.SimpleRandom, playableMaps.ToList(), source.ToList()); var next = activeMaps.GetNext(); LogDebug($"{system.Name} {difficultyRange.MinDifficulty}/{difficultyRange.MaxDifficulty} {potentialContracts.Count} {validParticipants.Count} {next._encounters.Count}"); var mapEncounterContractData = Globals.Sim.FillMapEncounterContractData(system, difficultyRange, potentialContracts, validParticipants, next); system.SetCurrentContractFactions(); var gameContext = new GameContext(Globals.Sim.Context); gameContext.SetObject(GameContextObjectTagEnum.TargetStarSystem, system); if (mapEncounterContractData.FlatContracts.rootList == null || mapEncounterContractData.FlatContracts.rootList.Count < 1) { loops++; LogDebug("Recursion..."); if (loops > 10) { loops = 0; return(null); } return(GenerateContract(system, minDiff, maxDiff, employer, opFor, usingBreadcrumbs, includeOwnershipCheck)); } return(CreateProceduralContract(system, usingBreadcrumbs, next, mapEncounterContractData, gameContext)); }
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; }
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); }
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]); }
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; }
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); }