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; }