private static void add_default_actuators(MechDef mechdef, SimGameState simgame) { void process_location(ChassisLocations location) { var total_slots = ArmActuatorSlot.None; foreach (var item in mechdef.Inventory.Where(i => i.MountedLocation == location && i.Is <ArmActuator>()).Select(i => i.GetComponent <ArmActuator>())) { total_slots = total_slots | item.Type; } AddDefaultToInventory(mechdef, simgame, location, ArmActuatorSlot.PartShoulder, ref total_slots); AddDefaultToInventory(mechdef, simgame, location, ArmActuatorSlot.PartUpper, ref total_slots); } process_location(ChassisLocations.RightArm); process_location(ChassisLocations.LeftArm); }
public static string GetMechCountDescrString(SimGameState s, MechDef d) { int pieces = s.GetItemCount(d.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); int needed = s.Constants.Story.DefaultMechPartMax; int varpieces = GetNumPartsForAssembly(s, d); int owned = GetNumberOfMechsOwnedOfType(s, d); string ownedorknown; if (owned == 0 && d.Chassis.IsOmni() && IsVariantKnown(s, d)) { ownedorknown = "K"; } else { ownedorknown = owned.ToString(); } return($"{pieces}({varpieces})/{needed}({ownedorknown})"); }
static void Postfix(MechRepresentationSimGame __instance, MechDef mechDef) { if (!chassisScaleFactors.ContainsKey(mechDef.ChassisID)) { return; } Logger.Debug($"[MechRepresentationSimGame_Init_POSTFIX] Rescaling..."); string identifier = mechDef.ChassisID; float fallbackScale = simGameScaleDefault; Vector3 adjustedLocalScale = GetScaleVector(identifier, fallbackScale, true); Logger.Debug($"[MechRepresentationSimGame_Init_POSTFIX] {identifier}: {adjustedLocalScale}"); __instance.rootTransform.localScale = adjustedLocalScale; }
public static void Postfix(object data, LocalizableText ___NameField, LocalizableText ___VariantField) { MechDef mechDef = data as MechDef; if (MechNamesHelper.HasUiName(mechDef)) { ___NameField.SetText(mechDef.Description.UIName, Array.Empty <object>()); } else { ___NameField.SetText(mechDef.Description.Name, Array.Empty <object>()); ___VariantField.SetText("( {0} {1} )", new object[] { mechDef.Chassis.Description.Name, mechDef.Chassis.VariantName }); } }
public void ValidateMech(MechDef mechDef, Errors errors) { foreach (var location in MechDefBuilder.Locations) { var inventory = mechDef.Inventory.Where(x => x.MountedLocation == location).Select(x => x.Def); var hardpoints = mechDef.Chassis.GetLocationDef(location).Hardpoints; var calc = new HardpointOmniUsageCalculator(inventory, hardpoints); if (calc.OmniFree < 0) { if (errors.Add(MechValidationType.InvalidHardpoints, ErrorMessage(location))) { return; } } } }
public static MechDef GetSalvageRedirect(SimGameState s, MechDef m) { if (!SimpleMechAssembly_Main.Settings.UseOnlyCCAssemblyOptions) { if (SimpleMechAssembly_Main.Settings.StructurePointBasedSalvageMechPartSalvageRedirect.TryGetValue(m.Description.Id, out string red)) { if (s.DataManager.MechDefs.TryGet(red, out MechDef n) && n != null) { SimpleMechAssembly_Main.Log.Log($"mechpart salvage redirection (settings): {m.Description.Id}->{red}"); return(n); } } string c = m.MechTags.FirstOrDefault((x) => x.StartsWith("mech_MechPartSalvageRedirect_")); if (c != null) { c = c.Replace("mech_MechPartSalvageRedirect_", ""); if (s.DataManager.MechDefs.TryGet(c, out MechDef n) && n != null) { SimpleMechAssembly_Main.Log.Log($"mechpart salvage redirection (tag): {m.Description.Id}->{c}"); return(n); } } } IAssemblyVariant v = CCIntegration.GetCCAssemblyVariant(m.Chassis); if (v != null && v.Lootable != null) { if (s.DataManager.MechDefs.TryGet(v.Lootable, out MechDef o)) { SimpleMechAssembly_Main.Log.Log($"mechpart salvage redirection (lootable): {m.Description.Id}->{v.Lootable}"); return(o); } } if (!SimpleMechAssembly_Main.Settings.AllowNonMainVariants && !m.IsMechDefMain()) { MechDef ma = m.Chassis.GetMainMechDef(s.DataManager); if (ma != null) { SimpleMechAssembly_Main.Log.Log($"mechpart salvage redirection (main): {m.Description.Id}->{ma.Description.Id}"); return(ma); } } return(m); }
// Evaluates whether a given mech needs any armor repaired public static bool CheckArmorDamage(MechDef mech) { // Default to not requesting any armor repair bool mechNeedsArmor = false; // Using the repair priority for loop here as it is faster and simpler than foreach'ing over ChassisLocations and filtering out ones that don't have armor for (int index = 0; index < Globals.repairPriorities.Count; index++) { // Set current ChassisLocation ChassisLocations thisLoc = Globals.repairPriorities.ElementAt(index).Value; // Get current mech location loadout from the looped chassis definitions LocationLoadoutDef thisLocLoadout = mech.GetLocationLoadoutDef(thisLoc); // Friendly name for this location string thisLocName = thisLoc.ToString(); // Work out difference of armor lost for each location - default to 0 int armorDifference = 0; // Consider rear armour in difference calculation if this is a RT, CT or LT if (thisLocLoadout == mech.CenterTorso || thisLocLoadout == mech.RightTorso || thisLocLoadout == mech.LeftTorso) { armorDifference = (int)Mathf.Abs(thisLocLoadout.CurrentArmor - thisLocLoadout.AssignedArmor) + (int)Mathf.Abs(thisLocLoadout.CurrentRearArmor - thisLocLoadout.AssignedRearArmor); } else { armorDifference = (int)Mathf.Abs(thisLocLoadout.CurrentArmor - thisLocLoadout.AssignedArmor); } // If any difference betwen the location's current and assigned armor is detected, flag this mech for armor repair if (armorDifference > 0) { Logger.LogDebug(mech.Name + " requires armor repair based on armor loss from: " + thisLocName); mechNeedsArmor = true; break; // Stop evaluating other locations once a repair requirement is determined on any location (no point checking further) } } if (!mechNeedsArmor) { Logger.LogInfo(mech.Name + " does not require armor repairs."); } return(mechNeedsArmor); }
public static void UnStorageOmniMechPopup(SimGameState s, MechDef d, Action onClose) { if (Settings.OmniMechTag == null) { onClose?.Invoke(); throw new InvalidOperationException("omnimechs disabled"); } int mechbay = s.GetFirstFreeMechBay(); if (mechbay < 0) { onClose?.Invoke(); return; } IEnumerable <MechDef> mechs = GetAllOmniVariants(s, d); string desc = "Yang: We know the following Omni variants. What should I ready this 'Mech as?\n\n"; GenericPopupBuilder pop = GenericPopupBuilder.Create("Ready 'Mech?", desc); pop.AddButton("nothing", onClose, true, null); foreach (MechDef m in mechs) { MechDef var = m; // new var to keep it for lambda if (!CheckOmniKnown(s, d, m)) { if (Settings.ShowAllVariantsInPopup) { pop.Body += $"unknown: [[DM.MechDefs[{m.Description.Id}],{m.Chassis.Description.UIName} {m.Chassis.VariantName}]]\n"; } continue; } pop.AddButton($"{var.Chassis.VariantName}", delegate { Log.Log("ready omni as: " + var.Description.Id); s.ScrapInactiveMech(d.Chassis.Description.Id, false); ReadyMech(s, new MechDef(var, s.GenerateSimGameUID(), false), mechbay); onClose?.Invoke(); }, true, null); int com = GetNumberOfMechsOwnedOfType(s, m); int cost = m.GetMechSellCost(s); pop.Body += $"[[DM.MechDefs[{m.Description.Id}],{m.Chassis.Description.UIName} {m.Chassis.VariantName}]] ({com} Complete) ({SimGameState.GetCBillString(cost)})\n"; } pop.AddFader(new UIColorRef?(LazySingletonBehavior <UIManager> .Instance.UILookAndColorConstants.PopupBackfill), 0f, true); pop.Render(); }
public string ValidateDrop(MechLabItemSlotElement drop_item, MechDef mech, List <InvItem> new_inventory, List <IChange> changes) { var inventory = new_inventory.Select(x => { var r = new MechComponentRef(x.item); Traverse.Create(r).Property(nameof(MechComponentRef.MountedLocation)).SetValue(x.location); return(r); }).ToList(); var mechDef = new MechDef(mech); mechDef.SetInventory(inventory.ToArray()); var errors = new Errors(); validator.ValidateMech(mechDef, errors); return(errors.FirstOrDefault()?.Message ?? string.Empty); }
public static MechDef GetMechDef(string mechID, SimGameState __instance) { List <MechDef> list = new List <MechDef>(__instance.ActiveMechs.Values); if (__instance.ActiveMechs == null) { return(null); } for (int i = 0; i < list.Count; i++) { MechDef mechDef = list[i]; if (mechDef != null && string.Compare(mechID, mechDef.Description.Id) == 0) //&& (string.IsNullOrEmpty(uniqueID) || string.Compare(uniqueID, mechDef.GUID) == 0)) { return(mechDef); } } return(null); }
internal static int PartDestroyed(MechDef mech) { if (mech.IsLocationDestroyed(ChassisLocations.CenterTorso)) { return(Control.Settings.CenterTorsoDestroyedParts); } float total = Control.Settings.SalvageArmWeight * 2 + Control.Settings.SalvageHeadWeight + Control.Settings.SalvageLegWeight * 2 + Control.Settings.SalvageTorsoWeight * 2 + 1; float val = total; val -= mech.IsLocationDestroyed(ChassisLocations.Head) ? Control.Settings.SalvageHeadWeight : 0; val -= mech.IsLocationDestroyed(ChassisLocations.LeftTorso) ? Control.Settings.SalvageTorsoWeight : 0; val -= mech.IsLocationDestroyed(ChassisLocations.RightTorso) ? Control.Settings.SalvageTorsoWeight : 0; val -= mech.IsLocationDestroyed(ChassisLocations.LeftLeg) ? Control.Settings.SalvageLegWeight : 0; val -= mech.IsLocationDestroyed(ChassisLocations.RightLeg) ? Control.Settings.SalvageLegWeight : 0; val -= mech.IsLocationDestroyed(ChassisLocations.LeftArm) ? Control.Settings.SalvageArmWeight : 0; val -= mech.IsLocationDestroyed(ChassisLocations.LeftLeg) ? Control.Settings.SalvageArmWeight : 0; var constants = UnityGameInstance.BattleTechGame.Simulation.Constants; int numparts = (int)(constants.Story.DefaultMechPartMax * val / total + 0.5f); if (numparts <= 0) { numparts = 1; } if (numparts > constants.Story.DefaultMechPartMax) { numparts = constants.Story.DefaultMechPartMax; } return(numparts); }
public static IEnumerable <MechDef> GetAllAssemblyVariants(SimGameState s, MechDef m) { if (m.IsVehicle()) { return(GetAllVehicleMechVariants(s, m)); } if (m.Chassis.IsOmni()) { return(GetAllOmniVariants(s, m)); } if (IsCrossAssemblyAllowed(s)) { return(GetAllNonOmniVariants(s, m)); } return(new List <MechDef>() { m }); }
public static List <KeyValuePair <string, int> > GetUpkeepLabels(SimGameState sgs) { Mod.Log.Info?.Write($" === Calculating Active Mech Labels === "); List <KeyValuePair <string, int> > labels = new List <KeyValuePair <string, int> >(); foreach (KeyValuePair <int, MechDef> entry in sgs.ActiveMechs) { MechDef mechDef = entry.Value; int mechCost = CaculateUpkeepCost(mechDef); string mechName = string.IsNullOrEmpty(mechDef.Description.UIName) ? mechDef.Name : mechDef.Description.UIName; Mod.Log.Debug?.Write($" Adding mech:{mechName} with cost:{mechCost}"); string upkeepLabel = new Text(Mod.LocalizedText.Labels[ModText.LT_Label_Mech_Upkeep], new object[] { mechName }).ToString(); labels.Add(new KeyValuePair <string, int>(upkeepLabel, mechCost)); } return(labels); }
public static bool Prefix(SimGameState __instance, WorkOrderEntry_RepairMechStructure order) { if (order.IsMechLabComplete) { return(true); } else { MechDef mechByID = __instance.GetMechByID(order.MechLabParent.MechID); LocationLoadoutDef locationLoadoutDef = mechByID.GetLocationLoadoutDef(order.Location); locationLoadoutDef.CurrentInternalStructure = mechByID.GetChassisLocationDef(order.Location).InternalStructure; // Original method resets currentArmor to assignedArmor here for some reason! Removed them from this override Logger.LogDebug("ALERT: Intercepted armor reset from ML_RepairMech and prevented it."); mechByID.RefreshBattleValue(); order.SetMechLabComplete(true); return(false); // Prevent original method from firing } }
private static void SalvageParts(ContractHelper contract, Vehicle vehicle, MechDef mech) { if (!string.IsNullOrEmpty(Control.Instance.Settings.NoVehiclePartsTag)) { if (vehicle.VehicleDef.VehicleTags.Contains(Control.Instance.Settings.NoVehiclePartsTag)) { Control.Instance.LogDebug(DInfo.Salvage, "Salvaging {0} - no parts by tags", mech.Description.Id); return; } } var simgame = contract.Contract.BattleTechGame.Simulation; var parts = NumParts(vehicle, simgame); if (string.IsNullOrEmpty(CustomSalvage.Control.Instance.Settings.NoSalvageVehicleTag) || !vehicle.VehicleDef.VehicleTags.Contains(CustomSalvage.Control.Instance.Settings.NoSalvageVehicleTag)) { contract.AddMechPartsToPotentialSalvage(simgame.Constants, mech, parts); } }
public static bool IsIgnoreFullActuators(MechDef mech) { if (!ArmActuatorFeature.settings.ForceFullDefaultActuators) { return(true); } if (mech.Chassis.Is <ArmActuatorSupport>(out var s) && s.IgnoreFullActuators) { return(true); } if (!string.IsNullOrEmpty(ArmActuatorFeature.settings.IgnoreFullActuatorsTag) && mech.Chassis.ChassisTags.Contains(ArmActuatorFeature.settings.IgnoreFullActuatorsTag)) { return(true); } return(false); }
internal ArmorWeightSavingCalculator(MechDef mechDef) : base(mechDef.Inventory.Where(c => c.Def.IsArmor()).ToList(), Control.settings.ArmorTypes) { var num = 0f; num += mechDef.Head.AssignedArmor; num += mechDef.CenterTorso.AssignedArmor; num += mechDef.CenterTorso.AssignedRearArmor; num += mechDef.LeftTorso.AssignedArmor; num += mechDef.LeftTorso.AssignedRearArmor; num += mechDef.RightTorso.AssignedArmor; num += mechDef.RightTorso.AssignedRearArmor; num += mechDef.LeftArm.AssignedArmor; num += mechDef.RightArm.AssignedArmor; num += mechDef.LeftLeg.AssignedArmor; num += mechDef.RightLeg.AssignedArmor; var tonnage = num / (UnityGameInstance.BattleTechGame.MechStatisticsConstants.ARMOR_PER_TENTH_TON * 10f); WeightSavings = Count == 0 ? 0 : WeightSavingForTonnage(tonnage); }
private static bool IsStructureDamaged(ref float percent, Mech mech, MechDef mechDef, ChassisLocations location) { if (float.IsNaN(percent)) { float hp, maxHp; if (mech != null) { hp = mech.GetCurrentStructure(location); maxHp = mech.GetMaxStructure(location); } else // if ( mechDef != null ) { hp = mechDef.GetLocationLoadoutDef(location).CurrentInternalStructure; maxHp = mechDef.GetChassisLocationDef(location).InternalStructure; } percent = hp / maxHp; } return(percent < 1f); }
public static bool CanBeFieldedFF(MechDef mechdef) { if (IsIgnoreFullActuators(mechdef)) { return(CanBeFielded(mechdef)); } bool check_side(ChassisLocations location, ArmActuatorSlot limit) { var total_slots = ArmActuatorSlot.None; foreach (var item in mechdef.Inventory.Where(i => i.MountedLocation == location && i.Is <ArmActuator>())) { var a = item.GetComponent <ArmActuator>(); if ((a.Type & total_slots) != 0) { return(false); } total_slots = total_slots | a.Type; } if (total_slots < limit) { return(false); } if (total_slots > limit) { return(false); } return(true); } ArmActuatorSlot left = ArmActuatorSlot.Hand; ArmActuatorSlot right = ArmActuatorSlot.Hand; if (mechdef.Chassis.Is <ArmActuatorSupport>(out var support)) { left = support.LeftLimit; right = support.RightLimit; } return(check_side(ChassisLocations.LeftArm, left) && check_side(ChassisLocations.RightArm, right)); }
public static void Postfix(MechDef __instance) { try { var mechDef = __instance; var details = mechDef.Chassis.Description.Details; Control.Logger.Debug?.Log($"id={mechDef.Description.Id} details={details}"); var description = mechDef.Description; Traverse.Create(description) .Property <string>(nameof(description.Details)) .Value = details; } catch (Exception e) { Control.Logger.Error.Log(e); } }
public static MechDef GetMechDefFromVariantName(this MechLabPanel mechLabPanel, string variant) { foreach (KeyValuePair <string, ChassisDef> chassisDefs in mechLabPanel.Sim.DataManager.ChassisDefs) { string chassisId = chassisDefs.Key; ChassisDef chassisDef = chassisDefs.Value; if (chassisDef.VariantName == variant || chassisDef.VariantName.ToUpper() == variant) { string mechDefId = chassisDef.Description.Id.Replace("chassisdef", "mechdef"); Logger.Debug("[MechLabPanelExtensions_GetMechDefFromVariantName] Found MechDef: " + mechDefId); MechDef mechDef = mechLabPanel.Sim.DataManager.MechDefs.Get(mechDefId); return(mechDef); } } Logger.Debug("[MechLabPanelExtensions_GetMechDefFromVariantName] No MechDef found for VariantName: " + variant); return(null); }
public static void Prefix(SimGameState __instance, MechDef def) { try { foreach (var mechComponentRef in def.Inventory) { if (mechComponentRef.DamageLevel == ComponentDamageLevel.Destroyed) { continue; } SimGameStateAddItemStatPatch.OnAddItemStat(__instance, mechComponentRef); } } catch (Exception e) { Control.mod.Logger.LogError(e); } }
static bool Prefix(int idx, MechDef mech, bool active, bool forcePlacement, bool displayMechPopup, string mechAddedHeader, SimGameState __instance) { Logger.Debug("AddMech Prefix Patch Installed"); if (displayMechPopup) { if (string.IsNullOrEmpty(mech.GUID)) { mech.SetGuid(__instance.GenerateSimGameUID()); } var companyStats = Traverse.Create(__instance).Field("companyStats").GetValue <StatCollection>(); companyStats.ModifyStat <int>("Mission", 0, "COMPANY_MechsAdded", StatCollection.StatOperation.Int_Add, 1, -1, true); if (string.IsNullOrEmpty(mechAddedHeader)) { mechAddedHeader = "'Mech Chassis Complete"; int num = (int)WwiseManager.PostEvent <AudioEventList_ui>(AudioEventList_ui.ui_sim_popup_newChassis, WwiseManager.GlobalAudioObject, (AkCallbackManager.EventCallback)null, (object)null); } mechAddedHeader += ": {0}"; __instance.GetInterruptQueue().QueuePauseNotification( string.Format(mechAddedHeader, (object)mech.Description.UIName), mech.Chassis.YangsThoughts, __instance.GetCrewPortrait(SimGameCrew.Crew_Yang), "notification_mechreadycomplete", (Action)(() => { int firstFreeMechBay = __instance.GetFirstFreeMechBay(); if (firstFreeMechBay >= 0) { __instance.ActiveMechs[firstFreeMechBay] = mech; SortMechLabMechs(__instance.GetMaxActiveMechs(), __instance.ActiveMechs, __instance.ReadyingMechs); } else { __instance.CreateMechPlacementPopup(mech); } }), "Continue", (Action)null, (string)null); return(false); } return(true); }
internal static void AddGyroIfPossible(MechDef mechDef) { if (!Control.settings.AutoFixMechDefGyro) { return; } if (mechDef.Inventory.Any(x => x.Def != null && x.Def.IsCenterTorsoUpgrade())) { return; } var componentRefs = new List <MechComponentRef>(mechDef.Inventory); var componentRef = new MechComponentRef(Control.GearGyroGeneric, null, ComponentType.Upgrade, ChassisLocations.CenterTorso); componentRefs.Add(componentRef); mechDef.SetInventory(componentRefs.ToArray()); }
internal static void AddCockpitIfPossible(MechDef mechDef) { if (!Control.settings.AutoFixMechDefCockpit) { return; } if (mechDef.Inventory.Any(x => x.Def != null && x.Def.IsCockpit())) { return; } var componentRefs = new List <MechComponentRef>(mechDef.Inventory); var componentRef = new MechComponentRef(Control.settings.AutoFixMechDefCockpitId, null, ComponentType.Upgrade, ChassisLocations.Head); componentRefs.Add(componentRef); mechDef.SetInventory(componentRefs.ToArray()); }
public static bool UnreadyVehicle(int baySlot, MechDef def, SimGameState __instance) { if (!def.IsVehicle()) { return(true); } if (def == null || (baySlot > 0 && !__instance.ActiveMechs.ContainsKey(baySlot))) { return(false); } if (__instance.ActiveMechs.ContainsKey(baySlot)) { __instance.ActiveMechs.Remove(baySlot); } __instance.AddItemStat(def.Chassis.Description.Id, def.GetType(), false); return(false); }
public static void StartLogMechDefDependencies(MechDef __instance) { if (UnpatchManager) { return; } if (monitoringMech != null) { Warn("Already logging dependencies for " + GetName(monitoringMech)); } monitoringMech = __instance; if (DebugLog) { Verbo("Start logging dependencies of {0}.", GetName(monitoringMech)); } if (!depender.ContainsKey(__instance)) { depender[__instance] = new HashSet <string>(); } }
public static bool GetHardpointCountForLocation_Prefix(MechDef mechDef, ChassisLocations loc, ref int numBallistic, ref int numEnergy, ref int numMissile, ref int numSmall) { try { HardpointInfo stockHardpoints = GetStockHardpointsByLocation(mechDef, loc); numBallistic += stockHardpoints.NumBallistic; numEnergy += stockHardpoints.NumEnergy; numMissile += stockHardpoints.NumMissile; numSmall += stockHardpoints.NumSmall; return(false); } catch (Exception e) { _harmonyManager.Log(e); return(true); } }
public static void Postfix(SimGameState __instance, WorkOrderEntry entry) { if (!Core.Settings.RepairRearm) { return; } if (entry.Type == WorkOrderType.MechLabModifyArmor) { Logger.LogDebug("CompleteWorkOrder"); WorkOrderEntry_MechLab workOrderEntry_MechLab = entry as WorkOrderEntry_MechLab; MechDef mechBayID = __instance.GetMechByID(workOrderEntry_MechLab.MechLabParent.MechID); if (mechBayID.MechTags.Contains("XLRP_Armor_Repairing")) { mechBayID.MechTags.Remove("XLRP_Armor_Repairing"); mechBayID.MechTags.Remove("XLRP_R&R"); mechBayID.MechTags.Where(tag => tag.StartsWith("XLRPArmor")).Do(x => mechBayID.MechTags.Remove(x)); } } }
public static void Postfix(MechDef mechDef, ref Dictionary <MechValidationType, List <string> > errorMessages) { try { for (int i = 0; i < mechDef.Inventory.Length; i++) { MechComponentRef mechComponentRef = mechDef.Inventory[i]; if (mechComponentRef.DamageLevel == ComponentDamageLevel.Destroyed) { Logger.LogDebug("Flagging destroyed component warning: " + mechDef.Name); errorMessages[MechValidationType.Underweight].Add(string.Format("DESTROYED COMPONENT: 'Mech has destroyed components", new object[0])); break; } } } catch (Exception ex) { Logger.LogError(ex); } }