Decompiled source of AtlyssArchipelago v0.2.3
plugins/AtlyssArchipelago.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Net.WebSockets; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Archipelago.MultiClient.Net; using Archipelago.MultiClient.Net.BounceFeatures.DeathLink; using Archipelago.MultiClient.Net.Colors; using Archipelago.MultiClient.Net.ConcurrentCollection; using Archipelago.MultiClient.Net.Converters; using Archipelago.MultiClient.Net.DataPackage; using Archipelago.MultiClient.Net.Enums; using Archipelago.MultiClient.Net.Exceptions; using Archipelago.MultiClient.Net.Extensions; using Archipelago.MultiClient.Net.Helpers; using Archipelago.MultiClient.Net.MessageLog.Messages; using Archipelago.MultiClient.Net.MessageLog.Parts; using Archipelago.MultiClient.Net.Models; using Archipelago.MultiClient.Net.Packets; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Mirror; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.7.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [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; } } } public class AttemptingStringEnumConverter : StringEnumConverter { public AttemptingStringEnumConverter() { } public AttemptingStringEnumConverter(Type namingStrategyType) : base(namingStrategyType) { } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { try { return ((StringEnumConverter)this).ReadJson(reader, objectType, existingValue, serializer); } catch (JsonSerializationException) { return objectType.IsValueType ? Activator.CreateInstance(objectType) : null; } } } internal interface IConcurrentHashSet<T> { bool TryAdd(T item); bool Contains(T item); void UnionWith(T[] otherSet); T[] ToArray(); ReadOnlyCollection<T> AsToReadOnlyCollection(); ReadOnlyCollection<T> AsToReadOnlyCollectionExcept(IConcurrentHashSet<T> otherSet); } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class AllowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal class DoesNotReturnIfAttribute : Attribute { public bool ParameterValue { get; } public DoesNotReturnIfAttribute(bool parameterValue) { ParameterValue = parameterValue; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class MaybeNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true)] internal sealed class NotNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] internal sealed class NotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public NotNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } } namespace AtlyssArchipelagoWIP { public static class ArchipelagoAchievementDetection { public static int CountIllusionStonesInInventory() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown Player mainPlayer = Player._mainPlayer; if ((Object)mainPlayer == (Object)null) { return 0; } PlayerInventory component = ((Component)mainPlayer).GetComponent<PlayerInventory>(); if ((Object)component == (Object)null) { return 0; } if (!(AccessTools.Field(typeof(PlayerInventory), "_heldItems")?.GetValue(component) is List<ItemData> list)) { return 0; } int num = 0; foreach (ItemData item in list) { if (item != null && !string.IsNullOrEmpty(item._itemName) && item._itemName.IndexOf("Illusion Stone", StringComparison.OrdinalIgnoreCase) >= 0) { num += Mathf.Max(1, item._quantity); } } return num; } } public static class ArchipelagoDungeonClearDetection { private static readonly Dictionary<string, string> TriggerTagToClearingCheck = new Dictionary<string, string>(StringComparer.Ordinal) { { "ATLYSS_ACHIEVEMENT_01", "Clearing Catacombs (1-6)" }, { "ATLYSS_ACHIEVEMENT_02", "Clearing Catacombs (6-12)" }, { "ATLYSS_ACHIEVEMENT_03", "Clearing Catacombs (12-18)" }, { "ATLYSS_ACHIEVEMENT_07", "Clearing Grove (15-20)" }, { "ATLYSS_ACHIEVEMENT_13", "Clearing Grove (20-25)" } }; public static string TryGetClearingAchievementCheckFromTriggerTag(string triggerTag) { if (string.IsNullOrEmpty(triggerTag)) { return null; } if (!TriggerTagToClearingCheck.TryGetValue(triggerTag, out string value)) { return null; } return value; } public static string TryGetClearingAchievementCheck(string sceneOrMapName, int difficultyIndex) { if (string.IsNullOrEmpty(sceneOrMapName) || difficultyIndex < 0 || difficultyIndex > 2) { return null; } bool flag = IsSanctumCatacombsScene(sceneOrMapName); bool flag2 = IsCrescentGroveScene(sceneOrMapName); if (!flag && !flag2) { return null; } if (flag) { return difficultyIndex switch { 0 => "Clearing Catacombs (1-6)", 1 => "Clearing Catacombs (6-12)", 2 => "Clearing Catacombs (12-18)", _ => null, }; } return difficultyIndex switch { 0 => "Clearing Grove (15-20)", 1 => "Clearing Grove (15-20)", 2 => "Clearing Grove (20-25)", _ => null, }; } public static string ResolveSceneToken(MapInstance mapInstance, PatternInstanceManager patternInstance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_0028: Unknown result type (might be due to invalid IL or missing references) if ((Object)mapInstance != (Object)null) { if (!string.IsNullOrEmpty(mapInstance._mapName)) { return mapInstance._mapName; } Scene loadedScene = mapInstance._loadedScene; if (((Scene)(ref loadedScene)).IsValid() && !string.IsNullOrEmpty(((Scene)(ref loadedScene)).path)) { return ((Scene)(ref loadedScene)).path; } if (((Scene)(ref loadedScene)).IsValid() && !string.IsNullOrEmpty(((Scene)(ref loadedScene)).name)) { return ((Scene)(ref loadedScene)).name; } } if ((Object)patternInstance != (Object)null) { Scene scene = ((Component)patternInstance).gameObject.scene; return ((Scene)(ref scene)).name; } return null; } internal static bool IsSanctumCatacombsScene(string sceneOrMapName) { if (sceneOrMapName.IndexOf("sanctumCatacombs", StringComparison.OrdinalIgnoreCase) < 0 && sceneOrMapName.IndexOf("Sanctum Catacombs", StringComparison.OrdinalIgnoreCase) < 0) { return sceneOrMapName.IndexOf("map_dungeon00", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } internal static bool IsCrescentGroveScene(string sceneOrMapName) { if (sceneOrMapName.IndexOf("crescentGrove", StringComparison.OrdinalIgnoreCase) < 0 && sceneOrMapName.IndexOf("Crescent Grove", StringComparison.OrdinalIgnoreCase) < 0) { return sceneOrMapName.IndexOf("map_dungeon01", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } } public static class ArchipelagoDungeonFloorAccess { public static bool IsSanctumCatacombsFloorUnlocked(AtlyssArchipelagoPlugin plugin, int floorIndex) { if ((Object)(object)plugin == (Object)null || !plugin.connected) { return true; } return floorIndex switch { 0 => HasPortalKey(plugin, "Sanctum Catacombs lvl 1 Portal"), 1 => HasPortalKey(plugin, "Sanctum Catacombs lvl 1 Portal") && HasPortalKey(plugin, "Sanctum Catacombs lvl 2 Portal"), 2 => HasPortalKey(plugin, "Sanctum Catacombs lvl 1 Portal") && HasPortalKey(plugin, "Sanctum Catacombs lvl 2 Portal") && HasPortalKey(plugin, "Sanctum Catacombs lvl 3 Portal"), _ => false, }; } public static bool IsCrescentGroveFloorUnlocked(AtlyssArchipelagoPlugin plugin, int floorIndex) { if ((Object)(object)plugin == (Object)null || !plugin.connected) { return true; } return floorIndex switch { 0 => HasPortalKey(plugin, "Crescent Grove lvl 1 Portal"), 1 => HasPortalKey(plugin, "Crescent Grove lvl 2 Portal"), _ => false, }; } private static bool HasPortalKey(AtlyssArchipelagoPlugin plugin, string portalKey) { bool received; if (plugin.randomPortalsEnabled) { return plugin.TryGetPortalReceived(portalKey, out received) && received; } return ArchipelagoProgressivePortalAccess.HasProgressivePortalUnlockedViaOrder(plugin, portalKey); } } public static class ArchipelagoGameDataTables { public readonly struct ProgressivePortalRequirement { public readonly int SanctumCount; public readonly int TuulCount; public ProgressivePortalRequirement(int sanctumCount, int tuulCount) { SanctumCount = sanctumCount; TuulCount = tuulCount; } } public const string CrescentRoadPortalKey = "Crescent Road Portal"; public const string CrescentKeepPortalKey = "Crescent Keep Portal"; public const string CrescentGroveLevel1PortalKey = "Crescent Grove lvl 1 Portal"; public const string CrescentGroveLevel2PortalKey = "Crescent Grove lvl 2 Portal"; public const string SanctumCatacombsLevel1PortalKey = "Sanctum Catacombs lvl 1 Portal"; public const string SanctumCatacombsLevel2PortalKey = "Sanctum Catacombs lvl 2 Portal"; public const string SanctumCatacombsLevel3PortalKey = "Sanctum Catacombs lvl 3 Portal"; public const int ProgressiveSanctumPortalItemCount = 11; public const int ProgressiveTuulPortalItemCount = 3; public const string ProgressiveSanctumPortalItemName = "Progressive Sanctum Portal"; public const string ProgressiveTuulPortalItemName = "Progressive Tuul Portal"; private const string SanctumCatacombsScene = "Assets/Scenes/map_dungeon00_sanctumCatacombs.unity"; public static readonly IReadOnlyDictionary<string, string> PortalScenes = new Dictionary<string, string> { { "Sanctum Portal", "Assets/Scenes/00_zone_forest/_zone00_sanctum.unity" }, { "Outer Sanctum Portal", "Assets/Scenes/00_zone_forest/_zone00_outerSanctum.unity" }, { "Arcwood Pass Portal", "Assets/Scenes/00_zone_forest/_zone00_arcwoodPass.unity" }, { "Effold Terrace Portal", "Assets/Scenes/00_zone_forest/_zone00_effoldTerrace.unity" }, { "Tuul Valley Portal", "Assets/Scenes/00_zone_forest/_zone00_tuulValley.unity" }, { "Sanctum Catacombs lvl 1 Portal", "Assets/Scenes/map_dungeon00_sanctumCatacombs.unity" }, { "Sanctum Catacombs lvl 2 Portal", "Assets/Scenes/map_dungeon00_sanctumCatacombs.unity" }, { "Sanctum Catacombs lvl 3 Portal", "Assets/Scenes/map_dungeon00_sanctumCatacombs.unity" }, { "Crescent Road Portal", "Assets/Scenes/00_zone_forest/_zone00_crescentRoad.unity" }, { "Tuul Enclave Portal", "Assets/Scenes/00_zone_forest/_zone00_tuulEnclave.unity" }, { "Luvora Garden Portal", "Assets/Scenes/00_zone_forest/_zone00_luvoraGarden.unity" }, { "Crescent Keep Portal", "Assets/Scenes/00_zone_forest/_zone00_crescentKeep.unity" }, { "Bularr Fortress Portal", "Assets/Scenes/00_zone_forest/_zone00_bularFortress.unity" }, { "Crescent Grove lvl 1 Portal", "Assets/Scenes/map_dungeon01_crescentGrove.unity" }, { "Crescent Grove lvl 2 Portal", "Assets/Scenes/map_dungeon01_crescentGrove.unity" }, { "Gate of the Moon Portal", "Assets/Scenes/00_zone_forest/_zone00_gateOfTheMoon.unity" }, { "Wall of the Stars Portal", "Assets/Scenes/00_zone_forest/_zone00_wallOfTheStars.unity" }, { "Redwoud Portal", "Assets/Scenes/map_zone00_redwoud.unity" }, { "Trial of the Stars Portal", "Assets/Scenes/00_zone_forest/_zone00_trialOfTheStars.unity" } }; public static readonly IReadOnlyList<string> ProgressiveSanctumPortalOrder = new List<string> { "Outer Sanctum Portal", "Arcwood Pass Portal", "Sanctum Catacombs lvl 1 Portal", "Sanctum Catacombs lvl 2 Portal", "Sanctum Catacombs lvl 3 Portal", "Effold Terrace Portal", "Crescent Road Portal", "Luvora Garden Portal", "Crescent Keep Portal", "Crescent Grove lvl 1 Portal", "Crescent Grove lvl 2 Portal" }; public static readonly IReadOnlyList<string> ProgressiveTuulPortalOrder = new List<string> { "Tuul Valley Portal", "Tuul Enclave Portal", "Bularr Fortress Portal" }; public static readonly IReadOnlyDictionary<string, ProgressivePortalRequirement> PortalProgressiveRequirements = new Dictionary<string, ProgressivePortalRequirement> { { "Outer Sanctum Portal", new ProgressivePortalRequirement(1, 0) }, { "Arcwood Pass Portal", new ProgressivePortalRequirement(2, 0) }, { "Sanctum Catacombs lvl 1 Portal", new ProgressivePortalRequirement(3, 0) }, { "Sanctum Catacombs lvl 2 Portal", new ProgressivePortalRequirement(4, 0) }, { "Sanctum Catacombs lvl 3 Portal", new ProgressivePortalRequirement(5, 0) }, { "Effold Terrace Portal", new ProgressivePortalRequirement(6, 0) }, { "Tuul Valley Portal", new ProgressivePortalRequirement(6, 1) }, { "Crescent Road Portal", new ProgressivePortalRequirement(7, 1) }, { "Luvora Garden Portal", new ProgressivePortalRequirement(8, 1) }, { "Crescent Keep Portal", new ProgressivePortalRequirement(9, 1) }, { "Tuul Enclave Portal", new ProgressivePortalRequirement(9, 2) }, { "Crescent Grove lvl 1 Portal", new ProgressivePortalRequirement(10, 2) }, { "Crescent Grove lvl 2 Portal", new ProgressivePortalRequirement(11, 2) }, { "Bularr Fortress Portal", new ProgressivePortalRequirement(11, 3) } }; public static readonly Dictionary<string, long> AllLocationNameToId = new Dictionary<string, long> { { "A Warm Welcome", 1L }, { "Communing Catacombs", 2L }, { "Diva Must Die", 3L }, { "The Keep Within", 4L }, { "Tethering Grove", 5L }, { "The Glyphik Booklet", 6L }, { "Cleaning Terrace", 7L }, { "Ancient Beings", 8L }, { "Wicked Wizboars", 9L }, { "Spiraling In The Grove", 10L }, { "Hell In The Grove", 11L }, { "Nulversa", 12L }, { "Finding Ammagon", 13L }, { "The Colossus", 14L }, { "Night Spirits", 15L }, { "Ridding Slimes", 16L }, { "Huntin' Hogs", 17L }, { "Purging the Grove", 18L }, { "Cleansing the Grove", 19L }, { "Call of Fury", 20L }, { "Mastery of Strength", 21L }, { "Mastery of Dexterity", 22L }, { "Mastery of Mind", 23L }, { "Beckoning Foes", 24L }, { "Ghostly Goods", 25L }, { "Makin' a Mekspear", 26L }, { "Makin' a Wizwand", 27L }, { "Makin' a Vile Blade", 28L }, { "Makin' a Golem Chestpiece", 29L }, { "Makin' a Ragespear", 30L }, { "Makin' a Monolith Chestpiece", 31L }, { "Makin' a Firebreath Blade", 32L }, { "Makin' a Follycannon", 33L }, { "Summore' Spectral Powder!", 34L }, { "Makin' More Mekspears", 35L }, { "Makin' More Wizwands", 36L }, { "Makin' More Vile Blades", 37L }, { "Summore' Golem Chestpieces", 38L }, { "Makin' More Ragespears", 39L }, { "Summore' Monolith Chestpieces", 40L }, { "Summore' Firebreath Blades", 41L }, { "Makin' More Follycannons", 42L }, { "Focusin' in", 43L }, { "Whatta' Rush!", 44L }, { "The Voice of Zuulneruda", 45L }, { "Killing Tomb", 46L }, { "Purging the Undead", 47L }, { "Rattlecage Rage", 48L }, { "Consumed Madness", 49L }, { "Eradicating the Undead", 50L }, { "Reviling the Rageboars", 51L }, { "Gatling Galius", 52L }, { "Reviling more Rageboars", 53L }, { "Facing Foes", 54L }, { "The Gall of Galius", 55L }, { "Dense Ingots", 56L }, { "Amberite Ingots", 57L }, { "Sapphite Ingots", 58L }, { "Reach Level 2", 59L }, { "Reach Level 4", 60L }, { "Reach Level 6", 61L }, { "Reach Level 8", 62L }, { "Reach Level 10", 63L }, { "Reach Level 12", 64L }, { "Reach Level 14", 65L }, { "Reach Level 16", 66L }, { "Reach Level 18", 67L }, { "Reach Level 20", 68L }, { "Reach Level 22", 69L }, { "Reach Level 24", 70L }, { "Reach Level 26", 71L }, { "Reach Level 28", 72L }, { "Reach Level 30", 73L }, { "Reach Level 32", 74L }, { "Buy Item #1 from Sally's Nook", 75L }, { "Buy Item #2 from Sally's Nook", 76L }, { "Buy Item #3 from Sally's Nook", 77L }, { "Buy Item #4 from Sally's Nook", 78L }, { "Buy Item #5 from Sally's Nook", 79L }, { "Buy Item #1 from Skrit's Sikrit Market", 80L }, { "Buy Item #2 from Skrit's Sikrit Market", 81L }, { "Buy Item #3 from Skrit's Sikrit Market", 82L }, { "Buy Item #4 from Skrit's Sikrit Market", 83L }, { "Buy Item #5 from Skrit's Sikrit Market", 84L }, { "Buy Item #1 from Frankie's Goods", 85L }, { "Buy Item #2 from Frankie's Goods", 86L }, { "Buy Item #3 from Frankie's Goods", 87L }, { "Buy Item #4 from Frankie's Goods", 88L }, { "Buy Item #5 from Frankie's Goods", 89L }, { "Buy Item #1 from Dye Merchant", 90L }, { "Buy Item #2 from Dye Merchant", 91L }, { "Buy Item #3 from Dye Merchant", 92L }, { "Buy Item #4 from Dye Merchant", 93L }, { "Buy Item #5 from Dye Merchant", 94L }, { "Buy Item #1 from Tesh's Wares", 95L }, { "Buy Item #2 from Tesh's Wares", 96L }, { "Buy Item #3 from Tesh's Wares", 97L }, { "Buy Item #4 from Tesh's Wares", 98L }, { "Buy Item #5 from Tesh's Wares", 99L }, { "Buy Item #1 from Nesh's Wares", 100L }, { "Buy Item #2 from Nesh's Wares", 101L }, { "Buy Item #3 from Nesh's Wares", 102L }, { "Buy Item #4 from Nesh's Wares", 103L }, { "Buy Item #5 from Nesh's Wares", 104L }, { "Buy Item #1 from Rikko's Treasures", 105L }, { "Buy Item #2 from Rikko's Treasures", 106L }, { "Buy Item #3 from Rikko's Treasures", 107L }, { "Buy Item #4 from Rikko's Treasures", 108L }, { "Buy Item #5 from Rikko's Treasures", 109L }, { "Buy Item #1 from Cotoo's Treasures", 110L }, { "Buy Item #2 from Cotoo's Treasures", 111L }, { "Buy Item #3 from Cotoo's Treasures", 112L }, { "Buy Item #4 from Cotoo's Treasures", 113L }, { "Buy Item #5 from Cotoo's Treasures", 114L }, { "Buy Item #1 from Ruka's Furnace", 115L }, { "Buy Item #2 from Ruka's Furnace", 116L }, { "Buy Item #3 from Ruka's Furnace", 117L }, { "Buy Item #4 from Ruka's Furnace", 118L }, { "Buy Item #5 from Ruka's Furnace", 119L }, { "Buy Item #1 from Torta's Fishing Shack", 120L }, { "Buy Item #2 from Torta's Fishing Shack", 121L }, { "Buy Item #3 from Torta's Fishing Shack", 122L }, { "Buy Item #4 from Torta's Fishing Shack", 123L }, { "Buy Item #5 from Torta's Fishing Shack", 124L }, { "Buy Item #1 from Mad Statue's Gift", 125L }, { "Buy Item #2 from Mad Statue's Gift", 126L }, { "Buy Item #3 from Mad Statue's Gift", 127L }, { "Buy Item #4 from Mad Statue's Gift", 128L }, { "Buy Item #5 from Mad Statue's Gift", 129L }, { "Fishing Lv. 1", 130L }, { "Fishing Lv. 2", 131L }, { "Fishing Lv. 3", 132L }, { "Fishing Lv. 4", 133L }, { "Fishing Lv. 5", 134L }, { "Fishing Lv. 6", 135L }, { "Fishing Lv. 7", 136L }, { "Fishing Lv. 8", 137L }, { "Fishing Lv. 9", 138L }, { "Fishing Lv. 10", 139L }, { "Mining Lv. 1", 140L }, { "Mining Lv. 2", 141L }, { "Mining Lv. 3", 142L }, { "Mining Lv. 4", 143L }, { "Mining Lv. 5", 144L }, { "Mining Lv. 6", 145L }, { "Mining Lv. 7", 146L }, { "Mining Lv. 8", 147L }, { "Mining Lv. 9", 148L }, { "Mining Lv. 10", 149L }, { "A New Journey", 150L }, { "Clearing Catacombs (1-6)", 151L }, { "Clearing Catacombs (6-12)", 152L }, { "Clearing Catacombs (12-18)", 153L }, { "Clearing Grove (15-20)", 154L }, { "Clearing Grove (20-25)", 155L }, { "Altered Vision", 156L }, { "Scaling the Tower", 157L }, { "Rude!", 158L }, { "Slime Diva", 159L }, { "Lord Zuulneruda", 160L }, { "Lord Kaluuz", 161L }, { "Colossus", 162L }, { "Valdur", 163L }, { "Galius", 164L }, { "Buy Fishing Rod", 165L }, { "Buy Pickaxe", 166L }, { "Defeat Creep: Lesser Wisp", 170L }, { "Defeat Creep: Slime", 171L }, { "Defeat Creep: Tar Spawn", 172L }, { "Defeat Creep: Greater Wisp", 173L }, { "Defeat Creep: Mini Geist", 174L }, { "Defeat Creep: Slimek", 175L }, { "Defeat Creep: Deathgel", 176L }, { "Defeat Creep: Geist", 177L }, { "Defeat Creep: Mekboar", 178L }, { "Defeat Creep: Mini Golem", 179L }, { "Defeat Creep: Toxin", 180L }, { "Defeat Creep: Blightwood", 181L }, { "Defeat Creep: Mouth", 182L }, { "Defeat Creep: Golem", 183L }, { "Defeat Creep: Hellsludge", 184L }, { "Defeat Creep: Klamkull", 185L }, { "Defeat Creep: Wizboar", 186L }, { "Defeat Creep: Miasma", 187L }, { "Defeat Creep: Vout", 188L }, { "Defeat Creep: Deadwood", 189L }, { "Defeat Creep: Stezza", 190L }, { "Defeat Creep: Alshar", 191L }, { "Defeat Creep: Blue Minichroom", 192L }, { "Defeat Creep: Red Minichroom", 193L }, { "Defeat Creep: Rageboar", 194L }, { "Defeat Creep: Maw", 195L }, { "Defeat Creep: Mandragora", 196L }, { "Defeat Creep: Gale Muchroom", 197L }, { "Defeat Creep: Aqua Muchroom", 198L }, { "Defeat Creep: Firebreath", 199L }, { "Defeat Creep: Poltergeist", 200L }, { "Defeat Creep: Vultia", 201L }, { "Defeat Creep: Boomboar", 202L }, { "Defeat Creep: Carbuncle", 203L }, { "Defeat Creep: Monolith", 204L }, { "Defeat Creep: Nagrath", 205L }, { "Defeat Creep: Barknaught", 206L }, { "Defeat Creep: Warboar", 207L }, { "Defeat Creep: Sirius", 208L }, { "Defeat Creep: Death Knight", 209L }, { "Defeat Creep: Demigolem", 210L }, { "Defeat Creep: Biggun", 211L }, { "Defeat Creep: Nograd", 212L }, { "Defeat Creep: Rokkamek", 213L }, { "Defeat Creep: Dolkin", 214L }, { "Defeat Creep: Gahool", 215L }, { "Defeat Creep: Kruole", 216L } }; internal static readonly Dictionary<string, long> AllQuestToLocation = new Dictionary<string, long> { { "A Warm Welcome", 1L }, { "Communing Catacombs", 2L }, { "Diva Must Die", 3L }, { "The Keep Within", 4L }, { "Tethering Grove", 5L }, { "The Glyphik Booklet", 6L }, { "Cleaning Terrace", 7L }, { "Ancient Beings", 8L }, { "Wicked Wizboars", 9L }, { "Spiraling In The Grove", 10L }, { "Hell In The Grove", 11L }, { "Nulversa", 12L }, { "Finding Ammagon", 13L }, { "The Colossus", 14L }, { "Night Spirits", 15L }, { "Ridding Slimes", 16L }, { "Huntin' Hogs", 17L }, { "Purging the Grove", 18L }, { "Cleansing the Grove", 19L }, { "Call of Fury", 20L }, { "Mastery of Strength", 21L }, { "Mastery of Dexterity", 22L }, { "Mastery of Mind", 23L }, { "Beckoning Foes", 24L }, { "Ghostly Goods", 25L }, { "Makin' a Mekspear", 26L }, { "Makin' a Wizwand", 27L }, { "Makin' a Vile Blade", 28L }, { "Makin' a Golem Chestpiece", 29L }, { "Makin' a Ragespear", 30L }, { "Makin' a Monolith Chestpiece", 31L }, { "Makin' a Firebreath Blade", 32L }, { "Makin' a Follycannon", 33L }, { "Summore' Spectral Powder!", 34L }, { "Makin' More Mekspears", 35L }, { "Makin' More Wizwands", 36L }, { "Makin' More Vile Blades", 37L }, { "Summore' Golem Chestpieces", 38L }, { "Makin' More Ragespears", 39L }, { "Summore' Monolith Chestpieces", 40L }, { "Summore' Firebreath Blades", 41L }, { "Makin' More Follycannons", 42L }, { "Focusin' in", 43L }, { "Whatta' Rush!", 44L }, { "The Voice of Zuulneruda", 45L }, { "Killing Tomb", 46L }, { "Purging the Undead", 47L }, { "Rattlecage Rage", 48L }, { "Consumed Madness", 49L }, { "Eradicating the Undead", 50L }, { "Reviling the Rageboars", 51L }, { "Gatling Galius", 52L }, { "Reviling more Rageboars", 53L }, { "Facing Foes", 54L }, { "The Gall of Galius", 55L }, { "Dense Ingots", 56L }, { "Amberite Ingots", 57L }, { "Sapphite Ingots", 58L } }; internal static readonly Dictionary<string, string[]> ApQuestVanillaCompletionNames = new Dictionary<string, string[]> { { "Nulversa", new string[3] { "Nulversa Magica", "Nulversa Viscera", "Nulversa, Greenversa!" } } }; internal static readonly KeyValuePair<string, long>[] AllQuestToLocationPairs = BuildAllQuestToLocationPairs(); public static readonly Dictionary<string, string> ItemNameMapping = new Dictionary<string, string> { { "Bunbag Pack", "(lv-0) STATUSCONSUMABLE_Bunbag" }, { "Bunjar Pack", "(lv-0) STATUSCONSUMABLE_Bunjar" }, { "Bunpot Pack", "(lv-0) STATUSCONSUMABLE_Bunpot" }, { "Regen Potion Pack", "(lv-10) STATUSCONSUMABLE_Regen Potion" }, { "Regen Vial Pack", "(lv-0) STATUSCONSUMABLE_Regen Vial" }, { "Magiclove Pack", "(lv-0) STATUSCONSUMABLE_Magiclove" }, { "Magiflower Pack", "(lv-0) STATUSCONSUMABLE_Magiflower" }, { "Magileaf Pack", "(lv-0) STATUSCONSUMABLE_Magileaf" }, { "Stamstar", "(lv-0) STATUSCONSUMABLE_Stamstar" }, { "Agility Potion Pack", "(lv-10) STATUSCONSUMABLE_Agility Potion" }, { "Agility Vial Pack", "(lv-0) STATUSCONSUMABLE_Agility Vial" }, { "Bolster Potion Pack", "(lv-10) STATUSCONSUMABLE_Bolster Potion" }, { "Bolster Vial Pack", "(lv-0) STATUSCONSUMABLE_Bolster Vial" }, { "Wisdom Potion Pack", "(lv-10) STATUSCONSUMABLE_Wisdom Potion" }, { "Wisdom Vial Pack", "(lv-0) STATUSCONSUMABLE_Wisdom Vial" }, { "Tome of Greater Experience", "(lv-0) STATUSCONSUMABLE_Tome of Greater Experience" }, { "Tome of Experience", "(lv-0) STATUSCONSUMABLE_Tome of Experience" }, { "Tome of Lesser Experience", "(lv-0) STATUSCONSUMABLE_Tome of Lesser Experience" }, { "Carrot Cake Pack", "(lv-0) STATUSCONSUMABLE_Carrot Cake" }, { "Minchroom Juice Pack", "(lv-0) STATUSCONSUMABLE_Minchroom Juice" }, { "Spectral Powder Pack", "(lv-0) STATUSCONSUMABLE_Spectral Powder" }, { "Geistlord Badge", "TRADEITEM_Geistlord Badge" }, { "Coldgeist Badge", "TRADEITEM_Coldgeist Badge" }, { "Earthcore Badge", "TRADEITEM_Earthcore Badge" }, { "Windcore Badge", "TRADEITEM_Windcore Badge" }, { "Iron Cluster", "TRADEITEM_Iron Cluster" }, { "Copper Cluster", "TRADEITEM_Copper Cluster" }, { "Mithril Cluster", "TRADEITEM_Mithril Cluster" }, { "Dense Ingot", "TRADEITEM_Dense Ingot" }, { "Sapphite Ingot", "TRADEITEM_Sapphite Ingot" }, { "Amberite Ingot", "TRADEITEM_Amberite Ingot" }, { "Soul Pearl", "TRADEITEM_Soul Pearl" }, { "Experience Bond", "TRADEITEM_Experience Bond" }, { "Fishing Rod", "Fishing Rod" }, { "Pickaxe", "Pickaxe" }, { "Crypt Blade", "(lv-2) WEAPON_Crypt Blade (Sword, Strength)" }, { "Femur Club", "(lv-2) WEAPON_Femur Club (Sword, Strength)" }, { "Ironbark Sword", "(lv-2) WEAPON_Ironbark Sword (Sword, Strength)" }, { "Slimecrust Blade", "(lv-2) WEAPON_Slimecrust Blade (Sword, Strength)" }, { "Gilded Sword", "(lv-4) WEAPON_Gilded Sword (Sword, Strength)" }, { "Splitbark Club", "(lv-4) WEAPON_Splitbark Club (Sword, Strength)" }, { "Demicrypt Blade", "(lv-6) WEAPON_Demicrypt Blade (Sword, Strength)" }, { "Dense Mace", "(lv-6) WEAPON_Dense Mace (Sword, Strength)" }, { "Iron Sword", "(lv-6) WEAPON_Iron Sword (Sword, Strength)" }, { "Dawn Mace", "(lv-8) WEAPON_Dawn Mace (Sword, Strength)" }, { "Rude Blade", "(lv-8) WEAPON_Rude Blade (Sword, Strength)" }, { "Vile Blade", "(lv-8) WEAPON_Vile Blade (Sword, Strength)" }, { "Amberite Sword", "(lv-12) WEAPON_Amberite Sword (Sword, Strength)" }, { "Nethercrypt Blade", "(lv-12) WEAPON_Nethercrypt Blade (Sword, Strength)" }, { "Coldgeist Blade", "(lv-16) WEAPON_Coldgeist Blade (Sword, Strength)" }, { "Mithril Sword", "(lv-16) WEAPON_Mithril Sword (Sword, Strength)" }, { "Serrated Blade", "(lv-16) WEAPON_Serrated Blade (Sword, Strength)" }, { "Nulrok Mace", "(lv-20) WEAPON_Nulrok Mace (Sword, Strength)" }, { "Firebreath Blade", "(lv-22) WEAPON_Firebreath Blade (Sword, Strength)" }, { "Valdur Blade", "(lv-24) WEAPON_Valdur Blade (Sword, Strength)" }, { "Fier Blade", "(lv-26) WEAPON_Fier Blade (Sword, Strength)" }, { "Slimek Axehammer", "(lv-4) WEAPON_Slimek Axehammer (Hammer, Strength)" }, { "Dense Hammer", "(lv-6) WEAPON_Dense Hammer (Hammer, Strength)" }, { "Iron Axehammer", "(lv-6) WEAPON_Iron Axehammer (Hammer, Strength)" }, { "Crypt Pounder", "(lv-8) WEAPON_Crypt Pounder (Hammer, Strength)" }, { "Quake Pummeler", "(lv-18) WEAPON_Quake Pummeler (Hammer, Strength)" }, { "Mini Geist Scythe", "(lv-4) WEAPON_Mini Geist Scythe (Greatblade, Strength)" }, { "Geist Scythe", "(lv-6) WEAPON_Geist Scythe (Greatblade, Strength)" }, { "Stone Greatblade", "(lv-8) WEAPON_Stone Greatblade (Greatblade, Strength)" }, { "Amberite Warstar", "(lv-12) WEAPON_Amberite Warstar (Greatblade, Strength)" }, { "Dolkin's Axe", "(lv-12) WEAPON_Dolkin's Axe (Greatblade, Strength)" }, { "Poltergeist Scythe", "(lv-14) WEAPON_Poltergeist Scythe (Greatblade, Strength)" }, { "Coldgeist Punisher", "(lv-16) WEAPON_Coldgeist Punisher (Greatblade, Strength)" }, { "Deadwood Axe", "(lv-16) WEAPON_Deadwood Axe (Greatblade, Strength)" }, { "Mithril Greatsword", "(lv-16) WEAPON_Mithril Greatsword (Greatblade, Strength)" }, { "Deathknight Runeblade", "(lv-22) WEAPON_Deathknight Runeblade (Greatblade, Strength)" }, { "Ryzer Greataxe", "(lv-26) WEAPON_Ryzer Greataxe (Greatblade, Strength)" }, { "Dense Spear", "(lv-6) WEAPON_Dense Spear (Polearm, Strength)" }, { "Iron Spear", "(lv-6) WEAPON_Iron Spear (Polearm, Strength)" }, { "Cryptsinge Halberd", "(lv-8) WEAPON_Cryptsinge Halberd (Polearm, Strength)" }, { "Mekspear", "(lv-8) WEAPON_Mekspear (Polearm, Strength)" }, { "Amberite Halberd", "(lv-12) WEAPON_Amberite Halberd (Polearm, Strength)" }, { "Necroroyal Halberd", "(lv-12) WEAPON_Necroroyal Halberd (Polearm, Strength)" }, { "Sinner Bardiche", "(lv-12) WEAPON_Sinner Bardiche (Polearm, Strength)" }, { "Mithril Halberd", "(lv-16) WEAPON_Mithril Halberd (Polearm, Strength)" }, { "Ragespear", "(lv-16) WEAPON_Ragespear (Polearm, Strength)" }, { "Serrated Spear", "(lv-16) WEAPON_Serrated Spear (Polearm, Strength)" }, { "Sapphite Spear", "(lv-18) WEAPON_Sapphite Spear (Polearm, Strength)" }, { "Nulrok Spear", "(lv-20) WEAPON_Nulrok Spear (Polearm, Strength)" }, { "Cryotribe Spear", "(lv-22) WEAPON_Cryotribe Spear (Polearm, Strength)" }, { "Flametribe Spear", "(lv-22) WEAPON_Flametribe Spear (Polearm, Strength)" }, { "Marrow Bauble", "(lv-2) WEAPON_Marrow Bauble (Scepter, Mind)" }, { "Splitbark Scepter", "(lv-2) WEAPON_Splitbark Scepter (Scepter, Mind)" }, { "Demicrypt Bauble", "(lv-6) WEAPON_Demicrypt Bauble (Scepter, Mind)" }, { "Iron Scepter", "(lv-6) WEAPON_Iron Scepter (Scepter, Mind)" }, { "Cryo Cane", "(lv-8) WEAPON_Cryo Cane (Scepter, Mind)" }, { "Slime Diva Baton", "(lv-8) WEAPON_Slime Diva Baton (Scepter, Mind)" }, { "Pyre Cane", "(lv-12) WEAPON_Pyre Cane (Scepter, Mind)" }, { "Wizwand", "(lv-12) WEAPON_Wizwand (Scepter, Mind)" }, { "Nethercrypt Bauble", "(lv-14) WEAPON_Nethercrypt Bauble (Scepter, Mind)" }, { "Aquapetal Staff", "(lv-16) WEAPON_Aquapetal Staff (Scepter, Mind)" }, { "Flamepetal Staff", "(lv-16) WEAPON_Flamepetal Staff (Scepter, Mind)" }, { "Mithril Scepter", "(lv-16) WEAPON_Mithril Scepter (Scepter, Mind)" }, { "Sapphite Scepter", "(lv-18) WEAPON_Sapphite Scepter (Scepter, Mind)" }, { "Voalstark Wand", "(lv-24) WEAPON_Voalstark Wand (Scepter, Mind)" }, { "Cryptcall Bell", "(lv-8) WEAPON_Cryptcall Bell (Magic Bell, Mind)" }, { "Iron Bell", "(lv-8) WEAPON_Iron Bell (Magic Bell, Mind)" }, { "Coldgeist Frostcaller", "(lv-16) WEAPON_Coldgeist Frostcaller (Magic Bell, Mind)" }, { "Mithril Bell", "(lv-16) WEAPON_Mithril Bell (Magic Bell, Mind)" }, { "Colossus Tone", "(lv-18) WEAPON_Colossus Tone (Magic Bell, Mind)" }, { "Sapphite Bell", "(lv-18) WEAPON_Sapphite Bell (Magic Bell, Mind)" }, { "Slimecrust Katars", "(lv-2) WEAPON_Slimecrust Katars (Katars, Dexterity)" }, { "Cryptsinge Katars", "(lv-4) WEAPON_Cryptsinge Katars (Katars, Dexterity)" }, { "Slimek Shivs", "(lv-4) WEAPON_Slimek Shivs (Katars, Dexterity)" }, { "Deathgel Shivs", "(lv-6) WEAPON_Deathgel Shivs (Katars, Dexterity)" }, { "Dense Katars", "(lv-6) WEAPON_Dense Katars (Katars, Dexterity)" }, { "Iron Katars", "(lv-8) WEAPON_Iron Katars (Katars, Dexterity)" }, { "Runic Katars", "(lv-10) WEAPON_Runic Katars (Katars, Dexterity)" }, { "Geistlord Claws", "(lv-12) WEAPON_Geistlord Claws (Katars, Dexterity)" }, { "Hellsludge Shivs", "(lv-14) WEAPON_Hellsludge Shivs (Katars, Dexterity)" }, { "Mithril Katars", "(lv-14) WEAPON_Mithril Katars (Katars, Dexterity)" }, { "Frostbite Claws", "(lv-16) WEAPON_Frostbite Claws (Katars, Dexterity)" }, { "Serrated Knuckles", "(lv-16) WEAPON_Serrated Knuckles (Katars, Dexterity)" }, { "Rummok Bladerings", "(lv-18) WEAPON_Rummok Bladerings (Katars, Dexterity)" }, { "Sapphite Katars", "(lv-18) WEAPON_Sapphite Katars (Katars, Dexterity)" }, { "Golemfist Katars", "(lv-20) WEAPON_Golemfist Katars (Katars, Dexterity)" }, { "Crypt Bow", "(lv-2) WEAPON_Crypt Bow (Bow, Dexterity)" }, { "Demicrypt Bow", "(lv-6) WEAPON_Demicrypt Bow (Bow, Dexterity)" }, { "Iron Bow", "(lv-6) WEAPON_Iron Bow (Bow, Dexterity)" }, { "Mekspike Bow", "(lv-8) WEAPON_Mekspike Bow (Bow, Dexterity)" }, { "Menace Bow", "(lv-8) WEAPON_Menace Bow (Bow, Dexterity)" }, { "Petrified Bow", "(lv-12) WEAPON_Petrified Bow (Bow, Dexterity)" }, { "Mithril Bow", "(lv-14) WEAPON_Mithril Bow (Bow, Dexterity)" }, { "Necroroyal Bow", "(lv-14) WEAPON_Necroroyal Bow (Bow, Dexterity)" }, { "Coldgeist Bow", "(lv-16) WEAPON_Coldgeist Bow (Bow, Dexterity)" }, { "Serrated Longbow", "(lv-16) WEAPON_Serrated Longbow (Bow, Dexterity)" }, { "Torrentius Longbow", "(lv-24) WEAPON_Torrentius Longbow (Bow, Dexterity)" }, { "Amberite Boomstick", "(lv-12) WEAPON_Amberite Boomstick (Shotgun, Dexterity)" }, { "Magitek Burstgun", "(lv-20) WEAPON_Magitek Burstgun (Shotgun, Dexterity)" }, { "Follycannon", "(lv-26) WEAPON_Follycannon (Shotgun, Dexterity)" }, { "Agility Ears", "(lv-1) HELM_Agility Ears" }, { "Festive Hat", "(lv-1) HELM_Festive Hat" }, { "Fishin Hat", "(lv-1) HELM_Fishin Hat" }, { "Leather Cap", "(lv-1) HELM_Leather Cap" }, { "Newfold Halo", "(lv-1) HELM_Newfold Halo" }, { "Orefinder Hat", "(lv-1) HELM_Orefinder Hat" }, { "Spooky Hat", "(lv-1) HELM_Spooky Hat" }, { "Top Hat", "(lv-1) HELM_Top Hat" }, { "Wizard Hat", "(lv-1) HELM_Wizard Hat" }, { "Acolyte Hood", "(lv-4) HELM_Acolyte Hood" }, { "Cryptsinge Halo", "(lv-4) HELM_Cryptsinge Halo" }, { "Initiate Spectacles", "(lv-4) HELM_Initiate Spectacles" }, { "Demicrypt Halo", "(lv-6) HELM_Demicrypt Halo" }, { "Dense Helm", "(lv-6) HELM_Dense Helm" }, { "Diva Crown", "(lv-6) HELM_Diva Crown" }, { "Iron Halo", "(lv-6) HELM_Iron Halo" }, { "Necromancer Hood", "(lv-8) HELM_Necromancer Hood" }, { "Geistlord Crown", "(lv-10) HELM_Geistlord Crown" }, { "Journeyman Spectacles", "(lv-10) HELM_Journeyman Spectacles" }, { "Amberite Helm", "(lv-12) HELM_Amberite Helm" }, { "Focus Circlet", "(lv-12) HELM_Focus Circlet" }, { "Magistrate Circlet", "(lv-12) HELM_Magistrate Circlet" }, { "Rage Circlet", "(lv-12) HELM_Rage Circlet" }, { "Focusi Glasses", "(lv-14) HELM_Focusi Glasses" }, { "Nethercrypt Halo", "(lv-14) HELM_Nethercrypt Halo" }, { "Carbuncle Hat", "(lv-16) HELM_Carbuncle Hat" }, { "Geistlord Eye", "(lv-16) HELM_Geistlord Eye" }, { "Glyphgrift Halo", "(lv-16) HELM_Glyphgrift Halo" }, { "Jestercast Memory", "(lv-16) HELM_Jestercast Memory" }, { "Knightguard Halo", "(lv-16) HELM_Knightguard Halo" }, { "Mithril Halo", "(lv-16) HELM_Mithril Halo" }, { "Sapphite Mindhat", "(lv-18) HELM_Sapphite Mindhat" }, { "Dire Helm", "(lv-22) HELM_Dire Helm" }, { "Druidic Halo", "(lv-22) HELM_Druidic Halo" }, { "Guardel Helm", "(lv-22) HELM_Guardel Helm" }, { "Leathen Cap", "(lv-22) HELM_Leathen Cap" }, { "Boarus Helm", "(lv-24) HELM_Boarus Helm" }, { "Deathknight Helm", "(lv-24) HELM_Deathknight Helm" }, { "Emerock Halo", "(lv-24) HELM_Emerock Halo" }, { "Wizlad Hood", "(lv-24) HELM_Wizlad Hood" }, { "Boarus Torment", "(lv-26) HELM_Boarus Torment" }, { "Initiate Cloak", "(lv-2) CAPE_Initiate Cloak" }, { "Slimewoven Cloak", "(lv-4) CAPE_Slimewoven Cloak" }, { "Nokket Cloak", "(lv-6) CAPE_Nokket Cloak" }, { "Rugged Cloak", "(lv-6) CAPE_Rugged Cloak" }, { "Regazuul Cape", "(lv-10) CAPE_Regazuul Cape" }, { "Flux Cloak", "(lv-12) CAPE_Flux Cloak" }, { "Cozy Cloak", "(lv-14) CAPE_Cozy Cloak" }, { "Nethercrypt Cloak", "(lv-14) CAPE_Nethercrypt Cloak" }, { "Cobblerage Cloak", "(lv-16) CAPE_Cobblerage Cloak" }, { "Deathward Cape", "(lv-16) CAPE_Deathward Cape" }, { "Forlorn Cloak", "(lv-16) CAPE_Forlorn Cloak" }, { "Meshlink Cape", "(lv-16) CAPE_Meshlink Cape" }, { "Sagecaller Cape", "(lv-16) CAPE_Sagecaller Cape" }, { "Roudon Cape", "(lv-18) CAPE_Roudon Cape" }, { "Blueversa Cape", "(lv-20) CAPE_Blueversa Cape" }, { "Greenversa Cape", "(lv-20) CAPE_Greenversa Cape" }, { "Nulversa Cape", "(lv-20) CAPE_Nulversa Cape" }, { "Redversa Cape", "(lv-20) CAPE_Redversa Cape" }, { "Windgolem Cloak", "(lv-22) CAPE_Windgolem Cloak" }, { "Mekwar Drape", "(lv-24) CAPE_Mekwar Drape" }, { "Aero Top", "(lv-1) CHESTPIECE_Aero Top" }, { "Bunhost Garb", "(lv-1) CHESTPIECE_Bunhost Garb" }, { "Festive Coat", "(lv-1) CHESTPIECE_Festive Coat" }, { "Fisher Overalls", "(lv-1) CHESTPIECE_Fisher Overalls" }, { "Leather Top", "(lv-1) CHESTPIECE_Leather Top" }, { "Necro Marrow", "(lv-1) CHESTPIECE_Necro Marrow" }, { "Noble Shirt", "(lv-1) CHESTPIECE_Noble Shirt" }, { "Nutso Top", "(lv-1) CHESTPIECE_Nutso Top" }, { "Orefinder Vest", "(lv-1) CHESTPIECE_Orefinder Vest" }, { "Ritualist Garb", "(lv-1) CHESTPIECE_Ritualist Garb" }, { "Sagecloth Top", "(lv-1) CHESTPIECE_Sagecloth Top" }, { "Silken Top", "(lv-1) CHESTPIECE_Silken Top" }, { "Spooky Garment", "(lv-1) CHESTPIECE_Spooky Garment" }, { "Vampiric Coat", "(lv-1) CHESTPIECE_Vampiric Coat" }, { "Ghostly Tabard", "(lv-2) CHESTPIECE_Ghostly Tabard" }, { "Poacher Cloth", "(lv-2) CHESTPIECE_Poacher Cloth" }, { "Ragged Shirt", "(lv-2) CHESTPIECE_Ragged Shirt" }, { "Slimecrust Chest", "(lv-2) CHESTPIECE_Slimecrust Chest" }, { "Worn Robe", "(lv-2) CHESTPIECE_Worn Robe" }, { "Cryptsinge Chest", "(lv-4) CHESTPIECE_Cryptsinge Chest" }, { "Journeyman Vest", "(lv-4) CHESTPIECE_Journeyman Vest" }, { "Slimek Chest", "(lv-4) CHESTPIECE_Slimek Chest" }, { "Dense Chestpiece", "(lv-6) CHESTPIECE_Dense Chestpiece" }, { "Trodd Tunic", "(lv-6) CHESTPIECE_Trodd Tunic" }, { "Iron Chestpiece", "(lv-7) CHESTPIECE_Iron Chestpiece" }, { "Tattered Battlerobe", "(lv-8) CHESTPIECE_Tattered Battlerobe" }, { "Apprentice Robe", "(lv-10) CHESTPIECE_Apprentice Robe" }, { "Duelist Garb", "(lv-10) CHESTPIECE_Duelist Garb" }, { "Skywrill Tabard", "(lv-10) CHESTPIECE_Skywrill Tabard" }, { "Sleeper's Robe", "(lv-10) CHESTPIECE_Sleeper's Robe" }, { "Warrior Chest", "(lv-10) CHESTPIECE_Warrior Chest" }, { "Amberite Breastplate", "(lv-12) CHESTPIECE_Amberite Breastplate" }, { "Golem Chestpiece", "(lv-12) CHESTPIECE_Golem Chestpiece" }, { "Lord Breastplate", "(lv-12) CHESTPIECE_Lord Breastplate" }, { "Nethercrypt Tabard", "(lv-12) CHESTPIECE_Nethercrypt Tabard" }, { "Reapsow Garb", "(lv-12) CHESTPIECE_Reapsow Garb" }, { "Witchlock Robe", "(lv-12) CHESTPIECE_Witchlock Robe" }, { "Chainmail Guard", "(lv-14) CHESTPIECE_Chainmail Guard" }, { "Ornamented Battlerobe", "(lv-14) CHESTPIECE_Ornamented Battlerobe" }, { "Carbuncle Robe", "(lv-16) CHESTPIECE_Carbuncle Robe" }, { "Chainscale Chest", "(lv-16) CHESTPIECE_Chainscale Chest" }, { "Gemveil Raiment", "(lv-16) CHESTPIECE_Gemveil Raiment" }, { "King Breastplate", "(lv-16) CHESTPIECE_King Breastplate" }, { "Mercenary Vestment", "(lv-16) CHESTPIECE_Mercenary Vestment" }, { "Mithril Chestpiece", "(lv-16) CHESTPIECE_Mithril Chestpiece" }, { "Reaper Gi", "(lv-16) CHESTPIECE_Reaper Gi" }, { "Witchwizard Robe", "(lv-16) CHESTPIECE_Witchwizard Robe" }, { "Berserker Chestpiece", "(lv-18) CHESTPIECE_Berserker Chestpiece" }, { "Fuguefall Duster", "(lv-18) CHESTPIECE_Fuguefall Duster" }, { "Magilord Overalls", "(lv-18) CHESTPIECE_Magilord Overalls" }, { "Monolith Chestpiece", "(lv-18) CHESTPIECE_Monolith Chestpiece" }, { "Sapphite Guard", "(lv-18) CHESTPIECE_Sapphite Guard" }, { "Druidic Robe", "(lv-20) CHESTPIECE_Druidic Robe" }, { "Emerock Chestpiece", "(lv-20) CHESTPIECE_Emerock Chestpiece" }, { "Fortified Vestment", "(lv-20) CHESTPIECE_Fortified Vestment" }, { "Roudon Chestpiece", "(lv-20) CHESTPIECE_Roudon Chestpiece" }, { "Earthbind Tabard", "(lv-22) CHESTPIECE_Earthbind Tabard" }, { "Gemveil Breastplate", "(lv-22) CHESTPIECE_Gemveil Breastplate" }, { "Roudon Robe", "(lv-22) CHESTPIECE_Roudon Robe" }, { "Ruggrok Vest", "(lv-22) CHESTPIECE_Ruggrok Vest" }, { "Executioner Vestment", "(lv-24) CHESTPIECE_Executioner Vestment" }, { "Fender Garb", "(lv-24) CHESTPIECE_Fender Garb" }, { "Wizlad Robe", "(lv-24) CHESTPIECE_Wizlad Robe" }, { "Aero Pants", "(lv-1) LEGGINGS_Aero Pants" }, { "Bunhost Leggings", "(lv-1) LEGGINGS_Bunhost Leggings" }, { "Festive Trousers", "(lv-1) LEGGINGS_Festive Trousers" }, { "Leather Britches", "(lv-1) LEGGINGS_Leather Britches" }, { "Necro Caustics", "(lv-1) LEGGINGS_Necro Caustics" }, { "Noble Pants", "(lv-1) LEGGINGS_Noble Pants" }, { "Nutso Pants", "(lv-1) LEGGINGS_Nutso Pants" }, { "Orefinder", "(lv-1) LEGGINGS_Orefinder Trousers" }, { "Ritualist Straps", "(lv-1) LEGGINGS_Ritualist Straps" }, { "Sagecloth Shorts", "(lv-1) LEGGINGS_Sagecloth Shorts" }, { "Silken Loincloth", "(lv-1) LEGGINGS_Silken Loincloth" }, { "Vampiric Leggings", "(lv-1) LEGGINGS_Vampiric Leggings" }, { "Ghostly Legwraps", "(lv-2) LEGGINGS_Ghostly Legwraps" }, { "Journeyman Shorts", "(lv-2) LEGGINGS_Journeyman Shorts" }, { "Slimecrust Leggings", "(lv-2) LEGGINGS_Slimecrust Leggings" }, { "Journeyman Leggings", "(lv-4) LEGGINGS_Journeyman Leggings" }, { "Slimek Leggings", "(lv-4) LEGGINGS_Slimek Leggings" }, { "Dense Leggings", "(lv-6) LEGGINGS_Dense Leggings" }, { "Sash Leggings", "(lv-8) LEGGINGS_Sash Leggings" }, { "Warrior Leggings", "(lv-10) LEGGINGS_Warrior Leggings" }, { "Amberite Leggings", "(lv-12) LEGGINGS_Amberite Leggings" }, { "Chainmail Leggings", "(lv-12) LEGGINGS_Chainmail Leggings" }, { "Darkcloth Pants", "(lv-12) LEGGINGS_Darkcloth Pants" }, { "Lord Greaves", "(lv-12) LEGGINGS_Lord Greaves" }, { "Reapsow Pants", "(lv-12) LEGGINGS_Reapsow Pants" }, { "Witchlock Loincloth", "(lv-12) LEGGINGS_Witchlock Loincloth" }, { "King Greaves", "(lv-16) LEGGINGS_King Greaves" }, { "Mercenary Leggings", "(lv-16) LEGGINGS_Mercenary Leggings" }, { "Reaper Leggings", "(lv-16) LEGGINGS_Reaper Leggings" }, { "Stridebond Pants", "(lv-16) LEGGINGS_Stridebond Pants" }, { "Witchwizard Garterbelt", "(lv-16) LEGGINGS_Witchwizard Garterbelt" }, { "Berserker Leggings", "(lv-18) LEGGINGS_Berserker Leggings" }, { "Fuguefall Pants", "(lv-18) LEGGINGS_Fuguefall Pants" }, { "Magilord Boots", "(lv-18) LEGGINGS_Magilord Boots" }, { "Sapphite Leggings", "(lv-18) LEGGINGS_Sapphite Leggings" }, { "Jadewail Trousers", "(lv-20) LEGGINGS_Jadewail Trousers" }, { "Temrak Britches", "(lv-20) LEGGINGS_Temrak Britches" }, { "Eschek Greaves", "(lv-22) LEGGINGS_Eschek Greaves" }, { "Gemveil Leggings", "(lv-22) LEGGINGS_Gemveil Leggings" }, { "Executioner Leggings", "(lv-24) LEGGINGS_Executioner Leggings" }, { "Fender Leggings", "(lv-24) LEGGINGS_Fender Leggings" }, { "Wooden Shield", "(lv-1) SHIELD_Wooden Shield" }, { "Crypt Buckler", "(lv-4) SHIELD_Crypt Buckler" }, { "Slimek Shield", "(lv-4) SHIELD_Slimek Shield" }, { "Demicrypt Buckler", "(lv-6) SHIELD_Demicrypt Buckler" }, { "Dense Shield", "(lv-6) SHIELD_Dense Shield" }, { "Iron Shield", "(lv-6) SHIELD_Iron Shield" }, { "Iris Shield", "(lv-8) SHIELD_Iris Shield" }, { "Omen Shield", "(lv-8) SHIELD_Omen Shield" }, { "Amberite Shield", "(lv-12) SHIELD_Amberite Shield" }, { "Slabton Shield", "(lv-12) SHIELD_Slabton Shield" }, { "Mithril Shield", "(lv-14) SHIELD_Mithril Shield" }, { "Nethercrypt Shield", "(lv-14) SHIELD_Nethercrypt Shield" }, { "Rustweary Shield", "(lv-16) SHIELD_Rustweary Shield" }, { "Rustwise Shield", "(lv-16) SHIELD_Rustwise Shield" }, { "Sapphite Shield", "(lv-18) SHIELD_Sapphite Shield" }, { "Rigor Buckler", "(lv-20) SHIELD_Rigor Buckler" }, { "Daemon Shield", "(lv-22) SHIELD_Daemon Shield" }, { "Irisun Shield", "(lv-22) SHIELD_Irisun Shield" }, { "Old Ring", "(lv-1) RING_Old Ring" }, { "Ring Of Ambition", "(lv-1) RING_Ring Of Ambition" }, { "Nograd's Amulet", "(lv-2) RING_Nograd's Amulet" }, { "The One Ring", "(lv-2) RING_The One Ring" }, { "Ambersquire Ring", "(lv-6) RING_Ambersquire Ring" }, { "Emeraldfocus Ring", "(lv-6) RING_Emeraldfocus Ring" }, { "Sapphireweave Ring", "(lv-6) RING_Sapphireweave Ring" }, { "Edon's Pendant", "(lv-8) RING_Edon's Pendant" }, { "Geistlord Ring", "(lv-12) RING_Geistlord Ring" }, { "Students Ring", "(lv-12) RING_Students Ring" }, { "Pearlpond Ring", "(lv-14) RING_Pearlpond Ring" }, { "Slitherwraith Ring", "(lv-14) RING_Slitherwraith Ring" }, { "Geistlord Band", "(lv-16) RING_Geistlord Band" }, { "Jadetrout Ring", "(lv-16) RING_Jadetrout Ring" }, { "Orbos Ring", "(lv-16) RING_Orbos Ring" }, { "Valor Ring", "(lv-16) RING_Valor Ring" }, { "Earthwoken Ring", "(lv-18) RING_Earthwoken Ring" }, { "Noji Talisman", "(lv-20) RING_Noji Talisman" }, { "Valdur Effigy", "(lv-24) RING_Valdur Effigy" }, { "Glyphik Booklet", "(lv-26) RING_Glyphik Booklet" }, { "Tessellated Drive", "(lv-26) RING_Tessellated Drive" }, { "Aqua Muchroom Cap", "TRADEITEM_Aqua Muchroom Cap" }, { "Barknaught Face", "TRADEITEM_Barknaught Face" }, { "Blightwood Log", "TRADEITEM_Blightwood Log" }, { "Blightwood Stick", "TRADEITEM_Blightwood Stick" }, { "Blue Minchroom Cap", "TRADEITEM_Blue Minchroom Cap" }, { "Boomboar Gear", "TRADEITEM_Boomboar Gear" }, { "Boomboar Head", "TRADEITEM_Boomboar Head" }, { "Boomboar Pouch", "TRADEITEM_Boomboar Pouch" }, { "Burnrose", "TRADEITEM_Burnrose" }, { "Carbuncle Foot", "TRADEITEM_Carbuncle Foot" }, { "Cursed Note", "TRADEITEM_Cursed Note" }, { "Deadwood Log", "TRADEITEM_Deadwood Log" }, { "Deathgel Core", "TRADEITEM_Deathgel Core" }, { "Deathknight Gauntlet", "TRADEITEM_Deathknight Gauntlet" }, { "Demigolem Core", "TRADEITEM_Demigolem Core" }, { "Demigolem Gem", "TRADEITEM_Demigolem Gem" }, { "Diva Necklace", "TRADEITEM_Diva Necklace" }, { "Firebreath Gland", "TRADEITEM_Firebreath Gland" }, { "Fluxfern", "TRADEITEM_Fluxfern" }, { "Gale Muchroom Cap", "TRADEITEM_Gale Muchroom Cap" }, { "Geist Collar", "TRADEITEM_Geist Collar" }, { "Ghostdust", "TRADEITEM_Ghostdust" }, { "Golem Core", "TRADEITEM_Golem Core" }, { "Golem Gem", "TRADEITEM_Golem Gem" }, { "Green Lipstick", "TRADEITEM_Green Lipstick" }, { "Hellsludge Core", "TRADEITEM_Hellsludge Core" }, { "Maw Eye", "TRADEITEM_Maw Eye" }, { "Mekboar Head", "TRADEITEM_Mekboar Head" }, { "Mekboar Spear", "TRADEITEM_Mekboar Spear" }, { "Monolith Core", "TRADEITEM_Monolith Core" }, { "Monolith Gem", "TRADEITEM_Monolith Gem" }, { "Mouth Bittertooth", "TRADEITEM_Mouth Bittertooth" }, { "Mouth Eye", "TRADEITEM_Mouth Eye" }, { "Rageboar Head", "TRADEITEM_Rageboar Head" }, { "Rageboar Spear", "TRADEITEM_Rageboar Spear" }, { "Red Minchroom Cap", "TRADEITEM_Red Minchroom Cap" }, { "Rock", "TRADEITEM_Rock" }, { "Slime Core", "TRADEITEM_Slime Core" }, { "Slime Diva Ears", "TRADEITEM_Slime Diva Ears" }, { "Slime Ears", "TRADEITEM_Slime Ears" }, { "Slimek Core", "TRADEITEM_Slimek Core" }, { "Slimek Ears", "TRADEITEM_Slimek Ears" }, { "Slimek Eye", "TRADEITEM_Slimek Eye" }, { "Vinethorn", "TRADEITEM_Vinethorn" }, { "Vout Antennae", "TRADEITEM_Vout Antennae" }, { "Vout Wing", "TRADEITEM_Vout Wing" }, { "Warboar Axe", "TRADEITEM_Warboar Axe" }, { "Warboar Head", "TRADEITEM_Warboar Head" }, { "Wizboar Head", "TRADEITEM_Wizboar Head" }, { "Wizboar Scepter", "TRADEITEM_Wizboar Scepter" }, { "Amberite Ore", "TRADEITEM_Amberite Ore" }, { "Dense Ore", "TRADEITEM_Dense Ore" }, { "Sapphite Ore", "TRADEITEM_Sapphite Ore" }, { "Coal", "TRADEITEM_Coal" }, { "Big Wan", "TRADEITEM_Big Wan" }, { "Bittering Katfish", "TRADEITEM_Bittering Katfish" }, { "Bonefish", "TRADEITEM_Bonefish" }, { "Smiling Wrellfish", "TRADEITEM_Smiling Wrellfish" }, { "Squangfish", "TRADEITEM_Squangfish" }, { "Sugeel", "TRADEITEM_Sugeel" }, { "Sugshrimp", "TRADEITEM_Sugshrimp" }, { "Windtail Fish", "TRADEITEM_Windtail Fish" }, { "Old Boot", "TRADEITEM_Old Boot" }, { "Agility Stone", "TRADEITEM_Agility Stone" }, { "Angela's Tear", "TRADEITEM_Angela's Tear" }, { "Epic Carrot", "TRADEITEM_Epic Carrot" }, { "Flux Stone", "TRADEITEM_Flux Stone" }, { "Illusion Stone", "TRADEITEM_Illusion Stone" }, { "Might Stone", "TRADEITEM_Might Stone" }, { "Starlight Gem", "TRADEITEM_Starlight Gem" }, { "Black Dye", "TRADEITEM_Black Dye" }, { "Blue Dye", "TRADEITEM_Blue Dye" }, { "Brown Dye", "TRADEITEM_Brown Dye" }, { "Cyan Dye", "TRADEITEM_Cyan Dye" }, { "Green Dye", "TRADEITEM_Green Dye" }, { "Grey Dye", "TRADEITEM_Grey Dye" }, { "Lime Dye", "TRADEITEM_Lime Dye" }, { "Orange Dye", "TRADEITEM_Orange Dye" }, { "Pink Dye", "TRADEITEM_Pink Dye" }, { "Purple Dye", "TRADEITEM_Purple Dye" }, { "Red Dye", "TRADEITEM_Red Dye" }, { "White Dye", "TRADEITEM_White Dye" }, { "Yellow Dye", "TRADEITEM_Yellow Dye" }, { "Crowns (Small)", "CURRENCY_250" }, { "Crowns (Medium)", "CURRENCY_500" }, { "Crowns (Large)", "CURRENCY_1000" }, { "Crowns (Huge)", "CURRENCY_2500" }, { "Tome of Naivety", "(lv-0) STATUSCONSUMABLE_Tome of Naivety" }, { "Tome of Unlearning", "(lv-0) STATUSCONSUMABLE_Tome of Unlearning" } }; public static readonly Dictionary<string, List<List<string>>> ProgressiveItemTiers = new Dictionary<string, List<List<string>>> { { "Progressive Any Weapon", new List<List<string>> { new List<string> { "Crypt Buckler", "Slimek Shield" }, new List<string> { "Demicrypt Buckler", "Dense Shield", "Iron Shield" }, new List<string> { "Iris Shield", "Omen Shield", "Rustweary Shield", "Rustwise Shield" }, new List<string> { "Amberite Shield", "Slabton Shield", "Mithril Shield", "Nethercrypt Shield" }, new List<string> { "Rigor Buckler", "Sapphite Shield", "Daemon Shield", "Irisun Shield" } } }, { "Progressive Any Helmet", new List<List<string>> { new List<string> { "Agility Ears", "Leather Cap", "Newfold Halo" }, new List<string> { "Acolyte Hood", "Cryptsinge Halo", "Initiate Spectacles", "Demicrypt Halo", "Dense Helm", "Diva Crown" }, new List<string> { "Iron Halo", "Necromancer Hood", "Journeyman Spectacles" }, new List<string> { "Geistlord Crown", "Geistlord Eye", "Amberite Helm", "Focus Circlet", "Magistrate Circlet", "Rage Circlet", "Focusi Glasses", "Nethercrypt Halo" }, new List<string> { "Carbuncle Hat", "Glyphgrift Halo", "Jestercast Memory", "Knightguard Halo", "Mithril Halo", "Wizlad Hood", "Dire Helm", "Druidic Halo", "Guardel Helm", "Leathen Cap" }, new List<string> { "Sapphite Mindhat", "Boarus Helm", "Deathknight Helm", "Emerock Halo", "Boarus Torment" } } }, { "Progressive Any Cape", new List<List<string>> { new List<string> { "Initiate Cloak", "Slimewoven Cloak", "Nokket Cloak", "Rugged Cloak" }, new List<string> { "Cobblerage Cloak", "Forlorn Cloak", "Flux Cloak", "Meshlink Cape", "Cozy Cloak", "Nethercrypt Cloak" }, new List<string> { "Regazuul Cape", "Deathward Cape", "Sagecaller Cape" }, new List<string> { "Windgolem Cloak", "Roudon Cape", "Blueversa Cape", "Greenversa Cape", "Nulversa Cape", "Redversa Cape" }, new List<string> { "Mekwar Drape" } } }, { "Progressive Any Chest Piece", new List<List<string>> { new List<string> { "Aero Top", "Leather Top", "Necro Marrow", "Nutso Top", "Sagecloth Top", "Ghostly Tabard", "Poacher Cloth", "Ragged Shirt", "Slimecrust Chest", "Worn Robe" }, new List<string> { "Cryptsinge Chest", "Journeyman Vest", "Slimek Chest", "Apprentice Robe", "Dense Chestpiece", "Trodd Tunic", "Tattered Battlerobe" }, new List<string> { "Iron Chestpiece", "Duelist Garb", "Amberite Breastplate", "Nethercrypt Tabard", "Chainmail Guard", "Skywrill Tabard", "Sleeper's Robe", "Warrior Chest", "Golem Chestpiece", "Carbuncle Robe" }, new List<string> { "Ornamented Battlerobe", "Chainscale Chest", "Mercenary Vestment", "Mithril Chestpiece", "Druidic Robe" }, new List<string> { "Gemveil Raiment", "Monolith Chestpiece", "Sapphite Guard", "Fortified Vestment", "Roudon Chestpiece", "Roudon Robe", "Earthbind Tabard", "Gemveil Breastplate", "Ruggrok Vest", "Emerock Chestpiece" } } }, { "Progressive Any Leggings", new List<List<string>> { new List<string> { "Aero Pants", "Leather Britches", "Necro Caustics", "Nutso Pants", "Sagecloth Shorts", "Ghostly Legwraps", "Slimecrust Leggings" }, new List<string> { "Journeyman Shorts", "Journeyman Leggings", "Slimek Leggings", "Dense Leggings", "Sash Leggings" }, new List<string> { "Amberite Leggings", "Chainmail Leggings", "Darkcloth Pants", "Warrior Leggings" }, new List<string> { "Mercenary Leggings", "Stridebond Pants" }, new List<string> { "Sapphite Leggings", "Jadewail Trousers", "Temrak Britches", "Eschek Greaves", "Gemveil Leggings" } } }, { "Progressive Any Trinket", new List<List<string>> { new List<string> { "Nograd's Amulet", "Old Ring", "Ring Of Ambition", "The One Ring" }, new List<string> { "Nograd's Amulet", "Students Ring" }, new List<string> { "The One Ring", "Geistlord Ring", "Geistlord Band" }, new List<string> { "Ambersquire Ring", "Emeraldfocus Ring", "Pearlpond Ring", "Slitherwraith Ring", "Jadetrout Ring" }, new List<string> { "Sapphireweave Ring", "Edon's Pendant", "Orbos Ring", "Valor Ring" }, new List<string> { "Earthwoken Ring", "Noji Talisman", "Valdur Effigy", "Glyphik Booklet", "Tessellated Drive" } } }, { "Progressive Fighter Weapon", new List<List<string>> { new List<string> { "Crypt Blade", "Femur Club", "Ironbark Sword", "Slimecrust Blade", "Gilded Sword", "Splitbark Club", "Slimek Axehammer", "Mini Geist Scythe", "Geist Scythe" }, new List<string> { "Demicrypt Blade", "Dense Mace", "Iron Sword", "Dense Hammer", "Iron Axehammer", "Crypt Pounder", "Stone Greatblade", "Dense Spear", "Iron Spear", "Cryptsinge Halberd", "Dawn Mace", "Rude Blade" }, new List<string> { "Vile Blade", "Poltergeist Scythe", "Mekspear", "Amberite Sword", "Nethercrypt Blade", "Amberite Warstar", "Dolkin's Axe", "Amberite Halberd", "Necroroyal Halberd", "Sinner Bardiche" }, new List<string> { "Coldgeist Blade", "Mithril Sword", "Serrated Blade", "Mithril Halberd", "Ragespear", "Serrated Spear" }, new List<string> { "Nulrok Mace", "Coldgeist Punisher", "Nulrok Spear", "Firebreath Blade", "Quake Pummeler", "Deadwood Axe", "Mithril Greatsword", "Sapphite Spear", "Valdur Blade", "Deathknight Runeblade", "Cryotribe Spear", "Flametribe Spear" }, new List<string> { "Fier Blade", "Ryzer Greataxe" } } }, { "Progressive Fighter Chest Piece", new List<List<string>> { new List<string> { "Lord Breastplate" }, new List<string> { "King Breastplate", "Berserker Chestpiece" }, new List<string> { "Executioner Vestment" } } }, { "Progressive Fighter Leggings", new List<List<string>> { new List<string> { "Lord Greaves" }, new List<string> { "King Greaves", "Berserker Leggings" }, new List<string> { "Executioner Leggings" } } }, { "Progressive Mystic Weapon", new List<List<string>> { new List<string> { "Marrow Bauble", "Splitbark Scepter", "Demicrypt Bauble", "Cryptcall Bell" }, new List<string> { "Iron Scepter", "Cryo Cane", "Slime Diva Baton", "Iron Bell" }, new List<string> { "Pyre Cane", "Wizwand", "Nethercrypt Bauble", "Aquapetal Staff", "Flamepetal Staff", "Coldgeist Frostcaller" }, new List<string> { "Mithril Scepter", "Mithril Bell" }, new List<string> { "Sapphite Scepter", "Colossus Tone", "Voalstark Wand", "Sapphite Bell" } } }, { "Progressive Mystic Helmet", new List<List<string>> { new List<string> { "Wizlad Hood" } } }, { "Progressive Mystic Chest Piece", new List<List<string>> { new List<string> { "Witchlock Robe" }, new List<string> { "Witchwizard Robe", "Magilord Overalls" }, new List<string> { "Wizlad Robe" } } }, { "Progressive Mystic Leggings", new List<List<string>> { new List<string> { "Witchlock Loincloth" }, new List<string> { "Witchwizard Garterbelt", "Magilord Boots" } } }, { "Progressive Bandit Weapon", new List<List<string>> { new List<string> { "Slimecrust Katars", "Cryptsinge Katars", "Slimek Shivs", "Crypt Bow" }, new List<string> { "Deathgel Shivs", "Dense Katars", "Iron Katars", "Runic Katars", "Demicrypt Bow", "Iron Bow", "Mekspike Bow", "Menace Bow" }, new List<string> { "Geistlord Claws", "Hellsludge Shivs", "Petrified Bow", "Necroroyal Bow" }, new List<string> { "Mithril Katars", "Frostbite Claws", "Serrated Knuckles", "Mithril Bow", "Coldgeist Bow", "Serrated Longbow", "Amberite Boomstick" }, new List<string> { "Rummok Bladerings", "Sapphite Katars", "Golemfist Katars", "Torrentius Longbow", "Magitek Burstgun" }, new List<string> { "Follycannon" } } }, { "Progressive Bandit Chest Piece", new List<List<string>> { new List<string> { "Reapsow Garb" }, new List<string> { "Reaper Gi", "Fuguefall Duster" }, new List<string> { "Fender Garb" } } }, { "Progressive Bandit Leggings", new List<List<string>> { new List<string> { "Reapsow Pants" }, new List<string> { "Reaper Leggings", "Fuguefall Pants" }, new List<string> { "Fender Leggings" } } } }; public static ProgressivePortalRequirement GetProgressivePortalRequirement(string portalKey) { if (PortalProgressiveRequirements.TryGetValue(portalKey, out var value)) { return value; } return new ProgressivePortalRequirement(0, 0); } public static bool IsProgressivePortalItem(string itemName) { if (!(itemName == "Progressive Sanctum Portal")) { return itemName == "Progressive Tuul Portal"; } return true; } internal static bool IsApQuestFinished(Func<string, bool> hasFinishedQuest, string apQuestName) { if (hasFinishedQuest(apQuestName)) { return true; } if (!ApQuestVanillaCompletionNames.TryGetValue(apQuestName, out string[] value)) { return false; } string[] array = value; foreach (string arg in array) { if (hasFinishedQuest(arg)) { return true; } } return false; } internal static bool IsApQuestFinishedInProfileJson(string finishedQuestsJson, string apQuestName) { if (finishedQuestsJson.Contains("\"" + apQuestName + "\"")) { return true; } if (!ApQuestVanillaCompletionNames.TryGetValue(apQuestName, out string[] value)) { return false; } string[] array = value; foreach (string text in array) { if (finishedQuestsJson.Contains("\"" + text + "\"")) { return true; } } return false; } private static KeyValuePair<string, long>[] BuildAllQuestToLocationPairs() { KeyValuePair<string, long>[] array = new KeyValuePair<string, long>[AllQuestToLocation.Count]; int num = 0; foreach (KeyValuePair<string, long> item in AllQuestToLocation) { array[num++] = item; } return array; } } internal static class ArchipelagoItemProgression { private static readonly HashSet<char>[] ClassFilterSets = new HashSet<char>[7] { null, new HashSet<char> { 'F' }, new HashSet<char> { 'M' }, new HashSet<char> { 'B' }, new HashSet<char> { 'F', 'M' }, new HashSet<char> { 'F', 'B' }, new HashSet<char> { 'M', 'B' } }; internal static readonly Dictionary<string, int> EquipmentItemTiers = new Dictionary<string, int> { { "Acolyte Hood", 1 }, { "Aero Pants", 1 }, { "Aero Top", 1 }, { "Agility Ears", 1 }, { "Amberite Boomstick", 3 }, { "Amberite Breastplate", 3 }, { "Amberite Halberd", 3 }, { "Amberite Helm", 3 }, { "Amberite Leggings", 3 }, { "Amberite Shield", 3 }, { "Amberite Sword", 3 }, { "Amberite Warstar", 3 }, { "Ambersquire Ring", 2 }, { "Apprentice Robe", 2 }, { "Aquapetal Staff", 4 }, { "Berserker Chestpiece", 4 }, { "Berserker Leggings", 4 }, { "Blueversa Cape", 4 }, { "Boarus Helm", 5 }, { "Boarus Torment", 5 }, { "Carbuncle Hat", 4 }, { "Carbuncle Robe", 4 }, { "Chainmail Guard", 3 }, { "Chainmail Leggings", 3 }, { "Chainscale Chest", 4 }, { "Cobblerage Cloak", 4 }, { "Coldgeist Blade", 4 }, { "Coldgeist Bow", 4 }, { "Coldgeist Frostcaller", 4 }, { "Coldgeist Punisher", 4 }, { "Colossus Tone", 4 }, { "Cozy Cloak", 3 }, { "Cryo Cane", 2 }, { "Cryotribe Spear", 5 }, { "Crypt Blade", 1 }, { "Crypt Bow", 1 }, { "Crypt Buckler", 1 }, { "Crypt Pounder", 2 }, { "Cryptcall Bell", 2 }, { "Cryptsinge Chest", 1 }, { "Cryptsinge Halberd", 2 }, { "Cryptsinge Halo", 1 }, { "Cryptsinge Katars", 1 }, { "Daemon Shield", 5 }, { "Darkcloth Pants", 3 }, { "Dawn Mace", 2 }, { "Deadwood Axe", 4 }, { "Deathgel Shivs", 2 }, { "Deathknight Helm", 5 }, { "Deathknight Runeblade", 5 }, { "Deathward Cape", 4 }, { "Demicrypt Bauble", 2 }, { "Demicrypt Blade", 2 }, { "Demicrypt Bow", 2 }, { "Demicrypt Buckler", 2 }, { "Demicrypt Halo", 2 }, { "Dense Chestpiece", 2 }, { "Dense Hammer", 2 }, { "Dense Helm", 2 }, { "Dense Katars", 2 }, { "Dense Leggings", 2 }, { "Dense Mace", 2 }, { "Dense Shield", 2 }, { "Dense Spear", 2 }, { "Dire Helm", 5 }, { "Diva Crown", 2 }, { "Dolkin's Axe", 3 }, { "Druidic Halo", 5 }, { "Druidic Robe", 4 }, { "Duelist Garb", 2 }, { "Earthbind Tabard", 5 }, { "Earthwoken Ring", 4 }, { "Edon's Pendant", 2 }, { "Emeraldfocus Ring", 2 }, { "Emerock Chestpiece", 4 }, { "Emerock Halo", 5 }, { "Eschek Greaves", 5 }, { "Executioner Leggings", 5 }, { "Executioner Vestment", 5 }, { "Femur Club", 1 }, { "Fender Garb", 5 }, { "Fender Leggings", 5 }, { "Fier Blade", 5 }, { "Firebreath Blade", 5 }, { "Flamepetal Staff", 4 }, { "Flametribe Spear", 5 }, { "Flux Cloak", 3 }, { "Focus Circlet", 3 }, { "Focusi Glasses", 3 }, { "Follycannon", 5 }, { "Forlorn Cloak", 4 }, { "Fortified Vestment", 4 }, { "Frostbite Claws", 4 }, { "Fuguefall Duster", 4 }, { "Fuguefall Pants", 4 }, { "Geist Scythe", 2 }, { "Geistlord Band", 4 }, { "Geistlord Claws", 3 }, { "Geistlord Crown", 2 }, { "Geistlord Eye", 4 }, { "Geistlord Ring", 3 }, { "Gemveil Breastplate", 5 }, { "Gemveil Leggings", 5 }, { "Gemveil Raiment", 4 }, { "Ghostly Legwraps", 1 }, { "Ghostly Tabard", 1 }, { "Gilded Sword", 1 }, { "Glyphgrift Halo", 4 }, { "Glyphik Booklet", 5 }, { "Golem Chestpiece", 3 }, { "Golemfist Katars", 4 }, { "Greenversa Cape", 4 }, { "Guardel Helm", 5 }, { "Hellsludge Shivs", 3 }, { "Initiate Cloak", 1 }, { "Initiate Spectacles", 1 }, { "Iris Shield", 2 }, { "Irisun Shield", 5 }, { "Iron Axehammer", 2 }, { "Iron Bell", 2 }, { "Iron Bow", 2 }, { "Iron Chestpiece", 2 }, { "Iron Halo", 2 }, { "Iron Katars", 2 }, { "Iron Scepter", 2 }, { "Iron Shield", 2 }, { "Iron Spear", 2 }, { "Iron Sword", 2 }, { "Ironbark Sword", 1 }, { "Jadetrout Ring", 4 }, { "Jadewail Trousers", 4 }, { "Jestercast Memory", 4 }, { "Journeyman Leggings", 1 }, { "Journeyman Shorts", 1 }, { "Journeyman Spectacles", 2 }, { "Journeyman Vest", 1 }, { "King Breastplate", 4 }, { "King Greaves", 4 }, { "Knightguard Halo", 4 }, { "Leathen Cap", 5 }, { "Leather Britches", 1 }, { "Leather Cap", 1 }, { "Leather Top", 1 }, { "Lord Breastplate", 3 }, { "Lord Greaves", 3 }, { "Magilord Boots", 4 }, { "Magilord Overalls", 4 }, { "Magistrate Circlet", 3 }, { "Magitek Burstgun", 4 }, { "Marrow Bauble", 1 }, { "Mekspear", 2 }, { "Mekspike Bow", 2 }, { "Mekwar Drape", 5 }, { "Menace Bow", 2 }, { "Mercenary Leggings", 4 }, { "Mercenary Vestment", 4 }, { "Meshlink Cape", 4 }, { "Mini Geist Scythe", 1 }, { "Mithril Bell", 4 }, { "Mithril Bow", 3 }, { "Mithril Chestpiece", 4 }, { "Mithril Greatsword", 4 }, { "Mithril Halberd", 4 }, { "Mithril Halo", 4 }, { "Mithril Katars", 3 }, { "Mithril Scepter", 4 }, { "Mithril Shield", 3 }, { "Mithril Sword", 4 }, { "Monolith Chestpiece", 4 }, { "Necro Caustics", 1 }, { "Necro Marrow", 1 }, { "Necromancer Hood", 2 }, { "Necroroyal Bow", 3 }, { "Necroroyal Halberd", 3 }, { "Nethercrypt Bauble", 3 }, { "Nethercrypt Blade", 3 }, { "Nethercrypt Cloak", 3 }, { "Nethercrypt Halo", 3 }, { "Nethercrypt Shield", 3 }, { "Nethercrypt Tabard", 3 }, { "Newfold Halo", 1 }, { "Nograd's Amulet", 1 }, { "Noji Talisman", 4 }, { "Nokket Cloak", 2 }, { "Nulrok Mace", 4 }, { "Nulrok Spear", 4 }, { "Nulversa Cape", 4 }, { "Nutso Pants", 1 }, { "Nutso Top", 1 }, { "Old Ring", 1 }, { "Omen Shield", 2 }, { "Orbos Ring", 4 }, { "Ornamented Battlerobe", 3 }, { "Pearlpond Ring", 3 }, { "Petrified Bow", 3 }, { "Poacher Cloth", 1 }, { "Poltergeist Scythe", 3 }, { "Pyre Cane", 3 }, { "Quake Pummeler", 4 }, { "Rage Circlet", 3 }, { "Ragespear", 4 }, { "Ragged Shirt", 1 }, { "Reaper Gi", 4 }, { "Reaper Leggings", 4 }, { "Reapsow Garb", 3 }, { "Reapsow Pants", 3 }, { "Redversa Cape", 4 }, { "Regazuul Cape", 2 }, { "Rigor Buckler", 4 }, { "Ring Of Ambition", 1 }, { "Roudon Cape", 4 }, { "Roudon Chestpiece", 4 }, { "Roudon Robe", 5 }, { "Rude Blade", 2 }, { "Rugged Cloak", 2 }, { "Ruggrok Vest", 5 }, { "Rummok Bladerings", 4 }, { "Runic Katars", 2 }, { "Rustweary Shield", 4 }, { "Rustwise Shield", 4 }, { "Ryzer Greataxe", 5 }, { "Sagecaller Cape", 4 }, { "Sagecloth Shorts", 1 }, { "Sagecloth Top", 1 }, { "Sapphireweave Ring", 2 }, { "Sapphite Bell", 4 }, { "Sapphite Guard", 4 }, { "Sapphite Katars", 4 }, { "Sapphite Leggings", 4 }, { "Sapphite Mindhat", 4 }, { "Sapphite Scepter", 4 }, { "Sapphite Shield", 4 }, { "Sapphite Spear", 4 }, { "Sash Leggings", 2 }, { "Serrated Blade", 4 }, { "Serrated Knuckles", 4 }, { "Serrated Longbow", 4 }, { "Serrated Spear", 4 }, { "Sinner Bardiche", 3 }, { "Skywrill Tabard", 2 }, { "Slabton Shield", 3 }, { "Sleeper's Robe", 2 }, { "Slime Diva Baton", 2 }, { "Slimecrust Blade", 1 }, { "Slimecrust Chest", 1 }, { "Slimecrust Katars", 1 }, { "Slimecrust Leggings", 1 }, { "Slimek Axehammer", 1 }, { "Slimek Chest", 1 }, { "Slimek Leggings", 1 }, { "Slimek Shield", 1 }, { "Slimek Shivs", 1 }, { "Slimewoven Cloak", 1 }, { "Slitherwraith Ring", 3 }, { "Splitbark Club", 1 }, { "Splitbark Scepter", 1 }, { "Stone Greatblade", 2 }, { "Stridebond Pants", 4 }, { "Students Ring", 3 }, { "Tattered Battlerobe", 2 }, { "Temrak Britches", 4 }, { "Tessellated Drive", 5 }, { "The One Ring", 1 }, { "Torrentius Longbow", 5 }, { "Trodd Tunic", 2 }, { "Valdur Blade", 5 }, { "Valdur Effigy", 5 }, { "Valor Ring", 4 }, { "Vile Blade", 2 }, { "Voalstark Wand", 5 }, { "Warrior Chest", 2 }, { "Warrior Leggings", 2 }, { "Windgolem Cloak", 5 }, { "Witchlock Loincloth", 3 }, { "Witchlock Robe", 3 }, { "Witchwizard Garterbelt", 4 }, { "Witchwizard Robe", 4 }, { "Wizlad Hood", 5 }, { "Wizlad Robe", 5 }, { "Wizwand", 3 }, { "Wooden Shield", 1 }, { "Worn Robe", 1 } }; internal static readonly Dictionary<string, string> EquipmentClassAffinity = new Dictionary<string, string> { { "Amberite Boomstick", "B" }, { "Amberite Halberd", "F" }, { "Amberite Shield", "FM" }, { "Amberite Sword", "F" }, { "Amberite Warstar", "F" }, { "Aquapetal Staff", "M" }, { "Berserker Chestpiece", "F" }, { "Berserker Leggings", "F" }, { "Coldgeist Blade", "F" }, { "Coldgeist Bow", "B" }, { "Coldgeist Frostcaller", "M" }, { "Coldgeist Punisher", "F" }, { "Colossus Tone", "M" }, { "Cryo Cane", "M" }, { "Cryotribe Spear", "F" }, { "Crypt Blade", "F" }, { "Crypt Bow", "B" }, { "Crypt Buckler", "FM" }, { "Crypt Pounder", "F" }, { "Cryptcall Bell", "M" }, { "Cryptsinge Halberd", "F" }, { "Cryptsinge Katars", "B" }, { "Daemon Shield", "FM" }, { "Dawn Mace", "F" }, { "Deadwood Axe", "F" }, { "Deathgel Shivs", "B" }, { "Deathknight Runeblade", "F" }, { "Demicrypt Bauble", "M" }, { "Demicrypt Blade", "F" }, { "Demicrypt Bow", "B" }, { "Demicrypt Buckler", "FM" }, { "Dense Hammer", "F" }, { "Dense Katars", "B" }, { "Dense Mace", "F" }, { "Dense Shield", "FM" }, { "Dense Spear", "F" }, { "Dolkin's Axe", "F" }, { "Executioner Leggings", "F" }, { "Executioner Vestment", "F" }, { "Femur Club", "F" }, { "Fender Garb", "B" }, { "Fender Leggings", "B" }, { "Fier Blade", "F" }, { "Firebreath Blade", "F" }, { "Flamepetal Staff", "M" }, { "Flametribe Spear", "F" }, { "Focus Circlet", "M" }, { "Focusi Glasses", "M" }, { "Follycannon", "B" }, { "Frostbite Claws", "B" }, { "Fuguefall Duster", "B" }, { "Fuguefall Pants", "B" }, { "Geist Scythe", "F" }, { "Geistlord Claws", "B" }, { "Gilded Sword", "F" }, { "Golemfist Katars", "B" }, { "Hellsludge Shivs", "B" }, { "Iris Shield", "FM" }, { "Irisun Shield", "FM" }, { "Iron Axehammer", "F" }, { "Iron Bell", "M" }, { "Iron Bow", "B" }, { "Iron Katars", "B" }, { "Iron Scepter", "M" }, { "Iron Shield", "FM" }, { "Iron Spear", "F" }, { "Iron Sword", "F" }, { "Ironbark Sword", "F" }, { "King Breastplate", "F" }, { "King Greaves", "F" }, { "Lord Breastplate", "F" }, { "Lord Greaves", "F" }, { "Magilord Boots", "M" }, { "Magilord Overalls", "M" }, { "Magitek Burstgun", "B" }, { "Marrow Bauble", "M" }, { "Mekspear", "F" }, { "Mekspike Bow", "B" }, { "Menace Bow", "B" }, { "Mini Geist Scythe", "F" }, { "Mithril Bell", "M" }, { "Mithril Bow", "B" }, { "Mithril Greatsword", "F" }, { "Mithril Halberd", "F" }, { "Mithril Katars", "B" }, { "Mithril Scepter", "M" }, { "Mithril Shield", "FM" }, { "Mithril Sword", "F" }, { "Necroroyal Bow", "B" }, { "Necroroyal Halberd", "F" }, { "Nethercrypt Bauble", "M" }, { "Nethercrypt Blade", "F" }, { "Nethercrypt Shield", "FM" }, { "Nulrok Mace", "F" }, { "Nulrok Spear", "F" }, { "Omen Shield", "FM" }, { "Petrified Bow", "B" }, { "Poltergeist Scythe", "F" }, { "Pyre Cane", "M" }, { "Quake Pummeler", "F" }, { "Ragespear", "F" }, { "Reaper Gi", "B" }, { "Reaper Leggings", "B" }, { "Reapsow Garb", "B" }, { "Reapsow Pants", "B" }, { "Rigor Buckler", "FM" }, { "Rude Blade", "F" }, { "Rummok Bladerings", "B" }, { "Runic Katars", "B" }, { "Rustweary Shield", "FM" }, { "Rustwise Shield", "FM" }, { "Ryzer Greataxe", "F" }, { "Sapphite Bell", "M" }, { "Sapphite Katars", "B" }, { "Sapphite Mindhat", "M" }, { "Sapphite Scepter", "M" }, { "Sapphite Shield", "FM" }, { "Sapphite Spear", "F" }, { "Serrated Blade", "F" }, { "Serrated Knuckles", "B" }, { "Serrated Longbow", "B" }, { "Serrated Spear", "F" }, { "Sinner Bardiche", "F" }, { "Slabton Shield", "FM" }, { "Slime Diva Baton", "M" }, { "Slimecrust Blade", "F" }, { "Slimecrust Katars", "B" }, { "Slimek Axehammer", "F" }, { "Slimek Shield", "FM" }, { "Slimek Shivs", "B" }, { "Splitbark Club", "F" }, { "Splitbark Scepter", "M" }, { "Stone Greatblade", "F" }, { "Torrentius Longbow", "B" }, { "Valdur Blade", "F" }, { "Vile Blade", "F" }, { "Voalstark Wand", "M" }, { "Witchlock Loincloth", "M" }, { "Witchlock Robe", "M" }, { "Witchwizard Garterbelt", "M" }, { "Witchwizard Robe", "M" }, { "Wizlad Hood", "M" }, { "Wizlad Robe", "M" }, { "Wizwand", "M" }, { "Wooden Shield", "FM" } }; internal static int LevelToMaxTier(int level) { if (level <= 5) { return 1; } if (level <= 10) { return 2; } if (level <= 15) { return 3; } if (level <= 20) { return 4; } return 5; } internal static bool TryGetEquipmentTier(string itemName, out int tier) { return EquipmentItemTiers.TryGetValue(itemName, out tier); } internal static bool TryGetClassAffinity(string itemName, out string affinity) { return EquipmentClassAffinity.TryGetValue(itemName, out affinity); } internal static bool ItemPassesClassFilter(int classFilterOption, string itemName) { if (classFilterOption <= 0 || classFilterOption >= ClassFilterSets.Length) { return true; } if (!TryGetClassAffinity(itemName, out string affinity)) { return true; } HashSet<char> hashSet = ClassFilterSets[classFilterOption]; string text = affinity; foreach (char item in text) { if (hashSet.Contains(item)) { return true; } } return false; } internal static bool ItemPassesGatedLevel(int playerLevel, string itemName) { if (!TryGetEquipmentTier(itemName, out var tier)) { return true; } return tier <= LevelToMaxTier(playerLevel); } } internal sealed class DeferredEquipmentGrant { public string ItemName; public string TraceId; public bool IsProgressiveEquipment; } public class ArchipelagoPortalUnlocks : MonoBehaviour { private struct PortalData { public string portalCaption; public string spawnID; public string sceneName; } private const string PortalContainerName = "_PORTALS"; private const string PortalContainerAltName = "_PORTAL"; private const string SanctumCatacombsMapName = "map_dungeon00_sanctumCatacombs"; private const string CrescentGroveMapName = "map_dungeon01_crescentGrove"; private const string MainMenuRootSceneName = "01_rootScene"; private static readonly string[] ProgressivePortalScenes = new string[11] { "Assets/Scenes/00_zone_forest/_zone00_outerSanctum.unity", "Assets/Scenes/00_zone_forest/_zone00_effoldTerrace.unity", "Assets/Scenes/00_zone_forest/_zone00_arcwoodPass.unity", "Assets/Scenes/00_zone_forest/_zone00_tuulValley.unity", "Assets/Scenes/00_zone_forest/_zone00_crescentRoad.unity", "Assets/Scenes/map_dungeon00_sanctumCatacombs.unity", "Assets/Scenes/00_zone_forest/_zone00_luvoraGarden.unity", "Assets/Scenes/00_zone_forest/_zone00_crescentKeep.unity", "Assets/Scenes/00_zone_forest/_zone00_tuulEnclave.unity", "Assets/Scenes/00_zone_forest/_zone00_bularFortress.unity", "Assets/Scenes/map_dungeon01_crescentGrove.unity" }; private static readonly Dictionary<string, PortalData> CanonicalUnlockedPortalDestinations = new Dictionary<string, PortalData>(StringComparer.OrdinalIgnoreCase) { { "Outer Sanctum", new PortalData { portalCaption = "Outer Sanctum", spawnID = "spawnPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_outerSanctum.unity" } }, { "Arcwood Pass", new PortalData { portalCaption = "Arcwood Pass", spawnID = "spawnPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_arcwoodPass.unity" } }, { "Effold Terrace", new PortalData { portalCaption = "Effold Terrace", spawnID = "startPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_effoldTerrace.unity" } }, { "Tuul Valley", new PortalData { portalCaption = "Tuul Valley", spawnID = "spawnPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_tuulValley.unity" } }, { "Crescent Road", new PortalData { portalCaption = "Crescent Road", spawnID = "spawnPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_crescentRoad.unity" } }, { "Sanctum Catacombs", new PortalData { portalCaption = "Sanctum Catacombs", spawnID = "spawnPoint", sceneName = "Assets/Scenes/map_dungeon00_sanctumCatacombs.unity" } }, { "Luvora Garden", new PortalData { portalCaption = "Luvora Garden", spawnID = "startPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_luvoraGarden.unity" } }, { "Crescent Keep", new PortalData { portalCaption = "Crescent Keep", spawnID = "startPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_crescentKeep.unity" } }, { "Tuul Enclave", new PortalData { portalCaption = "Tuul Enclave", spawnID = "spawnPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_tuulEnclave.unity" } }, { "Bularr Fortress", new PortalData { portalCaption = "Bularr Fortress", spawnID = "startPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_bularFortress.unity" } }, { "Crescent Grove", new PortalData { portalCaption = "Crescent Grove", spawnID = "startPoint", sceneName = "Assets/Scenes/map_dungeon01_crescentGrove.unity" } } }; private AtlyssArchipelagoPlugin basePlugin; private List<string> lockedScenes = new List<string>(); private Dictionary<PortalData, PortalData> LockedDataToPortalData = new Dictionary<PortalData, PortalData>(); private Dictionary<PortalData, PortalData> PortalDataToLockedData = new Dictionary<PortalData, PortalData> { { new PortalData { portalCaption = "Outer Sanctum", spawnID = "spawnPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_outerSanctum.unity" }, new PortalData { portalCaption = "Outer Sanctum (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_sanctum.unity" } }, { new PortalData { portalCaption = "Sanctum Arena", spawnID = "spawnPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_sanctumArena.unity" }, new PortalData { portalCaption = "Sanctum Arena (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_sanctum.unity" } }, { new PortalData { portalCaption = "Sanctum", spawnID = "gatePoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_sanctum.unity" }, new PortalData { portalCaption = "Sanctum (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_outerSanctum.unity" } }, { new PortalData { portalCaption = "Effold Terrace", spawnID = "startPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_effoldTerrace.unity" }, new PortalData { portalCaption = "Effold Terrace (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_outerSanctum.unity" } }, { new PortalData { portalCaption = "Arcwood Pass", spawnID = "spawnPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_arcwoodPass.unity" }, new PortalData { portalCaption = "Arcwood Pass (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_outerSanctum.unity" } }, { new PortalData { portalCaption = "Tuul Valley", spawnID = "spawnPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_tuulValley.unity" }, new PortalData { portalCaption = "Tuul Valley (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_outerSanctum.unity" } }, { new PortalData { portalCaption = "Outer Sanctum", spawnID = "arcwoodSpawn", sceneName = "Assets/Scenes/00_zone_forest/_zone00_outerSanctum.unity" }, new PortalData { portalCaption = "Outer Sanctum (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_arcwoodPass.unity" } }, { new PortalData { portalCaption = "Crescent Road", spawnID = "spawnPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_crescentRoad.unity" }, new PortalData { portalCaption = "Crescent Road (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_arcwoodPass.unity" } }, { new PortalData { portalCaption = "Executioner's Tomb", spawnID = "spawnPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_catacombsArena.unity" }, new PortalData { portalCaption = "Executioner's Tomb (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_arcwoodPass.unity" } }, { new PortalData { portalCaption = "Sanctum Catacombs", spawnID = "", sceneName = "Assets/Scenes/map_dungeon00_sanctumCatacombs.unity" }, new PortalData { portalCaption = "Sanctum Catacombs (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_arcwoodPass.unity" } }, { new PortalData { portalCaption = "Arcwood Pass", spawnID = "keepSpawn", sceneName = "Assets/Scenes/00_zone_forest/_zone00_arcwoodPass.unity" }, new PortalData { portalCaption = "Arcwood Pass (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_crescentRoad.unity" } }, { new PortalData { portalCaption = "Luvora Garden", spawnID = "startPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_luvoraGarden.unity" }, new PortalData { portalCaption = "Luvora Garden (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_crescentRoad.unity" } }, { new PortalData { portalCaption = "Crescent Keep", spawnID = "startPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_crescentKeep.unity" }, new PortalData { portalCaption = "Crescent Keep (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_crescentRoad.unity" } }, { new PortalData { portalCaption = "Outer Sanctum", spawnID = "terraceSpawn", sceneName = "Assets/Scenes/00_zone_forest/_zone00_outerSanctum.unity" }, new PortalData { portalCaption = "Outer Sanctum (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_effoldTerrace.unity" } }, { new PortalData { portalCaption = "Outer Sanctum", spawnID = "tullValleyPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_outerSanctum.unity" }, new PortalData { portalCaption = "Outer Sanctum (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_tuulValley.unity" } }, { new PortalData { portalCaption = "Tuul Enclave", spawnID = "spawnPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_tuulEnclave.unity" }, new PortalData { portalCaption = "Tuul Enclave (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_tuulValley.unity" } }, { new PortalData { portalCaption = "Tuul Valley", spawnID = "enclavePoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_tuulValley.unity" }, new PortalData { portalCaption = "Tuul Valley (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_tuulEnclave.unity" } }, { new PortalData { portalCaption = "Bularr Fortress", spawnID = "startPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_bularFortress.unity" }, new PortalData { portalCaption = "Bularr Fortress (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_tuulEnclave.unity" } }, { new PortalData { portalCaption = "Tuul Enclave", spawnID = "fortSpawn", sceneName = "Assets/Scenes/00_zone_forest/_zone00_tuulEnclave.unity" }, new PortalData { portalCaption = "Tuul Enclave (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_bularFortress.unity" } }, { new PortalData { portalCaption = "Crescent Road", spawnID = "gardenPoint", sceneName = "Assets/Scenes/00_zone_forest/_zone00_crescentRoad.unity" }, new PortalData { portalCaption = "Crescent Road (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_luvoraGarden.unity" } }, { new PortalData { portalCaption = "Crescent Road", spawnID = "keepSpawn", sceneName = "Assets/Scenes/00_zone_forest/_zone00_crescentRoad.unity" }, new PortalData { portalCaption = "Crescent Road (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_crescentKeep.unity" } }, { new PortalData { portalCaption = "Crescent Grove", spawnID = "startPoint", sceneName = "Assets/Scenes/map_dungeon01_crescentGrove.unity" }, new PortalData { portalCaption = "Crescent Grove (Locked!)", spawnID = "", sceneName = "Assets/Scenes/00_zone_forest/_zone00_crescentKeep.unity" } } }; private bool _deferPortalRefreshWhileShopOpen; private void Awake() { basePlugin = AtlyssArchipelagoPlugin.Instance; SceneManager.sceneLoaded += OnSceneLoaded; foreach (KeyValuePair<PortalData, PortalData> portalDataToLockedDatum in PortalDataToLockedData) { LockedDataToPortalData[portalDataToLockedDatum.Value] = portalDataToLockedDatum.Key; } } private void OnSceneLoaded(Scene s, LoadSceneMode m) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) ((MonoBehaviour)this).StartCoroutine(EnforcePortalLocksWhenReady(s)); } private IEnumerator EnforcePortalLocksWhenReady(Scene newScene) { //IL_000e: 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) if (!ShouldManagePortalsInScene(newScene)) { yield break; } yield return (object)new WaitUntil((Func<bool>)(() => ((Scene)(ref newScene)).isLoaded)); float connectDeadline = Time.unscaledTime + 30f; while (!ShouldEnforcePortalLocks() && Time.unscaledTime < connectDeadline) { yield return null; } if (!ShouldEnforcePortalLocks()) { yield break; } float deadline = Time.unscaledTime + 5f; while (Time.unscaledTime < deadline) { if (!ShouldEnforcePortalLocks() || TryApplyPortalLocksToScene(newScene)) { yield break; } yield return null; } if (ShouldEnforcePortalLocks()) { AtlyssArchipelagoPlugin.SLogWarn("Portal lock pass timed out for scene " + ((Scene)(ref newScene)).name + " (_PORTALS not found)."); } } private bool ShouldEnforcePortalLocks() { return basePlugin.PortalLockEnforcementActive; } private static bool ShouldManagePortalsInScene(Scene scene) { if (!((Scene)(ref scene)).IsValid() || !((Scene)(ref scene)).isLoaded) { return false; } if (((Scene)(ref scene)).name != "map_dungeon00_sanctumCatacombs" && ((Scene)(ref scene)).name != "map_dungeon01_crescentGrove") { return ((Scene)(ref scene)).name != "01_rootScene"; } return false; } private GameObject FindPortalContainerInScene(Scene scene) { GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); foreach (GameObject val in rootGameObjects) { if (((Object)val).name == "_PORTALS" || ((Object)val).name == "_PORTAL") { return val; } } return null; } private bool TryApplyPortalLocksToScene(Scene scene) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown if (!ShouldManagePortalsInScene(scene) || !ShouldEnforcePortalLocks()) { return true; } GameObject val = FindPortalContainerInScene(scene); if ((Object)val == (Object)null) { return false; } int num = 0; for (int i = 0; i < val.transform.childCount; i++) { Portal component = ((Component)val.transform.GetChild(i)).GetComponent<Portal>(); if ((Object)component == (Object)null) { continue; } ScenePortalData scenePortal = component._scenePortal; if (scenePortal != null && lockedScenes.Contains(scenePortal._subScene)) { PortalData key = new PortalData { portalCaption = scenePortal._portalCaptionTitle, spawnID = scenePortal._spawnPointTag, sceneName = scenePortal._subScene }; if (PortalDataToLockedData.TryGetValue(key, out var value)) { scenePortal._portalCaptionTitle = value.portalCaption; scenePortal._spawnPointTag = value.spawnID; scenePortal._subScene = value.sceneName; num++; } else { AtlyssArchipelagoPlugin.SLogError("The portal to " + scenePortal._portalCaptionTitle + " wasn't found in the dictionary!"); } } } if (num > 0) { AtlyssArchipelagoPlugin.SLogInfo($"Applied {num} portal lock(s) in {((Scene)(ref scene)).name}"); } return true; } public void ApplyPortalLocksToAllLoadedScenes() { //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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (!ShouldEnforcePortalLocks()) { return; } bool flag = false; for (int i = 0; i < SceneManager.sceneCount; i++) { Scene sceneAt = SceneManager.GetSceneAt(i); if (ShouldManagePortalsInScene(sceneAt) && !TryApplyPortalLocksToScene(sceneAt)) { flag = true; } } RefreshPortalsInAllLoadedScenes(); if (flag) { ((MonoBehaviour)this).StartCoroutine(RetryApplyPortalLocksToAllLoadedScenes()); } } private IEnumerator RetryApplyPortalLocksToAllLoadedScenes() { float deadline = Time.unscaledTime + 5f; while (Time.unscaledTime < deadline && ShouldEnforcePortalLocks()) { bool flag = false; for (int i = 0; i < SceneManager.sceneCount; i++) { Scene sceneAt = SceneManager.GetSceneAt(i); if (ShouldManagePortalsInScene(sceneAt) && !TryApplyPortalLocksToScene(sceneAt)) { flag = true; } } RefreshPortalsInAllLoadedScenes(); if (!flag) { break; } yield return null; } } private IEnumerator EnforcePortalLocks(Scene newScene) { //IL_000e: 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) yield return EnforcePortalLocksWhenReady(newScene); } private void RefreshPortalsInScene(Scene scene) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown if (!((Scene)(ref scene)).isLoaded) { return; } GameObject val = null; GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); foreach (GameObject val2 in rootGameObjects) { if (((Object)val2).name == "_PORTALS" || ((Object)val2).name == "_PORTAL") { val = val2; break; } } if ((Object)val == (Object)null) { return; } int num = 0; for (int j = 0; j < val.transform.childCount; j++) { Portal component = ((Component)val.transform.GetChild(j)).GetComponent<Portal>(); if ((Object)component == (Object)null) { continue; } ScenePortalData scenePortal = component._scenePortal; NormalizeUnlockedPortalRoute(scenePortal); if (scenePortal._portalCaptionTitle.EndsWith("(Locked!)")) { PortalData key = new PortalData { portalCaption = scenePortal._portalCaptionTitle, spawnID = scenePortal._spawnPointTag, sceneName = scenePortal._subScene }; if (LockedDataToPortalData.TryGetValue(key, out var value) && !lockedScenes.Contains(value.sceneName)) { scenePortal._portalCaptionTitle = value.portalCaption; scenePortal._spawnPointTag = value.spawnID; scenePortal._subScene = value.sceneName; num++; AtlyssArchipelagoPlugin.SLogInfo("Portal restored in real-time: " + value.portalCaption); } } } if (num > 0) { AtlyssArchipelagoPlugin.SLogInfo($"Refreshed {num} portal(s) in {((Scene)(ref scene)).name} without reload"); } } public void RefreshPortalsInAllLoadedScenes() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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) for (int i = 0; i < SceneManager.sceneCount; i++) { Scene sceneAt = SceneManager.GetSceneAt(i); if (((Scene)(ref sceneAt)).isLoaded) { RefreshPortalsInScene(sceneAt); } } } private void NormalizeUnlockedPortalRoute(ScenePortalData scenePortal) { if (scenePortal == null) { return; } string text = scenePortal._portalCaptionTitle ?? ""; bool flag = text.EndsWith("(Locked!)", StringComparison.OrdinalIgnoreCase); string key = (flag ? text.Substring(0, text.Length - " (Locked!)".Length) : text); if (CanonicalUnlockedPortalDestinations.TryGetValue(key, out var value) && !lockedScenes.Contains(value.sceneName)) { bool flag2 = false; if (scenePortal._subScene != value.sceneName) { scenePortal._subScene = value.sceneName; flag2 = true; } if (string.IsNullOrWhiteSpace(scenePortal._spawnPointTag)) { scenePortal._spawnPointTag = value.spawnID; flag2 = true; } if (flag) { scenePortal._portalCaptionTitle = value.portalCaption; flag2 = true; } if (flag2) { AtlyssArchipelagoPlugin.SLogWarn("Corrected portal routing after unlock: " + value.portalCaption); } } } public void ApplyAreaAccessMode() { string text = (basePlugin.randomPortalsEnabled ? "Random Portals" : "Progressive Portals"); AtlyssArchipelagoPlugin.SLogInfo("Portal Mode: " + text + " - Locking all portals"); lockedScenes.Clear(); string[] progressivePortalScenes = ProgressivePortalScenes; foreach (string sceneName in progressivePortalScenes) { BlockAccessToScene(sceneName); } } public void BlockAccessToScene(string sceneName) { if (!lockedScenes.Contains(sceneName)) { lockedScenes.Add(sceneName); AtlyssArchipelagoPlugin.SLogInfo(sceneName + " has been locked by Archipelago"); } } public void UnblockAccessToScene(string sceneName) { if (lockedScenes.Contains(sceneName)) { lockedScenes.Remove(sceneName); AtlyssArchipelagoPlugin.SLogInfo(sceneName + " is no longer being locked by Archipelago"); } RequestPortalSceneRefresh(); } private void RequestPortalSceneRefresh() { if (AtlyssArchipelagoPlugin.IsShopInterfaceOpen()) { _deferPortalRefreshWhileShopOpen = true; return; } _deferPortalRefreshWhileShopOpen = false; RefreshPortalsInAllLoadedScenes(); } public void FlushDeferredPortalRefresh() { if (_deferPortalRefreshWhileShopOpen) { _deferPortalRefreshWhileShopOpen = false; RefreshPortalsInAllLoadedScenes(); } } public bool IsSceneLocked(string sceneName) { return lockedScenes.Contains(sceneName); } } public sealed class ArchipelagoProfessionTools { private enum ToolKind { FishingRod, Pickaxe } public const string BuyFishingRodLocation = "Buy Fishing Rod"; public const string BuyPickaxeLocation = "Buy Pickaxe"; public const string FishingRodItem = "Fishing Rod"; public const string PickaxeItem = "Pickaxe"; private static readonly string[] FishingRodShopNames = new string[2] { "Fishing Rod", "Wooden Fishing Rod" }; private static readonly string[] PickaxeShopNames = new string[3] { "Pickaxe", "Mining Pickaxe", "Wooden Pickaxe" }; private const string PoolToolRepeatPurchaseMessage = "Profession Tools: Pool. Your tool comes from the multiworld — the shop check is already sent; you cannot buy another here."; private const string StaticToolRepeatPurchaseMessage = "You already have this profession tool — you cannot buy another here."; public const string CannotSellProfessionToolMessage = "Profession Tools: You cannot sell the Fishing Rod or Pickaxe. Check your inventory or Spike storage."; private readonly AtlyssArchipelagoPlugin _plugin; public bool IsPoolMode => _plugin.professionToolsOption == 1; public static bool IsProfessionToolItemName(string itemName) { if (string.IsNullOrWhiteSpace(itemName)) { return false; } if (!string.Equals(itemName, "Fishing Rod", StringComparison.OrdinalIgnoreCase) && !string.Equals(itemName, "Pickaxe", StringComparison.OrdinalIgnoreCase) && !MatchesToolName(itemName, FishingRodShopNames)) { return MatchesToolName(itemName, PickaxeShopNames); } return true; } public ArchipelagoProfessionTools(AtlyssArchipelagoPlugin plugin) { _plugin = plugin; } public bool TryBlockProfessionToolDiscard(ItemData itemData) { if ((Object)(object)_plugin == (Object)nu