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