using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using REPOLib;
using SpawnConfig.ExtendedClasses;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Index154.SpawnConfig")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.2.9.0")]
[assembly: AssemblyInformationalVersion("1.2.9+aac39fd6160fa756b975f9ed98b735a0e38390e6")]
[assembly: AssemblyProduct("SpawnConfig")]
[assembly: AssemblyTitle("Index154.SpawnConfig")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.9.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace SpawnConfig
{
public class ConfigManager
{
internal ConfigEntry<bool> preventSpawns = null;
internal ConfigEntry<bool> addMissingGroups = null;
internal ConfigEntry<bool> removeUnloadedLevelWeights = null;
internal ConfigEntry<double> repeatMultiplier = null;
internal ConfigEntry<bool> ignoreInvalidGroups = null;
internal ConfigEntry<int> groupCountMultiplier = null;
internal ConfigEntry<bool> enableVarietyPlus = null;
internal ConfigEntry<int> consecutiveLevelCount = null;
internal ConfigEntry<double> consecutiveWeightMultiplierMin = null;
internal ConfigEntry<double> consecutiveWeightMultiplierMax = null;
internal ConfigEntry<double> varietyMultiplierTwo = null;
internal ConfigEntry<double> varietyMultiplierThree = null;
internal void Setup(ConfigFile configFile)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Expected O, but got Unknown
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Expected O, but got Unknown
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Expected O, but got Unknown
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Expected O, but got Unknown
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Expected O, but got Unknown
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Expected O, but got Unknown
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: Expected O, but got Unknown
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Expected O, but got Unknown
//IL_019e: Unknown result type (might be due to invalid IL or missing references)
//IL_01a8: Expected O, but got Unknown
preventSpawns = configFile.Bind<bool>("General", "Prevent enemy spawning", false, new ConfigDescription("Prevent enemy spawning entirely, turning the game into a no-stakes gathering simulator or for when you want to test something in peace", (AcceptableValueBase)null, Array.Empty<object>()));
addMissingGroups = configFile.Bind<bool>("General", "Re-add missing groups", false, new ConfigDescription("Whether the mod should update your custom SpawnGroups config at launch by adding all loaded enemy groups that are missing from it", (AcceptableValueBase)null, Array.Empty<object>()));
removeUnloadedLevelWeights = configFile.Bind<bool>("General", "Remove unused level weight multipliers", false, new ConfigDescription("Installing a mod which adds a new level will automatically add a config entry for it to the levelWeightMultipliers of every enemy group in your SpawnGroups config. These config entries will remain even if you later uninstall or disable that mod again. If you want to quickly get rid of unused entries in a situation like that then you can enable this setting and launch the game once to have the mod automatically remove them", (AcceptableValueBase)null, Array.Empty<object>()));
repeatMultiplier = configFile.Bind<double>("General", "Repeat spawn weight multiplier", 0.5, new ConfigDescription("All three weights of an enemy group will be multiplied by this value for the current level after having been spawned once. Reduces the chance of encountering multiple copies of a group in the same level. Set to 1.0 to \"disable\"", (AcceptableValueBase)null, Array.Empty<object>()));
ignoreInvalidGroups = configFile.Bind<bool>("General", "Ignore groups with invalid spawnObjects", true, new ConfigDescription("If set to true, any group containing a single invalid spawn object will be ignored completely. If set to false, only the individual spawn object will be ignored and the group can still spawn as long as it contains at least one valid enemy", (AcceptableValueBase)null, Array.Empty<object>()));
groupCountMultiplier = configFile.Bind<int>("General", "Group count multiplier", 1, new ConfigDescription("The amount of enemy groups spawned each level is multiplied by this number. This will apply on top of what you configure in `GroupsPerLevel.json`", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
enableVarietyPlus = configFile.Bind<bool>("Variety+", "Enable Variety+", true, new ConfigDescription("Set this to false to completely disable all the settings & systems in the Variety+ category", (AcceptableValueBase)null, Array.Empty<object>()));
consecutiveLevelCount = configFile.Bind<int>("Variety+", "Consecutive level count", 2, new ConfigDescription("How many previous levels to take into account for applying the consecutive level weight multipliers. The min multiplier applies to groups spawned on the most recent level and the max multiplier applies to the least recent (equal to this setting)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 10), Array.Empty<object>()));
consecutiveWeightMultiplierMin = configFile.Bind<double>("Variety+", "Consecutive level weight multiplier min", 0.6, new ConfigDescription("If an enemy group has spawned exactly one level ago, its weights will be multiplied by this number. This value should be lower than or equal to the max multiplier", (AcceptableValueBase)null, Array.Empty<object>()));
consecutiveWeightMultiplierMax = configFile.Bind<double>("Variety+", "Consecutive level weight multiplier max", 0.8, new ConfigDescription("An enemy group's weights will be multiplied by this number if it has spawned X levels ago with X being equal to your 'Consecutive level count' setting. For enemies spawned between X and 1 levels ago the game will apply a multiplier between your min and max corresponding to the difference", (AcceptableValueBase)null, Array.Empty<object>()));
}
}
public class JsonManager
{
public static List<ExtendedGroupCounts> GetGroupCountsFromJSON(string path)
{
List<ExtendedGroupCounts> result = new List<ExtendedGroupCounts>();
if (File.Exists(path))
{
string text = File.ReadAllText(path);
if (text != null && text != "")
{
result = JsonConvert.DeserializeObject<List<ExtendedGroupCounts>>(text);
}
}
return result;
}
public static List<ExtendedEnemySetup> GetSpawnGroupsFromJSON(string path)
{
List<ExtendedEnemySetup> result = new List<ExtendedEnemySetup>();
if (File.Exists(path))
{
string text = File.ReadAllText(path);
if (text != null && text != "")
{
result = JsonConvert.DeserializeObject<List<ExtendedEnemySetup>>(text);
if (!text.Contains("allowDuplicates"))
{
SpawnConfig.missingProperties = true;
}
}
}
return result;
}
public static string SpawnGroupsToJSON(List<ExtendedEnemySetup> eesList)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
StringBuilder stringBuilder = new StringBuilder();
StringWriter stringWriter = new StringWriter(stringBuilder);
JsonWriter val = (JsonWriter)new JsonTextWriter((TextWriter)stringWriter);
try
{
val.Formatting = (Formatting)1;
val.WriteStartArray();
foreach (ExtendedEnemySetup ees in eesList)
{
val.WriteStartObject();
val.WritePropertyName("name");
val.WriteValue(ees.name);
val.WritePropertyName("levelRangeCondition");
val.WriteValue(ees.levelRangeCondition);
val.WritePropertyName("minLevel");
val.WriteValue(ees.minLevel);
val.WritePropertyName("maxLevel");
val.WriteValue(ees.maxLevel);
val.WritePropertyName("runsPlayed");
val.WriteValue(ees.runsPlayed);
val.WritePropertyName("spawnObjects");
val.WriteStartArray();
foreach (string spawnObject in ees.spawnObjects)
{
val.WriteValue(spawnObject);
}
val.WriteEndArray();
val.WritePropertyName("difficulty1Weight");
val.WriteValue(ees.difficulty1Weight);
val.WritePropertyName("difficulty2Weight");
val.WriteValue(ees.difficulty2Weight);
val.WritePropertyName("difficulty3Weight");
val.WriteValue(ees.difficulty3Weight);
val.WritePropertyName("levelWeightMultipliers");
val.WriteStartObject();
val.Formatting = (Formatting)0;
int num = 0;
foreach (KeyValuePair<string, float> levelWeightMultiplier in ees.levelWeightMultipliers)
{
if (num > 0)
{
val.WriteRaw(", ");
}
val.WriteRaw("\"" + levelWeightMultiplier.Key + "\": ");
val.WriteRaw(levelWeightMultiplier.Value.ToString("0.0", CultureInfo.InvariantCulture));
num++;
}
val.WriteEndObject();
val.Formatting = (Formatting)1;
val.WritePropertyName("soloGroup");
val.WriteValue(ees.soloGroup);
val.WritePropertyName("allowDuplicates");
val.WriteValue(ees.allowDuplicates);
val.WritePropertyName("alterAmountChance");
val.WriteValue(ees.alterAmountChance);
val.WritePropertyName("alterAmountMin");
val.WriteValue(ees.alterAmountMin);
val.WritePropertyName("alterAmountMax");
val.WriteValue(ees.alterAmountMax);
val.WriteEndObject();
}
val.WriteEndArray();
}
finally
{
((IDisposable)val)?.Dispose();
}
return stringBuilder.ToString();
}
public static string GroupCountsToJSON(List<ExtendedGroupCounts> gcList)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
StringBuilder stringBuilder = new StringBuilder();
StringWriter stringWriter = new StringWriter(stringBuilder);
JsonWriter val = (JsonWriter)new JsonTextWriter((TextWriter)stringWriter);
try
{
val.Formatting = (Formatting)1;
val.WriteStartArray();
foreach (ExtendedGroupCounts gc in gcList)
{
val.Formatting = (Formatting)1;
val.WriteStartObject();
val.WritePropertyName("level");
val.WriteValue(gc.level);
val.WritePropertyName("possibleGroupCounts");
val.WriteStartArray();
foreach (GroupCountEntry possibleGroupCount in gc.possibleGroupCounts)
{
val.WriteStartObject();
val.Formatting = (Formatting)0;
val.WriteRaw("\"counts\": ");
val.WriteRaw("[");
val.WriteRaw(possibleGroupCount.counts[0] + ",");
val.WriteRaw(possibleGroupCount.counts[1] + ",");
val.WriteRaw(possibleGroupCount.counts[2].ToString() ?? "");
val.WriteRaw("], \"weight\": ");
val.WriteRaw(possibleGroupCount.weight.ToString());
val.WriteRaw(", \"minPlayerCount\": ");
val.WriteRaw(possibleGroupCount.minPlayerCount.ToString());
val.WriteRaw(", \"maxPlayerCount\": ");
val.WriteRaw(possibleGroupCount.maxPlayerCount.ToString());
val.WriteEndObject();
val.Formatting = (Formatting)1;
}
val.WriteEndArray();
val.WriteEndObject();
}
val.WriteEndArray();
}
finally
{
((IDisposable)val)?.Dispose();
}
return stringBuilder.ToString();
}
}
public class ListManager
{
public static Dictionary<string, EnemySetup> enemySetupsDict = new Dictionary<string, EnemySetup>();
public static Dictionary<string, PrefabRef> spawnObjectsDict = new Dictionary<string, PrefabRef>();
public static Dictionary<string, ExtendedEnemySetup> extendedSetups = new Dictionary<string, ExtendedEnemySetup>();
public static Dictionary<string, ExtendedSpawnObject> extendedSpawnObjects = new Dictionary<string, ExtendedSpawnObject>();
public static Dictionary<int, ExtendedGroupCounts> extendedGroupCounts = new Dictionary<int, ExtendedGroupCounts>();
public static List<List<string>> previousSpawns = new List<List<string>>();
public static List<int> difficulty1Counts = new List<int>();
public static List<int> difficulty2Counts = new List<int>();
public static List<int> difficulty3Counts = new List<int>();
public static List<string> loadedLevelNames = new List<string>();
public static List<int> levelNumbers = new List<int>();
public static double GetLevelNumMultiplier(int levelsAgo)
{
double num = 1.0;
if (levelsAgo == 1)
{
return SpawnConfig.configManager.consecutiveWeightMultiplierMin.Value;
}
if (levelsAgo == SpawnConfig.configManager.consecutiveLevelCount.Value)
{
return SpawnConfig.configManager.consecutiveWeightMultiplierMax.Value;
}
double num2 = (SpawnConfig.configManager.consecutiveWeightMultiplierMax.Value - SpawnConfig.configManager.consecutiveWeightMultiplierMin.Value) / (double)(SpawnConfig.configManager.consecutiveLevelCount.Value - 1);
return SpawnConfig.configManager.consecutiveWeightMultiplierMin.Value + (double)(levelsAgo - 1) * num2;
}
}
[BepInPlugin("Index154.SpawnConfig", "SpawnConfig", "1.2.9")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class SpawnConfig : BaseUnityPlugin
{
internal static ConfigManager configManager = null;
internal static ConfigFile Conf = null;
internal static readonly string configVersion = "1.0";
internal static readonly string exportPath = Path.Combine(Paths.ConfigPath, "SpawnConfig");
internal static readonly string spawnGroupsPath = Path.Combine(exportPath, "SpawnGroups.json");
internal static readonly string spawnGroupsBackupPath = Path.Combine(exportPath, "SpawnGroups_Backup.json");
internal static readonly string defaultSpawnGroupsPath = Path.Combine(exportPath, "Defaults", "SpawnGroups-Readonly.json");
internal static readonly string groupsPerLevelPath = Path.Combine(exportPath, "GroupsPerLevel.json");
internal static readonly string defaultGroupsPerLevelPath = Path.Combine(exportPath, "Defaults", "GroupsPerLevel-Readonly.json");
internal static readonly string groupsPerLevelExplainedPath = Path.Combine(exportPath, "GroupsPerLevel-Explained.json");
internal static readonly string spawnGroupsExplainedPath = Path.Combine(exportPath, "SpawnGroups-Explained.json");
public static bool missingProperties = false;
public static SpawnConfig Instance { get; private set; } = null;
internal static ManualLogSource Logger { get; private set; } = null;
internal static Harmony? Harmony { get; set; }
private void Awake()
{
Logger = ((BaseUnityPlugin)this).Logger;
Instance = this;
configManager = new ConfigManager();
Conf = ((BaseUnityPlugin)this).Config;
configManager.Setup(((BaseUnityPlugin)this).Config);
Directory.CreateDirectory(exportPath);
Directory.CreateDirectory(Path.Combine(exportPath, "Defaults"));
Patch();
Logger.LogInfo((object)"Index154.SpawnConfig has loaded!");
}
internal static void Patch()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
if (Harmony == null)
{
Harmony = new Harmony("Index154.SpawnConfig");
}
Logger.LogDebug((object)"Patching...");
Harmony.PatchAll();
Logger.LogDebug((object)"Finished patching!");
}
internal static void Unpatch()
{
Logger.LogDebug((object)"Unpatching...");
Harmony? harmony = Harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
Logger.LogDebug((object)"Finished unpatching!");
}
public static void ReadAndUpdateJSON()
{
List<ExtendedEnemySetup> list = JsonManager.GetSpawnGroupsFromJSON(spawnGroupsPath);
List<ExtendedGroupCounts> list2 = JsonManager.GetGroupCountsFromJSON(groupsPerLevelPath);
List<ExtendedGroupCounts> list3 = ListManager.extendedGroupCounts.Select<KeyValuePair<int, ExtendedGroupCounts>, ExtendedGroupCounts>((KeyValuePair<int, ExtendedGroupCounts> obj) => obj.Value).ToList();
File.WriteAllText(defaultGroupsPerLevelPath, JsonManager.GroupCountsToJSON(list3));
if (list2.Count < 1)
{
Logger.LogInfo((object)"No custom group count config found! Creating default file");
File.WriteAllText(groupsPerLevelPath, JsonManager.GroupCountsToJSON(list3));
list2 = list3;
}
if (list2[0].level != 1)
{
Logger.LogError((object)"Your custom group count config must contain at least a valid level 1 entry!");
list2 = list3;
}
List<ExtendedEnemySetup> list4 = ListManager.extendedSetups.Select<KeyValuePair<string, ExtendedEnemySetup>, ExtendedEnemySetup>((KeyValuePair<string, ExtendedEnemySetup> obj) => obj.Value).ToList();
File.WriteAllText(defaultSpawnGroupsPath, JsonManager.SpawnGroupsToJSON(list4));
if (list.Count < 1)
{
Logger.LogInfo((object)"No custom spawn groups config found! Creating default file");
File.WriteAllText(spawnGroupsPath, JsonManager.SpawnGroupsToJSON(list4));
list = list4;
}
bool flag = false;
foreach (ExtendedEnemySetup item in list)
{
if (item.Update())
{
flag = true;
}
}
Dictionary<string, ExtendedEnemySetup> dictionary = list.ToDictionary((ExtendedEnemySetup obj) => obj.name);
foreach (KeyValuePair<string, ExtendedEnemySetup> extendedSetup in ListManager.extendedSetups)
{
if (!dictionary.ContainsKey(extendedSetup.Value.name) && configManager.addMissingGroups.Value)
{
Logger.LogInfo((object)("Missing group entry found: " + extendedSetup.Value.name));
dictionary.Add(extendedSetup.Value.name, extendedSetup.Value);
flag = true;
}
}
list = dictionary.Values.ToList();
if (flag || missingProperties)
{
Logger.LogInfo((object)"-----------------------------------------------------------");
Logger.LogInfo((object)"Automatic changes have been made to SpawnConfig.json!");
File.WriteAllText(spawnGroupsPath, JsonManager.SpawnGroupsToJSON(list));
}
ListManager.extendedSetups = list.ToDictionary((ExtendedEnemySetup obj) => obj.name);
ListManager.extendedGroupCounts = list2.ToDictionary((ExtendedGroupCounts obj) => obj.level);
File.WriteAllText(groupsPerLevelPath, JsonManager.GroupCountsToJSON(list2));
File.Delete(spawnGroupsExplainedPath);
File.Delete(groupsPerLevelExplainedPath);
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "Index154.SpawnConfig";
public const string PLUGIN_NAME = "SpawnConfig";
public const string PLUGIN_VERSION = "1.2.9";
}
}
namespace SpawnConfig.Patches
{
[HarmonyPatch(typeof(BigMessageUI))]
public class BigMessageUIPatch
{
[HarmonyPatch("BigMessage")]
[HarmonyPostfix]
public static void ChangeBigMessageTimer(BigMessageUI __instance, string message, string emoji, float size, Color colorMain, Color colorFlash)
{
}
}
[HarmonyPatch(typeof(EnemyDirector))]
public class EnemyDirectorPatch
{
public static bool setupDone = false;
public static int currentDifficultyPick = 3;
public static bool onlyOneSetup = false;
public static List<string> enemyList = new List<string>();
public static List<string> enemiesSpawned = new List<string>();
public static List<string> enemiesSpawnedToDelete = new List<string>();
public static Dictionary<string, int> enemyCounts = new Dictionary<string, int>();
public static int enemyListIndex = 0;
public static int enemySpawnCount = 0;
public static void EnemySpawnSimulation(List<EnemySetup>[] enemiesDifficulties)
{
SpawnConfig.Logger.LogInfo((object)"Consolidated spawn distribution (100 runs, 15 levels each, 3 enemies per tier per level):");
Dictionary<string, int> dictionary = new Dictionary<string, int>();
Dictionary<string, float> dictionary2 = new Dictionary<string, float>();
for (int i = 0; i < 100; i++)
{
enemyList.Clear();
enemiesSpawned.Clear();
enemiesSpawnedToDelete.Clear();
enemyListIndex = 0;
for (int j = 0; j < 15; j++)
{
enemiesSpawnedToDelete.Clear();
foreach (string item in enemiesSpawned)
{
bool flag = false;
foreach (string item2 in enemiesSpawnedToDelete)
{
if (item == item2)
{
flag = true;
break;
}
}
if (!flag)
{
enemiesSpawnedToDelete.Add(item);
}
}
foreach (List<EnemySetup> enemiesList in enemiesDifficulties)
{
for (int l = 0; l < 3; l++)
{
string key = PickEnemySimulation(enemiesList);
if (!dictionary.ContainsKey(key))
{
dictionary.Add(key, 1);
}
else
{
dictionary[key]++;
}
}
}
for (int m = 0; m < 9; m++)
{
string text = enemyList[enemyListIndex];
enemyListIndex++;
int num = 0;
foreach (string item3 in enemiesSpawned)
{
if (item3 == text)
{
num++;
}
}
int num2 = 2;
while (num < 4 && num2 > 0)
{
enemiesSpawned.Add(text);
num++;
num2--;
}
}
foreach (string item4 in enemiesSpawnedToDelete)
{
enemiesSpawned.Remove(item4);
}
}
}
foreach (List<EnemySetup> list in enemiesDifficulties)
{
foreach (EnemySetup item5 in list)
{
if (dictionary.ContainsKey(((Object)item5).name))
{
if (Object.op_Implicit((Object)(object)item5.rarityPreset))
{
dictionary2.Add(((Object)item5).name, item5.rarityPreset.chance);
}
else
{
dictionary2.Add(((Object)item5).name, 100f);
}
}
}
}
foreach (KeyValuePair<string, int> item6 in dictionary)
{
SpawnConfig.Logger.LogInfo((object)(item6.Key + " = " + item6.Value + " (" + dictionary2[item6.Key] + ")"));
}
foreach (List<EnemySetup> list2 in enemiesDifficulties)
{
foreach (EnemySetup item7 in list2)
{
if (!dictionary.ContainsKey(((Object)item7).name))
{
SpawnConfig.Logger.LogInfo((object)(((Object)item7).name + " = 0 (" + item7.rarityPreset.chance + ")"));
}
}
}
}
public static string PickEnemySimulation(List<EnemySetup> _enemiesList)
{
ListExtension.Shuffle<EnemySetup>((IList<EnemySetup>)_enemiesList);
EnemySetup val = null;
float num = -1f;
foreach (EnemySetup _enemies in _enemiesList)
{
int num2 = 0;
foreach (string item in enemiesSpawned)
{
if (item == ((Object)_enemies).name)
{
num2++;
}
}
int num3 = 0;
foreach (string enemy in enemyList)
{
if (enemy == ((Object)_enemies).name)
{
num3++;
}
}
float num4 = 100f;
if (Object.op_Implicit((Object)(object)_enemies.rarityPreset))
{
num4 = _enemies.rarityPreset.chance;
}
float num5 = Mathf.Max(1f, num4 - 30f * (float)num2 - 10f * (float)num3);
float num6 = Random.Range(0f, num5);
if (num6 > num)
{
val = _enemies;
num = num6;
}
}
enemyList.Add(((Object)val).name);
return ((Object)val).name;
}
[HarmonyPatch("Start")]
[HarmonyPostfix]
public static void SetupAfterBundles(EnemyDirector __instance)
{
EnemyDirector __instance2 = __instance;
BundleLoader.OnAllBundlesLoaded += delegate
{
SpawnConfig.Logger.LogInfo((object)"All bundles have been loaded! Running setup...");
SetupOnStart(__instance2);
};
}
public static void SetupOnStart(EnemyDirector __instance)
{
if (setupDone)
{
return;
}
List<EnemySetup>[] array = new List<EnemySetup>[3] { __instance.enemiesDifficulty3, __instance.enemiesDifficulty2, __instance.enemiesDifficulty1 };
SpawnConfig.Logger.LogInfo((object)"-----------------------------------------------------------");
SpawnConfig.Logger.LogInfo((object)"Found the following level types:");
SpawnConfig.Logger.LogInfo((object)"-----------------------------------------------------------");
foreach (Level level in RunManager.instance.levels)
{
SpawnConfig.Logger.LogInfo((object)((Object)level).name.Replace("Level - ", ""));
ListManager.loadedLevelNames.Add(((Object)level).name.Replace("Level - ", ""));
}
int num = 3;
List<EnemySetup>[] array2 = array;
foreach (List<EnemySetup> list in array2)
{
foreach (EnemySetup item in list)
{
foreach (PrefabRef spawnObject in item.spawnObjects)
{
ExtendedSpawnObject extendedSpawnObject = new ExtendedSpawnObject(spawnObject);
if (!ListManager.spawnObjectsDict.ContainsKey(spawnObject.PrefabName))
{
ListManager.spawnObjectsDict.Add(spawnObject.PrefabName, spawnObject);
}
}
ExtendedEnemySetup extendedEnemySetup = new ExtendedEnemySetup(item, num);
if (!ListManager.extendedSetups.ContainsKey(((Object)item).name))
{
ListManager.extendedSetups.Add(extendedEnemySetup.name, extendedEnemySetup);
}
}
num--;
}
SpawnConfig.Logger.LogInfo((object)"-----------------------------------------------------------");
SpawnConfig.Logger.LogInfo((object)"Found the following enemy spawnObjects:");
SpawnConfig.Logger.LogInfo((object)"-----------------------------------------------------------");
foreach (KeyValuePair<string, PrefabRef> item2 in ListManager.spawnObjectsDict)
{
if (!item2.Key.Contains("Director"))
{
SpawnConfig.Logger.LogInfo((object)item2.Key);
}
}
int num2 = -1;
for (int j = 0; j < 21; j++)
{
float num3 = Mathf.Clamp01((float)j / 9f);
float num4 = Mathf.Clamp01((float)(j - 9) / 10f);
int num5;
int num6;
int num7;
if (num4 > 0f)
{
num5 = (int)__instance.amountCurve3_2.Evaluate(num4);
num6 = (int)__instance.amountCurve2_2.Evaluate(num4);
num7 = (int)__instance.amountCurve1_2.Evaluate(num4);
}
else
{
num5 = (int)__instance.amountCurve3_1.Evaluate(num3);
num6 = (int)__instance.amountCurve2_1.Evaluate(num3);
num7 = (int)__instance.amountCurve1_1.Evaluate(num3);
}
if (j == 0 || num5 != ListManager.difficulty3Counts[num2] || num6 != ListManager.difficulty2Counts[num2] || num7 != ListManager.difficulty1Counts[num2])
{
ListManager.levelNumbers.Add(j + 1);
ListManager.difficulty3Counts.Add(num5);
ListManager.difficulty2Counts.Add(num6);
ListManager.difficulty1Counts.Add(num7);
num2++;
}
}
for (int k = 0; k < ListManager.difficulty1Counts.Count; k++)
{
ExtendedGroupCounts extendedGroupCounts = new ExtendedGroupCounts(k);
if (!ListManager.extendedGroupCounts.ContainsKey(extendedGroupCounts.level))
{
ListManager.extendedGroupCounts.Add(extendedGroupCounts.level, extendedGroupCounts);
}
}
SpawnConfig.ReadAndUpdateJSON();
SpawnConfig.Logger.LogInfo((object)"-----------------------------------------------------------");
SpawnConfig.Logger.LogInfo((object)"Checking for invalid enemy objects and groups...");
SpawnConfig.Logger.LogInfo((object)"-----------------------------------------------------------");
List<string> list2 = new List<string>();
bool flag = false;
foreach (KeyValuePair<string, ExtendedEnemySetup> extendedSetup in ListManager.extendedSetups)
{
bool flag2 = false;
int num8 = 0;
List<int> list3 = new List<int>();
foreach (string spawnObject2 in extendedSetup.Value.spawnObjects)
{
if (!ListManager.spawnObjectsDict.ContainsKey(spawnObject2))
{
if (SpawnConfig.configManager.ignoreInvalidGroups.Value)
{
SpawnConfig.Logger.LogError((object)("Unable to resolve enemy name \"" + spawnObject2 + "\" in group \"" + extendedSetup.Value.name + "\"! This group will be ignored"));
flag2 = true;
flag = true;
}
else
{
SpawnConfig.Logger.LogError((object)("Unable to resolve enemy name \"" + spawnObject2 + "\" in group \"" + extendedSetup.Value.name + "\"! This enemy will be removed but the group can still spawn"));
list3.Add(num8);
flag = true;
}
}
num8++;
}
for (int num9 = list3.Count - 1; num9 > -1; num9--)
{
extendedSetup.Value.spawnObjects.RemoveAt(list3[num9]);
}
if (extendedSetup.Value.spawnObjects.Count < 1 && !flag2)
{
SpawnConfig.Logger.LogError((object)("The group \"" + extendedSetup.Value.name + "\" contains no valid enemies! This group will be ignored"));
flag2 = true;
flag = true;
}
if (flag2)
{
list2.Add(extendedSetup.Key);
}
}
if (!flag)
{
SpawnConfig.Logger.LogInfo((object)"No issues found!");
}
SpawnConfig.Logger.LogInfo((object)"-----------------------------------------------------------");
foreach (string item3 in list2)
{
ListManager.extendedSetups.Remove(item3);
}
setupDone = true;
}
[HarmonyPatch("AmountSetup")]
[HarmonyPrefix]
public static bool AmountSetupOverride(EnemyDirector __instance)
{
if (!SemiFunc.IsMasterClientOrSingleplayer())
{
return false;
}
if (!setupDone)
{
SpawnConfig.Logger.LogWarning((object)"Setup function hasn't run yet! Trying again now...");
SetupOnStart(__instance);
}
__instance.enemyListCurrent.Clear();
__instance.enemyList.Clear();
enemySpawnCount = 0;
onlyOneSetup = false;
__instance.enemiesDifficulty1.Clear();
__instance.enemiesDifficulty2.Clear();
__instance.enemiesDifficulty3.Clear();
foreach (KeyValuePair<string, ExtendedEnemySetup> extendedSetup in ListManager.extendedSetups)
{
if (extendedSetup.Value.difficulty1Weight > 0f)
{
__instance.enemiesDifficulty1.Add(extendedSetup.Value.GetEnemySetup());
}
if (extendedSetup.Value.difficulty2Weight > 0f)
{
__instance.enemiesDifficulty2.Add(extendedSetup.Value.GetEnemySetup());
}
if (extendedSetup.Value.difficulty3Weight > 0f)
{
__instance.enemiesDifficulty3.Add(extendedSetup.Value.GetEnemySetup());
}
}
EnemySetup val = ScriptableObject.CreateInstance<EnemySetup>();
((Object)val).name = "Fallback";
val.spawnObjects = new List<PrefabRef>();
if (__instance.enemiesDifficulty1.Count < 1)
{
__instance.enemiesDifficulty1.Add(val);
}
if (__instance.enemiesDifficulty2.Count < 1)
{
__instance.enemiesDifficulty2.Add(val);
}
if (__instance.enemiesDifficulty3.Count < 1)
{
__instance.enemiesDifficulty3.Add(val);
}
int num = 0;
int num2 = 0;
int num3 = 0;
int num4 = RunManager.instance.levelsCompleted + 1;
while (ListManager.previousSpawns.Count >= num4)
{
ListManager.previousSpawns.RemoveAt(0);
}
while (ListManager.previousSpawns.Count < num4)
{
ListManager.previousSpawns.Add(new List<string>());
}
SpawnConfig.Logger.LogInfo((object)"-----------------------------------------------------------");
int num5 = 0;
int num6 = num4;
while (num5 == 0)
{
if (ListManager.extendedGroupCounts.ContainsKey(num6))
{
num5 = num6;
SpawnConfig.Logger.LogInfo((object)("Using group count configs from [Level " + num6 + "]!"));
}
else
{
SpawnConfig.Logger.LogDebug((object)("Found no config for [Level " + num6 + "]..."));
num6--;
}
if (num6 < 1)
{
SpawnConfig.Logger.LogError((object)"No config entry for level 1 found in GroupsPerLevel.json! Enemy spawning will break!");
return false;
}
}
int num7 = 0;
int num8 = 1;
if (GameManager.instance.gameMode == 1)
{
num8 = LevelGenerator.Instance.ModulesReadyPlayers;
}
List<GroupCountEntry> list = new List<GroupCountEntry>();
foreach (GroupCountEntry possibleGroupCount in ListManager.extendedGroupCounts[num5].possibleGroupCounts)
{
if (num8 >= possibleGroupCount.minPlayerCount && (num8 <= possibleGroupCount.maxPlayerCount || possibleGroupCount.maxPlayerCount == 0))
{
list.Add(possibleGroupCount);
num7 += possibleGroupCount.weight;
}
}
if (list.Count < 1)
{
SpawnConfig.Logger.LogError((object)("No possible group counts found! Ignoring all playerCount restrictions as a fallback. Make sure there is at least one entry for the current player count of " + num8 + "!"));
list = ListManager.extendedGroupCounts[num5].possibleGroupCounts;
}
int num9 = Random.Range(1, num7 + 1);
SpawnConfig.Logger.LogDebug((object)("Selecting group counts based on random number " + num9 + "..."));
foreach (GroupCountEntry item in list)
{
int weight = item.weight;
if (item.counts.Count < 3)
{
SpawnConfig.Logger.LogError((object)"Found possibleGroupCounts entry with less than 3 numbers in the \"counts\" value! Missing group counts will lead to 0 groups spawning for the corresponding difficulty tier!");
while (item.counts.Count < 3)
{
item.counts.Add(0);
}
}
SpawnConfig.Logger.LogDebug((object)("=> [" + item.counts[0] + "," + item.counts[1] + "," + item.counts[2] + "] = " + weight + " / " + num9));
if (weight >= num9)
{
num = item.counts[2];
num2 = item.counts[1];
num3 = item.counts[0];
if (SpawnConfig.configManager.groupCountMultiplier.Value != 1)
{
SpawnConfig.Logger.LogInfo((object)("Applying global group count multiplier: " + SpawnConfig.configManager.groupCountMultiplier.Value));
num *= SpawnConfig.configManager.groupCountMultiplier.Value;
num2 *= SpawnConfig.configManager.groupCountMultiplier.Value;
num3 *= SpawnConfig.configManager.groupCountMultiplier.Value;
}
SpawnConfig.Logger.LogInfo((object)("Selected group counts: [" + num3 + "," + num2 + "," + num + "]"));
break;
}
num9 -= weight;
}
__instance.totalAmount = num3 + num2 + num;
for (int i = 0; i < num; i++)
{
PickEnemiesCustom(__instance.enemiesDifficulty3, __instance);
}
for (int j = 0; j < num2; j++)
{
PickEnemiesCustom(__instance.enemiesDifficulty2, __instance);
}
for (int k = 0; k < num3; k++)
{
PickEnemiesCustom(__instance.enemiesDifficulty1, __instance);
}
SpawnConfig.Logger.LogInfo((object)"-----------------------------------------------------------");
SpawnConfig.Logger.LogInfo((object)("Spawned a total of [" + __instance.totalAmount + "] enemy groups"));
return false;
}
public static void PickEnemiesCustom(List<EnemySetup> _enemiesList, EnemyDirector __instance)
{
if (!SemiFunc.IsMasterClientOrSingleplayer() || onlyOneSetup)
{
return;
}
if (_enemiesList == __instance.enemiesDifficulty1)
{
currentDifficultyPick = 1;
}
if (_enemiesList == __instance.enemiesDifficulty2)
{
currentDifficultyPick = 2;
}
if (_enemiesList == __instance.enemiesDifficulty3)
{
currentDifficultyPick = 3;
}
SpawnConfig.Logger.LogInfo((object)"-----------------------------------------------------------");
SpawnConfig.Logger.LogInfo((object)("Picking difficulty " + currentDifficultyPick + " setup..."));
SpawnConfig.Logger.LogInfo((object)"Enemy group weights:");
SpawnConfig.Logger.LogInfo((object)"-----------------------------------------------------------");
int num = DataDirector.instance.SettingValueFetch((Setting)31);
string currentLevelName = ((Object)RunManager.instance.levelCurrent).name.Replace("Level - ", "");
List<EnemySetup> list = new List<EnemySetup>();
float num2 = 0f;
foreach (EnemySetup _enemies in _enemiesList)
{
if ((!_enemies.levelsCompletedCondition || (RunManager.instance.levelsCompleted >= _enemies.levelsCompletedMin && (RunManager.instance.levelsCompleted <= _enemies.levelsCompletedMax || _enemies.levelsCompletedMax == -1))) && num >= _enemies.runsPlayed)
{
float num3 = 1f;
if (ListManager.extendedSetups.ContainsKey(((Object)_enemies).name))
{
num3 = ListManager.extendedSetups[((Object)_enemies).name].GetWeight(currentDifficultyPick, __instance.enemyList, currentLevelName);
}
if (!(num3 < 1f))
{
num2 += num3;
list.Add(_enemies);
SpawnConfig.Logger.LogInfo((object)(((Object)_enemies).name + " = " + num3));
}
}
}
if (list.Count < 1)
{
SpawnConfig.Logger.LogError((object)"No selectable enemy groups found! This level will have one less enemy than intended");
__instance.totalAmount--;
return;
}
EnemySetup val = null;
float num4 = Random.Range(1f, num2);
SpawnConfig.Logger.LogDebug((object)("Selecting a group based on random number " + num4 + "..."));
foreach (EnemySetup item in list)
{
float num5 = 1f;
if (ListManager.extendedSetups.ContainsKey(((Object)item).name))
{
num5 = ListManager.extendedSetups[((Object)item).name].GetWeight(currentDifficultyPick, __instance.enemyList, currentLevelName);
}
SpawnConfig.Logger.LogDebug((object)(((Object)item).name + " = " + num5 + " / " + num4));
if (num5 >= num4)
{
SpawnConfig.Logger.LogInfo((object)(" ==> Selected: " + ((Object)item).name));
val = item;
break;
}
num4 -= num5;
}
if (ListManager.extendedSetups.ContainsKey(((Object)val).name) && ListManager.extendedSetups[((Object)val).name].soloGroup && !onlyOneSetup)
{
List<string> list2 = new List<string>();
foreach (EnemySetup enemy in __instance.enemyList)
{
list2.Add(((Object)enemy).name);
}
__instance.enemyList.Clear();
__instance.enemyList.Add(val);
onlyOneSetup = true;
__instance.totalAmount = 1;
SpawnConfig.Logger.LogInfo((object)"This is a solo group (soloGroup = true)! Removing all other spawns...");
}
else
{
__instance.enemyList.Add(val);
}
}
[HarmonyPatch("DebugResult")]
[HarmonyPrefix]
public static void Debug()
{
SpawnConfig.Logger.LogInfo((object)("Spawned a total of [" + enemySpawnCount + "] enemy objects"));
SpawnConfig.Logger.LogInfo((object)"-----------------------------------------------------------");
}
}
[HarmonyPatch(typeof(LevelGenerator))]
public class LevelGeneratorPatch
{
public static int PickNonDirector(EnemySetup enemySetup)
{
int num = -1;
int num2 = 0;
int num3 = enemySetup.spawnObjects.Count;
while (num == -1)
{
int num4 = Random.Range(num2, num3);
if (!enemySetup.spawnObjects[num4].PrefabName.Contains("Director"))
{
num = num4;
}
else if (num2 == num3)
{
num = num2;
}
else if (num4 == num2)
{
num2++;
}
else if (num4 == num3)
{
num3--;
}
}
return num;
}
[HarmonyPatch("EnemySpawn")]
[HarmonyPrefix]
public static void LogAndModifySpawns(EnemySetup enemySetup, Vector3 position, LevelGenerator __instance)
{
int index = ListManager.previousSpawns.Count - 1;
if (!ListManager.previousSpawns[index].Contains(((Object)enemySetup).name))
{
ListManager.previousSpawns[index].Add(((Object)enemySetup).name);
}
bool flag = false;
bool flag2 = false;
int num = 0;
foreach (PrefabRef spawnObject in enemySetup.spawnObjects)
{
if (spawnObject.PrefabName.Contains("Gnome") && !flag)
{
flag = true;
num++;
}
else if (spawnObject.PrefabName.Contains("Bang") && !flag2)
{
flag2 = true;
num++;
}
}
if (flag)
{
enemySetup.spawnObjects.Insert(0, ListManager.spawnObjectsDict["Enemy - Gnome Director"]);
}
if (flag2)
{
enemySetup.spawnObjects.Insert(0, ListManager.spawnObjectsDict["Enemy - Bang Director"]);
}
if (ListManager.extendedSetups.ContainsKey(((Object)enemySetup).name))
{
int num2 = (int)Math.Round(1.0 / ListManager.extendedSetups[((Object)enemySetup).name].alterAmountChance);
if (num2 < 1)
{
num2 = 1;
}
int num3 = Random.Range(1, num2 + 1);
if (num3 <= 1 && enemySetup.spawnObjects.Count > 0)
{
int i = Random.Range(ListManager.extendedSetups[((Object)enemySetup).name].alterAmountMin, ListManager.extendedSetups[((Object)enemySetup).name].alterAmountMax + 1);
if (i > 0)
{
while (i > 0)
{
enemySetup.spawnObjects.Add(enemySetup.spawnObjects[PickNonDirector(enemySetup)]);
i--;
}
}
else if (i < 0)
{
for (; i < 0; i++)
{
if (enemySetup.spawnObjects.Count <= 0)
{
break;
}
enemySetup.spawnObjects.RemoveAt(PickNonDirector(enemySetup));
}
}
}
}
Dictionary<string, int> dictionary = new Dictionary<string, int>();
foreach (PrefabRef spawnObject2 in enemySetup.spawnObjects)
{
EnemyDirectorPatch.enemySpawnCount++;
if (dictionary.ContainsKey(spawnObject2.PrefabName))
{
dictionary[spawnObject2.PrefabName] = dictionary[spawnObject2.PrefabName] + 1;
}
else
{
dictionary.Add(spawnObject2.PrefabName, 1);
}
}
string text = "";
foreach (KeyValuePair<string, int> item in dictionary)
{
if (!item.Key.Contains("Director"))
{
if (text != "")
{
text += ", ";
}
text = text + item.Key + " x " + item.Value;
}
}
if (text == "")
{
text = "No spawn objects found in group...";
}
if (SpawnConfig.configManager.preventSpawns.Value)
{
enemySetup.spawnObjects.Clear();
SpawnConfig.Logger.LogInfo((object)"Forcibly prevented enemy spawn!");
return;
}
SpawnConfig.Logger.LogInfo((object)("Spawning [" + ((Object)enemySetup).name + "] (" + text.Replace("Enemy - ", "") + ")"));
}
}
}
namespace SpawnConfig.ExtendedClasses
{
public class ExtendedEnemySetup
{
public string name = "Nameless";
public bool levelsCompletedCondition = false;
public int levelsCompletedMax = 10;
public int levelsCompletedMin = 0;
public bool levelRangeCondition = false;
public int minLevel = 0;
public int maxLevel = 0;
public int runsPlayed = 0;
public List<string> spawnObjects = new List<string>();
public float difficulty1Weight = 0f;
public float difficulty2Weight = 0f;
public float difficulty3Weight = 0f;
public Dictionary<string, float> levelWeightMultipliers = new Dictionary<string, float>();
public bool thisGroupOnly = false;
public bool soloGroup = false;
public bool allowDuplicates = true;
public double alterAmountChance = 0.0;
public int alterAmountMin = 0;
public int alterAmountMax = 0;
public ExtendedEnemySetup()
{
}
public ExtendedEnemySetup(EnemySetup enemySetup, int difficulty)
{
name = ((Object)enemySetup).name;
if (enemySetup.levelsCompletedCondition)
{
levelRangeCondition = true;
minLevel = enemySetup.levelsCompletedMin + 1;
maxLevel = enemySetup.levelsCompletedMax + 1;
}
if (maxLevel == 1)
{
maxLevel = 0;
}
runsPlayed = enemySetup.runsPlayed;
spawnObjects = (from obj in enemySetup.spawnObjects
where !obj.PrefabName.Contains("Director")
select obj.PrefabName).ToList();
float num = 100f;
if (Object.op_Implicit((Object)(object)enemySetup.rarityPreset))
{
num = (float)Math.Round(-2.08f * (100f - enemySetup.rarityPreset.chance) + 98.45f);
if (num > 100f)
{
num = 100f;
}
if (num == 98f)
{
num = 100f;
}
if (num <= 15f && num > 2f)
{
num = 5f;
}
if (num < 2f)
{
num = 2f;
}
SpawnConfig.Logger.LogDebug((object)(name + " (rarity) = " + enemySetup.rarityPreset.chance));
}
difficulty1Weight = ((difficulty == 1) ? num : 0f);
difficulty2Weight = ((difficulty == 2) ? num : 0f);
difficulty3Weight = ((difficulty == 3) ? num : 0f);
foreach (string loadedLevelName in ListManager.loadedLevelNames)
{
if (!levelWeightMultipliers.ContainsKey(loadedLevelName))
{
levelWeightMultipliers.Add(loadedLevelName, 1f);
}
}
}
public EnemySetup GetEnemySetup()
{
EnemySetup val = ScriptableObject.CreateInstance<EnemySetup>();
((Object)val).name = name;
val.spawnObjects = new List<PrefabRef>();
val.levelsCompletedCondition = levelRangeCondition;
val.levelsCompletedMin = minLevel - 1;
val.levelsCompletedMax = maxLevel - 1;
val.runsPlayed = runsPlayed;
foreach (string spawnObject in spawnObjects)
{
val.spawnObjects.Add(ListManager.spawnObjectsDict[spawnObject]);
}
return val;
}
public float GetWeight(int difficulty, List<EnemySetup> enemyList, string currentLevelName)
{
float num = difficulty1Weight;
switch (difficulty)
{
case 2:
num = difficulty2Weight;
break;
case 3:
num = difficulty3Weight;
break;
}
if (levelWeightMultipliers.ContainsKey(currentLevelName))
{
num *= levelWeightMultipliers[currentLevelName];
}
if (SpawnConfig.configManager.enableVarietyPlus.Value)
{
int num2 = RunManager.instance.levelsCompleted;
int num3 = SpawnConfig.configManager.consecutiveLevelCount.Value;
if (num2 < num3)
{
num3 = num2;
}
for (int i = 0; i < num3; i++)
{
if (ListManager.previousSpawns[num2 - 1].Contains(name))
{
num = (float)((double)num * ListManager.GetLevelNumMultiplier(i + 1));
}
num2--;
}
}
if (enemyList.Select((EnemySetup obj) => ((Object)obj).name).ToList().Contains(name))
{
num = (float)((double)num * SpawnConfig.configManager.repeatMultiplier.Value);
if (!allowDuplicates)
{
num = 0f;
}
}
if ((double)num < 0.1)
{
num = 0f;
}
return num;
}
public void UpdateWithDefaults(ExtendedEnemySetup defaultSetup)
{
PropertyInfo[] properties = defaultSetup.GetType().GetProperties();
PropertyInfo[] array = properties;
foreach (PropertyInfo propertyInfo in array)
{
object value = propertyInfo.GetValue(defaultSetup);
object value2 = propertyInfo.GetValue(this);
object value3 = propertyInfo.GetValue(ListManager.extendedSetups[defaultSetup.name]);
if (value == value2 && value3 != value)
{
SpawnConfig.Logger.LogInfo((object)("Updating unmodified property " + propertyInfo?.ToString() + ": " + value?.ToString() + " => " + value3));
propertyInfo.SetValue(this, value3);
}
}
}
public bool Update()
{
bool result = false;
if (levelsCompletedCondition)
{
levelRangeCondition = true;
minLevel = levelsCompletedMin;
maxLevel = levelsCompletedMax;
levelsCompletedCondition = false;
result = true;
}
if (!levelRangeCondition && maxLevel == 10)
{
maxLevel = 0;
result = true;
}
if (thisGroupOnly)
{
soloGroup = true;
thisGroupOnly = false;
result = true;
}
if (SpawnConfig.configManager.removeUnloadedLevelWeights.Value)
{
Dictionary<string, float> dictionary = new Dictionary<string, float>();
bool flag = false;
foreach (KeyValuePair<string, float> levelWeightMultiplier in levelWeightMultipliers)
{
if (!ListManager.loadedLevelNames.Contains(levelWeightMultiplier.Key))
{
result = true;
flag = true;
}
else
{
dictionary.Add(levelWeightMultiplier.Key, levelWeightMultiplier.Value);
}
}
if (flag)
{
levelWeightMultipliers = dictionary;
}
}
foreach (string loadedLevelName in ListManager.loadedLevelNames)
{
if (!levelWeightMultipliers.ContainsKey(loadedLevelName))
{
levelWeightMultipliers.Add(loadedLevelName, 1f);
result = true;
}
}
return result;
}
}
public class ExtendedGroupCounts
{
public int level = 1;
public List<GroupCountEntry> possibleGroupCounts = new List<GroupCountEntry>();
public ExtendedGroupCounts(int i)
{
level = ListManager.levelNumbers[i];
possibleGroupCounts.Add(new GroupCountEntry(i));
}
}
public class GroupCountEntry
{
public List<int> counts = new List<int>();
public int weight = 1;
public int minPlayerCount = 1;
public int maxPlayerCount = 0;
public GroupCountEntry(int i)
{
counts = new List<int>(3)
{
ListManager.difficulty1Counts[i],
ListManager.difficulty2Counts[i],
ListManager.difficulty3Counts[i]
};
}
}
public class ExtendedSpawnObject
{
public string name = "Nameless";
public bool disabled = false;
public int biggerGroupChance = 0;
public int groupIncreaseAmount = 0;
[JsonIgnore]
public bool alteredGroupSize = false;
public ExtendedSpawnObject(PrefabRef spawnObject)
{
name = spawnObject.PrefabName;
}
public PrefabRef GetSpawnObject()
{
return ListManager.spawnObjectsDict[name];
}
}
}