static bool Prefix(SG_HiringHall_Screen __instance, Pilot ___selectedPilot, string button) { Mod.Log.Debug?.Write("Updating Dialog"); if (___selectedPilot != null && "Hire".Equals(button, StringComparison.InvariantCultureIgnoreCase) && __instance.HireButtonValid()) { Mod.Log.Debug?.Write(" -- pilot is selected"); CrewDetails details = ModState.GetCrewDetails(___selectedPilot.pilotDef); int modifiedBonus = (int)Mathf.RoundToInt(details.AdjustedBonus); string salaryS = new Text(Mod.LocalizedText.Labels[ModText.LT_Crew_Hire_Button], new string[] { SimGameState.GetCBillString(Mathf.RoundToInt(modifiedBonus)) }) .ToString(); Mod.Log.Debug?.Write($" -- bonus will be: {salaryS}"); GenericPopupBuilder.Create("Confirm?", salaryS) .AddButton("Cancel") .AddButton("Accept", __instance.HireCurrentPilot) .CancelOnEscape() .AddFader(LazySingletonBehavior <UIManager> .Instance.UILookAndColorConstants.PopupBackfill) .Render(); return(false); } return(true); }
static void Postfix(SG_HiringHall_Screen __instance, Pilot ___selectedPilot, LocalizableText ___MWInitialCostText, UIColorRefTracker ___MWCostColor, HBSDOTweenButton ___HireButton) { Mod.Log.Debug?.Write("Updating UpdateMoneySpot"); if (___selectedPilot != null) { Mod.Log.Debug?.Write(" -- pilot is selected"); // Account for the salary CrewDetails details = ModState.GetCrewDetails(___selectedPilot.pilotDef); int modifiedBonus = (int)Mathf.RoundToInt(details.AdjustedBonus); string bonus = new Text(Mod.LocalizedText.Labels[ModText.LT_Crew_Bonus_Label], new string[] { SimGameState.GetCBillString(Mathf.RoundToInt(modifiedBonus)) }) .ToString(); Mod.Log.Debug?.Write($" -- bonus will be: {bonus}"); ___MWInitialCostText.SetText(bonus); if (modifiedBonus > ModState.SimGameState.Funds) { Mod.Log.Debug?.Write(" -- Disabling hire."); ___MWCostColor.SetUIColor(UIColor.Red); ___HireButton.SetState(ButtonState.Disabled); } else { Mod.Log.Debug?.Write(" -- Enabling hire."); ___MWCostColor.SetUIColor(UIColor.White); ___HireButton.SetState(ButtonState.Enabled); } } }
static void Postfix(AAR_ContractObjectivesWidget __instance, Contract ___theContract) { try { List <Pilot> deployedPilots = ___theContract.PlayerUnitResults.Select(ur => ur.pilot).ToList(); int hazardPaySum = 0; foreach (Pilot p in deployedPilots) { CrewDetails details = ModState.GetCrewDetails(p.pilotDef); hazardPaySum -= details.HazardPay; } Mod.Log.Debug?.Write($"Total hazard pay for mission is: {hazardPaySum}"); string hazardPayTitleS = new Text(Mod.LocalizedText.Labels[ModText.LT_Contract_Hazard_Pay], new object[] { SimGameState.GetCBillString(hazardPaySum) }).ToString(); string guid = Guid.NewGuid().ToString(); MissionObjectiveResult hazardPayObjective = new MissionObjectiveResult(hazardPayTitleS, guid, false, true, ObjectiveStatus.Succeeded, false); Traverse addObjective = Traverse.Create(__instance).Method("AddObjective", new Type[] { typeof(MissionObjectiveResult) }); addObjective.GetValue(new object[] { hazardPayObjective }); } catch (Exception e) { Mod.Log.Warn?.Write(e, "Failed to build hazard pay for contract!"); } }
static void Postfix(SimGameState __instance, Pilot pilot, ref bool __result) { int currentMRBLevel = __instance.GetCurrentMRBLevel(); CrewDetails details = ModState.GetCrewDetails(pilot.pilotDef); __result = details.CanBeHiredAtMRBLevel(currentMRBLevel); }
static void Postfix(SGBarracksMWDetailPanel __instance, Pilot p, SGBarracksAdvancementPanel ___advancement, GameObject ___advancementSectionGO, SGBarracksDossierPanel ___dossier, SGBarracksServicePanel ___servicePanel, GameObject ___serviceSectionGO, HBSDOTweenButton ___customizeButton) { if (p == null) { return; } CrewDetails details = ModState.GetCrewDetails(p.pilotDef); GameObject skillsButton = __instance.gameObject.FindFirstChildNamed(ModConsts.GO_HBS_Barracks_Skill_Button); if (skillsButton == null) { Mod.Log.Debug?.Write("SkillsButton is null!"); } if (details.IsMechTechCrew || details.IsMedTechCrew || details.IsAerospaceCrew) { __instance.OnServiceSectionClicked(); skillsButton.SetActive(false); } else { skillsButton.SetActive(true); } }
public static void Postfix(SimGameState __instance, ref int __result, EconomyScale expenditureLevel, bool proRate) { Mod.Log.Trace?.Write($"SGS:GE entered with {__result}"); // Evaluate old versus new cost int vanillaCosts = 0; int newCosts = 0; for (int i = 0; i < __instance.PilotRoster.Count; i++) { PilotDef def = __instance.PilotRoster[i].pilotDef; vanillaCosts += __instance.GetMechWarriorValue(def); CrewDetails details = ModState.GetCrewDetails(def); newCosts += details.AdjustedSalary; } // Multiply old costs by expenditure. New has that built in. Then subtract them from the running total float expenditureCostModifier = __instance.GetExpenditureCostModifier(expenditureLevel); int vanillaTotal = Mathf.CeilToInt((float)vanillaCosts * expenditureCostModifier); Mod.Log.Trace?.Write($"Removing {vanillaCosts} costs x {expenditureCostModifier} expenditureMulti " + $"= {vanillaTotal} total vanilla costs."); __result -= vanillaTotal; // Add the new costs __result += newCosts; }
static bool Prefix(SimGameState __instance, PilotDef def, ref int __result) { CrewDetails details = ModState.GetCrewDetails(def); __result = details != null ? details.Salary : 0; return(false); }
public CrewDetails GetDetails(int id) { var crew = GetById(id); var pilot = _pilotService.GetById(crew.PilotId); var airhostesses = _airhostessService.GetByCrewId(id); return(CrewDetails.Create(crew, pilot, airhostesses)); }
static List <Pilot> AllMechWarriors() { List <Pilot> allPilots = ModState.SimGameState.PilotRoster.ToList(); return(allPilots.Where((p) => { CrewDetails cd = ModState.GetCrewDetails(p.pilotDef); return cd.IsMechWarrior; }).ToList()); }
public CrewDetails GetDetails(int id) { var crew = _unitOfWork.Set <Crew>() .Details(x => x.Id == id).FirstOrDefault(); if (crew == null) { throw new NotFoundException("Crew with such id was not found"); } return(CrewDetails.Create(crew)); }
public SaveFile() { Header = new Header(); Progress = new Progress(); ShipDesignation = new ShipDesignation(); Score = new Score(); ShipDetails = new ShipDetails(); CrewOverview = new CrewOverview(); ShipResources = new ShipResources(); CrewDetails = new CrewDetails(); FTLRemainder = new FTLRemainder("Remainder"); }
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(); } } } } }
public static SimGameEventDef CreateHeadHuntingEvent(Pilot pilot, CrewDetails details, float retentionCost, float buyoutPayment) { SimGameEventDef rawEventDef = ModState.SimGameState.DataManager.SimGameEventDefs.Get(ModConsts.Event_HeadHunting); int counterOffer = SalaryHelper.CalcCounterOffer(details) * -1; int buyout = details.AdjustedBonus; Mod.Log.Info?.Write($"For headhunting event, counterOffer: {counterOffer} buyout: {buyout}"); // Change the description fields BaseDescriptionDef rawBaseDescDef = rawEventDef.Description; StringBuilder detailsSB = new StringBuilder(rawBaseDescDef.Details); detailsSB.Append("\n\n"); detailsSB.Append("<margin=5em>\n"); detailsSB.Append( new Text(Mod.LocalizedText.Events[ModText.ET_HeadHunted_Retention], new object[] { SimGameState.GetCBillString(counterOffer) }).ToString() ); detailsSB.Append( new Text(Mod.LocalizedText.Events[ModText.ET_HeadHunted_Buyout], new object[] { SimGameState.GetCBillString(buyout) }).ToString() ); detailsSB.Append("</margin>\n"); BaseDescriptionDef newBaseDescDef = new BaseDescriptionDef(rawBaseDescDef.Id, rawBaseDescDef.Name, detailsSB.ToString(), rawBaseDescDef.Icon); // Change the options to have the correct pay values SimGameEventOption[] newOptions = rawEventDef.Options; foreach (SimGameEventOption sgeOption in newOptions) { if (ModConsts.Event_Option_HeadHunting_Leaves.Equals(sgeOption.Description.Id)) { // Mechwarrior leaves, company gets a payoff UpdateFundsStat(pilot, buyout, sgeOption); } else if (ModConsts.Event_Option_HeadHunting_Retained.Equals(sgeOption.Description.Id)) { // Mechwarrior statys, company pays them retention UpdateFundsStat(pilot, counterOffer, sgeOption); } } SimGameEventDef eventDef = new SimGameEventDef( rawEventDef.PublishState, rawEventDef.EventType, rawEventDef.Scope, newBaseDescDef, rawEventDef.Requirements, rawEventDef.AdditionalRequirements, rawEventDef.AdditionalObjects, newOptions, rawEventDef.Weight, rawEventDef.OneTimeEvent, rawEventDef.Tags); return(eventDef); }
public IList <CrewDetails> GetAllDetails() { var crews = GetAll(); var pilots = _pilotService.GetAll(); var airhostesses = _airhostessService.GetAll(); var joined = from crew in crews join pilot in pilots on crew.PilotId equals pilot.Id join airhostess in airhostesses on crew.Id equals airhostess.CrewId into crewAirhostesses select CrewDetails.Create(crew, pilot, crewAirhostesses); return(joined.ToList()); }
public static int CalcCounterOffer(CrewDetails details) { float counterOfferBounds = details.AdjustedBonus * Mod.Config.HeadHunting.CounterOfferVariance; float delta = counterOfferBounds - details.AdjustedBonus; float variance = delta * (float)Mod.Random.NextDouble(); Mod.Log.Debug?.Write($"Counter offer => adjustedBonus: {details.AdjustedBonus} + variance: {variance}"); int rawCounterOffer = (int)Math.Ceiling(details.AdjustedBonus + variance); int counterOffer = (rawCounterOffer / 10) * 10; // Round to nearest 10 cbills Mod.Log.Debug?.Write($" -- counterOffer: {counterOffer}"); return(counterOffer); }
static bool Prefix(SimGameState __instance, PilotDef def, ref string __result) { string salaryLabel = "------"; if (!def.IsFree) { CrewDetails details = ModState.GetCrewDetails(def); string cbillString = SimGameState.GetCBillString(Mathf.RoundToInt(details.AdjustedSalary)); salaryLabel = new Text(Mod.LocalizedText.Labels[ModText.LT_Crew_Salary_Label], new object[] { cbillString }) .ToString(); } __result = salaryLabel; return(false); }
// This is stupidly slow, but because the way the weighted works it's not easy to get a list of the // remaining elements. So we (unfortunately) iterate through the pilots until we find a mechwarrior. static Pilot NextSGSMechwarrior() { //___sim.PilotRoster.GetNext(true); Pilot mechWarrior = null; while (mechWarrior == null) { Pilot pilot = ModState.SimGameState.PilotRoster.GetNext(true); CrewDetails cd = ModState.GetCrewDetails(pilot.pilotDef); if (cd.IsMechWarrior) { mechWarrior = pilot; } } return(mechWarrior); }
static void Postfix(SimGameState __instance) { foreach (Pilot pilot in __instance.PilotRoster) { if (pilot.pilotDef.IsFree && pilot.pilotDef.IsImmortal) { continue; // player character, skip } // Initialize new details for the pre-generated pilots Mod.Log.Info?.Write($"Creating details for career-default pilot: {pilot.Name}"); // TODO: Randomize founders across all pilots CrewDetails details = CrewGenerator.GenerateDetailsForVanillaMechwarrior(pilot.pilotDef, true); Mod.Log.Info?.Write($" -- pilot will have GUID: {details.GUID}"); } }
static void Postfix(SG_HiringHall_MWSelectedPanel __instance, Pilot p, LocalizableText ___BaseSalaryText) { if (p != null && ___BaseSalaryText != null) { Mod.Log.Debug?.Write($"Updating MWSelectedPanel for pilot: {p.Name}"); // Account for the salary CrewDetails details = ModState.GetCrewDetails(p.pilotDef); int modifiedSalary = (int)Mathf.RoundToInt(details.AdjustedSalary); string modifiedSalaryS = SimGameState.GetCBillString(modifiedSalary); Mod.Log.Debug?.Write($" -- salary will be: {modifiedSalaryS}"); string salaryS = new Text(Mod.LocalizedText.Labels[ModText.LT_Crew_Salary_Label], new string[] { modifiedSalaryS }) .ToString(); ___BaseSalaryText.SetText(salaryS); } }
static void Postfix(SG_HiringHall_DetailPanel __instance, Pilot p, LocalizableText ___DescriptionText) { CrewDetails details = ModState.GetCrewDetails(p.pilotDef); StringBuilder sb = new StringBuilder(); // Check hazard pay if (details.HazardPay > 0) { string hazardPayS = new Text(Mod.LocalizedText.Labels[ModText.LT_Crew_Hazard_Pay], new object[] { SimGameState.GetCBillString(details.HazardPay) }).ToString(); Mod.Log.Debug?.Write($"Hazard pay is: {hazardPayS}"); sb.Append(hazardPayS); sb.Append("\n\n"); } // Convert favored and hated faction if (details.FavoredFactionId > 0) { FactionValue faction = FactionEnumeration.GetFactionByID(details.FavoredFactionId); string favoredFactionS = new Text(Mod.LocalizedText.Labels[ModText.LT_Crew_Dossier_Biography_Faction_Favored], new object[] { faction.FactionDef.CapitalizedName }).ToString(); sb.Append(favoredFactionS); sb.Append("\n\n"); Mod.Log.Debug?.Write($" Favored Faction is: {favoredFactionS}"); //Mod.Log.Debug?.Write($" Favored Faction => name: '{faction.Name}' friendlyName: '{faction.FriendlyName}' " + // $"factionDef.Name: {faction.FactionDef?.Name} factionDef.CapitalizedName: {faction.FactionDef.CapitalizedName} " + // $"factionDef.ShortName: {faction.FactionDef?.ShortName} factionDef.CapitalizedShortName: {faction.FactionDef.CapitalizedShortName} " + // $""); } if (details.HatedFactionId > 0) { FactionValue faction = FactionEnumeration.GetFactionByID(details.HatedFactionId); string hatedFactionS = new Text(Mod.LocalizedText.Labels[ModText.LT_Crew_Dossier_Biography_Faction_Hated], new object[] { faction.FactionDef.CapitalizedName }).ToString(); sb.Append(hatedFactionS); sb.Append("\n\n"); Mod.Log.Debug?.Write($" Hated Faction is: {hatedFactionS}"); } sb.Append(Interpolator.Interpolate(p.pilotDef.Description.GetLocalizedDetails().ToString(true), ModState.SimGameState.Context, true)); ___DescriptionText.SetText(sb.ToString()); }
static void Postfix(SGBarracksMWDetailPanel __instance, Pilot ___curPilot, SGBarracksAdvancementPanel ___advancement, GameObject ___advancementSectionGO, SGBarracksDossierPanel ___dossier, SGBarracksServicePanel ___servicePanel, GameObject ___serviceSectionGO, HBSDOTweenButton ___customizeButton) { if (___curPilot == null) { return; } CrewDetails details = ModState.GetCrewDetails(___curPilot.pilotDef); if (details.IsMechTechCrew || details.IsMedTechCrew || details.IsAerospaceCrew) { ___advancementSectionGO.SetActive(false); } }
static void Postfix(SG_HiringHall_Screen __instance, GameObject ___WarningAreaObject, HBSDOTweenButton ___HireButton, LocalizableText ___WarningText, HBSTooltip ___NoHireTooltip, Pilot ___selectedPilot) { Mod.Log.Debug?.Write("Updating MWSelectedPanel:WarningsCheck"); // Use the warnings area to display the contract length terms if (___selectedPilot != null && ___HireButton.State == ButtonState.Enabled) { ___WarningAreaObject.SetActive(true); CrewDetails details = ModState.GetCrewDetails(___selectedPilot.pilotDef); string contractTermS = new Text(Mod.LocalizedText.Labels[ModText.LT_Crew_Contract_Term], new object[] { details.ContractTerm } ).ToString(); ___WarningText.SetText(contractTermS); } }
static void Postfix(Contract __instance) { try { List <Pilot> deployedPilots = __instance.PlayerUnitResults.Select(ur => ur.pilot).ToList(); int hazardPaySum = 0; foreach (Pilot p in deployedPilots) { CrewDetails details = ModState.GetCrewDetails(p.pilotDef); hazardPaySum -= details.HazardPay; } Mod.Log.Debug?.Write($"Total hazard pay for contract is: {hazardPaySum}"); int newResult = Mathf.FloorToInt(__instance.MoneyResults - hazardPaySum); Traverse.Create(__instance).Property("MoneyResults").SetValue(newResult); } catch (Exception e) { Mod.Log.Error?.Write(e, "Failed to add hazard pay costs to contract"); } }
static void Prefix(LanceConfiguratorPanel __instance, ref List <Pilot> pilots) { if (ModState.SimGameState == null) { return; // Only patch if we're in SimGame } // Remove any pilots who are aerospace, mechtechs, or medtechs Mod.Log.Debug?.Write("Filtering pilots for LanceConfiguratorPanel"); List <Pilot> selectablePilots = new List <Pilot>(); foreach (Pilot p in pilots) { CrewDetails details = ModState.GetCrewDetails(p.pilotDef); if (details.IsMechWarrior || details.IsVehicleCrew) { Mod.Log.Debug?.Write($"Pilot {p.Name} is a mechwarrior or vehicle crew, adding as option"); selectablePilots.Add(p); } } pilots.Clear(); pilots.AddRange(selectablePilots); }
public static Pilot TestAllCrews() { // Determine our headhunting roll float randomRoll = (float)Mod.Random.NextDouble(); float econMod = Mod.Config.HeadHunting.EconMods[(int)ModState.SimGameState.ExpenditureLevel + 2]; float modifiedRoll = randomRoll + econMod; Mod.Log.Info?.Write($"HeadHunting roll: {modifiedRoll} = randomRoll: {randomRoll} + econMod: {econMod}"); if (econMod >= 100 || econMod <= 0) { Mod.Log.Info?.Write($" outside 0-100 bounds, failing roll."); return(null); } // Determine a random order for the list List <Pilot> pilots = ModState.SimGameState.PilotRoster.ToList(); pilots.Shuffle <Pilot>(); Pilot headHuntedPilot = null; foreach (Pilot pilot in pilots) { CrewDetails cd = ModState.GetCrewDetails(pilot.pilotDef); Mod.Log.Debug?.Write($"Checking pilot: {pilot.Name} for poaching for expertise: {cd.Expertise}"); float crewChance = Mod.Config.HeadHunting.ChanceBySkill[cd.Expertise]; Mod.Log.Debug?.Write($" -- chance for crew: {crewChance} vs. modifiedRoll: {modifiedRoll}"); if (crewChance <= modifiedRoll) { Mod.Log.Info?.Write($"Pilot: {pilot.Name} should be headhunted."); headHuntedPilot = pilot; break; } } return(headHuntedPilot); }
static bool Prefix(SGBarracksRosterList __instance, Pilot pilot, UnityAction <SGBarracksRosterSlot> pilotSelectedOnClick, bool isInHireHall, Dictionary <string, SGBarracksRosterSlot> ___currentRoster) { if (ModState.SimGameState == null) { return(true); // Only patch if we're in SimGame } Mod.Log.Debug?.Write($"Adding pilot {pilot.Callsign} to roster list."); if (!___currentRoster.ContainsKey(pilot.GUID)) { SGBarracksRosterSlot slot = __instance.GetSlot(); if (isInHireHall) { slot.InitNoDrag(pilot, ModState.SimGameState, pilotSelectedOnClick, showTheCost: true); slot.SetDraggable(isDraggable: false); // Update the pilot's contract end date CrewDetails details = ModState.GetCrewDetails(pilot.pilotDef); details.ExpirationDay = ModState.SimGameState.DaysPassed + details.ContractTerm; Mod.Log.Debug?.Write($" - pilot's contract ends on day: {details.ExpirationDay}"); ModState.UpdateOrCreateCrewDetails(pilot.pilotDef, details); } else { slot.Init(pilot, __instance, pilotSelectedOnClick); } ___currentRoster.Add(pilot.GUID, slot); slot.AddToRadioSet(__instance.listRadioSet); // Performance tweak; skip //ForceRefreshImmediate(); } return(false); }
static void Postfix(BattleTech.UI.AAR_ContractResults_Screen __instance, Contract ___theContract) { StringBuilder bodySB = new StringBuilder(); bodySB.Append(new Text(Mod.LocalizedText.Dialogs[ModText.DIAT_AAR_Body], new object[] { }).ToString()); int killedPilotsMod = Mod.Config.Attitude.PerMission.PilotKilledMod * ___theContract.KilledPilots.Count; if (___theContract.KilledPilots.Count > 0) { Mod.Log.Debug?.Write($"Player lost {___theContract.KilledPilots.Count} pilots, applying a modifier of {killedPilotsMod} to all pilots."); bodySB.Append( new Text(Mod.LocalizedText.Dialogs[ModText.DIAT_AAR_Mod_Pilot_Killed], new object[] { killedPilotsMod }).ToString() ); } // Add the monospace tag bodySB.Append(new Text(Mod.LocalizedText.Dialogs[ModText.DIAT_AAR_Mod_Font], new object[] { }).ToString()); // Calculate the contract bonus int contractBonus = Mod.Config.Attitude.PerMission.ContractFailedMod; if (___theContract.State == Contract.ContractState.Complete) { contractBonus = Mod.Config.Attitude.PerMission.ContractSuccessMod; Mod.Log.Debug?.Write($"Contract was successful, applying contract modifier of: {contractBonus}"); bodySB.Append( new Text(Mod.LocalizedText.Dialogs[ModText.DIAT_AAR_Mod_Contract_Success], new object[] { contractBonus }).ToString() ); } else if (___theContract.IsGoodFaithEffort) { contractBonus = Mod.Config.Attitude.PerMission.ContractFailedGoodFaithMod; Mod.Log.Debug?.Write($"Contract was a good faith effort, applying contract modifier of: {contractBonus}"); bodySB.Append( new Text(Mod.LocalizedText.Dialogs[ModText.DIAT_AAR_Mod_Contract_GoodFaith], new object[] { contractBonus }).ToString() ); } else { Mod.Log.Debug?.Write($"Contract was failed, applying contract modifier of: {contractBonus}"); bodySB.Append( new Text(Mod.LocalizedText.Dialogs[ModText.DIAT_AAR_Mod_Contract_Failed], new object[] { contractBonus }).ToString() ); } bodySB.Append("\n"); // Find just combat pilots (for benched mod) List <Pilot> allPilots = __instance.Sim.PilotRoster.ToList(); List <Pilot> combatPilots = allPilots.Where(p => { CrewDetails details = ModState.GetCrewDetails(p.pilotDef); return(details.IsCombatCrew); }).ToList(); Mod.Log.Debug?.Write($"All Combat pilots are: {string.Join(", ", combatPilots.Select(p => p.Name).ToList())}"); List <Pilot> deployedPilots = ___theContract.PlayerUnitResults.Select(ur => ur.pilot).ToList(); Mod.Log.Debug?.Write($"Deployed pilots were: {string.Join(", ", deployedPilots.Select(p => p.Name).ToList())}"); // Iterate pilots apply modifiers foreach (Pilot p in allPilots) { CrewDetails details = ModState.GetCrewDetails(p.pilotDef); if (details.IsPlayer) { continue; } int startingAttitude = details.Attitude; Mod.Log.Debug?.Write($"Applying attitude modifiers to pilot: {p.Name}"); // Apply modifier for contract success details.Attitude += contractBonus; // Applied killed pilots modifier details.Attitude += killedPilotsMod; List <string> detailDescs = new List <string>(); // Check for bench - only applies to combat pilots if (deployedPilots.Contains(p)) { Mod.Log.Debug?.Write($" -- combat pilot was deployed, adding {Mod.Config.Attitude.PerMission.DeployedOnMissionMod} attitude"); details.Attitude += Mod.Config.Attitude.PerMission.DeployedOnMissionMod; detailDescs.Add( new Text(Mod.LocalizedText.Dialogs[ModText.DIAT_AAR_Mod_Deployed], new object[] { Mod.Config.Attitude.PerMission.DeployedOnMissionMod }).ToString() ); } else if (combatPilots.Contains(p)) { Mod.Log.Debug?.Write($" -- combat pilot was benched, adding {Mod.Config.Attitude.PerMission.BenchedOnMissionMod} attitude"); details.Attitude += Mod.Config.Attitude.PerMission.BenchedOnMissionMod; detailDescs.Add( new Text(Mod.LocalizedText.Dialogs[ModText.DIAT_AAR_Mod_Benched], new object[] { Mod.Config.Attitude.PerMission.BenchedOnMissionMod }).ToString() ); } // Check favored / hated factions if (details.FavoredFactionId > 0) { if (details.FavoredFactionId == ___theContract.Override.employerTeam.FactionValue.FactionID) { Mod.Log.Debug?.Write($" -- pilot favors employer faction, applying modifier: {Mod.Config.Attitude.PerMission.FavoredFactionIsEmployerMod}"); details.Attitude += Mod.Config.Attitude.PerMission.FavoredFactionIsEmployerMod; detailDescs.Add( new Text(Mod.LocalizedText.Dialogs[ModText.DIAT_AAR_Mod_Favored_Employer], new object[] { Mod.Config.Attitude.PerMission.FavoredFactionIsEmployerMod }).ToString() ); } if (details.FavoredFactionId == ___theContract.Override.targetTeam.FactionValue.FactionID) { Mod.Log.Debug?.Write($" -- pilot favors target faction, applying modifier: {Mod.Config.Attitude.PerMission.FavoredFactionIsTargetMod}"); details.Attitude += Mod.Config.Attitude.PerMission.FavoredFactionIsTargetMod; detailDescs.Add( new Text(Mod.LocalizedText.Dialogs[ModText.DIAT_AAR_Mod_Favored_Target], new object[] { Mod.Config.Attitude.PerMission.FavoredFactionIsTargetMod }).ToString() ); } } if (details.HatedFactionId > 0) { if (details.HatedFactionId == ___theContract.Override.employerTeam.FactionValue.FactionID) { Mod.Log.Debug?.Write($" -- pilot hates employer faction, applying modifier: {Mod.Config.Attitude.PerMission.HatedFactionIsEmployerMod}"); details.Attitude += Mod.Config.Attitude.PerMission.HatedFactionIsEmployerMod; detailDescs.Add( new Text(Mod.LocalizedText.Dialogs[ModText.DIAT_AAR_Mod_Hated_Employer], new object[] { Mod.Config.Attitude.PerMission.HatedFactionIsEmployerMod }).ToString() ); } if (details.HatedFactionId == ___theContract.Override.targetTeam.FactionValue.FactionID) { Mod.Log.Debug?.Write($" -- pilot hates target faction, applying modifier: {Mod.Config.Attitude.PerMission.HatedFactionIsTargetMod}"); details.Attitude += Mod.Config.Attitude.PerMission.HatedFactionIsTargetMod; detailDescs.Add( new Text(Mod.LocalizedText.Dialogs[ModText.DIAT_AAR_Mod_Hated_Target], new object[] { Mod.Config.Attitude.PerMission.HatedFactionIsTargetMod }).ToString() ); } } // Clamp values to max and min details.Attitude = Mathf.Clamp(details.Attitude, Mod.Config.Attitude.ThresholdMin, Mod.Config.Attitude.ThresholdMax); string detailsS = string.Join(", ", detailDescs); bodySB.Append( new Text(Mod.LocalizedText.Dialogs[ModText.DIAT_AAR_Pilot_Line], new object[] { details.Attitude, p.Callsign, detailsS }).ToString() ); ModState.UpdateOrCreateCrewDetails(p.pilotDef, details); } // Close the mspace tag bodySB.Append("</mspace>"); // Display a dialog with changes string localDialogTitle = new Text(Mod.LocalizedText.Dialogs[ModText.DIAT_AAR_Title]).ToString(); string localDialogText = bodySB.ToString(); GenericPopup gp = GenericPopupBuilder.Create(localDialogTitle, localDialogText) .Render(); TextMeshProUGUI contentText = (TextMeshProUGUI)Traverse.Create(gp).Field("_contentText").GetValue(); contentText.alignment = TextAlignmentOptions.Left; }
public static void Postfix(SGCaptainsQuartersStatusScreen __instance, EconomyScale expenditureLevel, bool showMoraleChange, Transform ___SectionTwoExpensesList, TextMeshProUGUI ___SectionTwoExpensesField, SimGameState ___simState) { // Redo all the mechwarrior cost float expenditureCostModifier = ___simState.GetExpenditureCostModifier(expenditureLevel); ClearListLineItems(___SectionTwoExpensesList, ___simState); int ongoingMechWariorCosts = 0; //int oldCosts = 0; List <KeyValuePair <string, int> > list = new List <KeyValuePair <string, int> >(); foreach (Pilot item in ___simState.PilotRoster) { string key = item.pilotDef.Description.DisplayName; CrewDetails details = ModState.GetCrewDetails(item.pilotDef); //oldCosts += Mathf.CeilToInt(expenditureCostModifier * (float)___simState.GetMechWarriorValue(item.pilotDef)); Mod.Log.Debug?.Write($" Pilot: {item.Name} has salary: {details.AdjustedSalary}"); list.Add(new KeyValuePair <string, int>(key, details.AdjustedSalary)); } // Sort by most expensive list.Sort((KeyValuePair <string, int> a, KeyValuePair <string, int> b) => b.Value.CompareTo(a.Value)); // Create a new line item for each list.ForEach(delegate(KeyValuePair <string, int> entry) { ongoingMechWariorCosts += entry.Value; AddListLineItem(___SectionTwoExpensesList, ___simState, entry.Key, SimGameState.GetCBillString(entry.Value)); }); ___SectionTwoExpensesField.SetText(SimGameState.GetCBillString(ongoingMechWariorCosts)); // Rectify the salary field //SimGameState simGameState = UnityGameInstance.BattleTechGame.Simulation; //if (__instance == null || ___SectionOneExpensesList == null || ___SectionOneExpensesField == null || simGameState == null) //{ // Mod.Log.Debug?.Write($"SGCQSS:RD - skipping"); // return; //} //// TODO: Add this to mech parts maybe? ////float expenditureCostModifier = simGameState.GetExpenditureCostModifier(expenditureLevel); //// Determine the level of aerospace support ////Statistic aerospaceAssets = simGameState.CompanyStats.GetStatistic("AerospaceAssets"); ////int aerospaceSupport = aerospaceAssets != null ? aerospaceAssets.Value<int>() : 0; //Mod.Log.Info?.Write($"SGCQSS:RD - entered. Parsing current keys."); //List<KeyValuePair<string, int>> currentKeys = GetCurrentKeys(___SectionOneExpensesList, ___simState); //// Extract the active mechs from the list, then re-add the updated price //List<KeyValuePair<string, int>> filteredKeys = FilterActiveMechs(currentKeys, ___simState); //List<KeyValuePair<string, int>> activeMechs = GetUpkeepLabels(___simState); //filteredKeys.AddRange(activeMechs); //// Add the new costs //int newActiveMechCosts = MonthlyCostCalcs.SumMonthlyMechCosts(___simState); //filteredKeys.Sort(new ExpensesSorter()); //Mod.Log.Info?.Write($"SGCQSS:RD - Clearing items"); //ClearListLineItems(___SectionOneExpensesList, ___simState); //Mod.Log.Info?.Write($"SGCQSS:RD - Adding listLineItems"); //int totalCost = 0; //try //{ // foreach (KeyValuePair<string, int> kvp in filteredKeys) // { // Mod.Log.Info?.Write($"SGCQSS:RD - Adding key:{kvp.Key} value:{kvp.Value}"); // totalCost += kvp.Value; // AddListLineItem(___SectionOneExpensesList, ___simState, kvp.Key, SimGameState.GetCBillString(kvp.Value)); // } //} //catch (Exception e) //{ // Mod.Log.Info?.Write($"SGCQSS:RD - failed to add lineItemParts due to: {e.Message}"); //} //// Update summary costs //int newCosts = totalCost; //string newCostsS = SimGameState.GetCBillString(newCosts); //Mod.Log.Debug?.Write($"SGCQSS:RD - total:{newCosts} = activeMechs:{newActiveMechCosts}"); //try //{ // ___SectionOneExpensesField.SetText(SimGameState.GetCBillString(newCosts)); // Mod.Log.Debug?.Write($"SGCQSS:RD - updated "); //} //catch (Exception e) //{ // Mod.Log.Info?.Write($"SGCQSS:RD - failed to update summary costs section due to: {e.Message}"); //} }
static bool Prefix(string button) { Mod.Log.Info?.Write($"RBP invoked for button: {button}"); if ("Hiring".Equals(button, StringComparison.InvariantCultureIgnoreCase)) { if (Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt)) { Mod.Log.Info?.Write("-- Regenerating pilots in system."); ModState.SimGameState.CurSystem.AvailablePilots.Clear(); ModState.SimGameState.CurSystem.GeneratePilots(ModState.SimGameState.Constants.Story.DefaultPilotsPerSystem); } else if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl) && Mod.Config.HeadHunting.Enabled && ModState.SimGameState.TravelState == SimGameTravelStatus.IN_SYSTEM) { Mod.Log.Info?.Write("-- Forcing poaching on random crew."); // Randomize pilots instead of sorting by skill? List <Pilot> pilots = ModState.SimGameState.PilotRoster.ToList(); pilots.Sort((p1, p2) => { CrewDetails p1cd = ModState.GetCrewDetails(p1.pilotDef); CrewDetails p2cd = ModState.GetCrewDetails(p2.pilotDef); return(CrewDetails.CompareByValue(p1cd, p2cd)); }); int idx = Mod.Random.Next(0, pilots.Count - 1); Pilot random = pilots[idx]; Mod.Log.Info?.Write($"-- Headhunted pilot: {random.Name}"); CrewDetails cd = ModState.GetCrewDetails(random.pilotDef); SimGameEventDef newEvent = EventHelper.CreateHeadHuntingEvent(random, cd, cd.HiringBonus, cd.HiringBonus); Traverse mechWarriorEventTrackerT = Traverse.Create(ModState.SimGameState).Field("mechWarriorEventTracker"); SimGameEventTracker mechWarriorEventTracker = mechWarriorEventTrackerT.GetValue <SimGameEventTracker>(); ModState.HeadHuntedPilot = random; Mod.Log.Info?.Write($"-- Firing debug event"); ModState.SimGameState.Context.SetObject(GameContextObjectTagEnum.TargetMechWarrior, random); ModState.SimGameState.OnEventTriggered(newEvent, EventScope.MechWarrior, mechWarriorEventTracker); return(false); } else if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift) && ModState.SimGameState.TravelState == SimGameTravelStatus.IN_SYSTEM) { Mod.Log.Info?.Write("-- Forcing contract expiration on random crew."); // Randomize pilots instead of sorting by skill? List <Pilot> pilots = ModState.SimGameState.PilotRoster.ToList(); pilots.Sort((p1, p2) => { CrewDetails p1cd = ModState.GetCrewDetails(p1.pilotDef); CrewDetails p2cd = ModState.GetCrewDetails(p2.pilotDef); return(CrewDetails.CompareByValue(p1cd, p2cd)); }); int idx = Mod.Random.Next(0, pilots.Count - 1); Pilot random = pilots[idx]; Mod.Log.Info?.Write($"-- Expired pilot: {random.Name}"); CrewDetails cd = ModState.GetCrewDetails(random.pilotDef); ModState.ExpiredContracts.Enqueue((random, cd)); SimGameEventDef newEvent = EventHelper.ModifyContractExpirationEventForPilot(random, cd); Traverse mechWarriorEventTrackerT = Traverse.Create(ModState.SimGameState).Field("mechWarriorEventTracker"); SimGameEventTracker mechWarriorEventTracker = mechWarriorEventTrackerT.GetValue <SimGameEventTracker>(); ModState.SimGameState.OnEventTriggered(newEvent, EventScope.MechWarrior, mechWarriorEventTracker); return(false); } } return(true); }
static void Postfix(SGBarracksDossierPanel __instance, Pilot p, LocalizableText ___healthText, List <GameObject> ___healthList, LocalizableText ___salary, LocalizableText ___firstName, LocalizableText ___lastName) { if (p == null) { return; } Mod.DossierLog.Debug?.Write($"Updating Dossier for pilot: {p.Name}"); CrewDetails details = ModState.GetCrewDetails(p.pilotDef); if (details.IsMechTechCrew || details.IsMedTechCrew || details.IsAerospaceCrew) { ___healthText.SetText("N/A"); for (int i = 0; i < ___healthList.Count; i++) { ___healthList[i].SetActive(false); } } string nameS = new Text(Mod.LocalizedText.Labels[ModText.LT_Crew_Name_Format], new object[] { p.FirstName, p.LastName }).ToString(); ___firstName.SetText(nameS); // Set the firstname label to 'Name' instead of 'First Name' Mod.DossierLog.Debug?.Write("Updating firstName to Name"); GameObject firstNameGO = __instance.gameObject.FindFirstChildNamed(ModConsts.GO_HBS_Barracks_Dossier_LastName); GameObject firstNameLabelGO = firstNameGO.transform.parent.GetChild(0).GetChild(0).gameObject; LocalizableText firstNameLabel = firstNameLabelGO.GetComponentInChildren <LocalizableText>(); string firstNameS = new Text(Mod.LocalizedText.Labels[ModText.LT_Crew_Dossier_Contract_Term]).ToString(); firstNameLabel.SetText(firstNameS); // Set the lastname label to 'Contract End' and the name value to the remaining days Mod.DossierLog.Debug?.Write("Updating lastName to ContractTerm"); GameObject lastNameGO = __instance.gameObject.FindFirstChildNamed(ModConsts.GO_HBS_Barracks_Dossier_LastName); GameObject lastNameLabelGO = lastNameGO.transform.parent.GetChild(0).GetChild(0).gameObject; // should be text_lastName -> parent -> layout-label -> label LocalizableText lastNameLabel = lastNameLabelGO.GetComponentInChildren <LocalizableText>(); string contractTermS = new Text(Mod.LocalizedText.Labels[ModText.LT_Crew_Dossier_Contract_Term]).ToString(); lastNameLabel.SetText(contractTermS); string contractTermRemaining = "------"; if (!details.IsPlayer && details.ContractTerm != 0) { int daysRemaining = details.ExpirationDay - ModState.SimGameState.DaysPassed; if (daysRemaining < 0) { daysRemaining = 0; } contractTermRemaining = new Text(Mod.LocalizedText.Labels[ModText.LT_Crew_Dossier_Days_Remaining], new object[] { daysRemaining }).ToString(); Mod.DossierLog.Debug?.Write($" {daysRemaining} daysRemaining = {ModState.SimGameState.DaysPassed} daysPassed - {details.ExpirationDay} endDay"); } ___lastName.SetText(contractTermRemaining); Mod.DossierLog.Debug?.Write($" -- done updating dossier for pilot: {p.Name}"); }
public static SimGameEventDef ModifyContractExpirationEventForPilot(Pilot pilot, CrewDetails details) { SimGameEventDef rawEventDef = ModState.SimGameState.DataManager.SimGameEventDefs.Get(ModConsts.Event_ContractExpired); // Change the description fields BaseDescriptionDef rawBaseDescDef = rawEventDef.Description; StringBuilder detailsSB = new StringBuilder(rawBaseDescDef.Details); detailsSB.Append("\n"); detailsSB.Append("<margin=5em>\n"); // TODO: Localize detailsSB.Append($" Hiring Bonus: {SimGameState.GetCBillString(details.AdjustedBonus)}\n\n"); detailsSB.Append($" Monthly Salary: {SimGameState.GetCBillString(details.AdjustedSalary)}\n\n"); detailsSB.Append("</margin>\n"); BaseDescriptionDef newBaseDescDef = new BaseDescriptionDef(rawBaseDescDef.Id, rawBaseDescDef.Name, detailsSB.ToString(), rawBaseDescDef.Icon); // Change the options to have the correct pay values SimGameEventOption[] newOptions = rawEventDef.Options; foreach (SimGameEventOption sgeOption in newOptions) { if (ModConsts.Event_Option_ContractExpired_Hire_Bonus.Equals(sgeOption.Description.Id)) { (Pilot Pilot, CrewDetails Details)expired = ModState.ExpiredContracts.Peek(); UpdateFundsStat(pilot, expired.Details.AdjustedBonus, sgeOption); } } SimGameEventDef expiredEventDef = new SimGameEventDef( rawEventDef.PublishState, rawEventDef.EventType, rawEventDef.Scope, newBaseDescDef, rawEventDef.Requirements, rawEventDef.AdditionalRequirements, rawEventDef.AdditionalObjects, newOptions, rawEventDef.Weight, rawEventDef.OneTimeEvent, rawEventDef.Tags); return(expiredEventDef); }