/* * Future proofed method to allow for string custom contract type names * instead of relying only on the enum values */ public void SetContractType(ContractTypeValue contractTypeValue) { if (AllowMissionControl()) { List <Type> encounters = null; string type = contractTypeValue.Name; CurrentContractType = type; if (AvailableEncounters.ContainsKey(type)) { encounters = AvailableEncounters[type]; int index = UnityEngine.Random.Range(0, encounters.Count); Type selectedEncounter = encounters[index]; Main.Logger.Log($"[MissionControl] Setting contract type to '{type}' and using Encounter Rule of '{selectedEncounter.Name}'"); SetEncounterRule(selectedEncounter); } else { Main.Logger.Log($"[MissionControl] Unknown contract / encounter type of '{type}'. Using fallback ruleset."); SetEncounterRule(typeof(FallbackEncounterRules)); } IsContractValid = true; } else { Main.Logger.Log($"[MissionControl] Mission Control is not allowed to run. Possibly a story mission or flashpoint contract."); EncounterRules = null; EncounterRulesName = null; } }
/* * Future proofed method to allow for string custom contract type names * instead of relying only on the enum values */ public bool SetContractType(ContractTypeValue contractTypeValue) { List <Type> encounters = null; string type = contractTypeValue.Name; CurrentContractType = type; if (AvailableEncounters.ContainsKey(type)) { encounters = AvailableEncounters[type]; } else { Main.Logger.LogError($"[MissionControl] Unknown contract / encounter type of '{type}'"); EncounterRules = null; return(false); } int index = UnityEngine.Random.Range(0, encounters.Count); Type selectedEncounter = encounters[index]; Main.Logger.Log($"[MissionControl] Setting contract type to '{type}' and using Encounter Rule of '{selectedEncounter.Name}'"); SetEncounterRule(selectedEncounter); IsContractValid = true; return(true); }
private void AddContractType(MetadataDatabase mdd, ContractType_MDD contractTypeMDD) { ContractTypeValue contractTypeValue = ContractTypeEnumeration.Instance.CreateEnumValueFromDatabase(mdd, contractTypeMDD.EnumValueRow); if (!AvailableCustomContractTypes.ContainsKey(contractTypeValue.Name)) { AvailableCustomContractTypes.Add(contractTypeValue.Name, new List <ContractTypeValue>()); } Main.LogDebug($"[DataManager.AddContractType] Adding custom contract type: {contractTypeValue.Name}"); AvailableCustomContractTypes[contractTypeValue.Name].Add(contractTypeValue); }
public static Contract CreateTravelContract( string mapName, string mapPath, string encounterGuid, ContractTypeValue contractTypeValue, ContractOverride ovr, GameContext context, FactionValue employer, FactionValue target, FactionValue targetsAlly, FactionValue employersAlly, FactionValue neutralToAll, FactionValue hostileToAll, bool isGlobal, int difficulty) { LogDebug("CreateTravelContract"); var starSystem = context.GetObject(GameContextObjectTagEnum.TargetStarSystem) as StarSystem; var seed = Globals.Rng.Next(0, int.MaxValue); ovr.FullRehydrate(); var contractOverride = new ContractOverride(); contractOverride.CopyContractTypeData(ovr); contractOverride.contractName = ovr.contractName; contractOverride.difficulty = ovr.difficulty; contractOverride.longDescription = ovr.longDescription; contractOverride.shortDescription = ovr.shortDescription; contractOverride.travelOnly = true; contractOverride.useTravelCostPenalty = !isGlobal; contractOverride.disableNegotations = ovr.disableNegotations; contractOverride.disableAfterAction = ovr.disableAfterAction; contractOverride.salvagePotential = ovr.salvagePotential; contractOverride.contractRewardOverride = ovr.contractRewardOverride; contractOverride.travelSeed = seed; contractOverride.difficultyUIModifier = ovr.difficultyUIModifier; var simGameEventResult = new SimGameEventResult(); var gameResultAction = new SimGameResultAction(); const int length = 14; gameResultAction.Type = SimGameResultAction.ActionType.System_StartNonProceduralContract; gameResultAction.value = mapName; gameResultAction.additionalValues = new string[length]; gameResultAction.additionalValues[0] = starSystem.ID; gameResultAction.additionalValues[1] = mapPath; gameResultAction.additionalValues[2] = encounterGuid; gameResultAction.additionalValues[3] = ovr.ID; gameResultAction.additionalValues[4] = isGlobal.ToString(); gameResultAction.additionalValues[5] = employer.Name; gameResultAction.additionalValues[6] = target.Name; gameResultAction.additionalValues[7] = difficulty.ToString(); gameResultAction.additionalValues[8] = "true"; gameResultAction.additionalValues[9] = targetsAlly.Name; gameResultAction.additionalValues[10] = seed.ToString(); gameResultAction.additionalValues[11] = employersAlly.Name; gameResultAction.additionalValues[12] = neutralToAll.Name; gameResultAction.additionalValues[13] = hostileToAll.Name; simGameEventResult.Actions = new SimGameResultAction[1]; simGameEventResult.Actions[0] = gameResultAction; contractOverride.OnContractSuccessResults.Add(simGameEventResult); return(new Contract(mapName, mapPath, encounterGuid, contractTypeValue, Globals.Sim.BattleTechGame, contractOverride, context, true, actualDifficulty) { Override = { travelSeed = seed } }); }
public static bool Prefix(ref bool __result, SimGameResultAction action, object additionalObject) { try { SimGameState simulation = UnityGameInstance.BattleTechGame.Simulation; if (simulation == null || action.Type != SimGameResultAction.ActionType.System_AddContract) { return(true); } // In vanilla the SimGameResultAction.ActionType.System_AddContract is only used for travel-contracts (breadcrumbs) // I use it to add custom contracts by custom events which need to have negotiations disabled as they are "self-employed opportunity contracts" SimGameState.AddContractData addContractData = simulation.ParseContractActionData(action.value, action.additionalValues); ContractOverride contractOverride = simulation.DataManager.ContractOverrides.Get(addContractData.ContractName).Copy(); ContractTypeValue contractTypeValue = contractOverride.ContractTypeValue; // Call original method if contract is a breadcrumb (used by campaign a lot) if (contractTypeValue.IsTravelOnly) { return(true); } // Custom handling else { // Validate target system and enrich contractData StarSystem targetSystem; Logger.Debug($"[SimGameState_ApplyEventAction_PREFIX] addContractData.TargetSystem: {addContractData.TargetSystem}"); if (!string.IsNullOrEmpty(addContractData.TargetSystem)) { string validatedSystemString = simulation.GetValidatedSystemString(addContractData.TargetSystem); addContractData.IsGlobal = validatedSystemString != simulation.CurSystem.ID; if (simulation.GetSystemById(validatedSystemString) != null) { targetSystem = simulation.GetSystemById(validatedSystemString); } else { throw new Exception("Couldn't find StarSystem for: " + validatedSystemString); } } else { targetSystem = simulation.CurSystem; } Logger.Debug($"[SimGameState_ApplyEventAction_PREFIX] targetSystem.ID: {targetSystem.ID}"); // Internal helper method IEnumerator InjectAdditionalContractRoutine() { while (!targetSystem.InitialContractsFetched) { yield return(new WaitForSeconds(0.2f)); } InjectAdditionalContract(); yield break; } // Internal helper method void InjectAdditionalContract(bool refresh = true) { // Get the contract Contract contract = simulation.GetValidContractForContractDataAndSystem(addContractData, targetSystem); targetSystem.SystemContracts.Add(contract); if (refresh) { SGContractsWidget ___contractsWidget = (SGContractsWidget)AccessTools.Field(typeof(SGRoomController_CmdCenter), "contractsWidget").GetValue(simulation.RoomManager.CmdCenterRoom); List <Contract> allContracts = simulation.GetAllCurrentlySelectableContracts(true); ContractDisplayStyle?___contractDisplayAutoSelect = Traverse.Create(___contractsWidget).Field("contractDisplayAutoSelect").GetValue <ContractDisplayStyle?>(); ___contractsWidget.ListContracts(allContracts, ___contractDisplayAutoSelect); } } if (simulation.TimeMoving) { simulation.PauseTimer(); simulation.StopPlayMode(); } // Need to check this as the initial contract fetching routine clears all existing contracts Logger.Debug($"[SimGameState_ApplyEventAction_PREFIX] targetSystem.InitialContractsFetched: {targetSystem.InitialContractsFetched}"); if (!targetSystem.InitialContractsFetched) { SceneSingletonBehavior <UnityGameInstance> .Instance.StartCoroutine(InjectAdditionalContractRoutine()); return(false); } else { InjectAdditionalContract(false); // Skip original method return(false); } } } catch (Exception e) { Logger.Error(e); return(true); } }
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); }