public static void DumpMechs(SimGameState s, StreamWriter w, StreamWriter csv) { List <DumperDataEntry> mechs = new List <DumperDataEntry>(); Dictionary <string, DumperDataEntry> blacklist = new Dictionary <string, DumperDataEntry>(); mechs.Add(GetMechDesc()); foreach (KeyValuePair <string, MechDef> kv in s.DataManager.MechDefs) { int part = s.GetItemCount(kv.Key, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); int mechstor = s.GetItemCount(kv.Value.Chassis.Description.Id, kv.Value.GetType(), SimGameState.ItemCountType.UNDAMAGED_ONLY); int active = 0; int sma_parts = -1; MechDef d = kv.Value; foreach (KeyValuePair <int, MechDef> a in s.ActiveMechs) { if (kv.Value.ChassisID == a.Value.ChassisID) { active++; //d = a.Value; } } if (Del_SMA_GetNumPartsForAssembly != null) { sma_parts = Del_SMA_GetNumPartsForAssembly(s, kv.Value); } DumperDataEntry e = FillMech(d, part, s.Constants.Story.DefaultMechPartMax, mechstor, active, sma_parts); if (kv.Value.MechTags.Contains("BLACKLISTED")) { blacklist.Add(kv.Key, e); } else { mechs.Add(e); } } foreach (KeyValuePair <string, ItemCollectionDef> kv in s.DataManager.ItemCollectionDefs) { foreach (ItemCollectionDef.Entry e in kv.Value.Entries) { if (e.Type == ShopItemType.Mech || e.Type == ShopItemType.MechPart) { if (blacklist.ContainsKey(e.ID)) { mechs.Add(blacklist[e.ID]); blacklist.Remove(e.ID); } } } } WriteDataEntries(mechs, w, csv); }
public static void QueryMechAssemblyPopup(SimGameState s, MechDef d, MechBayPanel refresh = null, SimpleMechAssembly_InterruptManager_AssembleMechEntry close = null) { if (GetNumPartsForAssembly(s, d) < s.Constants.Story.DefaultMechPartMax) { if (close != null) { close.NewClose(); } return; } IEnumerable <MechDef> ownedMechVariantParts = GetAllAssemblyVariants(s, d) .Where(m => s.GetItemCount( m.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY) > 0 || CheckOmniKnown(s, d, m)); int selectedMechParts = s.GetItemCount(d.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); int numberOfChassisOwned = GetNumberOfMechsOwnedOfType(s, d); string desc = $"Yang: {d.Chassis.YangsThoughts}\n\n"; IEnumerable <string> additionalVariants = ownedMechVariantParts .Where(m => m.Description.Id != d.Description.Id) .Select(m => { int count = s.GetItemCount(m.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); int com = GetNumberOfMechsOwnedOfType(s, m); return($"[[DM.MechDefs[{m.Description.Id}], {m.Chassis.VariantName}]] ({count} Parts/{com} Complete)"); }); string selectedMechDisplayTitle = $"[[DM.MechDefs[{d.Description.Id}],{d.Chassis.VariantName}]] ({selectedMechParts} Parts/{numberOfChassisOwned} Complete)"; if (additionalVariants.Count() > 1) { desc += $"We can build the {selectedMechDisplayTitle}, " + $"or one of these other variants of the {d.Chassis.Description.UIName}:\n\n"; desc += string.Join("\n", additionalVariants); VariantPopup(desc, s, ownedMechVariantParts, refresh, close); } else if (additionalVariants.Count() == 1) { desc += $"We can build the {selectedMechDisplayTitle}, or the\n" + $"{string.Join("", additionalVariants)} variant of the {d.Chassis.Description.UIName}."; VariantPopup(desc, s, ownedMechVariantParts, refresh, close); } else { desc += $"Should I build the {selectedMechDisplayTitle}?"; VariantPopup(desc, s, new[] { d }, refresh, close); } }
private static int MechAssemblyRemoveParts(SimGameState s, MechDef d, int required, int min) { int curr = s.GetItemCount(d.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); int removing = required; if (curr < required) { removing = curr; } if ((curr - removing) < min) { removing -= min - (curr - removing); } if (removing < 0) { removing = 0; } if (removing > curr) { removing = curr; Log.LogError($"warning: tried to remove more parts than in storage (st: {curr}, req: {required}, min: {min}"); } // the string variant of removeitem is private... for (int i = 0; i < removing; i++) { s.RemoveItemStat(d.Description.Id, "MECHPART", false); } Log.LogDebug("using parts " + d.Description.Id + " " + removing); return(removing); }
private static void RemoveMechs(SimGameState s, string constant, string[] additionals) { if (constant.Equals("RemoveMech")) { List <int> toremove = new List <int>(); foreach (string cid in additionals) { foreach (KeyValuePair <int, MechDef> kv in s.ActiveMechs) { if (kv.Value.Chassis.Description.Id.Equals(cid)) { toremove.Add(kv.Key); } } if (s.GetItemCount(cid, typeof(MechDef), SimGameState.ItemCountType.UNDAMAGED_ONLY) > 0) { s.RemoveItemStat(cid, typeof(MechDef), false); } } foreach (int k in toremove) { s.ActiveMechs.Remove(k); } } }
public static bool ScrapInactiveVehicle(string id, bool pay, SimGameState __instance, ref bool __result) { if (!__instance.DataManager.Exists(BattleTechResourceType.ChassisDef, id)) { return(true); } var def = __instance.DataManager.ChassisDefs.Get(id); if (!def.IsVehicle()) { return(true); } __result = false; if (__instance.GetItemCount(id, typeof(MechDef), SimGameState.ItemCountType.UNDAMAGED_ONLY) > 0) { __instance.RemoveItemStat(id, typeof(MechDef), false); __result = true; if (pay) { var mdef = __instance.DataManager.MechDefs.Get(ChassisHandler.GetMDefFromCDef(id)); __instance.AddFunds(Mathf.RoundToInt((float)mdef.Description.Cost * __instance.Constants.Finances.MechScrapModifier), "Scrapping", true, true); } } return(false); }
// does not account for matching to assemble, too complex (ref CustomSalvage instead) public static string AppendExistingPartialCount(string localItemName) { // only proceed with mech parts if (!localItemName.Contains("Partial Mech Salvage")) { return(localItemName); } SimGameState sim = UnityGameInstance.BattleTechGame.Simulation; // take "Jenner" off "Jenner Partial Mech Salvage" string mechName = localItemName.Split(' ')[0]; // find all existing chassis variants that match this name List <ChassisDef> matchingChassis = sim.GetAllInventoryMechDefs() .Where(x => ParseName(x.Description.Name) == mechName.ToLower()).ToList(); Mod.Log.Debug?.Write("Matching chassis:"); matchingChassis.Do(chassisDef => Mod.Log.Debug?.Write($"\t{chassisDef.Description.Name}")); // aggregate the total count of matching chassis variants int count = 0; foreach (ChassisDef chassis in matchingChassis) { Mod.Log.Debug?.Write($"{chassis.Description.Name}, parsed {ParseName(chassis.Description.Name)}"); string id = chassis.Description.Id.Replace("chassisdef", "mechdef"); count += sim.GetItemCount(id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); } return($"{localItemName} (Have {count})"); }
private static int MechAssemblyRemoveParts(SimGameState s, MechDef d, int required, int min) { int curr = s.GetItemCount(d.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); int removing = required; if (curr < required) { removing = curr; } if ((curr - removing) < min) { removing -= min - (curr - removing); } if (removing < 0) { removing = 0; } // the string variant of removeitem is private... //string stat = string.Format("{0}.{1}.{2}", "Item", "MECHPART", d.Description.Id); object[] args = new object[] { d.Description.Id, "MECHPART", false }; Traverse method = Traverse.Create(s).Method("RemoveItemStat", args); for (int i = 0; i < removing; i++) { //s.CompanyStats.ModifyStat("SimGameState", 0, stat, StatCollection.StatOperation.Int_Subtract, 1, -1, true); method.GetValue(args); } Log.LogDebug("using parts " + d.Description.Id + " " + removing); return(removing); }
public static bool ScrapVehiclePart(string id, float partCount, float partMax, bool pay, SimGameState __instance, ref bool __result) { var mid = CustomSalvage.ChassisHandler.GetMDefFromCDef(id); Control.Instance.LogDebug(DInfo.General, "Scrapping {2}x{0}/{1}", id, mid, partCount); __result = false; if (__instance.GetItemCount(mid, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY) > 0) { var sim = new Traverse(__instance); sim.Method("RemoveItemStat", new Type[] { typeof(string), typeof(string), typeof(bool) }, new object[] { mid, "MECHPART", false }).GetValue(); __result = true; if (pay) { if (!__instance.DataManager.Exists(BattleTechResourceType.ChassisDef, id)) { __result = false; return(false); } int val = Mathf.RoundToInt((float)__instance.DataManager.ChassisDefs.Get(id).Description.Cost *__instance.Constants.Finances.MechScrapModifier *(partCount / partMax)); __instance.AddFunds(val, "Scrapping", true, true); } } return(false); }
private static bool HasBullShark(SimGameState s) { if (s.GetItemCount("chassisdef_bullshark_BSK-MAZ", typeof(MechDef), SimGameState.ItemCountType.UNDAMAGED_ONLY) > 0) { return(true); } return(false); }
public static void Postfix(ListElementController_SalvageMechPart_NotListView __instance, InventoryItemElement_NotListView theWidget, SimGameState ___simState) { int pieces = ___simState.GetItemCount(__instance.mechDef.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); int needed = ___simState.Constants.Story.DefaultMechPartMax; int varpieces = SimpleMechAssembly_Main.GetNumPartsForAssembly(___simState, __instance.mechDef); int owned = SimpleMechAssembly_Main.GetNumberOfMechsOwnedOfType(___simState, __instance.mechDef); theWidget.mechPartsNumbersText.SetText(string.Format("{0}({1})/{3}({2})", pieces, varpieces, owned, needed)); }
public static void Postfix(SG_Shop_ItemSelectedPanel __instance, InventoryDataObject_BASE theController, SimGameState ___simState, LocalizableText ___MechPartCountText) { if (theController.mechDef == null) { return; } int pieces = ___simState.GetItemCount(theController.mechDef.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); int needed = ___simState.Constants.Story.DefaultMechPartMax; int varpieces = SimpleMechAssembly_Main.GetNumPartsForAssembly(___simState, theController.mechDef); int owned = SimpleMechAssembly_Main.GetNumberOfMechsOwnedOfType(___simState, theController.mechDef); ___MechPartCountText.SetText(string.Format("{0}({1})/{3}({2})", pieces, varpieces, owned, needed)); }
public static ChassisCount MapChassisUnitElement(MechBayChassisUnitElement mbcue, SimGameState sgs) { int chassisQty = sgs.GetItemCount(mbcue.ChassisDef.Description.Id, typeof(MechDef), SimGameState.ItemCountType.UNDAMAGED_ONLY); Mod.Log.Info?.Write($"Part : {mbcue.ChassisDef.Description.Name} has chassisQty: {chassisQty} " + $"partsCount: {mbcue.PartsCount} partsMax: {mbcue.PartsMax}"); return(new ChassisCount() { ChassisDef = mbcue.ChassisDef, PartsCount = mbcue.PartsCount, PartsMax = mbcue.PartsMax, ChassisQty = chassisQty }); }
public static int GetNumPartsForAssembly(SimGameState s, MechDef m) { List <MechDef> vars = GetAllAssemblyVariants(s, m); Dictionary <string, bool> has = new Dictionary <string, bool>(); int p = 0; foreach (MechDef d in vars) { if (has.ContainsKey(d.Description.Id)) { continue; } p += s.GetItemCount(d.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); has.Add(d.Description.Id, true); } return(p); }
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})"); }
public static int GetNumberOfMechsOwnedOfType(SimGameState s, MechDef m) { int com = s.GetItemCount(m.Chassis.Description.Id, m.GetType(), SimGameState.ItemCountType.UNDAMAGED_ONLY); foreach (KeyValuePair <int, MechDef> a in s.ActiveMechs) { if (m.ChassisID == a.Value.ChassisID) { com++; } } foreach (KeyValuePair <int, MechDef> a in s.ReadyingMechs) { if (m.ChassisID == a.Value.ChassisID) { com++; } } return(com); }
public static void QueryMechAssemblyPopup(SimGameState s, MechDef d, Action onClose = null) { if (GetNumPartsForAssembly(s, d) < s.Constants.Story.DefaultMechPartMax) { onClose?.Invoke(); return; } IEnumerable <MechDef> mechs = GetAllAssemblyVariants(s, d); string desc = $"Yang: Concerning the [[DM.MechDefs[{d.Description.Id}],{d.Chassis.Description.UIName} {d.Chassis.VariantName}]]: {d.Chassis.YangsThoughts}\n\n We have Parts of the following {d.GetMechOmniVehicle()} variants. What should I build?\n"; GenericPopupBuilder pop = GenericPopupBuilder.Create($"Assemble {d.GetMechOmniVehicle()}?", desc); pop.AddButton("-", delegate { onClose?.Invoke(); }, true, null); foreach (MechDef m in mechs) { MechDef var = m; // new var to keep it for lambda int count = s.GetItemCount(var.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); int com = GetNumberOfMechsOwnedOfType(s, m); int cost = m.GetMechSellCost(s); if (count <= 0 && !CheckOmniKnown(s, d, m)) { if (Settings.ShowAllVariantsInPopup) { pop.Body += $"no parts: [[DM.MechDefs[{m.Description.Id}],{m.Chassis.Description.UIName} {m.Chassis.VariantName}]] ({com} Complete)\n"; } continue; } if (GetNumPartsForAssembly(s, var) >= s.Constants.Story.DefaultMechPartMax) { pop.AddButton(string.Format("{0}", var.Chassis.VariantName), delegate { PerformMechAssemblyStorePopup(s, var, onClose); }, true, null); } pop.Body += $"[[DM.MechDefs[{m.Description.Id}],{m.Chassis.Description.UIName} {m.Chassis.VariantName}]] ({count} Parts/{com} Complete) ({SimGameState.GetCBillString(cost)})\n"; } pop.AddFader(new UIColorRef?(LazySingletonBehavior <UIManager> .Instance.UILookAndColorConstants.PopupBackfill), 0f, true); pop.Render(); }
public static int GetNumPartsForAssembly(SimGameState s, MechDef m) { Dictionary <string, bool> has = new Dictionary <string, bool>(); int p = 0; foreach (MechDef d in GetAllAssemblyVariants(s, m)) { if (has.ContainsKey(d.Description.Id)) { continue; } int v = s.GetItemCount(d.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); if (v < 0) { Log.LogError($"warning: mechpart inventory count at {v} for {d.Description.Id}"); } p += v; has.Add(d.Description.Id, true); } return(p); }
public static float GetGearInventorySize(SimGameState sgs) { float totalUnits = 0.0f; foreach (MechComponentRef mcRef in sgs.GetAllInventoryItemDefs()) { if (mcRef.Def != null) { int itemCount = sgs.GetItemCount(mcRef.Def.Description, mcRef.Def.GetType(), sgs.GetItemCountDamageType(mcRef)); float itemSize = CalculateGearStorageSize(mcRef.Def); Mod.Log.Debug($" Inventory item:({mcRef.Def.Description.Id}) size:{itemSize} qty:{itemCount}"); totalUnits += itemSize; } else { Mod.Log.Info($" Gear ref missing for:{mcRef.ToString()}! Skipping size calculation."); } } Mod.Log.Debug($" Total storage units: {totalUnits}u"); return(totalUnits); }
static bool Prefix(Shop __instance, ref bool __result, string id, ShopItemType type, bool isDamaged, int cost) { try { SimGameState Sim = (SimGameState)ReflectionHelper.GetPrivateField(__instance, "Sim"); Type type2; if (type == ShopItemType.MechPart) { ReflectionHelper.InvokePrivateMethode(Sim, "RemoveItemStat", new object[] { id, "MECHPART", false }); Sim.AddFunds(cost, "Store", true); __result = true; return(false); } if (type == ShopItemType.Mech || type == ShopItemType.Chassis_DEPRECATED) { type2 = typeof(MechDef); } else { ComponentType componentType = Shop.ShopItemTypeToComponentType(type); type2 = SimGameState.GetTypeFromComponent(componentType); } int itemCount = Sim.GetItemCount(id, type2, (!isDamaged) ? SimGameState.ItemCountType.UNDAMAGED_ONLY : SimGameState.ItemCountType.DAMAGED_ONLY); if (itemCount < 1) { Logger.LogLine("Count 0"); __result = false; return(false); } Sim.AddFunds(cost, "Store", true); Sim.RemoveItemStat(id, type2, isDamaged); __result = true; return(false); } catch (Exception e) { Logger.LogError(e); return(false); } }
public static string GetAssembleNotEnoughPartsText(SimGameState s, MechDef d) { IEnumerable <MechDef> mechs = GetAllAssemblyVariants(s, d); string desc = $"Yang: I do not have enough parts to assemble a {d.GetMechOmniVehicle()} out of it."; if (!Settings.ShowAllVariantsInPopup) { return(desc); } desc += "\nKeep your eyes open for the following Variants:\n"; foreach (MechDef m in mechs) { int count = s.GetItemCount(m.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY); int com = GetNumberOfMechsOwnedOfType(s, m); if (count <= 0 && !CheckOmniKnown(s, d, m)) { desc += $"no parts: [[DM.MechDefs[{m.Description.Id}],{m.Chassis.Description.UIName} {m.Chassis.VariantName}]] ({com} Complete)\n"; continue; } desc += $"[[DM.MechDefs[{m.Description.Id}],{m.Chassis.Description.UIName} {m.Chassis.VariantName}]] ({count} Parts/{com} Complete)\n"; } return(desc); }
public static int GetMechParts(SimGameState simGame, MechDef mechDef) { return(simGame.GetItemCount(mechDef.Description.Id, "MECHPART", SimGameState.ItemCountType.UNDAMAGED_ONLY)); }
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(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); } }
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); } }