private static bool CreatePotentialContract( StarSystem system, SimGameState.ContractDifficultyRange diffRange, ContractOverride contractOvr, Dictionary <string, WeightedList <SimGameState.ContractParticipants> > validTargets, MapAndEncounters level, int encounterContractTypeID, out SimGameState.PotentialContract returnContract) { returnContract = new SimGameState.PotentialContract(); if (Globals.Sim.GetValidFaction(system, validTargets, contractOvr.requirementList, out var chosenContractParticipants)) { system.SetCurrentContractFactions(chosenContractParticipants.Employer, chosenContractParticipants.Target); if (Globals.Sim.DoesContractMeetRequirements(system, level, contractOvr)) { returnContract = new SimGameState.PotentialContract { contractOverride = contractOvr, difficulty = actualDifficulty, employer = chosenContractParticipants.Employer, target = chosenContractParticipants.Target, employerAlly = chosenContractParticipants.EmployersAlly, targetAlly = chosenContractParticipants.TargetsAlly, NeutralToAll = chosenContractParticipants.NeutralToAll, HostileToAll = chosenContractParticipants.HostileToAll }; return(true); } } return(false); }
public static bool Prefix(ref List<MapAndEncounters> __result, MetadataDatabase mdd, int contractTypeID, bool includeUnpublishedContractTypes) { if (ModState.IsSystemActionPatch == null) { return true; } if (ModState.SpecMapID != null) { ModState.IgnoreBiomes = "TRUE"; } List<MapAndEncounters> result = new List<MapAndEncounters>(); string text = "SELECT m.*, el.* FROM EncounterLayer AS el "; text += "INNER JOIN ContractType as ct ON el.ContractTypeId = ct.ContractTypeId "; text += "INNER JOIN Map as m ON el.MapID = m.MapID "; text += "INNER JOIN BiomeSkin as bs ON m.BiomeSkinID = bs.BiomeSkinID "; text += "LEFT JOIN ContentPackItem as cpi ON m.MapID = cpi.ContentPackItemID "; text += "LEFT JOIN ContentPack as cp ON cpi.ContentPackID = cp.ContentPackID "; text += "WHERE el.IncludeInBuild = 1 AND m.IncludeInBuild = 1 AND ct.ContractTypeID = @ContractTypeID "; text += "AND (cp.IsOwned=1 OR cp.IsOwned IS NULL) "; if (ModState.IgnoreBiomes != "TRUE") { text += "AND bs.BiomeSkinID IN @Name "; } if (ModState.SpecMapID != null) { text += "AND m.MapID = @MapID "; } if (!includeUnpublishedContractTypes) { text += "AND ct.IsPublished = 1 "; } text += "ORDER BY m.FriendlyName"; mdd.Query<Map_MDD, EncounterLayer_MDD, MapAndEncounters>(text, delegate (Map_MDD m, EncounterLayer_MDD e) { MapAndEncounters mapAndEncounters = result.Find((MapAndEncounters x) => x.Map.MapID == m.MapID); if (mapAndEncounters == null) { mapAndEncounters = new MapAndEncounters(m); result.Add(mapAndEncounters); } mapAndEncounters.AddEncounter(e); return mapAndEncounters; }, new { ContractTypeID = contractTypeID, Name = ModState.AddContractBiomes.ToArray(), MapID = ModState.SpecMapID }, null, true, "MapID", null, null); Utilities.Shuffle(result); __result = result; return false; }
private static void Prefix(SimGameState __instance, ref SimGameResultAction action) { try { if (action.Type == SimGameResultAction.ActionType.Flashpoint_AddContract || action.Type == SimGameResultAction.ActionType.Flashpoint_StartContract) { Logger.LogLine("FP name = " + action.additionalValues[2]); SimGameState simulation = UnityGameInstance.BattleTechGame.Simulation; if (action.additionalValues[3].Equals("{RANDOM}")) { Array values = Enum.GetValues(typeof(Faction)); Random random = new Random(); Faction randomFaction; do { randomFaction = (Faction)values.GetValue(random.Next(values.Length)); }while (Helper.IsExcluded(randomFaction)); action.additionalValues[3] = randomFaction.ToString(); } else if (action.additionalValues[3].Equals("{PLANETOWNER}")) { action.additionalValues[3] = simulation.ActiveFlashpoint.CurSystem.Owner.ToString(); } if (action.additionalValues[4].Equals("{RANDOM}")) { Array values = Enum.GetValues(typeof(Faction)); Random random = new Random(); Faction randomFaction; do { randomFaction = (Faction)values.GetValue(random.Next(values.Length)); }while (Helper.IsExcluded(randomFaction)); action.additionalValues[4] = randomFaction.ToString(); } else if (action.additionalValues[4].Equals("{PLANETOWNER}")) { action.additionalValues[4] = simulation.ActiveFlashpoint.CurSystem.Owner.ToString(); } if (string.IsNullOrEmpty(action.value)) { ContractOverride contractOverride = simulation.DataManager.ContractOverrides.Get(action.additionalValues[2]).Copy(); ContractType contractType = contractOverride.contractType; List <MapAndEncounters> releasedMapsAndEncountersByContractTypeAndOwnership = MetadataDatabase.Instance.GetReleasedMapsAndEncountersByContractTypeAndOwnership(new ContractType[] { contractType }); releasedMapsAndEncountersByContractTypeAndOwnership.Shuffle(); MapAndEncounters mapAndEncounters = releasedMapsAndEncountersByContractTypeAndOwnership[0]; action.value = mapAndEncounters.Map.MapName; } } } catch (Exception e) { Logger.LogError(e); } }
static bool Prefix(MapModule __instance, ref MapAndEncounters __result) { if (UiManager.Instance.ClickedQuickSkirmish) { Main.Logger.Log($"[MapModuleSelectedMapPatch Prefix] Patching SelectedMap"); if (mapAndEncounter == null) { List <MapAndEncounters> mapAndEncounters = MetadataDatabase.Instance.GetReleasedMapsAndEncountersByContractTypeAndOwnership((int)ContractType.ArenaSkirmish, false); int index = UnityEngine.Random.Range(0, mapAndEncounters.Count); mapAndEncounter = mapAndEncounters[index]; } __result = mapAndEncounter; return(false); } return(true); }
private static Contract CreateProceduralContract( StarSystem system, bool usingBreadcrumbs, MapAndEncounters level, SimGameState.MapEncounterContractData MapEncounterContractData, GameContext gameContext) { var flatContracts = MapEncounterContractData.FlatContracts; Globals.Sim.FilterContracts(flatContracts); var next = flatContracts.GetNext(); var id = next.contractOverride.ContractTypeValue.ID; MapEncounterContractData.Encounters[id].Shuffle(); var encounterLayerGuid = MapEncounterContractData.Encounters[id][0].EncounterLayerGUID; var contractOverride = next.contractOverride; var employer = next.employer; var target = next.target; var employerAlly = next.employerAlly; var targetAlly = next.targetAlly; var neutralToAll = next.NeutralToAll; var hostileToAll = next.HostileToAll; var contract = usingBreadcrumbs ? CreateTravelContract( level.Map.MapName, level.Map.MapPath, encounterLayerGuid, next.contractOverride.ContractTypeValue, contractOverride, gameContext, employer, target, targetAlly, employerAlly, neutralToAll, hostileToAll, false, actualDifficulty) : new Contract( level.Map.MapName, level.Map.MapPath, encounterLayerGuid, next.contractOverride.ContractTypeValue, Globals.Sim.BattleTechGame, contractOverride, gameContext, true, actualDifficulty); Globals.Sim.mapDiscardPile.Add(level.Map.MapID); Globals.Sim.contractDiscardPile.Add(contractOverride.ID); PrepContract(contract, employer, employerAlly, target, targetAlly, neutralToAll, hostileToAll, level.Map.BiomeSkinEntry.BiomeSkin, contract.Override.travelSeed, system); return(contract); }
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 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}'"); * } * } */ }
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); }
public static Contract GetValidContractForContractDataAndSystem(this SimGameState simGameState, SimGameState.AddContractData addContractData, StarSystem starSystem) { Logger.Debug($"[SimGameStateExtensions_GetValidContractForContractDataAndSystem] (addContractData) ContractName: {addContractData.ContractName}, Target: {addContractData.Target}, Employer: {addContractData.Employer}, TargetSystem: {addContractData.TargetSystem}, TargetAlly: {addContractData.TargetAlly}"); Logger.Debug($"[SimGameStateExtensions_GetValidContractForContractDataAndSystem] starSystem: {starSystem.Name}"); Logger.Debug($"[SimGameStateExtensions_GetValidContractForContractDataAndSystem] starSystem.Def.SupportedBiomes: {String.Join(", ", starSystem.Def.SupportedBiomes.Select(sb => sb.ToString()))}"); if (starSystem == null) { throw new Exception("starSystem is null"); } GameInstance gameInstance = simGameState.BattleTechGame; DataManager dataManager = simGameState.BattleTechGame.DataManager; GameContext gameContext = new GameContext(simGameState.Context); gameContext.SetObject(GameContextObjectTagEnum.TargetStarSystem, starSystem); ContractOverride contractOverride = dataManager.ContractOverrides.Get(addContractData.ContractName).Copy(); ContractTypeValue contractTypeValue = contractOverride.ContractTypeValue; FactionValue employer = string.IsNullOrEmpty(addContractData.Employer) ? FactionEnumeration.GetInvalidUnsetFactionValue() : FactionEnumeration.GetFactionByName(addContractData.Employer); FactionValue employersAlly = string.IsNullOrEmpty(addContractData.EmployerAlly) ? FactionEnumeration.GetInvalidUnsetFactionValue() : FactionEnumeration.GetFactionByName(addContractData.EmployerAlly); FactionValue target = string.IsNullOrEmpty(addContractData.Target) ? FactionEnumeration.GetInvalidUnsetFactionValue() : FactionEnumeration.GetFactionByName(addContractData.Target); FactionValue targetsAlly = string.IsNullOrEmpty(addContractData.TargetAlly) ? FactionEnumeration.GetInvalidUnsetFactionValue() : FactionEnumeration.GetFactionByName(addContractData.TargetAlly); FactionValue neutralToAll = string.IsNullOrEmpty(addContractData.NeutralToAll) ? FactionEnumeration.GetInvalidUnsetFactionValue() : FactionEnumeration.GetFactionByName(addContractData.NeutralToAll); FactionValue hostileToAll = string.IsNullOrEmpty(addContractData.HostileToAll) ? FactionEnumeration.GetInvalidUnsetFactionValue() : FactionEnumeration.GetFactionByName(addContractData.HostileToAll); if (employer.IsInvalidUnset || target.IsInvalidUnset) { throw new Exception("ContractData didn't have a valid employerValue and/or targetValue"); } // Get all valid encounters (all contract types) for the requested system List <MapAndEncounters> allValidMapAndEncountersForCurrentSystem = MetadataDatabase.Instance.GetReleasedMapsAndEncountersBySinglePlayerProceduralContractTypeAndTags(starSystem.Def.MapRequiredTags, starSystem.Def.MapExcludedTags, starSystem.Def.SupportedBiomes, true); // Remove all items that dont have an encounter layer for the requested contract type allValidMapAndEncountersForCurrentSystem.RemoveAll(MapAndEncounters => MapAndEncounters.Encounters.All(el => el.ContractTypeValue != contractTypeValue)); // Debug foreach (MapAndEncounters mae in allValidMapAndEncountersForCurrentSystem) { Logger.Info($"allValidMapAndEncountersForCurrentSystem (Map): {mae.Map.FriendlyName}"); Logger.Info($"allValidMapAndEncountersForCurrentSystem (Encounters): {String.Join(", ", Array.ConvertAll(mae.Encounters, item => item.FriendlyName))}"); Logger.Info($"-"); } // @ToDo: Remove Map "mapGeneral_taigaRiver_iTnd" for ContractTypeValue "Rescue" (Broken in Vanilla, no buildings at target zones) //if (contractTypeValue.FriendlyName == "Rescue") //{ // allValidMapAndEncountersForCurrentSystem.RemoveAll(MapAndEncounters => MapAndEncounters.Map.MapID == "mapGeneral_taigaRiver_iTnd"); //} // Get a random item Random random = new Random(); MapAndEncounters mapAndEncounters = allValidMapAndEncountersForCurrentSystem.OrderBy(MapAndEncounters => random.NextDouble()).First(); // Debug Logger.Info($"chosenMapAndEncounters (Map): {mapAndEncounters.Map.FriendlyName}"); Logger.Info($"chosenMapAndEncounters: {String.Join(", ", Array.ConvertAll(mapAndEncounters.Encounters, item => item.FriendlyName))}"); // Get the matching encounter layers List <EncounterLayer_MDD> encounterLayers = new List <EncounterLayer_MDD>(); foreach (EncounterLayer_MDD encounterLayer in mapAndEncounters.Encounters) { if (encounterLayer.ContractTypeRow.ContractTypeID == (long)contractTypeValue.ID) { encounterLayers.Add(encounterLayer); } } if (encounterLayers.Count <= 0) { throw new Exception("Map does not contain any encounters of type: " + contractTypeValue.Name); } // Debug foreach (EncounterLayer_MDD elMdd in encounterLayers) { Logger.Info($"chosenEncounter (Name): {elMdd.FriendlyName}"); Logger.Info($"chosenEncounter (ContractTypeValue): {elMdd.ContractTypeValue}"); } // Get GUID of a random valid encounter layer string encounterLayerGUID = encounterLayers[simGameState.NetworkRandom.Int(0, encounterLayers.Count)].EncounterLayerGUID; // Check if we need to travel if (addContractData.IsGlobal) { Logger.Debug($"[SimGameStateExtensions_GetValidContractForContractDataAndSystem] Custom handling of travel contracts isn't implemented. Falling back to default handling"); // Fallback to relevant part of default vanilla method simGameState.AddContract(addContractData); //Contract travelContract = simGameState.CreateTravelContract(mapAndEncounters.Map.MapName, mapAndEncounters.Map.MapPath, encounterLayerGUID, contractTypeValue, contractOverride, gameContext, employer, employersAlly, target, targetsAlly, neutralToAll, hostileToAll, addContractData.IsGlobal); //simGameState.PrepContract(travelContract, employer, employersAlly, target, targetsAlly, neutralToAll, hostileToAll, mapAndEncounters.Map.BiomeSkinEntry.BiomeSkin, travelContract.Override.travelSeed, starSystem); //simGameState.GlobalContracts.Add(travelContract); //return travelContract; } Contract contract = new Contract(mapAndEncounters.Map.MapName, mapAndEncounters.Map.MapPath, encounterLayerGUID, contractTypeValue, gameInstance, contractOverride, gameContext, true, contractOverride.difficulty, 0, null); Logger.Debug($"[SimGameStateExtensions_GetValidContractForContractDataAndSystem] Contract: {contract.Override.ID}({contractTypeValue}), Difficulty: {contract.Difficulty}, CanNegotiate: {contract.CanNegotiate}, Biome: {mapAndEncounters.Map.BiomeSkinEntry.Name}, Map: {mapAndEncounters.Map.MapName}"); simGameState.PrepContract(contract, employer, employersAlly, target, targetsAlly, neutralToAll, hostileToAll, mapAndEncounters.Map.BiomeSkinEntry.BiomeSkin, 0, starSystem); // Set negotiations if (!contract.CanNegotiate) { contract.SetNegotiatedValues(contract.Override.negotiatedSalary, contract.Override.negotiatedSalvage); } 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]; List <int> checkedContractTypeIds = new List <int>(); bool removeMap = true; // Main.LogDebug($""); // Main.LogDebug($"--- PROCESSING MAP '{level.Map.MapName}' ---"); // Main.LogDebug($""); foreach (EncounterLayer_MDD encounterLayerMDD in level.Encounters) { int contractTypeId = (int)encounterLayerMDD.ContractTypeRow.ContractTypeID; // Main.LogDebug($""); // Main.LogDebug($"--- PROCESSING CONTRACT TYPE {contractTypeId} ---"); // Main.LogDebug($""); // If the encounter ContractTypeID exists in the potential contracts list, continue if (MissionControl.Instance.PotentialContracts.ContainsKey(contractTypeId) && !checkedContractTypeIds.Contains(contractTypeId)) { checkedContractTypeIds.Add(contractTypeId); // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] Contract Type '{encounterLayerMDD.ContractTypeRow.Name}' is within potential contracts."); // If the contract overrides in the potential contracts by ContractTypeID has a `DoesContractMeetRequirements` success, mark remove = false List <ContractOverride> contractOverrides = MissionControl.Instance.PotentialContracts[contractTypeId]; // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] Contract Type '{encounterLayerMDD.ContractTypeRow.Name}' - There are '{contractOverrides.Count}' ContractOverrides (contracts)"); for (int j = contractOverrides.Count; j > 0; j--) { ContractOverride contractOverride = contractOverrides[j - 1]; // Main.LogDebug(""); // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] Encounter '{encounterLayerMDD.Name}' Contract Type '{encounterLayerMDD.ContractTypeRow.Name}' - ContractOverride is: {contractOverride.ID}"); // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] Contract Type '{encounterLayerMDD.ContractTypeRow.Name}' - ValidParticipants is: {validParticipants}. Cannot extract factions/participants due to BT intern restrictions."); bool doesContractHaveValidFactions = (bool)GetValidFactionMethod.Invoke(simGameState, new object[] { system, validParticipants, contractOverride.requirementList, null }); // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] Contract Type '{encounterLayerMDD.ContractTypeRow.Name}' - Contract '{contractOverride.ID}' has valid fations?: {doesContractHaveValidFactions}"); if (!doesContractHaveValidFactions) { // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] Contract Type '{encounterLayerMDD.ContractTypeRow.Name}' - Removing Contract '{contractOverride.ID}' from potential list due to not having any valid factions/participants on the contract."); contractOverrides.RemoveAt(j - 1); continue; } bool doesContractMeetReqs = (bool)DoesContractMeetRequirementsMethod.Invoke(simGameState, new object[] { system, level, contractOverride }); if (!doesContractMeetReqs) { // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] Contract Type '{encounterLayerMDD.ContractTypeRow.Name}' - Contract '{contractOverride.ID}' FAILS requirements with level '{level.Map.MapName}.{encounterLayerMDD.Name}'. Removing Contract '{contractOverride.ID}' from potential list due to not having met requirements on the contract."); contractOverrides.RemoveAt(j - 1); continue; } // 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] Contract Type '{encounterLayerMDD.ContractTypeRow.Name}' - Contract '{contractOverride.ID}' MEETS requirements with level '{level.Map.MapName}.{encounterLayerMDD.Name}' and has at least one valid contract override. Will keep as a possible 'active map' for selection on."); removeMap = false; } } else if (checkedContractTypeIds.Contains(contractTypeId)) { // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] Skipping checks for Encounter '{encounterLayerMDD.Name}' because already checked Contract Type '{encounterLayerMDD.ContractTypeRow.Name}'"); } else { // Main.LogDebug($"[FilterOnMapsWithEncountersWithValidContractRequirements] Contract Type '{encounterLayerMDD.ContractTypeRow.Name}' - Doesn't exist in the potential contracts."); } } 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}'"); } } }
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); } }