public void CheckForAndPerformUpgrade(MechComponentRef r, SimGameState s, UpgradeList l, ref float canFreeTonns, MechDef mech, List <string[]> changedAmmoTypes) { string baseid = r.Def.Description.Id; if (s.NetworkRandom.Float(0f, 1f) > l.UpgradePerComponentChance) { return; } string log = baseid; UpgradeList.UpgradeEntry ue = l.RollEntryFromMatchingSubList(baseid, s.NetworkRandom, s.CurrentDate, ref log, l.UpgradePerComponentChance); if (ue != null) { MechComponentDef d = s.GetComponentDefFromID(ue.ID); if (r.CanUpgrade(d, canFreeTonns, mech, r.MountedLocation, mech.Inventory)) { CheckChangedAmmo(r.Def, d, changedAmmoTypes); r.DoUpgrade(d, ref canFreeTonns); BTRandomMechComponentUpgrader_Init.Log.Log("changing " + log); } else { BTRandomMechComponentUpgrader_Init.Log.Log("cannot upgrade " + log); } } else { BTRandomMechComponentUpgrader_Init.Log.Log("upgrade unavailable " + log); } }
public void ModifyMech(MechDef mDef, SimGameState s, UpgradeList ulist, ref float canFreeTonns, List <string[]> changedAmmoTypes, MechDef fromData) { BTRandomMechComponentUpgrader_Init.Log.Log("checking addition sublists"); List <MechComponentRef> inv = mDef.Inventory.ToList(); foreach (UpgradeList.UpgradeEntry[] l in ulist.Additions) { if (s.NetworkRandom.Float(0f, 1f) < ulist.UpgradePerComponentChance) { string log = ""; UpgradeList.UpgradeEntry ue = ulist.RollEntryFromSubList(l, s.NetworkRandom, -1, s.CurrentDate, ref log, ulist.UpgradePerComponentChance); if (ue != null && !ue.ID.Equals("")) { MechComponentDef d = s.GetComponentDefFromID(ue.ID); ChassisLocations loc = mDef.SearchLocationToAddComponent(d, canFreeTonns, inv, null, ChassisLocations.None); if (loc == ChassisLocations.None) { BTRandomMechComponentUpgrader_Init.Log.Log("cannot add " + log); continue; } BTRandomMechComponentUpgrader_Init.Log.Log($"adding {log} into {loc}"); MechComponentRef r = new MechComponentRef(ue.ID, null, d.ComponentType, loc, -1, ComponentDamageLevel.Functional, false); r.SetComponentDef(d); inv.Add(r); canFreeTonns -= d.Tonnage; } else { BTRandomMechComponentUpgrader_Init.Log.Log("cannot add, nothing rolled " + log); } } } mDef.SetInventory(inv.ToArray()); }
public void ModifyMech(MechDef mDef, SimGameState s, UpgradeList ulist, ref float canFreeTonns, List <string[]> changedAmmoTypes, MechDef fromData) { BTRandomMechComponentUpgrader_Init.Log.Log("checking changed ammo types"); List <MechComponentRef> inv = mDef.Inventory.ToList(); foreach (string[] ca in changedAmmoTypes) { AmmunitionBoxDef basebox = GetMainAmmoBox(ca[0], s); AmmunitionBoxDef box = GetMainAmmoBox(ca[1], s); if (box == null && basebox == null) { BTRandomMechComponentUpgrader_Init.Log.Log($"changing ammo {ca[0]} -> {ca[1]} (both null ???)"); continue; } if (box == null) // removed ammo dependency, remove all ammoboxes as well, tonnagefixer will take care of missing tonnage { BTRandomMechComponentUpgrader_Init.Log.Log($"changing ammo {ca[0]} -> {ca[1]} (box null, removing all)"); inv.RemoveAll((a) => ca[0].Equals((a.Def as AmmunitionBoxDef)?.AmmoID)); continue; } if (basebox == null) // added ammo dependency, try to add an ammobox { TryAddAmmoBox(mDef, ref canFreeTonns, inv, ca, box); continue; } int numOldBox = CountAmmoBoxes(inv, ca[0]); float or = (float)GetAmmoTypeUsagePerTurn(inv, ca[0]) / basebox.Capacity; float ne = (float)GetAmmoTypeUsagePerTurn(inv, ca[1]) / box.Capacity; if (numOldBox <= 0 || (numOldBox == 1 && or > 0)) // should not happen, but just in case { TryAddAmmoBox(mDef, ref canFreeTonns, inv, ca, box); continue; } float ratio = ne / (or + ne); int swap = Mathf.RoundToInt(numOldBox * ratio); BTRandomMechComponentUpgrader_Init.Log.Log($"changing ammo {ca[0]} -> {ca[1]} (usage {or}/{ne}, changing {swap} boxes)"); foreach (MechComponentRef r in inv.Where((a) => ca[0].Equals((a.Def as AmmunitionBoxDef)?.AmmoID))) { if (swap <= 0) { break; } if (r.CanUpgrade(box, canFreeTonns, mDef, r.MountedLocation, inv)) { BTRandomMechComponentUpgrader_Init.Log.Log($"changing ammo {r.Def.Description.Id} -> {box.Description.Id}"); r.DoUpgrade(box, ref canFreeTonns); swap--; } else { BTRandomMechComponentUpgrader_Init.Log.Log($"cannot change ammo {r.Def.Description.Id} -> {box.Description.Id}"); } } if (swap > 0) { BTRandomMechComponentUpgrader_Init.Log.Log($"missed {swap} changes"); } } mDef.SetInventory(inv.ToArray()); }
public static void Prefix(UnitSpawnPointGameLogic __instance, ref MechDef mDef, Team team) { try { SimGameState s = __instance.Combat.BattleTechGame.Simulation; if (s == null) { BTRandomMechComponentUpgrader_Init.Log.Log("no simgame, aborting"); return; } if (mDef.Chassis.ChassisTags.Contains("deploy_director")) { BTRandomMechComponentUpgrader_Init.Log.Log($"DeployDirector, not upgrading"); return; } if (!s.DataManager.MechDefs.TryGet(mDef.Description.Id, out MechDef m)) { BTRandomMechComponentUpgrader_Init.Log.Log($"no mechdef found in datamanager for {mDef.Description.Id}"); return; } if (mDef != m) // if its a player mech, it is a different mechdef than in the datamanager) { BTRandomMechComponentUpgrader_Init.Log.Log("player modified mech, no upgrading"); return; } string teamName = team.IsLocalPlayer ? __instance.Combat.ActiveContract.Override.employerTeam.FactionValue.ToString() : team.FactionValue.ToString(); UpgradeList ulist = MechProcesser.GetUpgradeList(teamName); // check if we got a upgradelist for that faction if (ulist == null) { BTRandomMechComponentUpgrader_Init.Log.Log($"no UpgradeList found for {teamName}"); return; } MechDef n = MechProcesser.ProcessMech(mDef, s, ulist); if (MechProcesser.ValidateMech(n, s)) { mDef = n; BTRandomMechComponentUpgrader_Init.Log.Log("validated"); } else { BTRandomMechComponentUpgrader_Init.Log.Log("validation failed, using datamanager mechdef, inventory dump of invalid mechdef:"); foreach (MechComponentRef r in n.Inventory) { BTRandomMechComponentUpgrader_Init.Log.Log($"inventory {r.ComponentDefID} at {r.MountedLocation} {r.HardpointSlot}"); } } } catch (Exception e) { BTRandomMechComponentUpgrader_Init.Log.LogException(e); } }
public void ModifyMech(MechDef mDef, SimGameState s, UpgradeList ulist, ref float canFreeTonns, List <string[]> changedAmmoTypes, MechDef fromData) { BTRandomMechComponentUpgrader_Init.Log.Log("checking upgrade sublists"); foreach (MechComponentRef r in mDef.Inventory) { if (r.IsFixed) { continue; } CheckForAndPerformUpgrade(r, s, ulist, ref canFreeTonns, mDef, changedAmmoTypes); } }
public void ModifyMech(MechDef mDef, SimGameState s, UpgradeList ulist, ref float _, List <string[]> changedAmmoTypes, MechDef fromData) { BTRandomMechComponentUpgrader_Init.Log.Log("correcting tonage 1: inventory"); List <MechComponentRef> inv = mDef.Inventory.ToList(); float tonnage = 0; float max = 0; MechStatisticsRules.CalculateTonnage(mDef, ref tonnage, ref max); while (tonnage > mDef.Chassis.Tonnage) { int i = inv.FindIndex((x) => !x.IsFixed && ulist.CanRemove.Contains(x.ComponentDefID)); if (i == -1) { BTRandomMechComponentUpgrader_Init.Log.Log("no removable found"); break; } BTRandomMechComponentUpgrader_Init.Log.Log($"removed {inv[i].ComponentDefID} to reduce weight"); tonnage -= inv[i].Def.Tonnage; inv.RemoveAt(i); } foreach (string id in ulist.CanRemove) { MechComponentDef d = s.GetComponentDefFromID(id); while (tonnage + d.Tonnage <= mDef.Chassis.Tonnage) { ChassisLocations loc = ChassisLocations.None; foreach (ChassisLocations l in RMCU_Helper.Locations) { if (mDef.GetFreeSlotsInLoc(inv, l, null) >= d.InventorySize && d.CanPutComponentIntoLoc(l)) { loc = l; break; } } if (loc == ChassisLocations.None) { BTRandomMechComponentUpgrader_Init.Log.Log("no free location found!"); break; } MechComponentRef r = new MechComponentRef(d.Description.Id, null, d.ComponentType, loc, -1, ComponentDamageLevel.Functional, false); r.SetComponentDef(d); inv.Add(r); tonnage += d.Tonnage; BTRandomMechComponentUpgrader_Init.Log.Log($"added {r.ComponentDefID} to use free weight"); } } mDef.SetInventory(inv.ToArray()); }
public static void FinishedLoading(Dictionary <string, Dictionary <string, VersionManifestEntry> > customResources) { if (!customResources.ContainsKey("ComponentUpgradeList") || !customResources.ContainsKey("ComponentUpgradeSubList")) { Log.LogError("Error: Missing custom Resource!"); return; } string missing = ""; try { Dictionary <string, UpgradeList.UpgradeEntry[]> entries = new Dictionary <string, UpgradeList.UpgradeEntry[]>(); MechProcesser.UpgradeLists = new List <UpgradeList>(); foreach (KeyValuePair <string, VersionManifestEntry> kv in customResources["ComponentUpgradeSubList"]) { missing = kv.Value.FilePath; UpgradeList.UpgradeEntry[] sublist = LoadUpgradeSubList(kv.Value.FilePath); if (sublist.Length > 0) { sublist[0].Name = kv.Value.FileName; } entries.Add(kv.Value.FileName, sublist); } foreach (KeyValuePair <string, VersionManifestEntry> kv in customResources["ComponentUpgradeList"]) { missing = kv.Value.FilePath; UpgradeList ulist = LoadUpgradeList(kv.Value.FilePath); ulist.Name = kv.Value.FileName; LoadListComponents(ulist.LoadUpgrades, ulist.Upgrades, entries, out missing); LoadListComponents(ulist.LoadAdditions, ulist.Additions, entries, out missing); //ulist.CalculateLimits(); MechProcesser.UpgradeLists.Add(ulist); } MechProcesser.UpgradeLists.Sort(); Log.Log($"loaded with {MechProcesser.UpgradeLists.Count()} upgradelists"); foreach (UpgradeList l in MechProcesser.UpgradeLists) { Log.Log($"list: {l.Name} with sort {l.Sort}"); } } catch (Exception e) { MechProcesser.UpgradeLists = new List <UpgradeList>(); Log.LogException(e); Log.LogError(missing); } }
public static MechDef ProcessMech(MechDef mDef, SimGameState s, UpgradeList ulist, IEnumerable <IMechDefSpawnModifier> modifiers = null) { if (modifiers == null) { modifiers = DefaultModifiers; } BTRandomMechComponentUpgrader_Init.Log.Log($"upgrading {mDef.Description.Name} {mDef.Chassis.VariantName}, using UpgradeList {ulist.Name}"); MechDef n = new MechDef(mDef); // dont break original mechdef float canFreeTonns = Mathf.Floor(n.Inventory.Sum((r) => ulist.CanRemove.Contains(r.ComponentDefID) ? r.Def.Tonnage : 0f) * ulist.RemoveMaxFactor); List <string[]> changedAmmoTypes = new List <string[]>(); foreach (IMechDefSpawnModifier mod in modifiers) { mod.ModifyMech(n, s, ulist, ref canFreeTonns, changedAmmoTypes, mDef); } BTRandomMechComponentUpgrader_Init.Log.Log("all modifications done"); return(n); }
public void ModifyMech(MechDef mDef, SimGameState s, UpgradeList ulist, ref float _, List <string[]> changedAmmoTypes, MechDef fromData) { float tonnage = 0; float max = 0; MechStatisticsRules.CalculateTonnage(mDef, ref tonnage, ref max); float armorfact = mDef.GetMechArmorPointFactor(); BTRandomMechComponentUpgrader_Init.Log.Log($"correcting tonnage 2: armor (each armor point costs {armorfact} t)"); while (tonnage + armorfact <= mDef.Chassis.Tonnage) { bool assOne = false; foreach (ChassisLocations c in RMCU_Helper.Locations) { if (tonnage + armorfact >= mDef.Chassis.Tonnage) { break; } LocationLoadoutDef l = mDef.GetLocationLoadoutDef(c); if (l.AssignedArmor >= mDef.GetChassisLocationDef(c).MaxArmor) { continue; } l.AssignedArmor += 1; l.CurrentArmor += 1; tonnage += armorfact; BTRandomMechComponentUpgrader_Init.Log.Log($"increased {c} armor to {l.AssignedArmor}"); assOne = true; } foreach (ChassisLocations c in RMCU_Helper.RearArmoredLocs) { if (tonnage + armorfact >= mDef.Chassis.Tonnage) { break; } LocationLoadoutDef l = mDef.GetLocationLoadoutDef(c); if (l.AssignedRearArmor >= mDef.GetChassisLocationDef(c).MaxRearArmor) { continue; } l.AssignedRearArmor += 1; l.CurrentRearArmor += 1; tonnage += armorfact; BTRandomMechComponentUpgrader_Init.Log.Log($"increased {c} rear armor to {l.AssignedRearArmor}"); assOne = true; } if (!assOne) { BTRandomMechComponentUpgrader_Init.Log.Log("no free armor location found!"); break; } } while (tonnage > mDef.Chassis.Tonnage) { bool assOne = false; foreach (ChassisLocations c in RMCU_Helper.Locations) { if (tonnage <= mDef.Chassis.Tonnage) { break; } LocationLoadoutDef l = mDef.GetLocationLoadoutDef(c); if (l.AssignedArmor <= 1) { continue; } l.AssignedArmor -= 1; l.CurrentArmor -= 1; tonnage -= armorfact; BTRandomMechComponentUpgrader_Init.Log.Log($"decreased {c} armor to {l.AssignedArmor}"); assOne = true; } foreach (ChassisLocations c in RMCU_Helper.RearArmoredLocs) { if (tonnage <= mDef.Chassis.Tonnage) { break; } LocationLoadoutDef l = mDef.GetLocationLoadoutDef(c); if (l.AssignedRearArmor <= 1) { continue; } l.AssignedRearArmor -= 1; l.CurrentRearArmor -= 1; tonnage -= armorfact; BTRandomMechComponentUpgrader_Init.Log.Log($"decreased {c} rear armor to {l.AssignedRearArmor}"); assOne = true; } if (!assOne) { BTRandomMechComponentUpgrader_Init.Log.Log("no free armor location found!"); break; } } BTRandomMechComponentUpgrader_Init.Log.Log($"final weight: {tonnage}/{mDef.Chassis.Tonnage}"); }