using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; 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 HG; using Microsoft.CodeAnalysis; using On.RoR2; using On.RoR2.UI; using RoR2; using RoR2.CharacterAI; using RoR2.UI; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SpawnBox")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.7.0.0")] [assembly: AssemblyInformationalVersion("1.7.0+a54bcb00aa202b8139694512994406715ace9eb3")] [assembly: AssemblyProduct("SpawnBox")] [assembly: AssemblyTitle("SpawnBox")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.7.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 SpawnBox { internal enum AggressionPreset { Passive, Normal, Aggressive, Warpath } internal class AggressionController { private class DriverBaseline { public AISkillDriver Driver; public bool ShouldSprint; public float MoveInputScale; public float MaxDistance; public float MinUserHealthFraction; public float MaxUserHealthFraction; public float DriverUpdateTimerOverride; public float AimVectorMaxSpeedOverride; public float AimVectorDampTimeOverride; } internal static readonly string[] Labels = new string[4] { "Passive", "Normal", "Aggressive", "Warpath" }; private readonly List baselines = new List(); internal AggressionPreset CurrentPreset { get; private set; } = AggressionPreset.Normal; internal AggressionController(CharacterMaster master) { if ((Object)(object)master == (Object)null) { return; } BaseAI[] components = ((Component)master).GetComponents(); foreach (BaseAI val in components) { if ((Object)(object)val == (Object)null || val.skillDrivers == null) { continue; } AISkillDriver[] skillDrivers = val.skillDrivers; foreach (AISkillDriver val2 in skillDrivers) { if (!((Object)(object)val2 == (Object)null)) { baselines.Add(new DriverBaseline { Driver = val2, ShouldSprint = val2.shouldSprint, MoveInputScale = val2.moveInputScale, MaxDistance = val2.maxDistance, MinUserHealthFraction = val2.minUserHealthFraction, MaxUserHealthFraction = val2.maxUserHealthFraction, DriverUpdateTimerOverride = val2.driverUpdateTimerOverride, AimVectorMaxSpeedOverride = val2.aimVectorMaxSpeedOverride, AimVectorDampTimeOverride = val2.aimVectorDampTimeOverride }); } } } } internal void Apply(AggressionPreset preset) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Invalid comparison between Unknown and I4 CurrentPreset = preset; foreach (DriverBaseline baseline in baselines) { if ((Object)(object)baseline.Driver == (Object)null) { continue; } baseline.Driver.shouldSprint = baseline.ShouldSprint; baseline.Driver.moveInputScale = baseline.MoveInputScale; baseline.Driver.maxDistance = baseline.MaxDistance; baseline.Driver.minUserHealthFraction = baseline.MinUserHealthFraction; baseline.Driver.maxUserHealthFraction = baseline.MaxUserHealthFraction; baseline.Driver.driverUpdateTimerOverride = baseline.DriverUpdateTimerOverride; baseline.Driver.aimVectorMaxSpeedOverride = baseline.AimVectorMaxSpeedOverride; baseline.Driver.aimVectorDampTimeOverride = baseline.AimVectorDampTimeOverride; bool flag = (int)baseline.Driver.movementType == 3; switch (preset) { case AggressionPreset.Aggressive: baseline.Driver.shouldSprint = true; baseline.Driver.moveInputScale = Mathf.Max(baseline.MoveInputScale, 1f); if (!flag) { baseline.Driver.maxDistance = baseline.MaxDistance * 2f; break; } baseline.Driver.minUserHealthFraction = 2f; baseline.Driver.maxUserHealthFraction = -1f; break; case AggressionPreset.Passive: baseline.Driver.shouldSprint = false; baseline.Driver.moveInputScale = Mathf.Min(baseline.MoveInputScale, 0.6f); if (!flag) { baseline.Driver.maxDistance = baseline.MaxDistance * 0.5f; } else { baseline.Driver.maxUserHealthFraction = Mathf.Min(baseline.MaxUserHealthFraction * 1.5f, 1f); } break; case AggressionPreset.Warpath: baseline.Driver.shouldSprint = true; baseline.Driver.moveInputScale = Mathf.Max(baseline.MoveInputScale, 1.75f); if (!flag) { baseline.Driver.maxDistance = baseline.MaxDistance * 3f; } else { baseline.Driver.minUserHealthFraction = 2f; baseline.Driver.maxUserHealthFraction = -1f; } baseline.Driver.driverUpdateTimerOverride = 0.1f; baseline.Driver.aimVectorMaxSpeedOverride = 12f; baseline.Driver.aimVectorDampTimeOverride = 0.1f; break; } } } } internal class SpawnedCharacterInstance { public GameObject Master; public string DisplayName; public string AffixLabel; public string SizeLabel; public AggressionController Aggression; public ToughnessTier ToughnessTier = ToughnessTier.Normal; } internal static class AllySpawnerTab { private class Row { public GameObject MasterPrefab; public string DisplayName; public Texture Icon; public string Key; public bool IsFavorite; } private const int IconSize = 24; private static readonly List allRows = new List(); private static string search = ""; private static string quantityText = "1"; private static Vector2 scroll; private static readonly List spawnedObjects = new List(); private static ConfigEntry favoritesEntry; private static readonly HashSet favorites = new HashSet(); private static bool shareBuild = false; private static AggressionPreset selectedAggression = AggressionPreset.Normal; private static SizeTier selectedSize = SizeTier.Normal; private static ToughnessTier selectedToughness = ToughnessTier.Normal; private static int selectedEliteIndex = 0; private const string ExcludedMasterName = "HaulerDroneMaster"; private static void LoadFavorites() { favoritesEntry = SpawnBoxPlugin.PluginConfig.Bind("Favorites", "Allies", "", "Comma-separated list of favorited ally master names."); favorites.Clear(); string[] array = favoritesEntry.Value.Split(','); foreach (string text in array) { if (!string.IsNullOrEmpty(text)) { favorites.Add(text); } } } private static void SaveFavorites() { favoritesEntry.Value = string.Join(",", favorites); } private static void SortRows() { allRows.Sort((Row a, Row b) => (a.IsFavorite != b.IsFavorite) ? ((!a.IsFavorite) ? 1 : (-1)) : string.Compare(a.DisplayName, b.DisplayName)); } public static void BuildList() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 LoadFavorites(); allRows.Clear(); foreach (CharacterMaster allAiMaster in MasterCatalog.allAiMasters) { if (!((Object)(object)allAiMaster == (Object)null) && !((Object)(object)allAiMaster.bodyPrefab == (Object)null) && (int)allAiMaster.teamIndex == 1 && !(((Object)((Component)allAiMaster).gameObject).name == "HaulerDroneMaster")) { CharacterBody component = allAiMaster.bodyPrefab.GetComponent(); if (!((Object)(object)component == (Object)null) && !string.IsNullOrEmpty(component.baseNameToken)) { string name = ((Object)((Component)allAiMaster).gameObject).name; allRows.Add(new Row { MasterPrefab = ((Component)allAiMaster).gameObject, DisplayName = Language.GetString(component.baseNameToken), Icon = component.portraitIcon, Key = name, IsFavorite = favorites.Contains(name) }); } } } SortRows(); SpawnBoxPlugin.Log.LogInfo((object)$"SpawnBox: {allRows.Count} allies available."); } public static void Draw() { //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Search:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); search = GUILayout.TextField(search, Array.Empty()); GUILayout.Label("Qty:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) }); quantityText = GUILayout.TextField(quantityText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) }); GUILayout.EndHorizontal(); GUILayout.Label("High values may impact performance.", Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); selectedEliteIndex = UiCycler.Draw("Elite:", 70f, selectedEliteIndex, EnemySpawnerTab.eliteLabels, 140f); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); selectedAggression = (AggressionPreset)UiCycler.Draw("Aggression:", 70f, (int)selectedAggression, AggressionController.Labels, 140f); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); selectedSize = (SizeTier)UiCycler.Draw("Size:", 70f, (int)selectedSize, SizeController.Labels, 140f); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); selectedToughness = (ToughnessTier)UiCycler.Draw("Toughness:", 70f, (int)selectedToughness, ToughnessController.Labels, 140f); GUILayout.EndHorizontal(); shareBuild = GUILayout.Toggle(shareBuild, "Share my build with spawned allies (live)", Array.Empty()); bool flag = false; scroll = GUILayout.BeginScrollView(scroll, Array.Empty()); foreach (Row allRow in allRows) { if (!string.IsNullOrEmpty(search) && allRow.DisplayName.IndexOf(search, StringComparison.OrdinalIgnoreCase) < 0) { continue; } GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button(allRow.IsFavorite ? "Unpin" : "Pin", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) })) { allRow.IsFavorite = !allRow.IsFavorite; if (allRow.IsFavorite) { favorites.Add(allRow.Key); } else { favorites.Remove(allRow.Key); } SaveFavorites(); flag = true; } if ((Object)(object)allRow.Icon != (Object)null) { GUILayout.Label(allRow.Icon, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(24f), GUILayout.Height(24f) }); } else { GUILayout.Space(24f); } GUILayout.Label(allRow.DisplayName, Array.Empty()); if (GUILayout.Button("Spawn", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { SpawnMany(allRow.MasterPrefab, allRow.DisplayName, ParseQuantity()); } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); if (flag) { SortRows(); } } private static int ParseQuantity() { if (!int.TryParse(quantityText, out var result) || result <= 0) { return 1; } return result; } private static void SpawnMany(GameObject masterPrefab, string displayName, int count) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { return; } LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); if ((Object)(object)val == (Object)null) { return; } EliteDef val2 = ((selectedEliteIndex > 0 && selectedEliteIndex - 1 < EnemySpawnerTab.eliteOptions.Count) ? EnemySpawnerTab.eliteOptions[selectedEliteIndex - 1] : null); string affixLabel = (((Object)(object)val2 != (Object)null) ? EnemySpawnerTab.eliteLabels[selectedEliteIndex] : ""); string sizeLabel = SizeController.DisplayLabel(selectedSize); for (int i = 0; i < count; i++) { float num = 360f / (float)count * (float)i; Vector3 val3 = Quaternion.Euler(0f, num, 0f) * (val.transform.forward * 5f); Vector3 position = val.transform.position + val3; CharacterMaster val4 = new MasterSummon { masterPrefab = masterPrefab, position = position, rotation = Quaternion.identity, teamIndexOverride = (TeamIndex)1, useAmbientLevel = true, inventoryToCopy = (shareBuild ? val.inventory : null), ignoreTeamMemberLimit = true }.Perform(); if (Object.op_Implicit((Object)(object)val4) && (Object)(object)val2 != (Object)null && Object.op_Implicit((Object)(object)val4.inventory) && Object.op_Implicit((Object)(object)val2.eliteEquipmentDef)) { val4.inventory.SetEquipmentIndex(val2.eliteEquipmentDef.equipmentIndex, false); } if ((Object)(object)val4 != (Object)null) { ((Component)val4).gameObject.AddComponent(); AggressionController aggressionController = new AggressionController(val4); if (selectedAggression != AggressionPreset.Normal) { aggressionController.Apply(selectedAggression); } SizeController.Attach(val4, selectedSize); ToughnessController.Attach(val4, selectedToughness); RewardController.Attach(val4); spawnedObjects.Add(new SpawnedCharacterInstance { Master = ((Component)val4).gameObject, DisplayName = displayName, AffixLabel = affixLabel, SizeLabel = sizeLabel, Aggression = aggressionController, ToughnessTier = selectedToughness }); } } } internal static int SpawnedCount() { int num = 0; foreach (SpawnedCharacterInstance spawnedObject in spawnedObjects) { if ((Object)(object)spawnedObject.Master != (Object)null) { num++; } } return num; } internal static IReadOnlyList GetSpawned() { return spawnedObjects; } internal static void DespawnAll() { if (!NetworkServer.active) { return; } foreach (SpawnedCharacterInstance spawnedObject in spawnedObjects) { if (!((Object)(object)spawnedObject.Master == (Object)null)) { CharacterMaster component = spawnedObject.Master.GetComponent(); if (component != null) { component.DestroyBody(); } NetworkServer.Destroy(spawnedObject.Master); } } spawnedObjects.Clear(); } internal static void DespawnOne(SpawnedCharacterInstance instance) { if (!NetworkServer.active || instance == null) { return; } if ((Object)(object)instance.Master != (Object)null) { CharacterMaster component = instance.Master.GetComponent(); if (component != null) { component.DestroyBody(); } NetworkServer.Destroy(instance.Master); } spawnedObjects.Remove(instance); } internal static void SyncBuildToAllies(Inventory playerInventory) { if (!shareBuild || !NetworkServer.active) { return; } foreach (SpawnedCharacterInstance spawnedObject in spawnedObjects) { if (!((Object)(object)spawnedObject.Master == (Object)null)) { CharacterMaster component = spawnedObject.Master.GetComponent(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.inventory == (Object)null)) { component.inventory.CopyItemsFrom(playerInventory); component.inventory.CopyEquipmentFrom(playerInventory, false); } } } } } internal static class BuffPresets { internal class Preset { public string Name; public string Subtitle; public BuffDef[] Recipe; } internal static readonly List All = new List { new Preset { Name = "Ghost Protocol", Recipe = (BuffDef[])(object)new BuffDef[2] { Buffs.Cloak, Buffs.CloakSpeed } }, new Preset { Name = "Juggernaut", Recipe = (BuffDef[])(object)new BuffDef[2] { Buffs.ArmorBoost, Buffs.ElephantArmorBoost } }, new Preset { Name = "Berserker", Recipe = (BuffDef[])(object)new BuffDef[3] { Buffs.FullCrit, Buffs.AttackSpeedOnCrit, Buffs.HealingDisabled } }, new Preset { Name = "Warlord", Recipe = (BuffDef[])(object)new BuffDef[2] { Buffs.Warbanner, Buffs.WarCryBuff } }, new Preset { Name = "Bloodpact", Recipe = (BuffDef[])(object)new BuffDef[2] { Buffs.LifeSteal, Buffs.Energized } }, new Preset { Name = "Death Wish", Recipe = (BuffDef[])(object)new BuffDef[4] { Buffs.Weak, Buffs.Cripple, Buffs.Slow80, Buffs.HealingDisabled } } }; private static readonly List activePresetBuffs = new List(); internal static void BuildSubtitles() { foreach (Preset item in All) { List list = new List(); BuffDef[] recipe = item.Recipe; foreach (BuffDef val in recipe) { if ((Object)(object)val != (Object)null) { list.Add(BuffsTab.Prettify(((Object)val).name)); } else { SpawnBoxPlugin.Log.LogWarning((object)("SpawnBox: a BuffPresets recipe entry in \"" + item.Name + "\" is null - RoR2Content.Buffs field may be unresolved.")); } } item.Subtitle = string.Join(", ", list); } } internal static void Apply(Preset preset) { if (!NetworkServer.active || preset == null) { return; } LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); if ((Object)(object)val == (Object)null) { return; } Clear(); BuffDef[] recipe = preset.Recipe; foreach (BuffDef val2 in recipe) { if (!((Object)(object)val2 == (Object)null)) { val.AddBuff(val2); activePresetBuffs.Add(val2); PlayerPersistence.TrackPermanent(val2); } } } internal static void Clear() { if (!NetworkServer.active) { return; } LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); if ((Object)(object)val == (Object)null) { return; } foreach (BuffDef activePresetBuff in activePresetBuffs) { if (!((Object)(object)activePresetBuff == (Object)null)) { val.RemoveBuff(activePresetBuff); if (val.GetBuffCount(activePresetBuff) <= 0) { PlayerPersistence.Untrack(activePresetBuff); } } } activePresetBuffs.Clear(); } } internal static class BuffsTab { private class Row { public BuffDef Def; public string DisplayName; public Texture Icon; } private enum Section { None, Buffs, Debuffs, Elite, Presets } private const int IconSize = 24; internal const int TimedMaxStacks = 999; private const float DefaultDuration = 5f; private static readonly List buffRows = new List(); private static readonly List debuffRows = new List(); private static readonly List eliteRows = new List(); private static readonly List curatedBuffRows = new List(); private static readonly List curatedDebuffRows = new List(); private static Section expandedSection = Section.None; private static bool showAllBuffs = false; private static bool showAllDebuffs = false; private static string search = ""; private static string durationText = "5"; private static Vector2 scroll; public static void BuildList() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) buffRows.Clear(); debuffRows.Clear(); eliteRows.Clear(); curatedBuffRows.Clear(); curatedDebuffRows.Clear(); HashSet hashSet = new HashSet(BuffCatalog.buffIndiciesRandomEligible); HashSet hashSet2 = new HashSet(BuffCatalog.debuffIndiciesRandomEligible); BuffIndex[] nonHiddenBuffIndices = BuffCatalog.nonHiddenBuffIndices; foreach (BuffIndex val in nonHiddenBuffIndices) { BuffDef buffDef = BuffCatalog.GetBuffDef(val); if ((Object)(object)buffDef == (Object)null || buffDef.isElite) { continue; } Row item = new Row { Def = buffDef, DisplayName = Prettify(((Object)buffDef).name), Icon = (Texture)(object)(((Object)(object)buffDef.iconSprite != (Object)null) ? buffDef.iconSprite.texture : null) }; if (buffDef.isDebuff) { debuffRows.Add(item); if (hashSet2.Contains(val)) { curatedDebuffRows.Add(item); } } else { buffRows.Add(item); if (hashSet.Contains(val)) { curatedBuffRows.Add(item); } } } nonHiddenBuffIndices = BuffCatalog.eliteBuffIndices; for (int i = 0; i < nonHiddenBuffIndices.Length; i++) { BuffDef buffDef2 = BuffCatalog.GetBuffDef(nonHiddenBuffIndices[i]); if (!((Object)(object)buffDef2 == (Object)null)) { Row item2 = new Row { Def = buffDef2, DisplayName = Prettify(((Object)buffDef2).name), Icon = (Texture)(object)(((Object)(object)buffDef2.iconSprite != (Object)null) ? buffDef2.iconSprite.texture : null) }; eliteRows.Add(item2); } } buffRows.Sort((Row a, Row b) => string.Compare(a.DisplayName, b.DisplayName)); debuffRows.Sort((Row a, Row b) => string.Compare(a.DisplayName, b.DisplayName)); eliteRows.Sort((Row a, Row b) => string.Compare(a.DisplayName, b.DisplayName)); curatedBuffRows.Sort((Row a, Row b) => string.Compare(a.DisplayName, b.DisplayName)); curatedDebuffRows.Sort((Row a, Row b) => string.Compare(a.DisplayName, b.DisplayName)); BuffPresets.BuildSubtitles(); SpawnBoxPlugin.Log.LogInfo((object)($"SpawnBox: {buffRows.Count} buffs ({curatedBuffRows.Count} curated), " + $"{debuffRows.Count} debuffs ({curatedDebuffRows.Count} curated), " + $"{eliteRows.Count} elite buffs available.")); } internal static string Prettify(string rawName) { if (string.IsNullOrEmpty(rawName)) { return "(unnamed)"; } string text = rawName; if (text.Length > 2 && text[0] == 'b' && text[1] == 'd' && char.IsUpper(text[2])) { text = text.Substring(2); } StringBuilder stringBuilder = new StringBuilder(text.Length + 8); for (int i = 0; i < text.Length; i++) { if (i > 0 && char.IsUpper(text[i]) && !char.IsUpper(text[i - 1])) { stringBuilder.Append(' '); } stringBuilder.Append(text[i]); } return stringBuilder.ToString(); } private static void SetSection(Section s) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) expandedSection = ((expandedSection != s) ? s : Section.None); search = ""; scroll = Vector2.zero; } public static void Draw() { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Duration (s):", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(85f) }); durationText = GUILayout.TextField(durationText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); GUILayout.Label("- used by the Timed button on every row.", Array.Empty()); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUI.enabled = NetworkServer.active && (Object)(object)val != (Object)null; int currentSize = (int)PlayerPersistence.CurrentSize; int num = UiCycler.Draw("Your Size:", 85f, currentSize, SizeController.Labels, 120f); if (num != currentSize) { SizeTier sizeTier = (SizeTier)num; PlayerPersistence.SetSize(sizeTier); if ((Object)(object)val != (Object)null) { SizeController.ApplyToPlayer(val, sizeTier); } } GUI.enabled = true; GUILayout.EndHorizontal(); if (GUILayout.Button((expandedSection == Section.Buffs) ? "▾ Buffs" : "▸ Buffs", Array.Empty())) { SetSection(Section.Buffs); } if (expandedSection == Section.Buffs) { showAllBuffs = GUILayout.Toggle(showAllBuffs, "Show all (uncurated - some may do nothing on their own)", Array.Empty()); DrawSection(showAllBuffs ? buffRows : curatedBuffRows); } if (GUILayout.Button((expandedSection == Section.Debuffs) ? "▾ Debuffs" : "▸ Debuffs", Array.Empty())) { SetSection(Section.Debuffs); } if (expandedSection == Section.Debuffs) { showAllDebuffs = GUILayout.Toggle(showAllDebuffs, "Show all (uncurated - some may do nothing on their own)", Array.Empty()); DrawSection(showAllDebuffs ? debuffRows : curatedDebuffRows); } if (GUILayout.Button((expandedSection == Section.Elite) ? "▾ Elite" : "▸ Elite", Array.Empty())) { SetSection(Section.Elite); } if (expandedSection == Section.Elite) { DrawSection(eliteRows); } if (GUILayout.Button((expandedSection == Section.Presets) ? "▾ Presets" : "▸ Presets", Array.Empty())) { SetSection(Section.Presets); } if (expandedSection == Section.Presets) { DrawPresetsSection(); } } private static void DrawPresetsSection() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (GUILayout.Button("Clear Preset", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) })) { BuffPresets.Clear(); } scroll = GUILayout.BeginScrollView(scroll, Array.Empty()); foreach (BuffPresets.Preset item in BuffPresets.All) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.BeginVertical(Array.Empty()); GUILayout.Label(item.Name, Array.Empty()); GUILayout.Label(item.Subtitle, Array.Empty()); GUILayout.EndVertical(); if (GUILayout.Button("Apply", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { BuffPresets.Apply(item); } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); } private static void DrawSection(List rows) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Search:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); search = GUILayout.TextField(search, Array.Empty()); GUILayout.EndHorizontal(); LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); scroll = GUILayout.BeginScrollView(scroll, Array.Empty()); int num = 0; foreach (Row row in rows) { if (string.IsNullOrEmpty(search) || row.DisplayName.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0) { num++; GUILayout.BeginHorizontal(Array.Empty()); if ((Object)(object)row.Icon != (Object)null) { GUILayout.Label(row.Icon, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(24f), GUILayout.Height(24f) }); } else { GUILayout.Space(24f); } GUILayout.Label(row.DisplayName, Array.Empty()); int num2 = (((Object)(object)val != (Object)null) ? val.GetBuffCount(row.Def) : 0); GUILayout.Label((num2 > 0) ? $"x{num2}" : "", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) }); if (GUILayout.Button("Add", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) })) { AddPermanent(row.Def); } if (GUILayout.Button("Timed (" + durationText + "s)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) })) { AddTimed(row.Def); } if (GUILayout.Button("Clear", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { ClearBuff(row.Def); } GUILayout.EndHorizontal(); } } if (num == 0) { GUILayout.Label("No matches - try clearing Search or ticking Show all.", Array.Empty()); } GUILayout.EndScrollView(); } internal static float ParseDuration() { if (!float.TryParse(durationText, NumberStyles.Float, CultureInfo.InvariantCulture, out var result) || result <= 0f) { return 5f; } return result; } private static void AddPermanent(BuffDef def) { if (NetworkServer.active && !((Object)(object)def == (Object)null)) { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); if (!((Object)(object)val == (Object)null)) { val.AddBuff(def); PlayerPersistence.TrackPermanent(def); } } } private static void AddTimed(BuffDef def) { if (NetworkServer.active && !((Object)(object)def == (Object)null)) { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); if (!((Object)(object)val == (Object)null)) { val.AddTimedBuff(def, ParseDuration(), 999); PlayerPersistence.TrackTimed(def); } } } private static void ClearBuff(BuffDef def) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && !((Object)(object)def == (Object)null)) { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); if (!((Object)(object)val == (Object)null)) { val.SetBuffCount(def.buffIndex, 0); PlayerPersistence.Untrack(def); } } } } internal static class EnemySpawnerTab { private class Row { public GameObject MasterPrefab; public string DisplayName; public Texture Icon; public string Key; public bool IsFavorite; } private const int IconSize = 24; private static readonly List allRows = new List(); private static string search = ""; private static string quantityText = "1"; private static Vector2 scroll; private static readonly List spawnedObjects = new List(); private static ConfigEntry favoritesEntry; private static readonly HashSet favorites = new HashSet(); internal static readonly List eliteOptions = new List(); internal static string[] eliteLabels = new string[1] { "None" }; internal static readonly string[] teamLabels = new string[2] { "Bad (enemy)", "Good (ally)" }; private static int selectedEliteIndex = 0; private static bool spawnAsAlly = false; private static bool shareBuild = false; private static AggressionPreset selectedAggression = AggressionPreset.Normal; private static SizeTier selectedSize = SizeTier.Normal; private static ToughnessTier selectedToughness = ToughnessTier.Normal; public static void BuildEliteList() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected I4, but got Unknown eliteOptions.Clear(); List list = new List { "None" }; EliteDef[] eliteDefs = EliteCatalog.eliteDefs; foreach (EliteDef val in eliteDefs) { if (!((Object)(object)val == (Object)null) && (int)val.eliteIndex != -1) { eliteOptions.Add(val); list.Add((!string.IsNullOrEmpty(val.modifierToken)) ? Language.GetString(val.modifierToken) : $"Elite {(int)val.eliteIndex}"); } } eliteLabels = list.ToArray(); if (selectedEliteIndex >= eliteLabels.Length) { selectedEliteIndex = 0; } SpawnBoxPlugin.Log.LogInfo((object)$"SpawnBox: {eliteOptions.Count} elite affixes available."); } private static void LoadFavorites() { favoritesEntry = SpawnBoxPlugin.PluginConfig.Bind("Favorites", "Enemies", "", "Comma-separated list of favorited enemy master names."); favorites.Clear(); string[] array = favoritesEntry.Value.Split(','); foreach (string text in array) { if (!string.IsNullOrEmpty(text)) { favorites.Add(text); } } } private static void SaveFavorites() { favoritesEntry.Value = string.Join(",", favorites); } private static void SortRows() { allRows.Sort((Row a, Row b) => (a.IsFavorite != b.IsFavorite) ? ((!a.IsFavorite) ? 1 : (-1)) : string.Compare(a.DisplayName, b.DisplayName)); } public static void BuildList() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Invalid comparison between Unknown and I4 //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Invalid comparison between Unknown and I4 //IL_00f2: Unknown result type (might be due to invalid IL or missing references) LoadFavorites(); allRows.Clear(); HashSet hashSet = new HashSet(); foreach (SurvivorDef allSurvivorDef in SurvivorCatalog.allSurvivorDefs) { if (!((Object)(object)allSurvivorDef == (Object)null) && !((Object)(object)allSurvivorDef.bodyPrefab == (Object)null)) { CharacterBody component = allSurvivorDef.bodyPrefab.GetComponent(); if ((Object)(object)component != (Object)null) { hashSet.Add(component.bodyIndex); } } } foreach (CharacterMaster allAiMaster in MasterCatalog.allAiMasters) { if (!((Object)(object)allAiMaster == (Object)null) && !((Object)(object)allAiMaster.bodyPrefab == (Object)null) && ((int)allAiMaster.teamIndex == 2 || (int)allAiMaster.teamIndex == 4)) { CharacterBody component2 = allAiMaster.bodyPrefab.GetComponent(); if (!((Object)(object)component2 == (Object)null) && !string.IsNullOrEmpty(component2.baseNameToken) && !hashSet.Contains(component2.bodyIndex)) { string name = ((Object)((Component)allAiMaster).gameObject).name; allRows.Add(new Row { MasterPrefab = ((Component)allAiMaster).gameObject, DisplayName = Language.GetString(component2.baseNameToken), Icon = component2.portraitIcon, Key = name, IsFavorite = favorites.Contains(name) }); } } } SortRows(); SpawnBoxPlugin.Log.LogInfo((object)$"SpawnBox: {allRows.Count} enemies available."); } public static void Draw() { //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Search:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); search = GUILayout.TextField(search, Array.Empty()); GUILayout.Label("Qty:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) }); quantityText = GUILayout.TextField(quantityText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) }); GUILayout.EndHorizontal(); GUILayout.Label("High values may impact performance.", Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); spawnAsAlly = UiCycler.Draw("Team:", 70f, spawnAsAlly ? 1 : 0, teamLabels, 140f) == 1; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); selectedEliteIndex = UiCycler.Draw("Elite:", 70f, selectedEliteIndex, eliteLabels, 140f); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); selectedAggression = (AggressionPreset)UiCycler.Draw("Aggression:", 70f, (int)selectedAggression, AggressionController.Labels, 140f); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); selectedSize = (SizeTier)UiCycler.Draw("Size:", 70f, (int)selectedSize, SizeController.Labels, 140f); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); selectedToughness = (ToughnessTier)UiCycler.Draw("Toughness:", 70f, (int)selectedToughness, ToughnessController.Labels, 140f); GUILayout.EndHorizontal(); if (spawnAsAlly) { GUILayout.Label("Spawning on your team - some enemies may not behave safely off-script (report any that misbehave).", Array.Empty()); shareBuild = GUILayout.Toggle(shareBuild, "Share my build with spawned allies (live)", Array.Empty()); } bool flag = false; scroll = GUILayout.BeginScrollView(scroll, Array.Empty()); foreach (Row allRow in allRows) { if (!string.IsNullOrEmpty(search) && allRow.DisplayName.IndexOf(search, StringComparison.OrdinalIgnoreCase) < 0) { continue; } GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button(allRow.IsFavorite ? "Unpin" : "Pin", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) })) { allRow.IsFavorite = !allRow.IsFavorite; if (allRow.IsFavorite) { favorites.Add(allRow.Key); } else { favorites.Remove(allRow.Key); } SaveFavorites(); flag = true; } if ((Object)(object)allRow.Icon != (Object)null) { GUILayout.Label(allRow.Icon, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(24f), GUILayout.Height(24f) }); } else { GUILayout.Space(24f); } GUILayout.Label(allRow.DisplayName, Array.Empty()); if (GUILayout.Button("Spawn", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { SpawnMany(allRow.MasterPrefab, allRow.DisplayName, ParseQuantity()); } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); if (flag) { SortRows(); } } private static int ParseQuantity() { if (!int.TryParse(quantityText, out var result) || result <= 0) { return 1; } return result; } private static void SpawnMany(GameObject masterPrefab, string displayName, int count) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { return; } LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); if ((Object)(object)val == (Object)null) { return; } EliteDef val2 = ((selectedEliteIndex > 0 && selectedEliteIndex - 1 < eliteOptions.Count) ? eliteOptions[selectedEliteIndex - 1] : null); string affixLabel = (((Object)(object)val2 != (Object)null) ? eliteLabels[selectedEliteIndex] : ""); string sizeLabel = SizeController.DisplayLabel(selectedSize); for (int i = 0; i < count; i++) { float num = 360f / (float)count * (float)i; Vector3 val3 = Quaternion.Euler(0f, num, 0f) * (val.transform.forward * 5f); Vector3 position = val.transform.position + val3; CharacterMaster val4 = new MasterSummon { masterPrefab = masterPrefab, position = position, rotation = Quaternion.identity, teamIndexOverride = (TeamIndex)(spawnAsAlly ? 1 : 2), useAmbientLevel = true, inventoryToCopy = ((spawnAsAlly && shareBuild) ? val.inventory : null), ignoreTeamMemberLimit = true }.Perform(); if (Object.op_Implicit((Object)(object)val4) && (Object)(object)val2 != (Object)null && Object.op_Implicit((Object)(object)val4.inventory) && Object.op_Implicit((Object)(object)val2.eliteEquipmentDef)) { val4.inventory.SetEquipmentIndex(val2.eliteEquipmentDef.equipmentIndex, false); } if (Object.op_Implicit((Object)(object)val4)) { if (spawnAsAlly) { ((Component)val4).gameObject.AddComponent(); } AggressionController aggressionController = new AggressionController(val4); if (selectedAggression != AggressionPreset.Normal) { aggressionController.Apply(selectedAggression); } SizeController.Attach(val4, selectedSize); ToughnessController.Attach(val4, selectedToughness); RewardController.Attach(val4); spawnedObjects.Add(new SpawnedCharacterInstance { Master = ((Component)val4).gameObject, DisplayName = displayName, AffixLabel = affixLabel, SizeLabel = sizeLabel, Aggression = aggressionController, ToughnessTier = selectedToughness }); } } } internal static int SpawnedCount() { int num = 0; foreach (SpawnedCharacterInstance spawnedObject in spawnedObjects) { if ((Object)(object)spawnedObject.Master != (Object)null) { num++; } } return num; } internal static IReadOnlyList GetSpawned() { return spawnedObjects; } internal static void DespawnAll() { if (!NetworkServer.active) { return; } foreach (SpawnedCharacterInstance spawnedObject in spawnedObjects) { if (!((Object)(object)spawnedObject.Master == (Object)null)) { CharacterMaster component = spawnedObject.Master.GetComponent(); if (component != null) { component.DestroyBody(); } NetworkServer.Destroy(spawnedObject.Master); } } spawnedObjects.Clear(); } internal static void DespawnOne(SpawnedCharacterInstance instance) { if (!NetworkServer.active || instance == null) { return; } if ((Object)(object)instance.Master != (Object)null) { CharacterMaster component = instance.Master.GetComponent(); if (component != null) { component.DestroyBody(); } NetworkServer.Destroy(instance.Master); } spawnedObjects.Remove(instance); } internal static void SyncBuildToAllies(Inventory playerInventory) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Invalid comparison between Unknown and I4 if (!shareBuild || !NetworkServer.active) { return; } foreach (SpawnedCharacterInstance spawnedObject in spawnedObjects) { if (!((Object)(object)spawnedObject.Master == (Object)null)) { CharacterMaster component = spawnedObject.Master.GetComponent(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.inventory == (Object)null) && (int)component.teamIndex == 1) { component.inventory.CopyItemsFrom(playerInventory); component.inventory.CopyEquipmentFrom(playerInventory, false); } } } } } internal static class EquipmentSpawnerTab { private class Row { public EquipmentIndex Index; public string DisplayName; public Texture Icon; public string Key; public bool IsFavorite; } private const int IconSize = 24; private static readonly List allRows = new List(); private static string search = ""; private static Vector2 scroll; private static ConfigEntry favoritesEntry; private static readonly HashSet favorites = new HashSet(); private static void LoadFavorites() { favoritesEntry = SpawnBoxPlugin.PluginConfig.Bind("Favorites", "Equipment", "", "Comma-separated list of favorited equipment names."); favorites.Clear(); string[] array = favoritesEntry.Value.Split(','); foreach (string text in array) { if (!string.IsNullOrEmpty(text)) { favorites.Add(text); } } } private static void SaveFavorites() { favoritesEntry.Value = string.Join(",", favorites); } private static void SortRows() { allRows.Sort((Row a, Row b) => (a.IsFavorite != b.IsFavorite) ? ((!a.IsFavorite) ? 1 : (-1)) : string.Compare(a.DisplayName, b.DisplayName)); } public unsafe static void BuildList() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) LoadFavorites(); allRows.Clear(); AllEquipmentEnumerator enumerator = EquipmentCatalog.allEquipment.GetEnumerator(); try { while (((AllEquipmentEnumerator)(ref enumerator)).MoveNext()) { EquipmentIndex current = ((AllEquipmentEnumerator)(ref enumerator)).Current; EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(current); if (!((Object)(object)equipmentDef == (Object)null) && equipmentDef.canDrop) { string text = ((object)(*(EquipmentIndex*)(¤t))/*cast due to .constrained prefix*/).ToString(); allRows.Add(new Row { Index = current, DisplayName = Language.GetString(equipmentDef.nameToken), Icon = equipmentDef.pickupIconTexture, Key = text, IsFavorite = favorites.Contains(text) }); } } } finally { ((IDisposable)(*(AllEquipmentEnumerator*)(&enumerator))/*cast due to .constrained prefix*/).Dispose(); } SortRows(); SpawnBoxPlugin.Log.LogInfo((object)$"SpawnBox: {allRows.Count} equipment available."); } public static void Draw() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Search:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); search = GUILayout.TextField(search, Array.Empty()); GUILayout.EndHorizontal(); bool flag = false; scroll = GUILayout.BeginScrollView(scroll, Array.Empty()); foreach (Row allRow in allRows) { if (!string.IsNullOrEmpty(search) && allRow.DisplayName.IndexOf(search, StringComparison.OrdinalIgnoreCase) < 0) { continue; } GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button(allRow.IsFavorite ? "Unpin" : "Pin", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) })) { allRow.IsFavorite = !allRow.IsFavorite; if (allRow.IsFavorite) { favorites.Add(allRow.Key); } else { favorites.Remove(allRow.Key); } SaveFavorites(); flag = true; } if ((Object)(object)allRow.Icon != (Object)null) { GUILayout.Label(allRow.Icon, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(24f), GUILayout.Height(24f) }); } else { GUILayout.Space(24f); } GUILayout.Label(allRow.DisplayName, Array.Empty()); if (GUILayout.Button("Give", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { GiveEquipment(allRow.Index); } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); if (flag) { SortRows(); } } private static void GiveEquipment(EquipmentIndex index) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active) { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); Inventory val2 = (((Object)(object)val != (Object)null) ? val.inventory : null); if (!((Object)(object)val2 == (Object)null)) { val2.SetEquipmentIndex(index, false); } } } } internal static class FollowDriver { private const float FollowMinDistance = 12f; internal static GameObject ResolveAnchor() { if (SettingsTab.RecallAll) { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); if ((Object)(object)val != (Object)null) { return ((Component)val).gameObject; } } if (SettingsTab.DefendZone && (Object)(object)SpawnBoxPlugin.CurrentZoneTarget != (Object)null) { return SpawnBoxPlugin.CurrentZoneTarget; } return null; } internal static void Apply(CharacterMaster master, GameObject anchor) { if ((Object)(object)master == (Object)null) { return; } SpawnBoxFollowMarker spawnBoxFollowMarker = ((Component)master).GetComponent(); if ((Object)(object)anchor == (Object)null) { if ((Object)(object)spawnBoxFollowMarker != (Object)null && (Object)(object)spawnBoxFollowMarker.Driver != (Object)null) { ((Behaviour)spawnBoxFollowMarker.Driver).enabled = false; } return; } if ((Object)(object)spawnBoxFollowMarker == (Object)null) { spawnBoxFollowMarker = Attach(master); } if (!((Object)(object)spawnBoxFollowMarker == (Object)null) && !((Object)(object)spawnBoxFollowMarker.Driver == (Object)null)) { ((Behaviour)spawnBoxFollowMarker.Driver).enabled = true; BaseAI[] components = ((Component)master).GetComponents(); for (int i = 0; i < components.Length; i++) { components[i].SetCustomTargetGameObject(anchor); } } } private static SpawnBoxFollowMarker Attach(CharacterMaster master) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) AISkillDriver val = ((Component)master).gameObject.AddComponent(); val.customName = "SpawnBoxFollow"; val.skillSlot = (SkillSlot)(-1); val.movementType = (MovementType)1; val.moveTargetType = (TargetType)3; val.moveInputScale = 1f; val.minDistance = 12f; val.maxDistance = float.PositiveInfinity; val.shouldSprint = true; val.requireSkillReady = false; val.requireEquipmentReady = false; val.selectionRequiresTargetLoS = false; val.activationRequiresTargetLoS = false; val.activationRequiresAimTargetLoS = false; val.minUserHealthFraction = 0f; val.maxUserHealthFraction = float.PositiveInfinity; val.minTargetHealthFraction = 0f; val.maxTargetHealthFraction = float.PositiveInfinity; val.maxTimesSelected = -1; BaseAI[] components = ((Component)master).GetComponents(); foreach (BaseAI obj in components) { AISkillDriver[] skillDrivers = obj.skillDrivers; AISkillDriver[] array = (AISkillDriver[])(object)new AISkillDriver[((skillDrivers != null) ? skillDrivers.Length : 0) + 1]; array[0] = val; skillDrivers?.CopyTo(array, 1); obj.ReplaceSkillDrivers(array); } SpawnBoxFollowMarker spawnBoxFollowMarker = ((Component)master).gameObject.AddComponent(); spawnBoxFollowMarker.Driver = val; return spawnBoxFollowMarker; } } internal class SpawnBoxFollowMarker : MonoBehaviour { public AISkillDriver Driver; } internal static class InteractableSpawnerTab { private class Row { public string Path; public string DisplayName; public Texture Icon; public bool IsFavorite; } internal class SpawnedInstance { public GameObject Instance; public string DisplayName; } private const string PathPrefix = "SpawnCards/InteractableSpawnCard/"; private const int IconSize = 24; private static readonly List allRows = new List(); private static readonly Random rng = new Random(); private static string search = ""; private static Vector2 scroll; private static ConfigEntry favoritesEntry; private static readonly HashSet favorites = new HashSet(); private static readonly List spawnedObjects = new List(); private static void LoadFavorites() { favoritesEntry = SpawnBoxPlugin.PluginConfig.Bind("Favorites", "Interactables", "", "Comma-separated list of favorited interactable paths."); favorites.Clear(); string[] array = favoritesEntry.Value.Split(','); foreach (string text in array) { if (!string.IsNullOrEmpty(text)) { favorites.Add(text); } } } private static void SaveFavorites() { favoritesEntry.Value = string.Join(",", favorites); } private static void SortRows() { allRows.Sort((Row a, Row b) => (a.IsFavorite != b.IsFavorite) ? ((!a.IsFavorite) ? 1 : (-1)) : string.Compare(a.DisplayName, b.DisplayName)); } public static void BuildList() { LoadFavorites(); allRows.Clear(); List list = new List(); LegacyResourcesAPI.GetAllPaths(list); foreach (string item in list) { if (string.IsNullOrEmpty(item) || !item.StartsWith("SpawnCards/InteractableSpawnCard/")) { continue; } Texture icon = null; InteractableSpawnCard val = LegacyResourcesAPI.Load(item); if ((Object)(object)val != (Object)null && (Object)(object)((SpawnCard)val).prefab != (Object)null) { PingInfoProvider component = ((SpawnCard)val).prefab.GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component.pingIconOverride != (Object)null) { icon = (Texture)(object)component.pingIconOverride.texture; } } allRows.Add(new Row { Path = item, DisplayName = item.Substring("SpawnCards/InteractableSpawnCard/".Length), Icon = icon, IsFavorite = favorites.Contains(item) }); } SortRows(); SpawnBoxPlugin.Log.LogInfo((object)$"SpawnBox: {allRows.Count} interactables available."); } public static void Draw() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Search:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); search = GUILayout.TextField(search, Array.Empty()); GUILayout.EndHorizontal(); bool flag = false; scroll = GUILayout.BeginScrollView(scroll, Array.Empty()); foreach (Row allRow in allRows) { if (!string.IsNullOrEmpty(search) && allRow.DisplayName.IndexOf(search, StringComparison.OrdinalIgnoreCase) < 0) { continue; } GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button(allRow.IsFavorite ? "Unpin" : "Pin", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) })) { allRow.IsFavorite = !allRow.IsFavorite; if (allRow.IsFavorite) { favorites.Add(allRow.Path); } else { favorites.Remove(allRow.Path); } SaveFavorites(); flag = true; } if ((Object)(object)allRow.Icon != (Object)null) { GUILayout.Label(allRow.Icon, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(24f), GUILayout.Height(24f) }); } else { GUILayout.Space(24f); } GUILayout.Label(allRow.DisplayName, Array.Empty()); if (GUILayout.Button("Spawn", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { SpawnAt(allRow.Path, allRow.DisplayName); } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); if (flag) { SortRows(); } } private static void SpawnAt(string path, string displayName) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown if (!NetworkServer.active) { return; } InteractableSpawnCard val = LegacyResourcesAPI.Load(path); if (!Object.op_Implicit((Object)(object)val)) { SpawnBoxPlugin.Log.LogWarning((object)("SpawnBox: could not load interactable spawn card at " + path + ".")); return; } LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val2 = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); if (!((Object)(object)val2 == (Object)null)) { DirectorPlacementRule val3 = new DirectorPlacementRule { placementMode = (PlacementMode)1, position = val2.corePosition, minDistance = 5f, maxDistance = 20f }; DirectorSpawnRequest val4 = new DirectorSpawnRequest((SpawnCard)(object)val, val3, new Xoroshiro128Plus((ulong)rng.Next())); GameObject val5 = (Object.op_Implicit((Object)(object)DirectorCore.instance) ? DirectorCore.instance.TrySpawnObject(val4) : null); if (Object.op_Implicit((Object)(object)val5)) { spawnedObjects.Add(new SpawnedInstance { Instance = val5, DisplayName = displayName }); } else { SpawnBoxPlugin.Log.LogWarning((object)("SpawnBox: DirectorCore failed to spawn interactable at " + path + ".")); } } } internal static int SpawnedCount() { int num = 0; foreach (SpawnedInstance spawnedObject in spawnedObjects) { if ((Object)(object)spawnedObject.Instance != (Object)null) { num++; } } return num; } internal static IReadOnlyList GetSpawned() { return spawnedObjects; } internal static void DespawnAll() { if (!NetworkServer.active) { return; } foreach (SpawnedInstance spawnedObject in spawnedObjects) { if ((Object)(object)spawnedObject.Instance != (Object)null) { NetworkServer.Destroy(spawnedObject.Instance); } } spawnedObjects.Clear(); } internal static void DespawnOne(SpawnedInstance instance) { if (NetworkServer.active && instance != null) { if ((Object)(object)instance.Instance != (Object)null) { NetworkServer.Destroy(instance.Instance); } spawnedObjects.Remove(instance); } } } internal static class ItemSpawnerTab { private class Row { public ItemIndex Index; public string DisplayName; public Texture Icon; public string Key; public bool IsFavorite; public ItemTier Tier; } private const int IconSize = 24; private static readonly List allRows = new List(); private static string search = ""; private static string quantityText = "1"; private static string goldText = "500"; private static Vector2 scroll; private static ConfigEntry favoritesEntry; private static readonly HashSet favorites = new HashSet(); private static string selectedRarity = "All"; private static void LoadFavorites() { favoritesEntry = SpawnBoxPlugin.PluginConfig.Bind("Favorites", "Items", "", "Comma-separated list of favorited item names."); favorites.Clear(); string[] array = favoritesEntry.Value.Split(','); foreach (string text in array) { if (!string.IsNullOrEmpty(text)) { favorites.Add(text); } } } private static void SaveFavorites() { favoritesEntry.Value = string.Join(",", favorites); } private static void SortRows() { allRows.Sort((Row a, Row b) => (a.IsFavorite != b.IsFavorite) ? ((!a.IsFavorite) ? 1 : (-1)) : string.Compare(a.DisplayName, b.DisplayName)); } public static void BuildList() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) LoadFavorites(); allRows.Clear(); Enumerator enumerator = ItemCatalog.allItemDefs.GetEnumerator(); try { while (enumerator.MoveNext()) { ItemDef current = enumerator.Current; if (!((Object)(object)current == (Object)null) && !current.hidden && CategoryOf(current.tier) && current.DoesNotContainTag((ItemTag)9)) { string text = ((object)current.itemIndex/*cast due to .constrained prefix*/).ToString(); allRows.Add(new Row { Index = current.itemIndex, DisplayName = Language.GetString(current.nameToken), Icon = current.pickupIconTexture, Key = text, IsFavorite = favorites.Contains(text), Tier = current.tier }); } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } SortRows(); SpawnBoxPlugin.Log.LogInfo((object)$"SpawnBox: {allRows.Count} items available."); } private static bool CategoryOf(ItemTier tier) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)tier <= 4 || tier - 6 <= 3) { return true; } return false; } private static string RarityGroupOf(ItemTier tier) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected I4, but got Unknown switch ((int)tier) { case 0: return "Common"; case 1: return "Uncommon"; case 2: return "Legendary"; case 4: return "Boss"; case 3: return "Lunar"; case 6: case 7: case 8: case 9: return "Void"; default: return "All"; } } public static void Draw() { //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Gold:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); goldText = GUILayout.TextField(goldText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); if (GUILayout.Button("Give", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { GiveGold(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Rarity:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); if (GUILayout.Toggle(selectedRarity == "All", "All", GUIStyle.op_Implicit("button"), Array.Empty())) { selectedRarity = "All"; } if (GUILayout.Toggle(selectedRarity == "Common", "Common", GUIStyle.op_Implicit("button"), Array.Empty())) { selectedRarity = "Common"; } if (GUILayout.Toggle(selectedRarity == "Uncommon", "Uncommon", GUIStyle.op_Implicit("button"), Array.Empty())) { selectedRarity = "Uncommon"; } if (GUILayout.Toggle(selectedRarity == "Legendary", "Legendary", GUIStyle.op_Implicit("button"), Array.Empty())) { selectedRarity = "Legendary"; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Space(54f); if (GUILayout.Toggle(selectedRarity == "Boss", "Boss", GUIStyle.op_Implicit("button"), Array.Empty())) { selectedRarity = "Boss"; } if (GUILayout.Toggle(selectedRarity == "Lunar", "Lunar", GUIStyle.op_Implicit("button"), Array.Empty())) { selectedRarity = "Lunar"; } if (GUILayout.Toggle(selectedRarity == "Void", "Void", GUIStyle.op_Implicit("button"), Array.Empty())) { selectedRarity = "Void"; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Search:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); search = GUILayout.TextField(search, Array.Empty()); GUILayout.Label("Qty:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) }); quantityText = GUILayout.TextField(quantityText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) }); GUILayout.EndHorizontal(); bool flag = false; scroll = GUILayout.BeginScrollView(scroll, Array.Empty()); foreach (Row allRow in allRows) { if ((!string.IsNullOrEmpty(search) && allRow.DisplayName.IndexOf(search, StringComparison.OrdinalIgnoreCase) < 0) || (selectedRarity != "All" && RarityGroupOf(allRow.Tier) != selectedRarity)) { continue; } GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button(allRow.IsFavorite ? "Unpin" : "Pin", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) })) { allRow.IsFavorite = !allRow.IsFavorite; if (allRow.IsFavorite) { favorites.Add(allRow.Key); } else { favorites.Remove(allRow.Key); } SaveFavorites(); flag = true; } if ((Object)(object)allRow.Icon != (Object)null) { GUILayout.Label(allRow.Icon, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(24f), GUILayout.Height(24f) }); } else { GUILayout.Space(24f); } GUILayout.Label(allRow.DisplayName, Array.Empty()); if (GUILayout.Button("Give", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { GiveQuantity(allRow.Index, ParseQuantity()); } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); if (flag) { SortRows(); } } private static int ParseQuantity() { if (!int.TryParse(quantityText, out var result) || result <= 0) { return 1; } return result; } private static void GiveQuantity(ItemIndex index, int count) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active) { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); Inventory val2 = (((Object)(object)val != (Object)null) ? val.inventory : null); if (!((Object)(object)val2 == (Object)null)) { val2.GiveItemPermanent(index, count); } } } private static void GiveGold() { if (NetworkServer.active) { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); CharacterMaster val2 = (((Object)(object)val != (Object)null) ? val.master : null); if (!((Object)(object)val2 == (Object)null) && uint.TryParse(goldText, out var result)) { val2.GiveMoney(result); } } } } internal static class PlayerPersistence { private static readonly HashSet permanentTouched = new HashSet(); private static readonly HashSet timedTouched = new HashSet(); private static readonly Dictionary lastKnownCounts = new Dictionary(); private static SizeTier persistedSize = SizeTier.Normal; private static CharacterBody lastKnownBody; private static bool reapplyPending; internal static SizeTier CurrentSize => persistedSize; internal static void TrackPermanent(BuffDef def) { if (!((Object)(object)def == (Object)null)) { permanentTouched.Add(def); } } internal static void TrackTimed(BuffDef def) { if (!((Object)(object)def == (Object)null)) { timedTouched.Add(def); } } internal static void Untrack(BuffDef def) { if (!((Object)(object)def == (Object)null)) { permanentTouched.Remove(def); timedTouched.Remove(def); lastKnownCounts.Remove(def); } } internal static void SetSize(SizeTier tier) { persistedSize = tier; } internal static void Tick() { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); if ((Object)(object)val == (Object)(object)lastKnownBody) { if (!((Object)(object)val != (Object)null)) { return; } if (reapplyPending) { reapplyPending = false; Reapply(val); } foreach (BuffDef item in permanentTouched) { lastKnownCounts[item] = val.GetBuffCount(item); } { foreach (BuffDef item2 in timedTouched) { if (!permanentTouched.Contains(item2)) { lastKnownCounts[item2] = val.GetBuffCount(item2); } } return; } } lastKnownBody = val; if ((Object)(object)val != (Object)null) { reapplyPending = true; } } private static void Reapply(CharacterBody body) { if (!NetworkServer.active) { return; } foreach (BuffDef item in permanentTouched) { if (lastKnownCounts.TryGetValue(item, out var value)) { for (int i = 0; i < value; i++) { body.AddBuff(item); } } } foreach (BuffDef item2 in timedTouched) { if (!permanentTouched.Contains(item2) && lastKnownCounts.TryGetValue(item2, out var value2) && value2 > 0) { body.AddTimedBuff(item2, BuffsTab.ParseDuration(), 999); } } if (persistedSize != SizeTier.Normal) { SizeController.ApplyToPlayer(body, persistedSize); } } internal static void ResetOnRunStart() { permanentTouched.Clear(); timedTouched.Clear(); lastKnownCounts.Clear(); persistedSize = SizeTier.Normal; lastKnownBody = null; reapplyPending = false; } } [BepInPlugin("dileppy.spawnbox", "SpawnBox", "1.6.1")] public class SpawnBoxPlugin : BaseUnityPlugin { public const string PluginGUID = "dileppy.spawnbox"; public const string PluginName = "SpawnBox"; public const string PluginVersion = "1.6.1"; internal static SpawnBoxPlugin Instance; internal static ManualLogSource Log; internal static ConfigFile PluginConfig; internal static GameObject CurrentZoneTarget; private bool windowOpen; private int activeTab; private Rect windowRect = new Rect(100f, 100f, 760f, 680f); private const float KeybindWindowX = 100f; private const float KeybindWindowY = 100f; private KeyCode toggleKey; private HoldoutZoneController trackedZone; private float zoneCheckTimer; private const float ZoneCheckInterval = 0.5f; private float sizeSweepTimer; private const float SizeSweepInterval = 0.25f; private bool openedFromPauseMenu; private RectTransform pauseMenuMainPanelToRestore; private void Awake() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; PluginConfig = ((BaseUnityPlugin)this).Config; toggleKey = ((BaseUnityPlugin)this).Config.Bind("General", "ToggleKey", (KeyCode)283, "Key that opens the SpawnBox window.").Value; ItemCatalog.Init += new hook_Init(ItemCatalog_Init); MasterCatalog.Init += new hook_Init(MasterCatalog_Init); EquipmentCatalog.Init += new hook_Init(EquipmentCatalog_Init); EliteCatalog.Init += new hook_Init(EliteCatalog_Init); SurvivorCatalog.Init += new hook_Init(SurvivorCatalog_Init); BuffCatalog.Init += new hook_Init(BuffCatalog_Init); Inventory.onInventoryChangedGlobal += Inventory_OnChangedGlobal; PauseScreenController.Awake += new hook_Awake(PauseScreenController_Awake); CharacterBody.Start += new hook_Start(CharacterBody_Start); CharacterBody.RecalculateStats += new hook_RecalculateStats(CharacterBody_RecalculateStats); DirectorCore.TrySpawnObject += new hook_TrySpawnObject(DirectorCore_TrySpawnObject); SceneDirector.Start += new hook_Start(SceneDirector_Start); ObjectivePanelController.GetObjectiveSources += new hook_GetObjectiveSources(ObjectivePanelController_GetObjectiveSources); Run.onRunStartGlobal += Run_onRunStartGlobal; ((BaseUnityPlugin)this).Logger.LogInfo((object)"SpawnBox v1.6.1 online."); } private void OnDestroy() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown ItemCatalog.Init -= new hook_Init(ItemCatalog_Init); MasterCatalog.Init -= new hook_Init(MasterCatalog_Init); EquipmentCatalog.Init -= new hook_Init(EquipmentCatalog_Init); EliteCatalog.Init -= new hook_Init(EliteCatalog_Init); SurvivorCatalog.Init -= new hook_Init(SurvivorCatalog_Init); BuffCatalog.Init -= new hook_Init(BuffCatalog_Init); Inventory.onInventoryChangedGlobal -= Inventory_OnChangedGlobal; PauseScreenController.Awake -= new hook_Awake(PauseScreenController_Awake); CharacterBody.Start -= new hook_Start(CharacterBody_Start); CharacterBody.RecalculateStats -= new hook_RecalculateStats(CharacterBody_RecalculateStats); DirectorCore.TrySpawnObject -= new hook_TrySpawnObject(DirectorCore_TrySpawnObject); SceneDirector.Start -= new hook_Start(SceneDirector_Start); ObjectivePanelController.GetObjectiveSources -= new hook_GetObjectiveSources(ObjectivePanelController_GetObjectiveSources); Run.onRunStartGlobal -= Run_onRunStartGlobal; } private void Inventory_OnChangedGlobal(Inventory inventory) { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); Inventory val2 = (((Object)(object)val != (Object)null) ? val.inventory : null); if (!((Object)(object)val2 == (Object)null) && !((Object)(object)inventory != (Object)(object)val2)) { AllySpawnerTab.SyncBuildToAllies(val2); EnemySpawnerTab.SyncBuildToAllies(val2); SurvivorSpawnerTab.SyncBuildToAllies(val2); } } private void CharacterBody_Start(orig_Start orig, CharacterBody self) { orig.Invoke(self); try { SpawnBoxSizeMarker spawnBoxSizeMarker = (((Object)(object)self.master != (Object)null) ? ((Component)self.master).GetComponent() : null); if ((Object)(object)spawnBoxSizeMarker != (Object)null && spawnBoxSizeMarker.PlayerApplied) { spawnBoxSizeMarker.Scale = (spawnBoxSizeMarker.MoveSpeed = (spawnBoxSizeMarker.Damage = (spawnBoxSizeMarker.AttackSpeed = (spawnBoxSizeMarker.Health = 1f)))); Object.Destroy((Object)(object)spawnBoxSizeMarker); } } catch (Exception arg) { Log.LogError((object)$"SpawnBox: CharacterBody_Start stale size marker cleanup failed - {arg}"); } try { if ((Object)(object)(((Object)(object)self.master != (Object)null) ? ((Component)self.master).GetComponent() : null) != (Object)null) { RewardController.Configure(self); } } catch (Exception arg2) { Log.LogError((object)$"SpawnBox: CharacterBody_Start reward configuration failed - {arg2}"); } } private void CharacterBody_RecalculateStats(orig_RecalculateStats orig, CharacterBody self) { //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self); try { SpawnBoxSizeMarker spawnBoxSizeMarker = (((Object)(object)self.master != (Object)null) ? ((Component)self.master).GetComponent() : null); SpawnBoxToughnessMarker spawnBoxToughnessMarker = (((Object)(object)self.master != (Object)null) ? ((Component)self.master).GetComponent() : null); if ((Object)(object)spawnBoxSizeMarker == (Object)null && (Object)(object)spawnBoxToughnessMarker == (Object)null) { return; } float maxHealth = self.maxHealth; float num = (((Object)(object)self.healthComponent != (Object)null && maxHealth > 0f) ? (self.healthComponent.health / maxHealth) : 1f); if ((Object)(object)spawnBoxSizeMarker != (Object)null) { self.moveSpeed *= spawnBoxSizeMarker.MoveSpeed; self.damage *= spawnBoxSizeMarker.Damage; self.attackSpeed *= spawnBoxSizeMarker.AttackSpeed; self.maxHealth *= spawnBoxSizeMarker.Health; ModelLocator modelLocator = self.modelLocator; if ((Object)(object)modelLocator != (Object)null && (Object)(object)modelLocator.modelTransform != (Object)null) { Vector3 val = SizeController.GetTrueBaseScale(self.bodyIndex) * spawnBoxSizeMarker.Scale; if (modelLocator.modelTransform.localScale != val) { modelLocator.modelTransform.localScale = val; } } } if ((Object)(object)spawnBoxToughnessMarker != (Object)null) { self.damage *= spawnBoxToughnessMarker.Damage; self.maxHealth *= spawnBoxToughnessMarker.Health; } if ((Object)(object)self.healthComponent != (Object)null) { self.healthComponent.Networkhealth = num * self.maxHealth; } } catch (Exception arg) { Log.LogError((object)$"SpawnBox: CharacterBody_RecalculateStats stat scaling failed - {arg}"); } } private GameObject DirectorCore_TrySpawnObject(orig_TrySpawnObject orig, DirectorCore self, DirectorSpawnRequest directorSpawnRequest) { GameObject val = orig.Invoke(self, directorSpawnRequest); try { WorldTab.OnObjectSpawned(val); } catch (Exception arg) { Log.LogError((object)$"SpawnBox: DirectorCore_TrySpawnObject tracking failed - {arg}"); } return val; } private void SceneDirector_Start(orig_Start orig, SceneDirector self) { orig.Invoke(self); try { WorldTab.OnSceneDirectorStartComplete(); } catch (Exception arg) { Log.LogError((object)$"SpawnBox: SceneDirector_Start suppression cleanup failed - {arg}"); } } private void ObjectivePanelController_GetObjectiveSources(orig_GetObjectiveSources orig, ObjectivePanelController self, CharacterMaster master, List output) { orig.Invoke(self, master, output); try { if (WorldTab.IsExploring) { output.Clear(); } } catch (Exception arg) { Log.LogError((object)$"SpawnBox: ObjectivePanelController_GetObjectiveSources suppression failed - {arg}"); } } private void Run_onRunStartGlobal(Run run) { try { WorldTab.ResetOnRunStart(); } catch (Exception arg) { Log.LogError((object)$"SpawnBox: WorldTab.ResetOnRunStart failed - {arg}"); } try { PlayerPersistence.ResetOnRunStart(); } catch (Exception arg2) { Log.LogError((object)$"SpawnBox: PlayerPersistence.ResetOnRunStart failed - {arg2}"); } } private void PauseScreenController_Awake(orig_Awake orig, PauseScreenController self) { orig.Invoke(self); try { AddPauseMenuButton(self); } catch (Exception arg) { Log.LogError((object)$"SpawnBox: failed to add pause menu button - {arg}"); } } private void AddPauseMenuButton(PauseScreenController controller) { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown if ((Object)(object)controller.exitGameButton == (Object)null) { Log.LogWarning((object)"SpawnBox: PauseScreenController.exitGameButton was null, cannot add pause menu button."); return; } GameObject obj = Object.Instantiate(controller.exitGameButton, controller.exitGameButton.transform.parent); ((Object)obj).name = "SpawnBoxPauseButton"; LanguageTextMeshController component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } HGTextMeshProUGUI componentInChildren = obj.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { ((TMP_Text)componentInChildren).text = "SpawnBox"; } HGButton component2 = obj.GetComponent(); if ((Object)(object)component2 == (Object)null) { Log.LogWarning((object)"SpawnBox: cloned pause menu button has no HGButton component, cannot wire click."); return; } for (int i = 0; i < ((UnityEventBase)((Button)component2).onClick).GetPersistentEventCount(); i++) { ((UnityEventBase)((Button)component2).onClick).SetPersistentListenerState(i, (UnityEventCallState)0); } ((UnityEventBase)((Button)component2).onClick).RemoveAllListeners(); ((UnityEvent)((Button)component2).onClick).AddListener((UnityAction)delegate { OnPauseMenuButtonClicked(controller); }); } private void OnPauseMenuButtonClicked(PauseScreenController controller) { try { ((Component)controller.mainPanel).gameObject.SetActive(false); pauseMenuMainPanelToRestore = controller.mainPanel; openedFromPauseMenu = true; windowOpen = true; ((Rect)(ref windowRect)).x = ((float)Screen.width - ((Rect)(ref windowRect)).width) / 2f; ((Rect)(ref windowRect)).y = ((float)Screen.height - ((Rect)(ref windowRect)).height) / 2f; } catch (Exception arg) { Log.LogError((object)$"SpawnBox: pause menu button click failed - {arg}"); } } private void LateUpdate() { if (openedFromPauseMenu && (Object)(object)pauseMenuMainPanelToRestore != (Object)null) { ((Component)pauseMenuMainPanelToRestore).gameObject.SetActive(false); } } private void RestorePauseMenuIfNeeded() { if (!openedFromPauseMenu) { return; } openedFromPauseMenu = false; try { if ((Object)(object)pauseMenuMainPanelToRestore != (Object)null && PauseScreenController.instancesList.Count > 0) { ((Component)pauseMenuMainPanelToRestore).gameObject.SetActive(true); } } catch (Exception arg) { Log.LogError((object)$"SpawnBox: failed to restore pause menu after closing - {arg}"); } pauseMenuMainPanelToRestore = null; } private void UpdateZoneDefense(float deltaTime) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Invalid comparison between Unknown and I4 //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Invalid comparison between Unknown and I4 if (!SettingsTab.DefendZone && !SettingsTab.RecallAll) { return; } zoneCheckTimer -= deltaTime; if (zoneCheckTimer > 0f) { return; } zoneCheckTimer = 0.5f; if (SettingsTab.DefendZone) { if ((Object)(object)trackedZone != (Object)null) { if (!trackedZone.isAnyoneCharging || (int)trackedZone.chargingTeam != 1) { trackedZone = null; CurrentZoneTarget = null; } } else { HoldoutZoneController[] array = Object.FindObjectsOfType(); foreach (HoldoutZoneController val in array) { if (!((Object)(object)val == (Object)null) && val.isAnyoneCharging && (int)val.chargingTeam == 1) { trackedZone = val; CurrentZoneTarget = ((Component)val).gameObject; break; } } } } else { trackedZone = null; CurrentZoneTarget = null; } GameObject anchor = FollowDriver.ResolveAnchor(); ApplyAnchor(AllySpawnerTab.GetSpawned(), anchor); ApplyAnchor(EnemySpawnerTab.GetSpawned(), anchor); ApplyAnchor(SurvivorSpawnerTab.GetSpawned(), anchor); } private static void ApplyAnchor(IEnumerable instances, GameObject anchor) { foreach (SpawnedCharacterInstance instance in instances) { if (instance != null && !((Object)(object)instance.Master == (Object)null)) { FollowDriver.Apply(instance.Master.GetComponent(), anchor); } } } private void SweepMarkedSizes(float deltaTime) { sizeSweepTimer -= deltaTime; if (sizeSweepTimer > 0f) { return; } sizeSweepTimer = 0.25f; foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList) { if ((Object)(object)readOnlyInstances != (Object)null && (Object)(object)readOnlyInstances.master != (Object)null && (Object)(object)((Component)readOnlyInstances.master).GetComponent() != (Object)null) { readOnlyInstances.RecalculateStats(); } } } private void ItemCatalog_Init(orig_Init orig) { orig.Invoke(); ItemSpawnerTab.BuildList(); } private void MasterCatalog_Init(orig_Init orig) { orig.Invoke(); AllySpawnerTab.BuildList(); InteractableSpawnerTab.BuildList(); } private void EliteCatalog_Init(orig_Init orig) { orig.Invoke(); EnemySpawnerTab.BuildEliteList(); } private void SurvivorCatalog_Init(orig_Init orig) { orig.Invoke(); EnemySpawnerTab.BuildList(); SurvivorSpawnerTab.BuildList(); } private void EquipmentCatalog_Init(orig_Init orig) { orig.Invoke(); EquipmentSpawnerTab.BuildList(); } private void BuffCatalog_Init(orig_Init orig) { orig.Invoke(); BuffsTab.BuildList(); } private void Update() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (openedFromPauseMenu && PauseScreenController.instancesList.Count == 0) { windowOpen = false; openedFromPauseMenu = false; pauseMenuMainPanelToRestore = null; } if (Input.GetKeyDown(toggleKey)) { bool flag = windowOpen; windowOpen = !windowOpen; if (windowOpen && !flag) { ((Rect)(ref windowRect)).x = 100f; ((Rect)(ref windowRect)).y = 100f; } if (!windowOpen) { RestorePauseMenuIfNeeded(); } } if (SettingsTab.CloseRequested) { windowOpen = false; SettingsTab.CloseRequested = false; RestorePauseMenuIfNeeded(); } UpdateZoneDefense(Time.deltaTime); SweepMarkedSizes(Time.deltaTime); WorldTab.TickSuppression(); PlayerPersistence.Tick(); } private void OnGUI() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (windowOpen) { windowRect = GUILayout.Window(((Object)this).GetInstanceID(), windowRect, new WindowFunction(DrawWindow), "SpawnBox", Array.Empty()); } } private void DrawWindow(int id) { GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Toggle(activeTab == 0, "Items", GUIStyle.op_Implicit("button"), Array.Empty())) { activeTab = 0; } if (GUILayout.Toggle(activeTab == 1, "Equipment", GUIStyle.op_Implicit("button"), Array.Empty())) { activeTab = 1; } if (GUILayout.Toggle(activeTab == 2, "Allies", GUIStyle.op_Implicit("button"), Array.Empty())) { activeTab = 2; } if (GUILayout.Toggle(activeTab == 3, "Enemies", GUIStyle.op_Implicit("button"), Array.Empty())) { activeTab = 3; } if (GUILayout.Toggle(activeTab == 4, "Interactables", GUIStyle.op_Implicit("button"), Array.Empty())) { activeTab = 4; } if (GUILayout.Toggle(activeTab == 5, "Survivors", GUIStyle.op_Implicit("button"), Array.Empty())) { activeTab = 5; } if (GUILayout.Toggle(activeTab == 6, "Player", GUIStyle.op_Implicit("button"), Array.Empty())) { activeTab = 6; } if (GUILayout.Toggle(activeTab == 7, "World", GUIStyle.op_Implicit("button"), Array.Empty())) { activeTab = 7; } if (GUILayout.Toggle(activeTab == 8, "Settings", GUIStyle.op_Implicit("button"), Array.Empty())) { activeTab = 8; } GUILayout.EndHorizontal(); if (activeTab == 0) { ItemSpawnerTab.Draw(); } else if (activeTab == 1) { EquipmentSpawnerTab.Draw(); } else if (activeTab == 2) { AllySpawnerTab.Draw(); } else if (activeTab == 3) { EnemySpawnerTab.Draw(); } else if (activeTab == 4) { InteractableSpawnerTab.Draw(); } else if (activeTab == 5) { SurvivorSpawnerTab.Draw(); } else if (activeTab == 6) { BuffsTab.Draw(); } else if (activeTab == 7) { WorldTab.Draw(); } else { SettingsTab.Draw(); } GUI.DragWindow(); } } internal static class RewardController { private const float ValuePerHealth = 0.12f; internal static void Attach(CharacterMaster master) { if (!((Object)(object)master == (Object)null)) { ((Component)master).gameObject.AddComponent(); } } internal static void Configure(CharacterBody body) { if (!((Object)(object)body == (Object)null) && !(body.maxHealth <= 0f) && !((Object)(object)Run.instance == (Object)null)) { DeathRewards component = ((Component)body).GetComponent(); if (!((Object)(object)component == (Object)null)) { float num = body.maxHealth * 0.12f; float compensatedDifficultyCoefficient = Run.instance.compensatedDifficultyCoefficient; component.spawnValue = (int)Mathf.Max(1f, num); component.expReward = (uint)Mathf.Max(1f, num * compensatedDifficultyCoefficient); component.goldReward = (uint)Mathf.Max(1f, num * 2f * compensatedDifficultyCoefficient); } } } } internal class SpawnBoxRewardMarker : MonoBehaviour { } internal static class SettingsTab { private static bool alliesExpanded; private static bool enemiesExpanded; private static bool survivorsExpanded; private static bool interactablesExpanded; internal static bool DefendZone; internal static bool RecallAll; internal static bool CloseRequested; public static void Draw() { GUILayout.Label("Despawn everything SpawnBox has spawned, by category.", Array.Empty()); DefendZone = GUILayout.Toggle(DefendZone, "Defend Zone (redirect Good allies to hold the current zone-hold event, teleporter or otherwise)", Array.Empty()); RecallAll = GUILayout.Toggle(RecallAll, "Recall All (spawned units path to you and keep following until you switch this off)", Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Close Menu", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) })) { CloseRequested = true; } GUILayout.EndHorizontal(); DrawCategoryHeader("Allies", AllySpawnerTab.SpawnedCount(), ref alliesExpanded, AllySpawnerTab.DespawnAll); if (alliesExpanded) { foreach (SpawnedCharacterInstance instance in new List(AllySpawnerTab.GetSpawned())) { DrawCharacterRow(instance, delegate { AllySpawnerTab.DespawnOne(instance); }); } } DrawCategoryHeader("Enemies", EnemySpawnerTab.SpawnedCount(), ref enemiesExpanded, EnemySpawnerTab.DespawnAll); if (enemiesExpanded) { foreach (SpawnedCharacterInstance instance2 in new List(EnemySpawnerTab.GetSpawned())) { DrawCharacterRow(instance2, delegate { EnemySpawnerTab.DespawnOne(instance2); }); } } DrawCategoryHeader("Survivors", SurvivorSpawnerTab.SpawnedCount(), ref survivorsExpanded, SurvivorSpawnerTab.DespawnAll); if (survivorsExpanded) { foreach (SpawnedCharacterInstance instance3 in new List(SurvivorSpawnerTab.GetSpawned())) { DrawCharacterRow(instance3, delegate { SurvivorSpawnerTab.DespawnOne(instance3); }); } } DrawCategoryHeader("Interactables", InteractableSpawnerTab.SpawnedCount(), ref interactablesExpanded, InteractableSpawnerTab.DespawnAll); if (!interactablesExpanded) { return; } foreach (InteractableSpawnerTab.SpawnedInstance instance4 in new List(InteractableSpawnerTab.GetSpawned())) { DrawInteractableRow(instance4, delegate { InteractableSpawnerTab.DespawnOne(instance4); }); } } private static void DrawCategoryHeader(string label, int count, ref bool expanded, Action despawnAll) { GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button(expanded ? "-" : "+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(20f) })) { expanded = !expanded; } GUILayout.Label($"{label}: {count} spawned", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) }); if (GUILayout.Button("Despawn " + label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) })) { despawnAll(); } GUILayout.EndHorizontal(); } private static void DrawCharacterRow(SpawnedCharacterInstance instance, Action despawnOne) { if (instance == null || (Object)(object)instance.Master == (Object)null) { return; } CharacterMaster component = instance.Master.GetComponent(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Space(20f); List list = new List(); if (!string.IsNullOrEmpty(instance.AffixLabel)) { list.Add(instance.AffixLabel); } if (!string.IsNullOrEmpty(instance.SizeLabel)) { list.Add(instance.SizeLabel); } GUILayout.Label((list.Count == 0) ? instance.DisplayName : (instance.DisplayName + " (" + string.Join(", ", list) + ")"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) }); if ((Object)(object)component != (Object)null) { int currentPreset = (int)instance.Aggression.CurrentPreset; int num = UiCycler.Draw("Aggr:", 40f, currentPreset, AggressionController.Labels, 80f); if (num != currentPreset) { instance.Aggression.Apply((AggressionPreset)num); } int toughnessTier = (int)instance.ToughnessTier; int num2 = UiCycler.Draw("Tough:", 45f, toughnessTier, ToughnessController.Labels, 60f); if (num2 != toughnessTier) { instance.ToughnessTier = (ToughnessTier)num2; ToughnessController.Apply(component, (ToughnessTier)num2); } } if (GUILayout.Button("Despawn", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) })) { despawnOne(); } GUILayout.EndHorizontal(); } private static void DrawInteractableRow(InteractableSpawnerTab.SpawnedInstance instance, Action despawnOne) { if (instance != null && !((Object)(object)instance.Instance == (Object)null)) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Space(20f); GUILayout.Label(instance.DisplayName, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) }); if (GUILayout.Button("Despawn", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) })) { despawnOne(); } GUILayout.EndHorizontal(); } } } internal enum SizeTier { Miniature, Tiny, Shrunken, Normal, Enlarged, Giant, Colossal, Ridiculous } internal static class SizeController { private static readonly Dictionary Tiers = new Dictionary { { SizeTier.Miniature, ("Miniature", 0.3f, 0.55f, 0.4f, 2f, 0.4f) }, { SizeTier.Tiny, ("Tiny", 0.5f, 0.7f, 0.55f, 1.6f, 0.55f) }, { SizeTier.Shrunken, ("Shrunken", 0.7f, 0.85f, 0.75f, 1.25f, 0.75f) }, { SizeTier.Normal, ("Normal", 1f, 1f, 1f, 1f, 1f) }, { SizeTier.Enlarged, ("Enlarged", 1.4f, 1.1f, 1.3f, 0.85f, 1.35f) }, { SizeTier.Giant, ("Giant", 1.8f, 1.2f, 1.7f, 0.7f, 1.8f) }, { SizeTier.Colossal, ("Colossal", 2.5f, 1.35f, 2.5f, 0.55f, 2.4f) }, { SizeTier.Ridiculous, ("What the f...", 5f, 1.5f, 3.3f, 0.4f, 3f) } }; internal static readonly string[] Labels = new string[8] { "Miniature", "Tiny", "Shrunken", "Normal", "Enlarged", "Giant", "Colossal", "What the f..." }; private static CharacterBody trackedPlayerBody; private static readonly Dictionary trueBaseScaleCache = new Dictionary(); private static Vector3 trackedPlayerBaseAimLocalPos; private static Vector3 trackedPlayerModelPivotToBodyRoot; internal static string DisplayLabel(SizeTier tier) { if (tier != SizeTier.Normal) { return Tiers[tier].label; } return ""; } internal static void Attach(CharacterMaster master, SizeTier tier) { if (!((Object)(object)master == (Object)null) && tier != SizeTier.Normal) { (string, float, float, float, float, float) tuple = Tiers[tier]; SpawnBoxSizeMarker spawnBoxSizeMarker = ((Component)master).gameObject.AddComponent(); spawnBoxSizeMarker.Scale = tuple.Item2; spawnBoxSizeMarker.MoveSpeed = tuple.Item3; spawnBoxSizeMarker.Damage = tuple.Item4; spawnBoxSizeMarker.AttackSpeed = tuple.Item5; spawnBoxSizeMarker.Health = tuple.Item6; } } internal static Vector3 GetTrueBaseScale(BodyIndex bodyIndex) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (trueBaseScaleCache.TryGetValue(bodyIndex, out var value)) { return value; } Vector3 val = Vector3.one; GameObject bodyPrefab = BodyCatalog.GetBodyPrefab(bodyIndex); ModelLocator val2 = (((Object)(object)bodyPrefab != (Object)null) ? bodyPrefab.GetComponent() : null); if ((Object)(object)val2 != (Object)null && (Object)(object)val2.modelTransform != (Object)null) { val = val2.modelTransform.localScale; } trueBaseScaleCache[bodyIndex] = val; return val; } internal static void ApplyToPlayer(CharacterBody body, SizeTier tier) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || (Object)(object)body == (Object)null || (Object)(object)body.master == (Object)null) { return; } ModelLocator modelLocator = body.modelLocator; if ((Object)(object)modelLocator == (Object)null || (Object)(object)modelLocator.modelTransform == (Object)null) { return; } if ((Object)(object)trackedPlayerBody != (Object)(object)body) { trackedPlayerBody = body; trackedPlayerBaseAimLocalPos = (((Object)(object)body.aimOriginTransform != (Object)null) ? body.aimOriginTransform.localPosition : Vector3.zero); trackedPlayerModelPivotToBodyRoot = body.transform.position - modelLocator.modelTransform.position; } SpawnBoxSizeMarker spawnBoxSizeMarker = ((Component)body.master).GetComponent(); if (tier == SizeTier.Normal) { if ((Object)(object)spawnBoxSizeMarker != (Object)null) { spawnBoxSizeMarker.Scale = 1f; spawnBoxSizeMarker.MoveSpeed = 1f; spawnBoxSizeMarker.Damage = 1f; spawnBoxSizeMarker.AttackSpeed = 1f; spawnBoxSizeMarker.Health = 1f; Object.Destroy((Object)(object)spawnBoxSizeMarker); } modelLocator.modelTransform.localScale = GetTrueBaseScale(body.bodyIndex); } else { if ((Object)(object)spawnBoxSizeMarker == (Object)null) { spawnBoxSizeMarker = ((Component)body.master).gameObject.AddComponent(); } (string, float, float, float, float, float) tuple = Tiers[tier]; spawnBoxSizeMarker.Scale = tuple.Item2; spawnBoxSizeMarker.MoveSpeed = tuple.Item3; spawnBoxSizeMarker.Damage = tuple.Item4; spawnBoxSizeMarker.AttackSpeed = tuple.Item5; spawnBoxSizeMarker.Health = tuple.Item6; spawnBoxSizeMarker.PlayerApplied = true; } if ((Object)(object)body.aimOriginTransform != (Object)null) { Vector3 val = (trackedPlayerModelPivotToBodyRoot + trackedPlayerBaseAimLocalPos) * Tiers[tier].scale; body.aimOriginTransform.localPosition = val - trackedPlayerModelPivotToBodyRoot; } body.RecalculateStats(); } } internal class SpawnBoxSizeMarker : MonoBehaviour { public float Scale = 1f; public float MoveSpeed = 1f; public float Damage = 1f; public float AttackSpeed = 1f; public float Health = 1f; public bool PlayerApplied; } internal static class SurvivorSpawnerTab { private class Row { public GameObject MasterPrefab; public string DisplayName; public Texture Icon; public string Key; public bool IsFavorite; } private const int IconSize = 24; private static readonly List allRows = new List(); private static string search = ""; private static string quantityText = "1"; private static bool spawnAsAlly = true; private static bool shareBuild = false; private static int selectedEliteIndex = 0; private static Vector2 scroll; private static readonly List spawnedObjects = new List(); private static ConfigEntry favoritesEntry; private static readonly HashSet favorites = new HashSet(); private static AggressionPreset selectedAggression = AggressionPreset.Normal; private static SizeTier selectedSize = SizeTier.Normal; private static ToughnessTier selectedToughness = ToughnessTier.Normal; private static void LoadFavorites() { favoritesEntry = SpawnBoxPlugin.PluginConfig.Bind("Favorites", "Survivors", "", "Comma-separated list of favorited survivor master names."); favorites.Clear(); string[] array = favoritesEntry.Value.Split(','); foreach (string text in array) { if (!string.IsNullOrEmpty(text)) { favorites.Add(text); } } } private static void SaveFavorites() { favoritesEntry.Value = string.Join(",", favorites); } private static void SortRows() { allRows.Sort((Row a, Row b) => (a.IsFavorite != b.IsFavorite) ? ((!a.IsFavorite) ? 1 : (-1)) : string.Compare(a.DisplayName, b.DisplayName)); } public static void BuildList() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Invalid comparison between Unknown and I4 //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Invalid comparison between Unknown and I4 //IL_00f2: Unknown result type (might be due to invalid IL or missing references) LoadFavorites(); allRows.Clear(); HashSet hashSet = new HashSet(); foreach (SurvivorDef allSurvivorDef in SurvivorCatalog.allSurvivorDefs) { if (!((Object)(object)allSurvivorDef == (Object)null) && !((Object)(object)allSurvivorDef.bodyPrefab == (Object)null)) { CharacterBody component = allSurvivorDef.bodyPrefab.GetComponent(); if ((Object)(object)component != (Object)null) { hashSet.Add(component.bodyIndex); } } } foreach (CharacterMaster allAiMaster in MasterCatalog.allAiMasters) { if (!((Object)(object)allAiMaster == (Object)null) && !((Object)(object)allAiMaster.bodyPrefab == (Object)null) && ((int)allAiMaster.teamIndex == 2 || (int)allAiMaster.teamIndex == 4)) { CharacterBody component2 = allAiMaster.bodyPrefab.GetComponent(); if (!((Object)(object)component2 == (Object)null) && !string.IsNullOrEmpty(component2.baseNameToken) && hashSet.Contains(component2.bodyIndex)) { string name = ((Object)((Component)allAiMaster).gameObject).name; allRows.Add(new Row { MasterPrefab = ((Component)allAiMaster).gameObject, DisplayName = Language.GetString(component2.baseNameToken), Icon = component2.portraitIcon, Key = name, IsFavorite = favorites.Contains(name) }); } } } SortRows(); SpawnBoxPlugin.Log.LogInfo((object)$"SpawnBox: {allRows.Count} survivors available."); } public static void Draw() { //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Search:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); search = GUILayout.TextField(search, Array.Empty()); GUILayout.Label("Qty:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) }); quantityText = GUILayout.TextField(quantityText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) }); GUILayout.EndHorizontal(); GUILayout.Label("High values may impact performance.", Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); spawnAsAlly = UiCycler.Draw("Team:", 70f, spawnAsAlly ? 1 : 0, EnemySpawnerTab.teamLabels, 140f) == 1; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); selectedEliteIndex = UiCycler.Draw("Elite:", 70f, selectedEliteIndex, EnemySpawnerTab.eliteLabels, 140f); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); selectedAggression = (AggressionPreset)UiCycler.Draw("Aggression:", 70f, (int)selectedAggression, AggressionController.Labels, 140f); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); selectedSize = (SizeTier)UiCycler.Draw("Size:", 70f, (int)selectedSize, SizeController.Labels, 140f); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); selectedToughness = (ToughnessTier)UiCycler.Draw("Toughness:", 70f, (int)selectedToughness, ToughnessController.Labels, 140f); GUILayout.EndHorizontal(); if (spawnAsAlly) { shareBuild = GUILayout.Toggle(shareBuild, "Share my build with spawned allies (live)", Array.Empty()); } bool flag = false; scroll = GUILayout.BeginScrollView(scroll, Array.Empty()); foreach (Row allRow in allRows) { if (!string.IsNullOrEmpty(search) && allRow.DisplayName.IndexOf(search, StringComparison.OrdinalIgnoreCase) < 0) { continue; } GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button(allRow.IsFavorite ? "Unpin" : "Pin", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) })) { allRow.IsFavorite = !allRow.IsFavorite; if (allRow.IsFavorite) { favorites.Add(allRow.Key); } else { favorites.Remove(allRow.Key); } SaveFavorites(); flag = true; } if ((Object)(object)allRow.Icon != (Object)null) { GUILayout.Label(allRow.Icon, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(24f), GUILayout.Height(24f) }); } else { GUILayout.Space(24f); } GUILayout.Label(allRow.DisplayName, Array.Empty()); if (GUILayout.Button("Spawn", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { SpawnMany(allRow.MasterPrefab, allRow.DisplayName, ParseQuantity()); } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); if (flag) { SortRows(); } } private static int ParseQuantity() { if (!int.TryParse(quantityText, out var result) || result <= 0) { return 1; } return result; } private static void SpawnMany(GameObject masterPrefab, string displayName, int count) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { return; } LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); if ((Object)(object)val == (Object)null) { return; } EliteDef val2 = ((selectedEliteIndex > 0 && selectedEliteIndex - 1 < EnemySpawnerTab.eliteOptions.Count) ? EnemySpawnerTab.eliteOptions[selectedEliteIndex - 1] : null); string affixLabel = (((Object)(object)val2 != (Object)null) ? EnemySpawnerTab.eliteLabels[selectedEliteIndex] : ""); string sizeLabel = SizeController.DisplayLabel(selectedSize); for (int i = 0; i < count; i++) { float num = 360f / (float)count * (float)i; Vector3 val3 = Quaternion.Euler(0f, num, 0f) * (val.transform.forward * 5f); Vector3 position = val.transform.position + val3; CharacterMaster val4 = new MasterSummon { masterPrefab = masterPrefab, position = position, rotation = Quaternion.identity, teamIndexOverride = (TeamIndex)(spawnAsAlly ? 1 : 2), useAmbientLevel = true, inventoryToCopy = ((spawnAsAlly && shareBuild) ? val.inventory : null), ignoreTeamMemberLimit = true }.Perform(); if (Object.op_Implicit((Object)(object)val4) && (Object)(object)val2 != (Object)null && Object.op_Implicit((Object)(object)val4.inventory) && Object.op_Implicit((Object)(object)val2.eliteEquipmentDef)) { val4.inventory.SetEquipmentIndex(val2.eliteEquipmentDef.equipmentIndex, false); } if (Object.op_Implicit((Object)(object)val4)) { if (spawnAsAlly) { ((Component)val4).gameObject.AddComponent(); } AggressionController aggressionController = new AggressionController(val4); if (selectedAggression != AggressionPreset.Normal) { aggressionController.Apply(selectedAggression); } SizeController.Attach(val4, selectedSize); ToughnessController.Attach(val4, selectedToughness); RewardController.Attach(val4); spawnedObjects.Add(new SpawnedCharacterInstance { Master = ((Component)val4).gameObject, DisplayName = displayName, AffixLabel = affixLabel, SizeLabel = sizeLabel, Aggression = aggressionController, ToughnessTier = selectedToughness }); } } } internal static int SpawnedCount() { int num = 0; foreach (SpawnedCharacterInstance spawnedObject in spawnedObjects) { if ((Object)(object)spawnedObject.Master != (Object)null) { num++; } } return num; } internal static IReadOnlyList GetSpawned() { return spawnedObjects; } internal static void DespawnAll() { if (!NetworkServer.active) { return; } foreach (SpawnedCharacterInstance spawnedObject in spawnedObjects) { if (!((Object)(object)spawnedObject.Master == (Object)null)) { CharacterMaster component = spawnedObject.Master.GetComponent(); if (component != null) { component.DestroyBody(); } NetworkServer.Destroy(spawnedObject.Master); } } spawnedObjects.Clear(); } internal static void DespawnOne(SpawnedCharacterInstance instance) { if (!NetworkServer.active || instance == null) { return; } if ((Object)(object)instance.Master != (Object)null) { CharacterMaster component = instance.Master.GetComponent(); if (component != null) { component.DestroyBody(); } NetworkServer.Destroy(instance.Master); } spawnedObjects.Remove(instance); } internal static void SyncBuildToAllies(Inventory playerInventory) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Invalid comparison between Unknown and I4 if (!shareBuild || !NetworkServer.active) { return; } foreach (SpawnedCharacterInstance spawnedObject in spawnedObjects) { if (!((Object)(object)spawnedObject.Master == (Object)null)) { CharacterMaster component = spawnedObject.Master.GetComponent(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.inventory == (Object)null) && (int)component.teamIndex == 1) { component.inventory.CopyItemsFrom(playerInventory); component.inventory.CopyEquipmentFrom(playerInventory, false); } } } } } internal enum ToughnessTier { Paper, Soft, Normal, Sturdy, Tanky } internal static class ToughnessController { private static readonly Dictionary Tiers = new Dictionary { { ToughnessTier.Paper, (0.5f, 0.5f) }, { ToughnessTier.Soft, (0.75f, 0.75f) }, { ToughnessTier.Normal, (1f, 1f) }, { ToughnessTier.Sturdy, (1.4f, 1.4f) }, { ToughnessTier.Tanky, (1.75f, 1.75f) } }; internal static readonly string[] Labels = new string[5] { "Paper", "Soft", "Normal", "Sturdy", "Tanky" }; internal static void Attach(CharacterMaster master, ToughnessTier tier) { if (!((Object)(object)master == (Object)null) && tier != ToughnessTier.Normal) { (float, float) tuple = Tiers[tier]; SpawnBoxToughnessMarker spawnBoxToughnessMarker = ((Component)master).gameObject.AddComponent(); (spawnBoxToughnessMarker.Health, spawnBoxToughnessMarker.Damage) = tuple; } } internal static void Apply(CharacterMaster master, ToughnessTier tier) { if ((Object)(object)master == (Object)null) { return; } SpawnBoxToughnessMarker spawnBoxToughnessMarker = ((Component)master).GetComponent(); if (tier == ToughnessTier.Normal) { if ((Object)(object)spawnBoxToughnessMarker != (Object)null) { spawnBoxToughnessMarker.Health = 1f; spawnBoxToughnessMarker.Damage = 1f; Object.Destroy((Object)(object)spawnBoxToughnessMarker); } } else { if ((Object)(object)spawnBoxToughnessMarker == (Object)null) { spawnBoxToughnessMarker = ((Component)master).gameObject.AddComponent(); } (spawnBoxToughnessMarker.Health, spawnBoxToughnessMarker.Damage) = Tiers[tier]; } CharacterBody body = master.GetBody(); if (!((Object)(object)body == (Object)null)) { body.RecalculateStats(); if ((Object)(object)((Component)master).GetComponent() != (Object)null) { RewardController.Configure(body); } } } } internal class SpawnBoxToughnessMarker : MonoBehaviour { public float Health = 1f; public float Damage = 1f; } internal static class UiCycler { internal static int Draw(string label, float labelWidth, int index, string[] labels, float valueWidth) { GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(labelWidth) }); if (GUILayout.Button("<", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(24f) })) { index = (index - 1 + labels.Length) % labels.Length; } GUILayout.Label(labels[index], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(valueWidth) }); if (GUILayout.Button(">", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(24f) })) { index = (index + 1) % labels.Length; } return index; } } internal static class WorldTab { private class Row { public List Variants = new List(); public string Name; public string Subtitle; public string DisplayName; public int StageOrder; } private enum Section { None, Explore, Advance } private static readonly List allRows = new List(); private static readonly Random rng = new Random(); private static string search = ""; private static Vector2 scroll; private static bool built = false; private static Section expandedSection = Section.None; private static bool suppressingPopulation = false; private static readonly List suppressedSpawns = new List(); private static float suppressionStartTime; private const float PostStartGraceSeconds = 5f; private static bool sceneStartComplete = false; private static float graceEndTime; private const float InteractableSweepIntervalSeconds = 1f; private static float nextInteractableSweepTime; private static bool isExploring = false; private const float SuppressionTimeoutSeconds = 30f; internal static bool IsExploring => isExploring; public static void BuildList() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) allRows.Clear(); Dictionary dictionary = new Dictionary(); Enumerator enumerator = SceneCatalog.allStageSceneDefs.GetEnumerator(); try { while (enumerator.MoveNext()) { SceneDef current = enumerator.Current; if (!((Object)(object)current == (Object)null)) { string key = ((!string.IsNullOrEmpty(current.nameToken)) ? current.nameToken : current.baseSceneName); if (!dictionary.TryGetValue(key, out var value)) { string name = ((!string.IsNullOrEmpty(current.nameToken)) ? Language.GetString(current.nameToken) : current.baseSceneName); value = (dictionary[key] = new Row { StageOrder = current.stageOrder }); allRows.Add(value); value.Name = name; value.Subtitle = ((!string.IsNullOrEmpty(current.subtitleToken)) ? Language.GetString(current.subtitleToken) : ""); } value.Variants.Add(current); } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } foreach (Row allRow in allRows) { string text = ((allRow.Variants.Count > 1) ? $"{allRow.Name} ({allRow.Variants.Count} variants)" : allRow.Name); allRow.DisplayName = (string.IsNullOrEmpty(allRow.Subtitle) ? text : (text + "\n" + allRow.Subtitle)); } allRows.Sort((Row a, Row b) => (a.StageOrder == b.StageOrder) ? string.Compare(a.DisplayName, b.DisplayName) : a.StageOrder.CompareTo(b.StageOrder)); built = true; SpawnBoxPlugin.Log.LogInfo((object)$"SpawnBox: {allRows.Count} locations available."); } public static void Draw() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (!built && SceneCatalog.allStageSceneDefs.Length > 0) { BuildList(); } if (GUILayout.Button((expandedSection == Section.Explore) ? "▾ Explore (spawn into an empty environment)" : "▸ Explore (spawn into an empty environment)", Array.Empty())) { expandedSection = ((expandedSection != Section.Explore) ? Section.Explore : Section.None); } if (expandedSection == Section.Explore) { DrawSection(JumpTo, "Explore"); } if (GUILayout.Button((expandedSection == Section.Advance) ? "▾ Advance (continue your run from this point)" : "▸ Advance (continue your run from this point)", Array.Empty())) { expandedSection = ((expandedSection != Section.Advance) ? Section.Advance : Section.None); } if (expandedSection == Section.Advance) { DrawSection(AdvanceTo, "Advance"); } } private static void DrawSection(Action onClick, string buttonLabel) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Search:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); search = GUILayout.TextField(search, Array.Empty()); GUILayout.EndHorizontal(); scroll = GUILayout.BeginScrollView(scroll, Array.Empty()); foreach (Row allRow in allRows) { if (string.IsNullOrEmpty(search) || allRow.DisplayName.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(allRow.DisplayName, Array.Empty()); if (GUILayout.Button(buttonLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) })) { onClick(PickVariant(allRow)); } GUILayout.EndHorizontal(); } } GUILayout.EndScrollView(); } private static SceneDef PickVariant(Row row) { return row.Variants[rng.Next(row.Variants.Count)]; } private static void JumpTo(SceneDef scene) { if (NetworkServer.active && !((Object)(object)scene == (Object)null) && !((Object)(object)Run.instance == (Object)null) && !((Object)(object)Stage.instance == (Object)null)) { isExploring = true; suppressingPopulation = true; sceneStartComplete = false; suppressedSpawns.Clear(); suppressionStartTime = Time.time; Stage.instance.BeginAdvanceStage(scene); } } private static void AdvanceTo(SceneDef scene) { if (NetworkServer.active && !((Object)(object)scene == (Object)null) && !((Object)(object)Run.instance == (Object)null) && !((Object)(object)Stage.instance == (Object)null)) { isExploring = false; suppressingPopulation = false; sceneStartComplete = false; suppressedSpawns.Clear(); Stage.instance.BeginAdvanceStage(scene); } } internal static void ResetOnRunStart() { isExploring = false; } internal static void OnObjectSpawned(GameObject spawned) { ClearSuppressionIfStale(); if (suppressingPopulation && (Object)(object)spawned != (Object)null) { suppressedSpawns.Add(spawned); } } internal static void OnSceneDirectorStartComplete() { ClearSuppressionIfStale(); if (suppressingPopulation) { SweepAndClean(); SuppressInteractables(); nextInteractableSweepTime = Time.time + 1f; sceneStartComplete = true; graceEndTime = Time.time + 5f; } } internal static void TickSuppression() { if (isExploring && Time.time >= nextInteractableSweepTime) { SuppressInteractables(); nextInteractableSweepTime = Time.time + 1f; } if (!suppressingPopulation || !sceneStartComplete) { return; } ClearSuppressionIfStale(); if (suppressingPopulation) { SweepAndClean(); if (Time.time >= graceEndTime) { suppressingPopulation = false; sceneStartComplete = false; } } } private static void SweepAndClean() { foreach (GameObject suppressedSpawn in suppressedSpawns) { if (!((Object)(object)suppressedSpawn == (Object)null)) { CharacterMaster component = suppressedSpawn.GetComponent(); if (component != null) { component.DestroyBody(); } NetworkServer.Destroy(suppressedSpawn); } } suppressedSpawns.Clear(); CombatDirector[] array = Object.FindObjectsOfType(); foreach (CombatDirector val in array) { if ((Object)(object)val != (Object)null) { ((Behaviour)val).enabled = false; } } CampDirector[] array2 = Object.FindObjectsOfType(); foreach (CampDirector val2 in array2) { if ((Object)(object)val2 != (Object)null) { ((Behaviour)val2).enabled = false; } } } private static void SuppressInteractables() { MonoBehaviour[] array = Object.FindObjectsOfType(); foreach (MonoBehaviour val in array) { if (!((Object)(object)val == (Object)null) && val is IInteractable && ((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(false); } } } private static void ClearSuppressionIfStale() { if (suppressingPopulation && Time.time - suppressionStartTime > 30f) { suppressingPopulation = false; sceneStartComplete = false; suppressedSpawns.Clear(); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "SpawnBox"; public const string PLUGIN_NAME = "SpawnBox"; public const string PLUGIN_VERSION = "1.7.0"; } }