Beispiel #1
0
        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));
        }
Beispiel #2
0
        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;
        }