public static DateTime?GetSimGameDate(SimGameState simGame) { var startingDate = GetStartingDate(simGame); if (startingDate != null && startingDate != simGame.GetCampaignStartDate()) { simGame.SetCampaignStartDate((DateTime)startingDate); } return(startingDate?.AddDays(simGame.DaysPassed)); }
public static void Postfix(SimGameState __instance) { if (RngStart.Settings.NumberRandomRonin + RngStart.Settings.NumberProceduralPilots + RngStart.Settings.NumberRoninFromList > 0) { RandomizeRonin(__instance); } Logger.Debug($"Starting lance creation {RngStart.Settings.MinimumStartingWeight} - {RngStart.Settings.MaximumStartingWeight} tons"); // mechs if (RngStart.Settings.UseRandomMechs) { // memoize dictionary of tonnages since we may be looping a lot Logger.Debug($"Memoizing"); var AncestralMechDef = __instance.Constants.CareerMode.StartingPlayerMech; var lance = new List <string>(); //var lance = new List<MechDef>(); float currentLanceWeight = 0; var mechTonnages = new Dictionary <string, float>(); Logger.Debug($"A"); var startDate = __instance.GetCampaignStartDate(); //Trim the lists. foreach (var kvp in __instance.DataManager.ChassisDefs) { var mechDefId = kvp.Key.Replace("chassisdef", "mechdef"); if (!__instance.DataManager.Exists(BattleTechResourceType.MechDef, mechDefId)) { continue; } var minAppearanceDate = __instance.DataManager.MechDefs.Get(mechDefId).MinAppearanceDate; if (minAppearanceDate.HasValue && minAppearanceDate > startDate) { continue; } if (kvp.Key.Contains("DUMMY") && !kvp.Key.Contains("CUSTOM")) { // just in case someone calls their mech DUMMY continue; } if (kvp.Key.Contains("CUSTOM") || kvp.Key.Contains("DUMMY")) { continue; } if (RngStart.Settings.MaximumMechWeight != 100) { if (kvp.Value.Tonnage > RngStart.Settings.MaximumMechWeight || kvp.Value.Tonnage < 20) { continue; } } // passed checks, add to Dictionary mechTonnages.Add(kvp.Key, kvp.Value.Tonnage); } Logger.Debug($"B"); for (int xloop = 0; xloop < RngStart.Settings.Loops; xloop++) { Logger.Debug($"C"); int minLanceSize = RngStart.Settings.MinimumLanceSize; float maxWeight = RngStart.Settings.MaximumStartingWeight; float maxLanceSize = RngStart.Settings.MaximumLanceSize; bool firstTargetRun = false; var randomStarterMech = mechTonnages.ElementAt(rng.Next(0, mechTonnages.Count)); var StartermechString = randomStarterMech.Key.Replace("chassisdef", "mechdef"); var StarterMechTonnage = randomStarterMech.Value; Logger.Debug($"D"); Logger.Debug(StartermechString); Logger.Debug(AncestralMechDef); if (AncestralMechDef == "mechdef_centurion_TARGETDUMMY") { lance.Add(StartermechString); currentLanceWeight = randomStarterMech.Value; } else { lance.Add(AncestralMechDef); StartermechString = AncestralMechDef; Logger.Debug("Here, right?"); currentLanceWeight = __instance.DataManager.MechDefs.Get(AncestralMechDef).Chassis.Tonnage; StarterMechTonnage = currentLanceWeight; } Logger.Debug($"E"); int LanceCounter = 1; // cap the lance tonnage //__instance.ActiveMechs.Remove(0); bool dupe = false; bool excluded = false; bool blacklisted = false; int RVMechCount = 0; int MediumMechCount = 0; int GhettoCount = 0; int expandedWeight = 0; while (minLanceSize > lance.Count || currentLanceWeight < (RngStart.Settings.MinimumStartingWeight - expandedWeight)) { Logger.Debug($"F"); #region Def listing loops //Logger.Debug($"In while loop"); //foreach (var mech in __instance.DataManager.MechDefs) //{ // Logger.Debug($"K:{mech.Key} V:{mech.Value}"); //} //foreach (var chasis in __instance.DataManager.ChassisDefs) //{ // Logger.Debug($"K:{chasis.Key}"); //} #endregion // build lance collection from dictionary for speed var randomMech = mechTonnages.ElementAt(rng.Next(0, mechTonnages.Count)); var mechString = randomMech.Key.Replace("chassisdef", "mechdef"); // getting chassisdefs so renaming the key to match mechdefs Id var mechDef = new MechDef(__instance.DataManager.MechDefs.Get(mechString), __instance.GenerateSimGameUID()); //It's not a BUG, it's a FEATURE. if (LanceCounter > RngStart.Settings.SpiderLoops) { MechDef mechDefSpider = new MechDef(__instance.DataManager.MechDefs.Get("mechdef_spider_SDR-5V"), __instance.GenerateSimGameUID(), true); lance.Add(mechDefSpider.Description.Id); // worry about sorting later Traverse.Create(__instance).Method("AddMechs", new Type[] { typeof(List <string>) }).GetValue(lance); //for (int j = baySlot; j < 6; j++) //{ // __instance.AddMech(j, mechDefSpider, true, true, false, null); //} break; } Logger.Debug($"G"); if (mechDef.MechTags.Contains("BLACKLISTED")) { currentLanceWeight = 0; blacklisted = true; //Logger.Debug($"Blacklisted! {mechDef.Name}"); } Logger.Debug($"TestMech {mechDef.Name}"); foreach (var mechID in RngStart.Settings.ExcludedMechs) { if (mechID == mechDef.Description.Id) { currentLanceWeight = 0; excluded = true; Logger.Debug($"Excluded! {mechDef.Name}"); } } if (!RngStart.Settings.AllowDuplicateChassis) { foreach (var mech in lance) { Logger.Debug("Mech Chassis Comparer"); Logger.Debug(mech.Substring(0, 12) + ":" + mechDef.Description.Id.Substring(0, 12)); if (mech.Substring(0, 12) == mechDef.Description.Id.Substring(0, 12)) { currentLanceWeight = 0; dupe = true; Logger.Debug($"SAME SAME!"); } } } if (mechDef.Description.UIName.Contains("-RV") && RngStart.Settings.LimitRVMechs) { RVMechCount++; } if (mechDef.Chassis.weightClass == WeightClass.MEDIUM && RngStart.Settings.ForceSingleMedium) { MediumMechCount++; } if (mechDef.Chassis.Tonnage == 20) { GhettoCount++; } // does the mech fit into the lance? currentLanceWeight = currentLanceWeight + mechDef.Chassis.Tonnage; if (RngStart.Settings.MaximumStartingWeight >= currentLanceWeight) { lance.Add(mechDef.Description.Id); Logger.Debug($"Adding mech {mechString} {mechDef.Chassis.Tonnage} tons"); if (currentLanceWeight > RngStart.Settings.MinimumStartingWeight + mechDef.Chassis.Tonnage) { Logger.Debug($"Minimum lance tonnage met: done"); } Logger.Debug($"current: {currentLanceWeight} tons. " + $"tonnage remaining: {RngStart.Settings.MaximumStartingWeight - currentLanceWeight}. " + $"before lower limit hit: {Math.Max(0, RngStart.Settings.MinimumStartingWeight - currentLanceWeight)}"); } // invalid lance, reset if (currentLanceWeight > (RngStart.Settings.MaximumStartingWeight + expandedWeight) || lance.Count > maxLanceSize || dupe || blacklisted || excluded || firstTargetRun || RVMechCount > 1 || (lance.Count >= minLanceSize && MediumMechCount != 1) || GhettoCount > 1) { Logger.Debug($"Clearing invalid lance"); currentLanceWeight = StarterMechTonnage; lance.Clear(); lance.Add(StartermechString); dupe = false; blacklisted = false; excluded = false; firstTargetRun = false; RVMechCount = 0; LanceCounter++; if (StarterMechTonnage > 35) { MediumMechCount = 1; } else { MediumMechCount = 0; } GhettoCount = 0; if (xloop > RngStart.Settings.Loops / 2) { expandedWeight = 5; } continue; } Logger.Debug($"Done a loop"); } Logger.Debug($"New mode"); Logger.Debug($"Starting lance instantiation"); float tonnagechecker = 0; Traverse.Create(__instance).Method("AddMechs", new Type[] { typeof(List <string>) }).GetValue(lance); Logger.Debug($"{tonnagechecker}"); float Maxtonnagedifference = currentLanceWeight - RngStart.Settings.MaximumStartingWeight; float Mintonnagedifference = currentLanceWeight - RngStart.Settings.MinimumStartingWeight; Logger.Debug($"Over tonnage Maximum amount: {Maxtonnagedifference}"); Logger.Debug($"Over tonnage Minimum amount: {Mintonnagedifference}"); lance.Clear(); // valid lance created } } }
/// <summary> /// Derive the set of allowed mechs from which a lance might be derived /// </summary> /// <param name="simGame"></param> private void FilterAllowedMechs(SimGameState simGame) { if (Main.Settings.UseWhitelist) { AllowedMechs = new List <MechDef>(); // remove items on whitelist that aren't in the datamanager Main.Settings.Whitelist.FindAll(id => !simGame.DataManager.MechDefs.Exists(id)) .Do(id => Logger.LogWarning($"\tInvalid MechDef '{id}' in whitelist. Will remove from possibilities")); Main.Settings.Whitelist.RemoveAll(id => !simGame.DataManager.MechDefs.Exists(id)); AllowedMechs = Main.Settings.Whitelist.Select(id => simGame.DataManager.MechDefs.Get(id)).ToList(); } else { // extract the mechdefs var mechKeys = simGame.DataManager.MechDefs.Keys.ToList(); Logger.Log($"\tPossible mech count initial: {mechKeys.Count}"); // remove mechs from blacklist in settings if (Main.Settings.Debug && Main.Settings.DebugVerbose) { mechKeys.FindAll(id => Main.Settings.Blacklist.Contains(id)) .Do(id => Logger.LogVerbose($"\tRemoving blacklisted (by settings) MechDef '{id}' from possibilities")); } mechKeys.RemoveAll(id => Main.Settings.Blacklist.Contains(id)); Logger.Log($"\tPossible mech count after removing those in the blacklist (settings): {mechKeys.Count}"); // remove mechs with undesirable labels (i.e. from the Skirmish MechBay if (Main.Settings.Debug && Main.Settings.DebugVerbose) { mechKeys.FindAll(id => id.Contains("CUSTOM")) .Do(id => Logger.LogVerbose($"\tRemoving CUSTOM MechDef '{id}' from possibilities")); } mechKeys.RemoveAll(id => id.Contains("CUSTOM")); Logger.Log($"\tPossible mech count after removing those with CUSTOM in name: {mechKeys.Count}"); if (Main.Settings.Debug && Main.Settings.DebugVerbose) { mechKeys.FindAll(id => id.Contains("DUMMY")) .Do(id => Logger.LogVerbose($"\tRemoving DUMMY MechDef '{id}' from possibilities")); } mechKeys.RemoveAll(id => id.Contains("DUMMY")); Logger.Log($"\tPossible mech count after removing those with DUMMY in name: {mechKeys.Count}"); // convert keys to mechdefs AllowedMechs = mechKeys.Select(id => simGame.DataManager.MechDefs.Get(id)).ToList(); // remove mechs with undesirable tags if (Main.Settings.Debug && Main.Settings.DebugVerbose) { AllowedMechs.FindAll(mech => mech.MechTags.Contains("BLACKLISTED")) .Do(mech => Logger.LogVerbose($"\tRemoving blacklisted (by tag) MechDef '{mech.ChassisID}' from possibilities")); } AllowedMechs.RemoveAll(mech => mech.MechTags.Contains("BLACKLISTED")); Logger.Log($"\tPossible mech count after removing BLACKLISTED (by tag): {AllowedMechs.Count}"); // remove mechs outside weight restrictions if (Main.Settings.Debug && Main.Settings.DebugVerbose) { AllowedMechs.FindAll(mech => mech.Chassis.Tonnage < Main.Settings.MinimumMechTonnage) .Do(mech => Logger.LogVerbose($"\tRemoving underweight MechDef '{mech.ChassisID}' from possibilities")); } AllowedMechs.RemoveAll(mech => mech.Chassis.Tonnage < Main.Settings.MinimumMechTonnage); Logger.Log($"\tPossible mech count after removing underweight: {AllowedMechs.Count}"); if (Main.Settings.Debug && Main.Settings.DebugVerbose) { AllowedMechs.FindAll(mech => mech.Chassis.Tonnage > Main.Settings.MaximumMechTonnage) .Do(mech => Logger.LogVerbose($"\tRemoving overweight MechDef '{mech.ChassisID}' from possibilities")); } AllowedMechs.RemoveAll(mech => mech.Chassis.Tonnage > Main.Settings.MaximumMechTonnage); Logger.Log($"\tPossible mech count after removing overweight: {AllowedMechs.Count}"); // remove mechs that don't exist yet if (Main.Settings.MechsAdhereToTimeline) { var startDate = simGame.GetCampaignStartDate(); if (Main.Settings.Debug && Main.Settings.DebugVerbose) { AllowedMechs.FindAll(mech => mech.MinAppearanceDate.HasValue && mech.MinAppearanceDate > startDate) .Do(mech => Logger.LogVerbose($"\tRemoving anachronistic MechDef '{mech.ChassisID}' from possibilities")); } AllowedMechs.RemoveAll(mech => mech.MinAppearanceDate.HasValue && mech.MinAppearanceDate > startDate); Logger.Log($"\tPossible mech count after enforcing timeline: {AllowedMechs.Count}"); } } // remove mechs with broken names (weird, but seen it once before) AllowedMechs.FindAll(mech => mech.Description.UIName == null) .Do(mech => Logger.LogError($"\tRemoving MechDef with null UIName '{mech.ChassisID}' from possibilities")); AllowedMechs.RemoveAll(mech => mech.Description.UIName == null); Logger.Log($"\tPossible mech count after removing null UIName: {AllowedMechs.Count}"); }
public static void SimGameState__OnDefsLoadComplete_Postfix(SimGameState __instance) { if (UnitAppearanceDateMorphFeature.AppearanceDatesAdjusted == true) { Logger.Debug($"Appearance dates have already been adjusted."); return; } if (Myself.Settings.SetAppearanceDatesForMechsLackingSuch) { Logger.Debug($"Setting appearance dates for mechs lacking..."); var mechAppearanceData = CoreMod.CoreModSingleton.MechAppearanceData; var mechsSansAppearanceDates = __instance.DataManager.MechDefs .Where(pair => !pair.Value.MinAppearanceDate.HasValue) .Select(pair => pair.Value); mechsSansAppearanceDates //.AsParallel() //.ForAll .ToList() .ForEach (mechDef => { Logger.Trace($"Mech [{mechDef.Description.UIName}] lacks an appearance date, attempting to set it..."); var mechModelEntry = mechAppearanceData.FirstOrDefault(model => model.Name.Trim('"') == mechDef.Description.UIName); DateTime?appearanceDate = null; if (mechModelEntry != null) { appearanceDate = new DateTime(mechModelEntry.Year, 1, 1); } appearanceDate = mechDef.MinAppearanceDate ?? appearanceDate; Logger.Trace($"Setting appearance date for [{mechDef.Description.UIName}] to [{appearanceDate}]."); var traverse = Traverse.Create(mechDef).Property("MinAppearanceDate"); traverse.SetValue(appearanceDate); }); } Logger.Debug("Dynamically adjusting appearance dates..."); var appearanceFactor = AppearanceUtils.CalculateAppearanceDateFactor(__instance.GetCampaignStartDate(), Myself.Settings.CompressionFactorControlDate, Myself.Settings.CompressionFactorTargetDate, Logger); __instance.DataManager.MechDefs .Where(pair => pair.Value.MinAppearanceDate.HasValue) .Select(pair => pair.Value) .ToList() .ForEach //.AsParallel() //.ForAll (mechDef => { Logger.Trace($"Calculating new appearance date for [{mechDef.Description.Id}]..."); var appearanceDate = mechDef.MinAppearanceDate; var newAppearanceDate = AppearanceUtils.CalculateCompressedAppearanceDate(__instance.GetCampaignStartDate(), appearanceDate.Value, appearanceFactor, Logger); Logger.Trace($"Setting appearance date for [{mechDef.Description.Id}] to [{newAppearanceDate}] from [{appearanceDate}]..."); // mechDef.MinAppearanceDate = newAppearanceDate; var traverse = Traverse.Create(mechDef).Property("MinAppearanceDate"); traverse.SetValue(newAppearanceDate); }); UnitAppearanceDateMorphFeature.AppearanceDatesAdjusted = true; }