static void Postfix(SGDebugEventWidget __instance, SGDebugEventWidget.DebugType ___curType, SimGameState ___Sim) { try { /*public enum DebugType * { * All = -1, * Insert_Event, * Update_Tags, * Update_Stats, * Add_Mech, * Add_Funds, * Add_Pilot_Exp * }*/ if (___curType == SGDebugEventWidget.DebugType.Add_Funds) { ___Sim.CompanyStats.AddStatistic <int>("BtSaveEdit.FundsAdded", 1); Fields.cheater = true; SimGameInterruptManager interruptQueue = (SimGameInterruptManager)AccessTools.Field(typeof(SimGameState), "interruptQueue").GetValue(__instance); interruptQueue.QueueGenericPopup_NonImmediate("Save Edited!", "You have edited your save file in a way that disqualifies you from the war game, your missions wont be influenceing the war. All other fucntions work as normally.", true); } if (___curType == SGDebugEventWidget.DebugType.Add_Mech) { ___Sim.CompanyStats.AddStatistic <int>("BtSaveEdit.MechsAdded", 1); Fields.cheater = true; SimGameInterruptManager interruptQueue = (SimGameInterruptManager)AccessTools.Field(typeof(SimGameState), "interruptQueue").GetValue(__instance); interruptQueue.QueueGenericPopup_NonImmediate("Save Edited!", "You have edited your save file in a way that disqualifies you from the war game, your missions wont be influenceing the war. All other fucntions work as normally.", true); } } catch (Exception e) { PersistentMapClient.Logger.LogError(e); } }
// Needs to be prefix as SimGameState.CompletedContract is nulled in original method public static void Prefix(SimGameState __instance, SimGameInterruptManager ___interruptQueue) { try { Contract completedContract = __instance.CompletedContract; bool SimGameStateCompanyTagsHasAnyTrigger = __instance.CompanyTags.Any(tag => tag.Contains("triggerReward-")); Logger.Debug($"[SimGameState_ResolveCompleteContract_PREFIX] __instance.CompanyTags: {String.Join(", ", __instance.CompanyTags.ToArray())}"); Logger.Debug($"[SimGameState_ResolveCompleteContract_PREFIX] SimGameStateCompanyTagsHasAnyTrigger: {SimGameStateCompanyTagsHasAnyTrigger}"); if (completedContract.IsOpportunityMission() && SimGameStateCompanyTagsHasAnyTrigger) { foreach (string tag in __instance.CompanyTags.ToArray()) { if (tag.Contains("triggerReward-")) { Logger.Debug($"[SimGameState_ResolveCompleteContract_PREFIX] tag: {tag}"); __instance.SetTimeMoving(false, true); string itemCollectionId = tag.Replace("triggerReward-", ""); Logger.Debug($"[SimGameState_ResolveCompleteContract_PREFIX] itemCollectionId: {itemCollectionId}"); ___interruptQueue.QueueRewardsPopup(itemCollectionId); __instance.CompanyTags.Remove(tag); } } } Logger.Debug($"[SimGameState_ResolveCompleteContract_PREFIX] __instance.CompanyTags: {String.Join(", ", __instance.CompanyTags.ToArray())}"); } catch (Exception e) { Logger.Error(e); } }
public void launchMission() { Contract contract = ContractManager.getNewProceduralContract(location, employer, target); string title = Strings.T("Flareup Mission"); string primaryButtonText = Strings.T("Launch mission"); string cancel = Strings.T("Pass"); string message = $"{employer.FactionDef.Name.Replace("the ", "The ")} has a mission for us, Commander: {contract.Name}. Details will be provided en-route, but it seems to be a {contract.ContractTypeValue.FriendlyName.ToLower()} mission. Sounds urgent."; WIIC.modLog.Debug?.Write(message); SimGameInterruptManager queue = WIIC.sim.GetInterruptQueue(); queue.QueuePauseNotification(title, message, WIIC.sim.GetCrewPortrait(SimGameCrew.Crew_Sumire), string.Empty, delegate { try { WIIC.modLog.Info?.Write($"Accepted {type} mission {contract.Name}."); currentContractName = contract.Name; currentContractForceLoss = Utilities.rng.Next(WIIC.settings.combatForceLossMin, WIIC.settings.combatForceLossMax); WIIC.sim.RoomManager.ForceShipRoomChangeOfRoom(DropshipLocation.CMD_CENTER); WIIC.sim.ForceTakeContract(contract, false); } catch (Exception e) { WIIC.modLog.Error?.Write(e); } }, primaryButtonText, delegate { WIIC.modLog.Info?.Write($"Passed on {type} mission."); }, cancel); if (!queue.IsOpen) { queue.DisplayIfAvailable(); } }
static IEnumerator WaitThenQueueConversation(SimGameState simulation, Conversation conversation, string groupHeader, string groupSubHeader) { yield return(new WaitForSeconds(1)); SimGameInterruptManager interruptManager = (SimGameInterruptManager)ReflectionHelper.GetPrivateField(simulation, "interruptQueue"); interruptManager.QueueConversation(conversation, groupHeader, groupSubHeader, null, true); }
static void Postfix(Contract __instance, BattleTech.MissionResult result) { try { if (!__instance.IsFlashpointContract) { GameInstance game = LazySingletonBehavior <UnityGameInstance> .Instance.Game; if (game.Simulation.IsFactionAlly(__instance.Override.employerTeam.faction)) { if (Fields.cheater) { PersistentMapClient.Logger.Log("cheated save, skipping war upload"); return; } if (Fields.skipmission) { Fields.skipmission = false; SimGameInterruptManager interruptQueue = (SimGameInterruptManager)AccessTools.Field(typeof(SimGameState), "interruptQueue").GetValue(game.Simulation); interruptQueue.QueueGenericPopup_NonImmediate("Invalid Mission!", "Something went wrong with your mission, result not uploaded.", true); return; } bool updated = false; StarSystem system = game.Simulation.StarSystems.Find(x => x.ID == __instance.TargetSystem); foreach (StarSystem potential in game.Simulation.StarSystems) { if (Helper.IsCapital(system, __instance.Override.employerTeam.faction) || (!potential.Name.Equals(system.Name) && potential.Owner == __instance.Override.employerTeam.faction && Helper.GetDistanceInLY(potential.Position.x, potential.Position.y, system.Position.x, system.Position.y) <= game.Simulation.Constants.Travel.MaxJumpDistance)) { int planetSupport = Helper.CalculatePlanetSupport(game.Simulation, system, __instance.Override.employerTeam.faction, __instance.Override.targetTeam.faction); float num8 = (float)__instance.GetNegotiableReputationBaseValue(game.Simulation.Constants) * __instance.PercentageContractReputation; float num9 = Convert.ToSingle(__instance.GameContext.GetObject(GameContextObjectTagEnum.ContractBonusEmployerReputation)); float num10 = (float)__instance.GetBaseReputationValue(game.Simulation.Constants); float num11 = num8 + num9 + num10; int repchange = Mathf.RoundToInt(num11); PersistentMapAPI.MissionResult mresult = new PersistentMapAPI.MissionResult(__instance.Override.employerTeam.faction, __instance.Override.targetTeam.faction, result, system.Name, __instance.Difficulty, repchange, planetSupport); bool postSuccessfull = Web.PostMissionResult(mresult, game.Simulation.Player1sMercUnitHeraldryDef.Description.Name); if (!postSuccessfull) { SimGameInterruptManager interruptQueue = (SimGameInterruptManager)AccessTools.Field(typeof(SimGameState), "interruptQueue").GetValue(game.Simulation); interruptQueue.QueueGenericPopup_NonImmediate("Connection Failure", "Result could not be transfered", true); } updated = true; break; } } if (!updated) { SimGameInterruptManager interruptQueue = (SimGameInterruptManager)AccessTools.Field(typeof(SimGameState), "interruptQueue").GetValue(game.Simulation); interruptQueue.QueueGenericPopup_NonImmediate("You are surrounded!", "There is no more neighbor system in your factions control, so you didnt earn any influence here.", true); } } } return; } catch (Exception e) { PersistentMapClient.Logger.LogError(e); } }
static bool Prefix(SimGameState __instance, SimGameInterruptManager ___interruptQueue) { try { ___interruptQueue.QueuePauseNotification("Difficult Mission", "Careful, Commander. This drop looks like it might require more firepower than that.", __instance.GetCrewPortrait(SimGameCrew.Crew_Darius), string.Empty, new Action(__instance.RoomManager.CmdCenterRoom.lanceConfigBG.LC.ContinueConfirmClicked), "CONFIRM", null, "BACK"); return(false); } catch (Exception e) { Logger.LogError(e); return(true); } }
static void Postfix(SimGameState __instance, int timeLapse, SimGameInterruptManager ___interruptQueue, SimGameEventTracker ___companyEventTracker, SimGameEventTracker ___mechWarriorEventTracker, SimGameEventTracker ___deadEventTracker, SimGameEventTracker ___moraleEventTracker) { Mod.Log.Debug?.Write($"OnDayPassed called with timeLapse: {timeLapse}"); // Only check for events if another event isn't firing, and we're in orbit around a system if (!___interruptQueue.IsOpen && __instance.TravelState == SimGameTravelStatus.IN_SYSTEM) { foreach (Pilot pilot in __instance.PilotRoster) { CrewDetails details = ModState.GetCrewDetails(pilot.pilotDef); if (details.ExpirationDay <= __instance.DaysPassed) { Mod.Log.Debug?.Write($"CONTRACT FOR PILOT: {pilot.Name} HAS ELAPSED, FIRING EVENT"); ModState.ExpiredContracts.Enqueue((pilot, details)); } } if (ModState.ExpiredContracts.Count > 0) { // Fire the first event, if there are more they will be fired from OnEventDismissed{ Mod.Log.Info?.Write($"Contract expiration event fired."); (Pilot Pilot, CrewDetails Details)expired = ModState.ExpiredContracts.Peek(); SimGameEventDef newEvent = EventHelper.ModifyContractExpirationEventForPilot(expired.Pilot, expired.Details); ModState.SimGameState.OnEventTriggered(newEvent, EventScope.MechWarrior, ___mechWarriorEventTracker); } else if (Mod.Config.HeadHunting.Enabled && __instance.TravelState == SimGameTravelStatus.IN_SYSTEM) { // TODO: Only do check if not at planet with blacklisted tags if (HeadHuntingHelper.ShouldCheckHeadHunting()) { Pilot headHuntedCrew = HeadHuntingHelper.TestAllCrews(); if (headHuntedCrew != null) { CrewDetails cd = ModState.GetCrewDetails(headHuntedCrew.pilotDef); SimGameEventDef newEvent = EventHelper.CreateHeadHuntingEvent(headHuntedCrew, cd, cd.HiringBonus, cd.HiringBonus); ModState.HeadHuntedPilot = headHuntedCrew; ModState.SimGameState.OnEventTriggered(newEvent, EventScope.MechWarrior, ___mechWarriorEventTracker); HeadHuntingHelper.UpdateNextDayOnSuccess(); } else { HeadHuntingHelper.UpdateNextDayOnFailure(); } } } } }
static void Postfix(SimGameState __instance, GameInstanceSave gameInstanceSave) { try { if (__instance.HasTravelContract && Fields.warmission) { __instance.GlobalContracts.Add(__instance.ActiveTravelContract); } foreach (Contract contract in __instance.GlobalContracts) { contract.Override.contractDisplayStyle = ContractDisplayStyle.BaseCampaignStory; int maxPriority = Mathf.FloorToInt(7 / __instance.Constants.Salvage.PrioritySalvageModifier); contract.Override.salvagePotential = Mathf.Min(maxPriority, Mathf.RoundToInt(contract.SalvagePotential * Fields.settings.priorityContactPayPercentage)); contract.Override.negotiatedSalvage = 1f; } //tags: /* FundsAddedAction = 'BtSaveEdit.FundsAdded' * InventoryAddedAction = 'BtSaveEdit.InventoryAdded' * InventoryDeletedAction = 'BtSaveEdit.InventoryDeleted' * PilotChangedAction = 'BtSaveEdit.PilotChanged' * ReputationChangedAction = 'BtSaveEdit.ReputationChanged' * SaveCleanedAction = 'BtSaveEdit.SaveCleaned' * StarSystemsDeletedAction = 'BtSaveEdit.StarSystemsDeleted' * ContractsDeletedAction = 'BtSaveEdit.ContractsDeleted' * MechsRemovedAction = 'BtSaveEdit.MechsRemoved' * MechsAddedAction = 'BtSaveEdit.MechsAdded' * BlackMarketChangedAction = 'BtSaveEdit.BlackMarketAccessChanged' * CompanyTagsChangedAction = 'BtSaveEdit.CompanyTagsChanged' * StarSystemWarpAction = 'BtSaveEdit.ChangedCurrentStarSystem'*/ List <string> saveedits = new List <string>() { "BtSaveEdit.FundsAdded", "BtSaveEdit.InventoryAdded", "BtSaveEdit.ReputationChanged", "BtSaveEdit.MechsAdded" }; foreach (string cheat in saveedits) { if (__instance.CompanyStats.ContainsStatistic(cheat)) { Fields.cheater = true; SimGameInterruptManager interruptQueue = (SimGameInterruptManager)AccessTools.Field(typeof(SimGameState), "interruptQueue").GetValue(__instance); interruptQueue.QueueGenericPopup_NonImmediate("Save Edited!", "You have edited your save file in a way that disqualifies you from the war game, your missions wont be influenceing the war. All other fucntions work as normally.", true); break; } } } catch (Exception e) { PersistentMapClient.Logger.LogError(e); } }
static void Postfix(Contract __instance, BattleTech.MissionResult result) { try { GameInstance game = LazySingletonBehavior <UnityGameInstance> .Instance.Game; StarSystem system = game.Simulation.StarSystems.Find(x => x.ID == __instance.TargetSystem); int planetSupport = Helper.CalculatePlanetSupport(game.Simulation, system, __instance.Override.employerTeam.faction, __instance.Override.targetTeam.faction); PersistentMapAPI.MissionResult mresult = new PersistentMapAPI.MissionResult(__instance.Override.employerTeam.faction, __instance.Override.targetTeam.faction, result, system.Name, __instance.Difficulty, Mathf.RoundToInt(__instance.InitialContractReputation * __instance.PercentageContractReputation), planetSupport); bool postSuccessfull = Web.PostMissionResult(mresult, game.Simulation.Player1sMercUnitHeraldryDef.Description.Name); if (!postSuccessfull) { SimGameInterruptManager interruptQueue = (SimGameInterruptManager)AccessTools.Field(typeof(SimGameState), "interruptQueue").GetValue(game.Simulation); interruptQueue.QueueGenericPopup_NonImmediate("Connection Failure", "Result could not be transfered", true); } return; } catch (Exception e) { Logger.LogError(e); } }
static bool Prefix(SimGameState __instance, int quarterPassed) { try { int expenditures = __instance.GetExpenditures(false); if (Fields.warmission) { expenditures /= 2; } __instance.AddFunds(-expenditures * quarterPassed, "SimGame_Monthly", false); if (!__instance.IsGameOverCondition(false)) { SimGameInterruptManager interruptQueue = (SimGameInterruptManager)AccessTools.Field(typeof(SimGameState), "interruptQueue").GetValue(__instance); interruptQueue.QueueFinancialReport(); } __instance.RoomManager.RefreshDisplay(); AccessTools.Method(typeof(SimGameState), "OnNewQuarterBegin").Invoke(__instance, new object[] { }); return(false); } catch (Exception e) { Logger.LogError(e); return(true); } }
static void Postfix(Contract __instance, MissionResult result) { try { GameInstance game = LazySingletonBehavior <UnityGameInstance> .Instance.Game; StarSystem system = game.Simulation.StarSystems.Find(x => x.ID == __instance.TargetSystem); Faction oldOwner = system.Def.Owner; if (result == MissionResult.Victory) { system = Helper.PlayerAttackSystem(system, game.Simulation, __instance.Override.employerTeam.faction, __instance.Override.targetTeam.faction, true); } else { system = Helper.PlayerAttackSystem(system, game.Simulation, __instance.Override.employerTeam.faction, __instance.Override.targetTeam.faction, false); } if (system.Def.Owner != oldOwner) { SimGameInterruptManager interruptQueue = (SimGameInterruptManager)AccessTools.Field(typeof(SimGameState), "interruptQueue").GetValue(game.Simulation); interruptQueue.QueueGenericPopup_NonImmediate("Conquered", Helper.GetFactionName(system.Def.Owner, game.Simulation.DataManager) + " took " + system.Name + " from " + Helper.GetFactionName(oldOwner, game.Simulation.DataManager), true, null); } } catch (Exception e) { Logger.LogError(e); } }
// Run after completion of contracts and queue up any orders in the temp queue into the game's Mech Lab queue public static void Postfix(SimGameState __instance) { try { // If there are any work orders in the temporary queue, prompt the player if (Globals.tempMechLabQueue.Count > 0) { Logger.LogDebug("Processing temp Mech Lab queue orders."); int cbills = 0; int techCost = 0; int mechRepairCount = 0; int skipMechCount = 0; string mechRepairCountDisplayed = String.Empty; string skipMechCountDisplayed = String.Empty; string skipMechMessage = String.Empty; string finalMessage = String.Empty; // If player has disabled auto repairing mechs with destroyed components, check for them and remove them from the temp queue before continuing if (!ArmorRepair.ModSettings.AutoRepairMechsWithDestroyedComponents) { for (int index = 0; index < Globals.tempMechLabQueue.Count; index++) { WorkOrderEntry_MechLab order = Globals.tempMechLabQueue[index]; Logger.LogDebug("Checking for destroyed components."); bool destroyedComponents = false; MechDef mech = __instance.GetMechByID(order.MechID); destroyedComponents = Helpers.CheckDestroyedComponents(mech); if (destroyedComponents) { // Remove this work order from the temp mech lab queue if the mech has destroyed components and move to next iteration Logger.LogDebug("Removing " + mech.Name + " order from temp queue due to destroyed components and mod settings."); Globals.tempMechLabQueue.Remove(order); destroyedComponents = false; skipMechCount++; index++; } } } Logger.LogDebug("Temp Queue has " + Globals.tempMechLabQueue.Count + " entries."); // Calculate summary of total repair costs from the temp work order queue for (int index = 0; index < Globals.tempMechLabQueue.Count; index++) { WorkOrderEntry_MechLab order = Globals.tempMechLabQueue[index]; MechDef mech = __instance.GetMechByID(order.MechID); Logger.LogDebug("Adding " + mech.Name + " to RepairCount."); cbills += order.GetCBillCost(); techCost += order.GetCost(); mechRepairCount++; } mechRepairCount = Mathf.Clamp(mechRepairCount, 0, 4); Logger.LogDebug("Temp Queue has " + Globals.tempMechLabQueue.Count + " work order entries."); // If Yang's Auto Repair prompt is enabled, build a message prompt dialog for the player if (ArmorRepair.ModSettings.EnableAutoRepairPrompt) { // Calculate a friendly techCost of the work order in days, based on number of current mechtechs in the player's game. if (techCost != 0 && __instance.MechTechSkill != 0) { techCost = Mathf.CeilToInt((float)techCost / (float)__instance.MechTechSkill); } else { techCost = 1; // Safety in case of weird div/0 } // Generate a quick friendly description of how many mechs were damaged in battle switch (mechRepairCount) { case 0: { Logger.LogDebug("mechRepairCount was 0."); break; } case 1: { mechRepairCountDisplayed = "one of our 'Mechs was"; break; } case 2: { mechRepairCountDisplayed = "a couple of the 'Mechs were"; break; } case 3: { mechRepairCountDisplayed = "three of our 'Mechs were"; break; } case 4: { mechRepairCountDisplayed = "our whole lance was"; break; } } // Generate a friendly description of how many mechs were damaged but had components destroyed switch (skipMechCount) { case 0: { Logger.LogDebug("skipMechCount was 0."); break; } case 1: { skipMechCountDisplayed = "one of the 'Mechs is damaged but has"; break; } case 2: { skipMechCountDisplayed = "two of the 'Mechs are damaged but have"; break; } case 3: { skipMechCountDisplayed = "three of the 'Mechs are damaged but have "; break; } case 4: { skipMechCountDisplayed = "the whole lance is damaged but has"; break; } } // Check if there are any mechs to process if (mechRepairCount > 0 || skipMechCount > 0) { Logger.LogDebug("mechRepairCount is " + mechRepairCount + " skipMechCount is " + skipMechCount); // Setup the notification for mechs with damaged components that we might want to skip if (skipMechCount > 0 && mechRepairCount == 0) { skipMechMessage = String.Format("{0} destroyed components. I'll leave the repairs for you to review.", skipMechCountDisplayed); } else { skipMechMessage = String.Format("{0} destroyed components, so I'll leave those repairs to you.", skipMechCountDisplayed); } Logger.LogDebug("Firing Yang's UI notification."); SimGameInterruptManager notificationQueue = __instance.GetInterruptQueue(); // If all of the mechs needing repairs have damaged components and should be skipped from auto-repair, change the message notification structure to make more sense (e.g. just have an OK button) if (skipMechCount > 0 && mechRepairCount == 0) { finalMessage = String.Format( "Boss, {0} \n\n", skipMechMessage ); // Queue Notification notificationQueue.QueuePauseNotification( "'Mech Repairs Needed", finalMessage, __instance.GetCrewPortrait(SimGameCrew.Crew_Yang), string.Empty, delegate { Logger.LogDebug("[PROMPT] All damaged mechs had destroyed components and won't be queued for repair."); }, "OK" ); } else { if (skipMechCount > 0) { finalMessage = String.Format( "Boss, {0} damaged. It'll cost <color=#DE6729>{1}{2:n0}</color> and {3} days for these repairs. Want my crew to get started?\n\nAlso, {4}\n\n", mechRepairCountDisplayed, '¢', cbills.ToString(), techCost.ToString(), skipMechMessage ); } else { finalMessage = String.Format( "Boss, {0} damaged on the last engagement. It'll cost <color=#DE6729>{1}{2:n0}</color> and {3} days for the repairs.\n\nWant my crew to get started?", mechRepairCountDisplayed, '¢', cbills.ToString(), techCost.ToString() ); } // Queue up Yang's notification notificationQueue.QueuePauseNotification( "'Mech Repairs Needed", finalMessage, __instance.GetCrewPortrait(SimGameCrew.Crew_Yang), string.Empty, delegate { Logger.LogDebug("[PROMPT] Moving work orders from temp queue to Mech Lab queue: " + Globals.tempMechLabQueue.Count + " work orders"); foreach (WorkOrderEntry_MechLab workOrder in Globals.tempMechLabQueue.ToList()) { Logger.LogInfo("[PROMPT] Moving work order from temp queue to Mech Lab queue: " + workOrder.Description + " - " + workOrder.GetCBillCost()); Helpers.SubmitWorkOrder(__instance, workOrder); Globals.tempMechLabQueue.Remove(workOrder); } }, "Yes", delegate { Logger.LogInfo("[PROMPT] Discarding work orders from temp queue: " + Globals.tempMechLabQueue.Count + " work orders"); foreach (WorkOrderEntry_MechLab workOrder in Globals.tempMechLabQueue.ToList()) { Logger.LogInfo("[PROMPT] Discarding work order from temp queue: " + workOrder.Description + " - " + workOrder.GetCBillCost()); Globals.tempMechLabQueue.Remove(workOrder); } }, "No" ); } } } else // If Auto Repair prompt is not enabled, just proceed with queuing the remaining temp queue work orders and don't notify the player { foreach (WorkOrderEntry_MechLab workOrder in Globals.tempMechLabQueue.ToList()) { Logger.LogInfo("[AUTO] Moving work order from temp queue to Mech Lab queue: " + workOrder.Description + " - " + workOrder.GetCBillCost()); Helpers.SubmitWorkOrder(__instance, workOrder); Globals.tempMechLabQueue.Remove(workOrder); } } } } catch (Exception ex) { Globals.tempMechLabQueue.Clear(); Logger.LogError(ex); } }
static void Postfix(SimGameState __instance) { try { Fields.PaymentCall = false; if (Fields.Deployment) { if (Fields.DeploymentRemainingDays <= 0) { __instance.StopPlayMode(); Fields.Deployment = false; SimGameInterruptManager interruptQueue = (SimGameInterruptManager)AccessTools.Field(typeof(SimGameState), "interruptQueue").GetValue(__instance); interruptQueue.QueueGenericPopup("Deployment Over", "Thanks for your services."); Fields.DeploymentContracts = new Dictionary <string, Contract>(); __instance.CurSystem.SystemContracts.Clear(); __instance.RoomManager.RefreshTimeline(); AccessTools.Field(typeof(SimGameState), "activeBreadcrumb").SetValue(__instance, null); } else { Settings settings = Helper.LoadSettings(); System.Random rand = new System.Random(); int ChanceDivider = Mathf.Max(1, 2 ^ ((Fields.MissionsDoneCurrentMonth + 1) - Mathf.RoundToInt((__instance.Constants.Finances.QuarterLength * settings.MissionChancePerDay)))); if (rand.NextDouble() < settings.MissionChancePerDay / ChanceDivider) { __instance.PauseTimer(); __instance.StopPlayMode(); SimGameInterruptManager interruptQueue = (SimGameInterruptManager)AccessTools.Field(typeof(SimGameState), "interruptQueue").GetValue(__instance); Contract newcon = Helper.GetNewContract(__instance, Fields.DeploymentDifficulty, Fields.DeploymentEmployer, Fields.DeploymentTarget); newcon.SetInitialReward(0); newcon.Override.salvagePotential = Fields.DeploymentSalvage; newcon.SetNegotiatedValues(Fields.DeploymentNegotiatedPayment, Fields.DeploymentNegotiatedSalvage); newcon.Override.disableNegotations = true; SimGameEventResult simGameEventResult = new SimGameEventResult(); SimGameResultAction simGameResultAction = new SimGameResultAction(); int num2 = 11; simGameResultAction.Type = SimGameResultAction.ActionType.System_StartNonProceduralContract; simGameResultAction.value = newcon.mapName; simGameResultAction.additionalValues = new string[num2]; simGameResultAction.additionalValues[0] = __instance.CurSystem.ID; simGameResultAction.additionalValues[1] = newcon.mapPath; simGameResultAction.additionalValues[2] = newcon.encounterObjectGuid; simGameResultAction.additionalValues[3] = newcon.Override.ID; simGameResultAction.additionalValues[4] = (!newcon.Override.useTravelCostPenalty).ToString(); simGameResultAction.additionalValues[5] = Fields.DeploymentEmployer.ToString(); simGameResultAction.additionalValues[6] = Fields.DeploymentTarget.ToString(); simGameResultAction.additionalValues[7] = newcon.Difficulty.ToString(); simGameResultAction.additionalValues[8] = "true"; simGameResultAction.additionalValues[9] = Fields.DeploymentEmployer.ToString(); simGameResultAction.additionalValues[10] = newcon.Override.travelSeed.ToString(); simGameEventResult.Actions = new SimGameResultAction[1]; simGameEventResult.Actions[0] = simGameResultAction; newcon.Override.OnContractSuccessResults.Add(simGameEventResult); AccessTools.Field(typeof(SimGameState), "activeBreadcrumb").SetValue(__instance, newcon); Fields.DeploymentContracts.Add(newcon.Name, newcon); Action primaryAction = delegate() { __instance.QueueCompleteBreadcrumbProcess(true); }; interruptQueue.QueueTravelPauseNotification("New Mission", "Our Employer has a new mission for us.", __instance.GetCrewPortrait(SimGameCrew.Crew_Darius), string.Empty, new Action(primaryAction), "Proceed", new Action(__instance.OnBreadcrumbWait), "Not Yet"); } } } } catch (Exception e) { Logger.LogError(e); } }
private static bool Prefix(SimGameState __instance, string id) { try { __instance.AddItemStat(id, "MECHPART", false); Settings settings = Helper.Settings; Dictionary <MechDef, int> possibleMechs = new Dictionary <MechDef, int>(); MechDef currentVariant = __instance.DataManager.MechDefs.Get(id); int itemCount = 0; if (settings.AssembleVariants && !settings.VariantExceptions.Contains(id)) { foreach (KeyValuePair <string, MechDef> pair in __instance.DataManager.MechDefs) { if (pair.Value.Chassis.PrefabIdentifier.Equals(currentVariant.Chassis.PrefabIdentifier) && !settings.VariantExceptions.Contains(pair.Value.Description.Id) && pair.Value.Chassis.Tonnage.Equals(__instance.DataManager.MechDefs.Get(id).Chassis.Tonnage)) { int numberOfParts = __instance.GetItemCount(pair.Value.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); if (numberOfParts > 0) { itemCount += numberOfParts; possibleMechs.Add(new MechDef(pair.Value, __instance.GenerateSimGameUID()), numberOfParts); } } } } else { itemCount = __instance.GetItemCount(id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); } int defaultMechPartMax = __instance.GetMechPartsRequired(currentVariant); if (itemCount >= defaultMechPartMax) { MechDef mechDef = null; List <KeyValuePair <MechDef, int> > mechlist = possibleMechs.ToList(); mechlist = possibleMechs.OrderByDescending(o => o.Value).ToList(); if (settings.AssembleVariants && !settings.VariantExceptions.Contains(id)) { if (settings.AssembleMostParts) { // This is the list of mechs which have the most parts // (there could be more than one if the parts are equal) // Don't include the variant which we've just found a part for. List <MechDef> topMechList = new List <MechDef>(); if (mechlist[0].Key.ChassisID != currentVariant.ChassisID) { topMechList.Add(mechlist[0].Key); } for (int mechlistI = 1; mechlistI < mechlist.Count && mechlist[mechlistI - 1].Value == mechlist[mechlistI].Value; ++mechlistI) { MechDef mechToAdd = mechlist[mechlistI].Key; if (mechToAdd.ChassisID != currentVariant.ChassisID) { topMechList.Add(mechlist[mechlistI].Key); } } // Now if the most parts list is empty, choose the current variant. // If it has one element, choose it // (we prefer the variant which we have previously had the parts for, all else being equal) // if there's more than one variant, choose one from this list randomly. // // This approach gives the commander some control over what variant will be assembled. // For example, if the commander has 3 of one variant and 2 of another and the parts required is 6, // they can be sure that the first variant will be constructed once they get another part // no matter what it is. // So commanders can sell parts if they choose to manipulate this. switch (topMechList.Count) { case 0: mechDef = currentVariant; break; case 1: mechDef = topMechList[0]; break; default: Random rand = new Random(); int roll = (int)rand.NextDouble() * topMechList.Count; mechDef = topMechList[Math.Min(roll, topMechList.Count - 1)]; break; } } else { Random rand = new Random(); int numberOfDifferentVariants = mechlist.Count; double roll = rand.NextDouble(); double currentTotal = 0; foreach (KeyValuePair <MechDef, int> mech in mechlist) { currentTotal += (double)mech.Value / (double)defaultMechPartMax; if (roll <= currentTotal) { mechDef = mech.Key; break; } } } int j = 0; int i = 0; int currentPart = 1; while (i < defaultMechPartMax) { if (currentPart > mechlist[j].Value) { j++; currentPart = 1; } ReflectionHelper.InvokePrivateMethode(__instance, "RemoveItemStat", new object[] { mechlist[j].Key.Description.Id, "MECHPART", false }); currentPart++; i++; } } else { for (int i = 0; i < defaultMechPartMax; i++) { ReflectionHelper.InvokePrivateMethode(__instance, "RemoveItemStat", new object[] { id, "MECHPART", false }); } mechDef = new MechDef(__instance.DataManager.MechDefs.Get(id), __instance.GenerateSimGameUID()); } Random rng = new Random(); if (!settings.HeadRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.Head.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.Head.CurrentInternalStructure = Math.Max(1f, mechDef.Head.CurrentInternalStructure * (float)rng.NextDouble()); } if (!settings.LeftArmRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.LeftArm.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.LeftArm.CurrentInternalStructure = Math.Max(1f, mechDef.LeftArm.CurrentInternalStructure * (float)rng.NextDouble()); } if (!settings.RightArmRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.RightArm.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.RightArm.CurrentInternalStructure = Math.Max(1f, mechDef.RightArm.CurrentInternalStructure * (float)rng.NextDouble()); } if (!settings.LeftLegRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.LeftLeg.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.LeftLeg.CurrentInternalStructure = Math.Max(1f, mechDef.LeftLeg.CurrentInternalStructure * (float)rng.NextDouble()); } if (!settings.RightLegRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.RightLeg.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.RightLeg.CurrentInternalStructure = Math.Max(1f, mechDef.RightLeg.CurrentInternalStructure * (float)rng.NextDouble()); } if (!settings.CentralTorsoRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.CenterTorso.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.CenterTorso.CurrentInternalStructure = Math.Max(1f, mechDef.CenterTorso.CurrentInternalStructure * (float)rng.NextDouble()); } if (!settings.RightTorsoRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.RightTorso.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.RightTorso.CurrentInternalStructure = Math.Max(1f, mechDef.RightTorso.CurrentInternalStructure * (float)rng.NextDouble()); } if (!settings.LeftTorsoRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.LeftTorso.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.LeftTorso.CurrentInternalStructure = Math.Max(1f, mechDef.LeftTorso.CurrentInternalStructure * (float)rng.NextDouble()); } // each component is checked and destroyed if the settings are set that way // if RepairMechComponents is true it will variably make components either functional, nonfunctional, or destroyed based on settings foreach (MechComponentRef mechComponent in mechDef.Inventory) { if (!settings.RepairMechComponents || mechDef.IsLocationDestroyed(mechComponent.MountedLocation)) { mechComponent.DamageLevel = ComponentDamageLevel.Destroyed; continue; } if (settings.RepairMechComponents) { double repairRoll = rng.NextDouble(); if (repairRoll <= settings.RepairComponentsFunctionalThreshold) { mechComponent.DamageLevel = ComponentDamageLevel.Functional; } else if (repairRoll <= settings.RepairComponentsNonFunctionalThreshold) { mechComponent.DamageLevel = ComponentDamageLevel.NonFunctional; } else { mechComponent.DamageLevel = ComponentDamageLevel.Destroyed; } } } __instance.AddMech(0, mechDef, true, false, true, null); SimGameInterruptManager interrupt = (SimGameInterruptManager)ReflectionHelper.GetPrivateField(__instance, "interruptQueue"); interrupt.DisplayIfAvailable(); __instance.MessageCenter.PublishMessage(new SimGameMechAddedMessage(mechDef, defaultMechPartMax, true)); } return(false); } catch (Exception e) { Logger.LogError(e); return(true); } }
static void Postfix(Starmap __instance, SimGameState simGame) { try { Fields.currentMap = Web.GetStarMap(); List <StarSystem> needUpdates = new List <StarSystem>(); if (Fields.currentMap == null) { SimGameInterruptManager interruptQueue = (SimGameInterruptManager)AccessTools.Field(typeof(SimGameState), "interruptQueue").GetValue(simGame); interruptQueue.QueueGenericPopup_NonImmediate("Connection Failure", "Map could not be downloaded", true); return; } List <string> changes = new List <string>(); foreach (ParseSystem system in Fields.currentMap.systems) { if (system.activePlayers > 0) { GameObject starObject = GameObject.Find(system.name); Transform argoMarker = starObject.transform.Find("ArgoMarker"); argoMarker.gameObject.SetActive(true); argoMarker.localScale = new Vector3(4f, 4f, 4f); argoMarker.GetComponent <MeshRenderer>().material.color = Color.grey; GameObject playerNumber = new GameObject(); playerNumber.transform.parent = argoMarker; playerNumber.name = "PlayerNumberText"; playerNumber.layer = 25; TextMeshPro textComponent = playerNumber.AddComponent <TextMeshPro>(); textComponent.SetText(system.activePlayers.ToString()); textComponent.transform.localPosition = new Vector3(0, -0.35f, -0.05f); textComponent.fontSize = 6; textComponent.alignment = TextAlignmentOptions.Center; textComponent.faceColor = Color.black; textComponent.fontStyle = FontStyles.Bold; } StarSystem system2 = simGame.StarSystems.Find(x => x.Name.Equals(system.name)); if (system2 != null) { Faction newOwner = system.controlList.OrderByDescending(x => x.percentage).First().faction; Faction oldOwner = system2.Owner; AccessTools.Method(typeof(StarSystemDef), "set_Owner").Invoke(system2.Def, new object[] { newOwner }); AccessTools.Method(typeof(StarSystemDef), "set_ContractEmployers").Invoke(system2.Def, new object[] { Helper.GetEmployees(system2, simGame) }); AccessTools.Method(typeof(StarSystemDef), "set_ContractTargets").Invoke(system2.Def, new object[] { Helper.GetTargets(system2, simGame) }); system2.Tags.Remove(Helper.GetFactionTag(oldOwner)); system2.Tags.Add(Helper.GetFactionTag(newOwner)); if (Helper.IsBorder(system2, simGame) && simGame.Starmap != null) { system2.Tags.Add("planet_other_battlefield"); } else { system2.Tags.Remove("planet_other_battlefield"); } system2 = Helper.ChangeWarDescription(system2, simGame, system); if (newOwner != oldOwner) { changes.Add(Helper.GetFactionShortName(newOwner, simGame.DataManager) + " took " + system2.Name + " from " + Helper.GetFactionShortName(oldOwner, simGame.DataManager)); foreach (StarSystem changedSystem in simGame.Starmap.GetAvailableNeighborSystem(system2)) { if (!needUpdates.Contains(changedSystem)) { needUpdates.Add(changedSystem); } } } } } foreach (StarSystem changedSystem in needUpdates) { AccessTools.Method(typeof(StarSystemDef), "set_ContractEmployers").Invoke(changedSystem.Def, new object[] { Helper.GetEmployees(changedSystem, simGame) }); AccessTools.Method(typeof(StarSystemDef), "set_ContractTargets").Invoke(changedSystem.Def, new object[] { Helper.GetTargets(changedSystem, simGame) }); ParseSystem system = Fields.currentMap.systems.FirstOrDefault(x => x.name.Equals(changedSystem.Name)); if (system != null) { AccessTools.Method(typeof(StarSystemDef), "set_Description").Invoke(changedSystem.Def, new object[] { Helper.ChangeWarDescription(changedSystem, simGame, system).Def.Description }); } } if (changes.Count > 0 && !Fields.firstpass) { SimGameInterruptManager interruptQueue2 = (SimGameInterruptManager)AccessTools.Field(typeof(SimGameState), "interruptQueue").GetValue(simGame); interruptQueue2.QueueGenericPopup_NonImmediate("War Activities", string.Join("\n", changes.ToArray()), true); } else { Fields.firstpass = false; } } catch (Exception e) { Logger.LogError(e); } }
static void Prefix(SimGameState __instance, int timeLapse) { try { //DAILY System.Random rand = new System.Random(); foreach (KeyValuePair <Faction, FactionDef> pair in __instance.FactionsDict) { if (!Helper.IsExcluded(pair.Key) && Helper.IsAtWar(pair.Key)) { List <TargetSystem> availableTargets = Fields.availableTargets[pair.Key]; if (availableTargets.Count > 0) { List <TargetSystem> targets = availableTargets.OrderByDescending(x => Helper.GetOffenceValue(x.system) + Helper.GetDefenceValue(x.system) + Helper.GetNeighborValue(x.factionNeighbours, pair.Key)).ToList(); int numberOfAttacks = Mathf.Min(targets.Count, Mathf.CeilToInt(Fields.factionResources.Find(x => x.faction == pair.Key).offence / 100f)); for (int i = 0; i < numberOfAttacks; i++) { StarSystem system = __instance.StarSystems.Find(x => x.Name == targets[i].system.Name); if (system != null) { system = Helper.AttackSystem(system, __instance, pair.Key, rand); } } } } } //MONTHLY int num = (timeLapse <= 0) ? 1 : timeLapse; if ((__instance.DayRemainingInQuarter - num <= 0)) { foreach (KeyValuePair <string, string> changes in Fields.thisMonthChanges) { StarSystem changedSystem = __instance.StarSystems.Find(x => x.Name.Equals(changes.Key)); if (!Helper.GetFactionName(changedSystem.Owner, __instance.DataManager).Equals(changes.Value)) { War war = Helper.getWar(changedSystem.Owner); if (war != null) { if (war.attackers.ContainsKey(changedSystem.Owner)) { war.monthlyEvents.Add("<color=" + Fields.settings.attackercolor + ">" + Helper.GetFactionName(changedSystem.Owner, __instance.DataManager) + "</color>" + " took " + "<color=" + Fields.settings.planetcolor + ">" + changes.Key + "</color>" + " from " + "<color=" + Fields.settings.defendercolor + ">" + changes.Value + "</color>"); } else { war.monthlyEvents.Add("<color=" + Fields.settings.defendercolor + ">" + Helper.GetFactionName(changedSystem.Owner, __instance.DataManager) + "</color>" + " took " + "<color=" + Fields.settings.planetcolor + ">" + changes.Key + "</color>" + " from " + "<color=" + Fields.settings.attackercolor + ">" + changes.Value + "</color>"); } } } } foreach (War war in Fields.currentWars) { war.monthlyEvents.Add("\n"); } Dictionary <Faction, FactionDef> factions = (Dictionary <Faction, FactionDef>)AccessTools.Field(typeof(SimGameState), "factions").GetValue(__instance); foreach (KeyValuePair <Faction, FactionDef> pair in factions) { if (Helper.IsExcluded(pair.Key)) { continue; } List <Faction> fac = null; if (Fields.neighbourFactions.ContainsKey(pair.Key)) { fac = Fields.neighbourFactions[pair.Key]; } List <Faction> list = Helper.GetFactionsByString(Fields.settings.excludedFactionNames); if (fac != null && list != null && list.Count > 0) { fac = fac.Except(list).ToList(); if (Fields.Allies[pair.Key].Count() > 0) { fac = fac.Except(Fields.Allies[pair.Key]).ToList(); } } if (!Helper.IsAtWar(pair.Key) && !Helper.IsExcluded(pair.Key) && fac != null && fac.Count > 0) { if (rand.Next(0, 101) > Fields.WarFatique[pair.Key]) { Faction enemy; do { enemy = fac[rand.Next(fac.Count)]; } while (Helper.IsExcluded(enemy) || pair.Key == enemy); bool joinedWar = false; foreach (War war in Fields.currentWars) { if (war.attackers.ContainsKey(enemy) && !Fields.removeWars.Contains(war.name)) { war.defenders.Add(pair.Key, new WarProgression(new Dictionary <string, Faction>())); war.monthlyEvents.Add("<color=" + Fields.settings.defendercolor + ">" + Helper.GetFactionName(pair.Key, __instance.DataManager) + "</color>" + " joined the war."); joinedWar = true; break; } else if (war.defenders.ContainsKey(enemy) && !Fields.removeWars.Contains(war.name)) { war.attackers.Add(pair.Key, new WarProgression(new Dictionary <string, Faction>())); war.monthlyEvents.Add("<color=" + Fields.settings.attackercolor + ">" + Helper.GetFactionName(pair.Key, __instance.DataManager) + "</color>" + " joined the war."); joinedWar = true; break; } } if (!joinedWar) { string Name = Helper.GetFactionShortName(pair.Key, __instance.DataManager) + " VS " + Helper.GetFactionShortName(enemy, __instance.DataManager); Dictionary <Faction, WarProgression> attackers = new Dictionary <Faction, WarProgression>(); attackers.Add(pair.Key, new WarProgression(new Dictionary <string, Faction>())); Dictionary <Faction, WarProgression> defenders = new Dictionary <Faction, WarProgression>(); defenders.Add(enemy, new WarProgression(new Dictionary <string, Faction>())); War war = new War(Name, attackers, defenders); war.monthlyEvents.Add("<color=" + Fields.settings.attackercolor + ">" + Helper.GetFactionName(pair.Key, __instance.DataManager) + "</color>" + " declared war on " + "<color=" + Fields.settings.defendercolor + ">" + Helper.GetFactionName(enemy, __instance.DataManager) + "</color>" + ".\n"); if (Fields.currentWars.Contains(war)) { Logger.LogLine(war.name + "already exists"); } Fields.currentWars.Add(war); } } else { Fields.WarFatique[pair.Key] = Mathf.Max(0, Fields.WarFatique[pair.Key] -= Fields.settings.FatiqueRecoveredPerMonth); Helper.Diplomacy(pair.Key, ref __instance, rand); } } else if (Helper.IsAtWar(pair.Key)) { Fields.WarFatique[pair.Key] = Mathf.Min(100, Fields.WarFatique[pair.Key] + Fields.settings.FatiqueLostPerMonth); if (rand.Next(0, 101) < Fields.WarFatique[pair.Key]) { War war = Helper.getWar(pair.Key); if (war == null) { Logger.LogLine(pair.Key + " has no war at end war calculations"); } if (war.duration >= Fields.settings.minMonthDuration) { if (war.duration < Fields.settings.maxMonthDuration || Fields.settings.maxMonthDuration == -1) { if (!(Fields.currentWars.Find(x => x.name.Equals(war.name)).attackers.Count <= 0) && !(Fields.currentWars.Find(x => x.name.Equals(war.name)).defenders.Count <= 0)) { string color = ""; if (Fields.currentWars.Find(x => x.name.Equals(war.name)).attackers.ContainsKey(pair.Key)) { color = Fields.settings.attackercolor; Fields.currentWars.Find(x => x.name.Equals(war.name)).monthlyEvents.Add("\n<color=" + color + ">" + Helper.GetFactionName(pair.Key, __instance.DataManager) + "</color>" + " surrendered."); Dictionary <Faction, int> returnedPlanetsCount = new Dictionary <Faction, int>(); foreach (KeyValuePair <string, Faction> taken in Fields.currentWars.Find(x => x.name.Equals(war.name)).attackers[pair.Key].takenPlanets) { if (war.defenders.ContainsKey(taken.Value)) { StarSystem changedSystem = __instance.StarSystems.Find(x => x.Name.Equals(taken.Key)); PlanetControlState planetState = Fields.stateOfWar.FirstOrDefault(x => x.system.Equals(changedSystem.Name)); FactionControl oldControl = planetState.factionList.FirstOrDefault(x => x.faction == pair.Key); int percentage = oldControl.percentage; oldControl.percentage = 0; FactionControl ownerControl = planetState.factionList.FirstOrDefault(x => x.faction == taken.Value); ownerControl.percentage += percentage; changedSystem = Helper.ChangeOwner(changedSystem, ownerControl, __instance, true, true); changedSystem = Helper.ChangeWarDescription(changedSystem, __instance); if (!returnedPlanetsCount.ContainsKey(taken.Value)) { returnedPlanetsCount.Add(taken.Value, 1); } else { returnedPlanetsCount[taken.Value]++; } } } foreach (KeyValuePair <Faction, int> returned in returnedPlanetsCount) { Fields.currentWars.Find(x => x.name.Equals(war.name)).monthlyEvents.Add("<color=" + color + ">" + Helper.GetFactionName(pair.Key, __instance.DataManager) + "</color>" + " returned " + "<color=" + Fields.settings.planetcolor + ">" + returned.Value + "</color>" + " systems to " + "<color=" + Fields.settings.defendercolor + ">" + Helper.GetFactionName(returned.Key, __instance.DataManager) + "</color>"); } Fields.currentWars.Find(x => x.name.Equals(war.name)).attackers.Remove(pair.Key); } else { color = Fields.settings.defendercolor; Fields.currentWars.Find(x => x.name.Equals(war.name)).monthlyEvents.Add("\n<color=" + color + ">" + Helper.GetFactionName(pair.Key, __instance.DataManager) + "</color>" + " surrendered."); Dictionary <Faction, int> returnedPlanetsCount = new Dictionary <Faction, int>(); foreach (KeyValuePair <string, Faction> taken in Fields.currentWars.Find(x => x.name.Equals(war.name)).defenders[pair.Key].takenPlanets) { if (war.attackers.ContainsKey(taken.Value)) { StarSystem changedSystem = __instance.StarSystems.Find(x => x.Name.Equals(taken.Key)); PlanetControlState planetState = Fields.stateOfWar.FirstOrDefault(x => x.system.Equals(changedSystem.Name)); FactionControl oldControl = planetState.factionList.FirstOrDefault(x => x.faction == pair.Key); int percentage = oldControl.percentage; oldControl.percentage = 0; FactionControl ownerControl = planetState.factionList.FirstOrDefault(x => x.faction == taken.Value); ownerControl.percentage += percentage; changedSystem = Helper.ChangeOwner(changedSystem, ownerControl, __instance, true, true); changedSystem = Helper.ChangeWarDescription(changedSystem, __instance); if (!returnedPlanetsCount.ContainsKey(taken.Value)) { returnedPlanetsCount.Add(taken.Value, 1); } else { returnedPlanetsCount[taken.Value]++; } } } foreach (KeyValuePair <Faction, int> returned in returnedPlanetsCount) { Fields.currentWars.Find(x => x.name.Equals(war.name)).monthlyEvents.Add("<color=" + color + ">" + Helper.GetFactionName(pair.Key, __instance.DataManager) + "</color>" + " returned " + "<color=" + Fields.settings.planetcolor + ">" + returned.Value + "</color>" + " systems to " + "<color=" + Fields.settings.attackercolor + ">" + Helper.GetFactionName(returned.Key, __instance.DataManager) + "</color>"); } Fields.currentWars.Find(x => x.name.Equals(war.name)).defenders.Remove(pair.Key); } if (Fields.currentWars.Find(x => x.name.Equals(war.name)).attackers.Count <= 0) { Fields.currentWars.Find(x => x.name.Equals(war.name)).monthlyEvents.Add("\n<b>Attacking side lost the war.</b>"); foreach (KeyValuePair <Faction, WarProgression> defender in Fields.currentWars.Find(x => x.name.Equals(war.name)).defenders) { int count = Fields.currentWars.Find(x => x.name.Equals(war.name)).defenders[defender.Key].takenPlanets.Count; Fields.currentWars.Find(x => x.name.Equals(war.name)).monthlyEvents.Add("<color=" + Fields.settings.defendercolor + ">" + Helper.GetFactionName(defender.Key, __instance.DataManager) + "</color>" + " took " + "<color=" + Fields.settings.planetcolor + ">" + count + "</color>" + " systems in the war."); } if (!Fields.removeWars.Contains(war.name)) { Fields.removeWars.Add(war.name); } } else if (Fields.currentWars.Find(x => x.name.Equals(war.name)).defenders.Count <= 0) { Fields.currentWars.Find(x => x.name.Equals(war.name)).monthlyEvents.Add("\n<b>Defending side lost the war.</b>"); foreach (KeyValuePair <Faction, WarProgression> attackers in Fields.currentWars.Find(x => x.name.Equals(war.name)).attackers) { int count = Fields.currentWars.Find(x => x.name.Equals(war.name)).attackers[attackers.Key].takenPlanets.Count; Fields.currentWars.Find(x => x.name.Equals(war.name)).monthlyEvents.Add("<color=" + Fields.settings.attackercolor + ">" + Helper.GetFactionName(attackers.Key, __instance.DataManager) + "</color>" + " took " + "<color=" + Fields.settings.planetcolor + ">" + count + "</color>" + " systems in the war."); } if (!Fields.removeWars.Contains(war.name)) { Fields.removeWars.Add(war.name); } } } } else { Fields.currentWars.Find(x => x.name.Equals(war.name)).monthlyEvents.Add("\nThe War ended Undecided."); if (!Fields.removeWars.Contains(war.name)) { Fields.removeWars.Add(war.name); } } } } } } foreach (KeyValuePair <Faction, FactionDef> pair in factions) { if (Fields.currentEnemies.ContainsKey(pair.Key)) { Faction[] enemies = Fields.currentEnemies[pair.Key].ToArray(); ReflectionHelper.InvokePrivateMethode(pair.Value, "set_Enemies", new object[] { enemies }); } } SimGameInterruptManager interruptQueue = (SimGameInterruptManager)AccessTools.Field(typeof(SimGameState), "interruptQueue").GetValue(__instance); foreach (War war in Fields.currentWars) { war.duration += 1; if (!Fields.removeWars.Contains(war.name)) { war.monthlyEvents.Add("<color=" + Fields.settings.attackercolor + ">" + "\nAttackers:" + "</color>"); foreach (Faction fac in war.attackers.Keys) { war.monthlyEvents.Add(Helper.GetFactionName(fac, __instance.DataManager) + " | Exhaustion: " + Math.Round(Fields.WarFatique[fac], 1).ToString("F1") + "%"); } war.monthlyEvents.Add("<color=" + Fields.settings.defendercolor + ">" + "\nDefenders:" + "</color>"); foreach (Faction fac in war.defenders.Keys) { war.monthlyEvents.Add(Helper.GetFactionName(fac, __instance.DataManager) + " | Exhaustion: " + Math.Round(Fields.WarFatique[fac], 1).ToString("F1") + "%"); } } interruptQueue.QueueGenericPopup_NonImmediate(war.name, string.Join("\n", war.monthlyEvents.ToArray()) + "\n", true); war.monthlyEvents.Clear(); } if (Fields.DiplomacyLog.Count > 0) { interruptQueue.QueueGenericPopup_NonImmediate("Diplomacy", string.Join("\n", Fields.DiplomacyLog.ToArray()), true); } Fields.DiplomacyLog.Clear(); Fields.thisMonthChanges = new Dictionary <string, string>(); foreach (string war in Fields.removeWars) { Fields.currentWars.Remove(Fields.currentWars.Find(x => x.name.Equals(war))); } Fields.removeWars.Clear(); Helper.RefreshResources(__instance); Helper.RefreshEnemies(__instance); Helper.RefreshTargets(__instance); __instance.StopPlayMode(); } } catch (Exception e) { Logger.LogError(e); } }
static void Postfix(SimGameState __instance, string id) { try { __instance.AddItemStat(id, "MECHPART", false); Settings settings = Helper.LoadSettings(); Dictionary <MechDef, int> possibleMechs = new Dictionary <MechDef, int>(); int itemCount = 0; if (settings.AssembleVariants && !settings.VariantExceptions.Contains(id)) { foreach (KeyValuePair <string, MechDef> pair in __instance.DataManager.MechDefs) { if (pair.Value.Chassis.PrefabIdentifier.Equals(__instance.DataManager.MechDefs.Get(id).Chassis.PrefabIdentifier) && !settings.VariantExceptions.Contains(pair.Value.Description.Id) && pair.Value.Chassis.Tonnage.Equals(__instance.DataManager.MechDefs.Get(id).Chassis.Tonnage)) { int numberOfParts = __instance.GetItemCount(pair.Value.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); if (numberOfParts > 0) { itemCount += numberOfParts; possibleMechs.Add(new MechDef(pair.Value, __instance.GenerateSimGameUID()), numberOfParts); } } } } else { itemCount = __instance.GetItemCount(id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); } int defaultMechPartMax = __instance.Constants.Story.DefaultMechPartMax; if (itemCount >= defaultMechPartMax) { MechDef mechDef = null; List <KeyValuePair <MechDef, int> > mechlist = possibleMechs.ToList(); mechlist = possibleMechs.OrderByDescending(o => o.Value).ToList(); if (settings.AssembleVariants && !settings.VariantExceptions.Contains(id)) { if (settings.AssembleMostParts) { mechDef = mechlist[0].Key; } else { Random rand = new Random(); int numberOfDifferentVariants = mechlist.Count; double roll = rand.NextDouble(); double currentTotal = 0; foreach (KeyValuePair <MechDef, int> mech in mechlist) { currentTotal += (double)mech.Value / (double)defaultMechPartMax; if (roll <= currentTotal) { mechDef = mech.Key; break; } } } int j = 0; int i = 0; int currentPart = 1; while (i < defaultMechPartMax) { if (currentPart > mechlist[j].Value) { j++; currentPart = 1; } ReflectionHelper.InvokePrivateMethode(__instance, "RemoveItemStat", new object[] { mechlist[j].Key.Description.Id, "MECHPART", false }); currentPart++; i++; } } else { for (int i = 0; i < defaultMechPartMax; i++) { ReflectionHelper.InvokePrivateMethode(__instance, "RemoveItemStat", new object[] { id, "MECHPART", false }); } mechDef = new MechDef(__instance.DataManager.MechDefs.Get(id), __instance.GenerateSimGameUID()); } Random rng = new Random(); if (!settings.HeadRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.Head.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.Head.CurrentInternalStructure = Math.Max(1f, mechDef.Head.CurrentInternalStructure * (float)rng.NextDouble()); } if (!settings.LeftArmRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.LeftArm.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.LeftArm.CurrentInternalStructure = Math.Max(1f, mechDef.LeftArm.CurrentInternalStructure * (float)rng.NextDouble()); } if (!settings.RightArmRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.RightArm.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.RightArm.CurrentInternalStructure = Math.Max(1f, mechDef.RightArm.CurrentInternalStructure * (float)rng.NextDouble()); } if (!settings.LeftLegRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.LeftLeg.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.LeftLeg.CurrentInternalStructure = Math.Max(1f, mechDef.LeftLeg.CurrentInternalStructure * (float)rng.NextDouble()); } if (!settings.RightLegRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.RightLeg.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.RightLeg.CurrentInternalStructure = Math.Max(1f, mechDef.RightLeg.CurrentInternalStructure * (float)rng.NextDouble()); } if (!settings.CentralTorsoRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.CenterTorso.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.CenterTorso.CurrentInternalStructure = Math.Max(1f, mechDef.CenterTorso.CurrentInternalStructure * (float)rng.NextDouble()); } if (!settings.RightTorsoRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.RightTorso.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.RightTorso.CurrentInternalStructure = Math.Max(1f, mechDef.RightTorso.CurrentInternalStructure * (float)rng.NextDouble()); } if (!settings.LeftTorsoRepaired && (!settings.RepairMechLimbs || rng.NextDouble() > settings.RepairMechLimbsChance)) { mechDef.LeftTorso.CurrentInternalStructure = 0f; } else if (settings.RandomStructureOnRepairedLimbs) { mechDef.LeftTorso.CurrentInternalStructure = Math.Max(1f, mechDef.LeftTorso.CurrentInternalStructure * (float)rng.NextDouble()); } // each component is checked and destroyed if the settings are set that way // if RepairMechComponents is true it will variably make components either functional, nonfunctional, or destroyed based on settings foreach (MechComponentRef mechComponent in mechDef.Inventory) { if (!settings.RepairMechComponents || mechDef.IsLocationDestroyed(mechComponent.MountedLocation)) { mechComponent.DamageLevel = ComponentDamageLevel.Destroyed; continue; } if (settings.RepairMechComponents) { double repairRoll = rng.NextDouble(); if (repairRoll <= settings.RepairComponentsFunctionalThreshold) { mechComponent.DamageLevel = ComponentDamageLevel.Functional; } else if (repairRoll <= settings.RepairComponentsNonFunctionalThreshold) { mechComponent.DamageLevel = ComponentDamageLevel.NonFunctional; } else { mechComponent.DamageLevel = ComponentDamageLevel.Destroyed; } } } __instance.AddMech(0, mechDef, true, false, true, null); SimGameInterruptManager interrupt = (SimGameInterruptManager)ReflectionHelper.GetPrivateField(__instance, "interruptQueue"); interrupt.DisplayIfAvailable(); __instance.MessageCenter.PublishMessage(new SimGameMechAddedMessage(mechDef, true)); } } catch (Exception e) { Logger.LogError(e); } }
public void conclude() { WIIC.modLog.Info?.Write($"{type} finished at {location.Name}."); removeParticipationContracts(); string text = ""; if (type == "Attack") { if (attackerStrength <= 0) { text = Strings.T("Battle for {0} concludes - {1} holds off the {2} attack", location.Name, location.OwnerValue.FactionDef.ShortName, attacker.FactionDef.ShortName); } else if (defenderStrength <= 0) { text = Strings.T("Battle for {0} concludes - {1} takes the system from {2}", location.Name, attacker.FactionDef.ShortName, location.OwnerValue.FactionDef.ShortName); Utilities.applyOwner(location, attacker, true); } } else if (type == "Raid") { SimGameEventResult result = new SimGameEventResult(); result.Scope = EventScope.Company; result.TemporaryResult = true; result.ResultDuration = WIIC.settings.raidResultDuration; if (attackerStrength <= 0) { text = Strings.T("Raid on {0} concludes - {1} drives off the {2} forces", location.Name, location.OwnerValue.FactionDef.ShortName, attacker.FactionDef.ShortName); SimGameStat attackStat = new SimGameStat($"WIIC_{attacker.Name}_attack_strength", 1, false); SimGameStat defenseStat = new SimGameStat($"WIIC_{location.OwnerValue.Name}_defense_strength", -1, false); result.Stats = new SimGameStat[] { attackStat, defenseStat }; } else if (defenderStrength <= 0) { text = Strings.T("Raid on {0} concludes - {1} weakens {2} control", location.Name, attacker.FactionDef.ShortName, location.OwnerValue.FactionDef.ShortName); SimGameStat attackStat = new SimGameStat($"WIIC_{attacker.Name}_attack_strength", -1, false); SimGameStat defenseStat = new SimGameStat($"WIIC_{location.OwnerValue.Name}_defense_strength", 1, false); result.Stats = new SimGameStat[] { attackStat, defenseStat }; } SimGameEventResult[] results = { result }; SimGameState.ApplySimGameEventResult(new List <SimGameEventResult>(results)); } // At the current location, a flareup gets a popup - whether or not the player was involved, it's important. if (WIIC.sim.CurSystem == location) { SimGameInterruptManager queue = WIIC.sim.GetInterruptQueue(); string title = Strings.T($"{type} Complete"); string primaryButtonText = Strings.T("Acknowledged"); queue.QueuePauseNotification(title, text, WIIC.sim.GetCrewPortrait(SimGameCrew.Crew_Sumire), string.Empty, null, primaryButtonText); if (!queue.IsOpen) { queue.DisplayIfAvailable(); } // Things happening elsewhere in the galaxy just get an event toast. } else { sim.RoomManager.ShipRoom.AddEventToast(new Text(text)); } }
static void Postfix(Starmap __instance, SimGameState simGame) { try { PersistentMapClient.Logger.LogIfDebug($"methodSetOwner is:({methodSetOwner})"); PersistentMapClient.Logger.LogIfDebug($"methodSetContractEmployers is:({methodSetContractEmployers})"); PersistentMapClient.Logger.LogIfDebug($"methodSetContractTargets is:({methodSetContractTargets})"); PersistentMapClient.Logger.LogIfDebug($"methodSetDescription is:({methodSetDescription})"); PersistentMapClient.Logger.LogIfDebug($"fieldSimGameInterruptManager is:({fieldSimGameInterruptManager})"); Fields.currentMap = Web.GetStarMap(); if (Fields.currentMap == null) { PersistentMapClient.Logger.LogIfDebug("Map not found"); SimGameInterruptManager interruptQueue = (SimGameInterruptManager)fieldSimGameInterruptManager.GetValue(simGame); interruptQueue.QueueGenericPopup_NonImmediate("Connection Failure", "Map could not be downloaded", true); return; } List <string> changeNotifications = new List <string>(); List <StarSystem> transitiveContractUpdateTargets = new List <StarSystem>(); foreach (PersistentMapAPI.System system in Fields.currentMap.systems) { if (system == null) { PersistentMapClient.Logger.Log("System in map null"); } if (system.activePlayers > 0) { AddActivePlayersBadgeToSystem(system); } StarSystem system2 = simGame.StarSystems.Find(x => x.Name.Equals(system.name)); if (system2 != null) { if (system2.Tags == null) { PersistentMapClient.Logger.Log(system2.Name + ": Has no Tags"); } Faction newOwner = system.controlList.OrderByDescending(x => x.percentage).First().faction; Faction oldOwner = system2.Owner; // Update control to the new faction methodSetOwner.Invoke(system2.Def, new object[] { newOwner }); system2.Tags.Remove(Helper.GetFactionTag(oldOwner)); system2.Tags.Add(Helper.GetFactionTag(newOwner)); system2 = Helper.ChangeWarDescription(system2, simGame, system); // Update the contracts on the system methodSetContractEmployers.Invoke(system2.Def, new object[] { Helper.GetEmployees(system2, simGame) }); methodSetContractTargets.Invoke(system2.Def, new object[] { Helper.GetTargets(system2, simGame) }); // If the system is next to enemy factions, update the map to show the border if (Helper.IsBorder(system2, simGame) && simGame.Starmap != null) { system2.Tags.Add("planet_other_battlefield"); } else { system2.Tags.Remove("planet_other_battlefield"); } // If the owner changes, add a notice to the player and mark neighbors for contract updates if (newOwner != oldOwner) { string newOwnerName = Helper.GetFactionShortName(newOwner, simGame.DataManager); string oldOwnerName = Helper.GetFactionShortName(oldOwner, simGame.DataManager); changeNotifications.Add($"{newOwnerName} took {system2.Name} from {oldOwnerName}"); foreach (StarSystem changedSystem in simGame.Starmap.GetAvailableNeighborSystem(system2)) { if (!transitiveContractUpdateTargets.Contains(changedSystem)) { transitiveContractUpdateTargets.Add(changedSystem); } } } } } // For each system neighboring a system whose ownership changed, update their contracts as well foreach (StarSystem changedSystem in transitiveContractUpdateTargets) { methodSetContractEmployers.Invoke(changedSystem.Def, new object[] { Helper.GetEmployees(changedSystem, simGame) }); methodSetContractTargets.Invoke(changedSystem.Def, new object[] { Helper.GetTargets(changedSystem, simGame) }); // Update the description on these systems to show the new contract options PersistentMapAPI.System system = Fields.currentMap.systems.FirstOrDefault(x => x.name.Equals(changedSystem.Name)); if (system != null) { methodSetDescription.Invoke(changedSystem.Def, new object[] { Helper.ChangeWarDescription(changedSystem, simGame, system).Def.Description }); } } if (changeNotifications.Count > 0 && !Fields.firstpass) { SimGameInterruptManager interruptQueue2 = (SimGameInterruptManager)fieldSimGameInterruptManager.GetValue(simGame); interruptQueue2.QueueGenericPopup_NonImmediate("War Activities", string.Join("\n", changeNotifications.ToArray()), true); } else { Fields.firstpass = false; } } catch (Exception e) { PersistentMapClient.Logger.LogError(e); } }
public void conclude() { Settings s = WIIC.settings; removeParticipationContracts(); string text = Strings.T(completionText(), attacker.FactionDef.Name, location.OwnerValue.FactionDef.Name, location.Name); // Because shortnames can start with a lowercase 'the' ("the Aurigan Coalition", for example), we have to fix the capitalization or the result can look weird. text = text.Replace(". the ", ". The "); text = char.ToUpper(text[0]) + text.Substring(1); // At the current location, a flareup gets a popup - whether or not the player was involved, it's important. if (WIIC.sim.CurSystem == location) { SimGameInterruptManager queue = WIIC.sim.GetInterruptQueue(); string title = Strings.T($"{type} Complete"); string primaryButtonText = Strings.T("Acknowledged"); string itemCollection = reward(); WIIC.modLog.Info?.Write(text); WIIC.modLog.Info?.Write($"Reward: {itemCollection} for {employer.Name}"); Sprite sprite = attackerStrength > 0 ? attacker.FactionDef.GetSprite() : location.OwnerValue.FactionDef.GetSprite(); queue.QueuePauseNotification(title, text, sprite, string.Empty, delegate { try { if (itemCollection != null) { queue.QueueRewardsPopup(itemCollection); } } catch (Exception e) { WIIC.modLog.Error?.Write(e); } }, primaryButtonText); if (!queue.IsOpen) { queue.DisplayIfAvailable(); } // Things happening elsewhere in the galaxy just get an event toast. } else { WIIC.sim.RoomManager.ShipRoom.AddEventToast(new Text(text)); } // Now apply the owner or stat changes if (type == "Attack" && defenderStrength <= 0 && attackerStrength > 0) { Utilities.applyOwner(location, attacker, true); } else if (type == "Raid") { SimGameEventResult result = new SimGameEventResult(); result.Scope = EventScope.Company; result.TemporaryResult = true; result.ResultDuration = s.raidResultDuration; if (attackerStrength <= 0) { SimGameStat attackStat = new SimGameStat($"WIIC_{attacker.Name}_attack_strength", 1, false); SimGameStat defenseStat = new SimGameStat($"WIIC_{location.OwnerValue.Name}_defense_strength", -1, false); result.Stats = new SimGameStat[] { attackStat, defenseStat }; } else if (defenderStrength <= 0) { SimGameStat attackStat = new SimGameStat($"WIIC_{attacker.Name}_attack_strength", -1, false); SimGameStat defenseStat = new SimGameStat($"WIIC_{location.OwnerValue.Name}_defense_strength", 1, false); result.Stats = new SimGameStat[] { attackStat, defenseStat }; } SimGameEventResult[] results = { result }; SimGameState.ApplySimGameEventResult(new List <SimGameEventResult>(results)); } }
static void Postfix(SimGameState __instance, string id) { try { Settings settings = Helper.LoadSettings(); int itemCount = __instance.GetItemCount(id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); int defaultMechPartMax = __instance.Constants.Story.DefaultMechPartMax; if (itemCount + 1 >= defaultMechPartMax) { for (int i = 0; i < defaultMechPartMax - 1; i++) { ReflectionHelper.InvokePrivateMethode(__instance, "RemoveItemStat", new object[] { id, "MECHPART", false }); } MechDef mechDef = new MechDef(__instance.DataManager.MechDefs.Get(id), __instance.GenerateSimGameUID()); if (!settings.HeadRepaired) { mechDef.Head.CurrentInternalStructure = 0f; } if (!settings.LeftArmRepaired) { mechDef.LeftArm.CurrentInternalStructure = 0f; } if (!settings.RightArmRepaired) { mechDef.RightArm.CurrentInternalStructure = 0f; } if (!settings.LeftLegRepaired) { mechDef.LeftLeg.CurrentInternalStructure = 0f; } if (!settings.RightLegRepaired) { mechDef.RightLeg.CurrentInternalStructure = 0f; } if (!settings.CentralTorsoRepaired) { mechDef.CenterTorso.CurrentInternalStructure = 0f; } if (!settings.RightTorsoRepaired) { mechDef.RightTorso.CurrentInternalStructure = 0f; } if (!settings.LeftTorsoRepaired) { mechDef.LeftTorso.CurrentInternalStructure = 0f; } foreach (MechComponentRef comp in mechDef.Inventory) { if (mechDef.IsLocationDestroyed(comp.MountedLocation) || settings.NoItems) { comp.DamageLevel = ComponentDamageLevel.Destroyed; } } __instance.AddMech(0, mechDef, true, false, true, null); SimGameInterruptManager interrupt = (SimGameInterruptManager)ReflectionHelper.GetPrivateField(__instance, "interruptQueue"); interrupt.DisplayIfAvailable(); __instance.MessageCenter.PublishMessage(new SimGameMechAddedMessage(mechDef, true)); } else { __instance.AddItemStat(id, "MECHPART", false); } } catch (Exception e) { Logger.LogError(e); } }
// Run after completion of contracts and queue up any orders in the temp queue into the game's Mech Lab queue public static void Postfix(SimGameState __instance) { try { foreach (var mechDef in Core.CombatMechs) { if (mechDef.MechDefCurrentStructure < mechDef.MechDefMaxStructure) { continue; } bool componentDamage = false; for (int i = 0; i < mechDef.inventory.Length; i++) { if (mechDef.inventory[i].DamageLevel == ComponentDamageLevel.Destroyed || mechDef.inventory[i].DamageLevel == ComponentDamageLevel.NonFunctional) { componentDamage = true; } } if (componentDamage) { continue; } var tempWO = Helpers.CreateBaseMechLabOrder(__instance, mechDef); tempWO.AddSubEntry(Repair_ReArm.RepairArmorMechDef(mechDef)); Core.tempMechLabQueue.Add(tempWO); } // If there are any work orders in the temporary queue, prompt the player if (Core.tempMechLabQueue.Count > 0) { Logger.LogDebug("Processing temp Mech Lab queue orders."); int cbills = 0; int techCost = 0; int mechRepairCount = 0; int skipMechCount = 0; string mechRepairCountDisplayed = String.Empty; string skipMechCountDisplayed = String.Empty; string skipMechMessage = String.Empty; string finalMessage = String.Empty; //int Counter = Core.tempMechLabQueue.Count; //for (int index = Counter - 1; index < 0; index--) //{ // if (Counter == 0) // break; // WorkOrderEntry_MechLab order = Core.tempMechLabQueue[index]; // LogDebug("Checking for destroyed components."); // bool destroyedComponents = false; // MechDef mech = __instance.GetMechByID(order.MechID); // if (mech != null) // destroyedComponents = Helpers.CheckDestroyedComponents(mech); // else // destroyedComponents = true; // if (destroyedComponents) // { // // Remove this work order from the temp mech lab queue if the mech has destroyed components and move to next iteration // Logger.LogDebug("Removing " + mech.Name + " order from temp queue due to destroyed components and mod settings."); // Core.tempMechLabQueue.Remove(order); // destroyedComponents = false; // skipMechCount++; // } //} // Calculate summary of total repair costs from the temp work order queue for (int index = 0; index < Core.tempMechLabQueue.Count; index++) { if (Core.tempMechLabQueue.Count == 0) { break; } WorkOrderEntry_MechLab order = Core.tempMechLabQueue[index]; MechDef mech = __instance.GetMechByID(order.MechID); LogDebug("Adding " + mech.Name + " to RepairCount."); cbills += order.GetCBillCost(); techCost += order.GetCost(); mechRepairCount++; } mechRepairCount = Mathf.Clamp(mechRepairCount, 0, 6); // If Yang's Auto Repair prompt is enabled, build a message prompt dialog for the player if (true) { // Calculate a friendly techCost of the work order in days, based on number of current mechtechs in the player's game. if (techCost != 0 && __instance.MechTechSkill != 0) { techCost = Mathf.CeilToInt((float)techCost / (float)__instance.MechTechSkill); } else { techCost = 1; // Safety in case of weird div/0 } // Generate a quick friendly description of how many mechs were damaged in battle switch (mechRepairCount) { case 0: { Logger.LogDebug("mechRepairCount was 0."); break; } case 1: { mechRepairCountDisplayed = "one of our 'Mechs had only its armor"; break; } case 2: { mechRepairCountDisplayed = "a couple of the 'Mechs had only their armor"; break; } case 3: { mechRepairCountDisplayed = "three of our 'Mechs had only their armor"; break; } case 4: { mechRepairCountDisplayed = "an entire lance of ours had only their armor"; break; } case 5: { mechRepairCountDisplayed = "five of our 'Mechs had only their armor"; break; } case 6: { mechRepairCountDisplayed = "every 'Mech we dropped with had only their armor"; break; } } // Generate a friendly description of how many mechs were damaged but had components destroyed switch (skipMechCount) { case 0: { Logger.LogDebug("skipMechCount was 0."); break; } case 1: { skipMechCountDisplayed = "one of the 'Mechs is damaged but has"; break; } case 2: { skipMechCountDisplayed = "two of the 'Mechs are damaged but have"; break; } case 3: { skipMechCountDisplayed = "three of the 'Mechs are damaged but have "; break; } case 4: { skipMechCountDisplayed = "the whole lance is damaged but has"; break; } } // Check if there are any mechs to process if (mechRepairCount > 0 || skipMechCount > 0) { Logger.LogDebug("mechRepairCount is " + mechRepairCount + " skipMechCount is " + skipMechCount); // Setup the notification for mechs with damaged components that we might want to skip if (skipMechCount > 0 && mechRepairCount == 0) { skipMechMessage = String.Format("{0} destroyed components. I'll leave the repairs for you to review.", skipMechCountDisplayed); } else { skipMechMessage = String.Format("{0} destroyed components, so I'll leave those repairs to you.", skipMechCountDisplayed); } Logger.LogDebug("Firing Yang's UI notification."); SimGameInterruptManager notificationQueue = __instance.GetInterruptQueue(); // If all of the mechs needing repairs have damaged components and should be skipped from auto-repair, change the message notification structure to make more sense (e.g. just have an OK button) if (skipMechCount > 0 && mechRepairCount == 0) { finalMessage = String.Format( "Boss, {0} \n\n", skipMechMessage ); // Queue Notification notificationQueue.QueuePauseNotification( "'Mech Armor Repairs Needed", finalMessage, __instance.GetCrewPortrait(SimGameCrew.Crew_Yang), string.Empty, delegate { Logger.LogDebug("[PROMPT] All damaged mechs had destroyed components and won't be queued for repair."); }, "OK" ); } else { if (skipMechCount > 0) { finalMessage = String.Format( "Boss, {0} damaged. It'll cost <color=#DE6729>{1}{2:n0}</color> and {3} days for these repairs. Want my crew to get started?\n\nAlso, {4}\n\n", mechRepairCountDisplayed, '¢', cbills.ToString(), techCost.ToString(), skipMechMessage ); } else { finalMessage = String.Format( "Boss, {0} damaged on the last engagement. It'll cost <color=#DE6729>{1}{2:n0}</color> and {3} days for the repairs.\n\nWant my crew to get started?", mechRepairCountDisplayed, '¢', cbills.ToString(), techCost.ToString() ); } // Queue up Yang's notification notificationQueue.QueuePauseNotification( "'Mech Armor Repairs Needed", finalMessage, __instance.GetCrewPortrait(SimGameCrew.Crew_Yang), string.Empty, delegate { Logger.LogDebug("[PROMPT] Moving work orders from temp queue to Mech Lab queue: " + Core.tempMechLabQueue.Count + " work orders"); foreach (WorkOrderEntry_MechLab workOrder in Core.tempMechLabQueue.ToList()) { Helpers.SubmitWorkOrder(__instance, workOrder); Core.tempMechLabQueue.Remove(workOrder); } }, "Yes", delegate { foreach (WorkOrderEntry_MechLab workOrder in Core.tempMechLabQueue.ToList()) { Core.tempMechLabQueue.Remove(workOrder); } }, "No" ); } } } } } catch (Exception ex) { Core.tempMechLabQueue.Clear(); Error(ex); } }