Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ValhalLoot v1.0.0
ValhalLoot.dll
Decompiled 4 months 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.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; 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 BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using ItemManager; using JetBrains.Annotations; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: AssemblyFileVersion("1.0.0")] [assembly: Guid("E0E2F92E-557C-4A05-9D89-AA92A0BD75C4")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyProduct("ValhalLoot")] [assembly: AssemblyCompany("ruijven")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyDescription("")] [assembly: AssemblyTitle("ValhalLoot")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<8f532b54-25c0-4aad-a53e-9dd3b78c8708>Embedded] internal sealed class <8f532b54-25c0-4aad-a53e-9dd3b78c8708>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] [<8f532b54-25c0-4aad-a53e-9dd3b78c8708>Embedded] [CompilerGenerated] internal sealed class <6c1629e0-990f-46fb-933a-fb94e8696503>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <6c1629e0-990f-46fb-933a-fb94e8696503>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <6c1629e0-990f-46fb-933a-fb94e8696503>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] [<8f532b54-25c0-4aad-a53e-9dd3b78c8708>Embedded] [CompilerGenerated] internal sealed class <022029f3-5fce-4252-8684-e6648986aff8>NullableContextAttribute : Attribute { public readonly byte Flag; public <022029f3-5fce-4252-8684-e6648986aff8>NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace ValhalLoot { [BepInPlugin("ruijven.ValhalLoot", "ValhalLoot", "1.0.0")] [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(1)] [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ValhalLootPlugin : BaseUnityPlugin { [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(0)] public enum Toggle { On = 1, Off = 0 } [HarmonyPatch(typeof(Player), "ConsumeItem")] [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(0)] private static class Player_ConsumeItem_Patch { [HarmonyPrefix] [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(1)] private static bool Prefix(Player __instance, ItemData item, ref bool __result) { try { if (item != null && (Object)(object)item.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name == "valhalloot_ru") { ValhalLootLogger.LogInfo((object)("Player " + __instance.GetPlayerName() + " is using ValhalLoot chest")); if ((Object)(object)ValhalLootManager.Instance != (Object)null) { ValhalLootManager.Instance.ProcessChestUse(__instance, item); __result = true; return false; } } } catch (Exception ex) { ValhalLootLogger.LogError((object)("Error in ConsumeItem patch: " + ex.Message)); } return true; } } [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(0)] private class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order = null; [UsedImplicitly] public bool? Browsable = null; [UsedImplicitly] [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] public string Category = null; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(new byte[] { 2, 1 })] [UsedImplicitly] public Action<ConfigEntryBase> CustomDrawer = null; } [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] private class AcceptableShortcuts : AcceptableValueBase { public AcceptableShortcuts() : base(typeof(KeyboardShortcut)) { } public override object Clamp(object value) { return value; } public override bool IsValid(object value) { return true; } public override string ToDescriptionString() { return "# Acceptable values: " + string.Join(", ", UnityInput.Current.SupportedKeyCodes); } } internal const string ModName = "ValhalLoot"; internal const string ModVersion = "1.0.0"; internal const string Author = "ruijven"; private const string ModGUID = "ruijven.ValhalLoot"; private static string ConfigFileName = "ruijven.ValhalLoot.cfg"; private static string ConfigFileFullPath; internal static string ConnectionError; private readonly Harmony _harmony = new Harmony("ruijven.ValhalLoot"); public static readonly ManualLogSource ValhalLootLogger; private static readonly ConfigSync ConfigSync; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] private static ValhalLootConfig _valhalLootConfig; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] private static GameObject _valhalLootUIObject; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] public Texture2D tex = null; private static ConfigEntry<Toggle> _serverConfigLocked; public void Awake() { //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown RegisterTranslations(); bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet; ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; _serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only."); ConfigSync.AddLockingConfigEntry<Toggle>(_serverConfigLocked); _valhalLootConfig = new ValhalLootConfig(ConfigSync, ((BaseUnityPlugin)this).Config); try { AssetBundle val = AssetUtils.LoadAssetBundleFromResources("lootbundle_ru", Assembly.GetExecutingAssembly()); if ((Object)(object)val == (Object)null) { string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "", "assets", "lootbundle_ru"); val = AssetBundle.LoadFromFile(text); } if ((Object)(object)val == (Object)null) { ValhalLootLogger.LogError((object)"Failed to load lootbundle_ru asset bundle from resources or file path"); ValhalLootLogger.LogInfo((object)"Creating placeholder chest without custom assets"); } else { ValhalLootLogger.LogInfo((object)("Successfully loaded asset bundle: " + ((Object)val).name)); } } catch (Exception ex) { ValhalLootLogger.LogError((object)("Error loading asset bundle: " + ex.Message)); } GameObject val2 = new GameObject("ValhalLootManager"); Object.DontDestroyOnLoad((Object)(object)val2); ValhalLootManager valhalLootManager = val2.AddComponent<ValhalLootManager>(); _valhalLootUIObject = new GameObject("ValhalLootUI"); Object.DontDestroyOnLoad((Object)(object)_valhalLootUIObject); ValhalLootUI valhalLootUI = _valhalLootUIObject.AddComponent<ValhalLootUI>(); valhalLootManager.Initialize(_valhalLootConfig); valhalLootUI.Initialize(); _harmony.PatchAll(typeof(ValhalLootPlugin)); ValhalLootLogger.LogInfo((object)"ValhalLoot components created - initialization will complete when player enters world"); ValhalLootLogger.LogInfo((object)"Harmony patches applied for item usage detection"); Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmony.PatchAll(executingAssembly); SetupWatcher(); if (saveOnConfigSet) { ((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet; ((BaseUnityPlugin)this).Config.Save(); } } private void RegisterTranslations() { Dictionary<string, string> dictionary = new Dictionary<string, string> { { "valhalloot_chest_name", "Valhalla Chest" }, { "valhalloot_chest_description", "A chest containing treasures from Valhalla" }, { "valhalloot_ui_title", "Valhalla Loot" }, { "valhalloot_ui_select", "Select one item:" }, { "valhalloot_ui_close", "Close" } }; CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; localization.AddTranslation(ref text, dictionary); } public void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); _harmony.UnpatchSelf(); } private void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(ConfigFileFullPath)) { return; } try { ValhalLootLogger.LogDebug((object)"ReadConfigValues called"); ((BaseUnityPlugin)this).Config.Reload(); } catch { ValhalLootLogger.LogError((object)("There was an issue loading your " + ConfigFileName)); ValhalLootLogger.LogError((object)"Please check your config entries for spelling and format!"); } } private ConfigEntry<T> config<[<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags); ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val); SyncedConfigEntry<T> syncedConfigEntry = ConfigSync.AddConfigEntry<T>(val2); syncedConfigEntry.SynchronizedConfig = synchronizedSetting; return val2; } private ConfigEntry<T> config<[<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] T>(string group, string name, T value, string description, bool synchronizedSetting = true) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting); } static ValhalLootPlugin() { string configPath = Paths.ConfigPath; char directorySeparatorChar = Path.DirectorySeparatorChar; ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName; ConnectionError = ""; ValhalLootLogger = Logger.CreateLogSource("ValhalLoot"); ConfigSync = new ConfigSync("ruijven.ValhalLoot") { DisplayName = "ValhalLoot", CurrentVersion = "1.0.0", MinimumRequiredVersion = "1.0.0" }; _serverConfigLocked = null; } } [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(1)] public class LootEntry { public string ItemName { get; set; } = string.Empty; public int MinQuality { get; set; } public int MaxQuality { get; set; } public float Weight { get; set; } = 1f; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] [field: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] public Recipe Recipe { [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(2)] get; [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(2)] set; } = null; } [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(1)] [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] public class ValhalLootConfig { [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] public class YamlConfig { [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] [field: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] public YamlConfig Config { [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(2)] get; [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(2)] private set; } [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] [field: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] public Settings Settings { [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(2)] get; [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(2)] set; } [YamlMember(Alias = "LootChestTables")] public Dictionary<string, List<string>> ChestLoot { get; set; } = new Dictionary<string, List<string>>(); [YamlMember(Alias = "EnemyChestTables")] public Dictionary<string, List<string>> ChestEnemyMap { get; set; } = new Dictionary<string, List<string>>(); } [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] public class Settings { [YamlMember(Alias = "Minibosses")] public List<string> Minibosses { get; set; } = new List<string> { "Skeleton_Hildir", "Fenring_Cultist_Hildir", "GoblinBrute_Hildir", "Charred_Melee_Dyrnwyn" }; } private static readonly string ConfigFileName = "ValhalLoot.yml"; private static readonly string ConfigFilePath = Path.Combine(Paths.ConfigPath, ConfigFileName); private readonly ConfigSync _configSync; public ConfigEntry<float> CreatureDropChance { get; private set; } public ConfigEntry<float> BossDropChance { get; private set; } public ConfigEntry<float> MinibossDropChance { get; private set; } public Dictionary<string, List<LootEntry>> ChestLoot { get; private set; } = new Dictionary<string, List<LootEntry>>(); public Dictionary<string, List<LootEntry>> BiomeLoot => ChestLoot; public Dictionary<string, List<string>> ChestEnemyMap { get; private set; } = new Dictionary<string, List<string>>(); public Dictionary<string, List<string>> EnemyBiomeMap => ChestEnemyMap; public Dictionary<string, string> EnemyToChestMap { get; private set; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); public ValhalLootConfig(ConfigSync configSync, ConfigFile config) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown _configSync = configSync; CreatureDropChance = config.Bind<float>("Drop Chances", "RegularCreatures", 0.1f, new ConfigDescription("Chance for regular creatures to drop a ValhalLoot chest (0-1)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); BossDropChance = config.Bind<float>("Drop Chances", "Bosses", 0.3f, new ConfigDescription("Chance for bosses to drop a ValhalLoot chest (0-1)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); MinibossDropChance = config.Bind<float>("Drop Chances", "Minibosses", 0.5f, new ConfigDescription("Chance for minibosses to drop a ValhalLoot chest (0-1)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); _configSync.AddConfigEntry<float>(CreatureDropChance); _configSync.AddConfigEntry<float>(BossDropChance); _configSync.AddConfigEntry<float>(MinibossDropChance); LoadYamlConfig(); } public void LoadYamlConfig() { try { if (File.Exists(ConfigFilePath)) { string input = File.ReadAllText(ConfigFilePath); IDeserializer deserializer = new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); YamlConfig yamlConfig = deserializer.Deserialize<YamlConfig>(input); ConvertYamlConfig(yamlConfig); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"YAML configuration loaded successfully"); } else { CreateDefaultYamlConfig(); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Default YAML configuration created"); } } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error loading YAML configuration: " + ex.Message)); CreateDefaultYamlConfig(); } } private void ConvertYamlConfig(YamlConfig yamlConfig) { ChestLoot.Clear(); ChestEnemyMap.Clear(); EnemyToChestMap.Clear(); if (yamlConfig.Settings != null) { } foreach (KeyValuePair<string, List<string>> item in yamlConfig.ChestLoot) { string key = item.Key; List<LootEntry> list = new List<LootEntry>(); foreach (string item2 in item.Value) { LootEntry lootEntry = ParseLootEntry(item2); if (lootEntry != null) { list.Add(lootEntry); } } ChestLoot[key] = list; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$"Loaded {list.Count} loot entries for chest {key}"); } foreach (KeyValuePair<string, List<string>> item3 in yamlConfig.ChestEnemyMap) { string key2 = item3.Key; List<string> list2 = new List<string>(item3.Value); ChestEnemyMap[key2] = list2; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$"Loaded {list2.Count} enemy mappings for chest {key2}"); foreach (string item4 in list2) { EnemyToChestMap[item4] = key2; ValhalLootPlugin.ValhalLootLogger.LogDebug((object)("Mapped enemy " + item4 + " to chest " + key2)); } } } private void CreateDefaultYamlConfig() { YamlConfig yamlConfig = new YamlConfig { Settings = new Settings(), ChestLoot = new Dictionary<string, List<string>> { { "meadowsloot_ru", new List<string> { "CapeDeerHide:2-4:1.0", "HelmetLeather:2-4:1.0", "ArmorLeatherChest:2-4:1.0", "ArmorLeatherLegs:2-4:1.0", "AxeStone:2-4:1.0", "AxeFlint:2-4:1.0", "Club:2-4:1.0", "ShieldWood:2-4:1.0", "ShieldWoodTower:2-4:1.0", "Bow:2-4:1.0", "KnifeFlint:2-4:1.0", "SpearFlint:2-4:1.0", "Hoe:2-4:1.0", "Hammer:2-4:1.0", "PickaxeAntler:2-4:0.5" } }, { "blackforestloot_ru", new List<string> { "ArmorTrollLeatherChest:2-4:1.0", "ArmorTrollLeatherLegs:2-4:1.0", "HelmetTrollLeather:2-4:1.0", "CapeTrollHide:2-4:1.0", "ArmorBronzeChest:2-4:1.0", "ArmorBronzeLegs:2-4:1.0", "HelmetBronze:2-4:1.0", "MaceBronze:2-4:1.0", "SwordBronze:2-4:1.0", "AxeBronze:2-4:1.0", "KnifeCopper:2-4:1.0", "BowFineWood:2-4:1.0", "SpearBronze:2-4:1.0", "AtgeirBronze:2-4:1.0", "SledgeStagbreaker:2-4:1.0", "ShieldBoneTower:2-4:1.0", "ShieldBronzeBuckler:2-4:1.0", "Cultivator:2-4:1.0", "PickaxeBronze:2-4:1.0" } }, { "swamploot_ru", new List<string> { "KnifeChitin:2-4:1.0", "SpearChitin:2-4:1.0", "ArmorRootChest:2-4:1.0", "ArmorRootLegs:2-4:1.0", "HelmetRoot:2-4:1.0", "ArmorIronChest:2-4:1.0", "ArmorIronLegs:2-4:1.0", "HelmetIron:2-4:1.0", "AxeIron:2-4:1.0", "Battleaxe:2-4:1.0", "BowHuntsman:2-4:1.0", "MaceIron:2-4:1.0", "SledgeIron:2-4:1.0", "ShieldBanded:2-4:1.0", "ShieldIronBuckler:2-4:1.0", "ShieldIronTower:2-4:1.0", "ShieldSerpentscale:2-4:1.0", "SpearElderbark:2-4:1.0", "SwordIron:2-4:1.0", "AtgeirIron:2-4:1.0", "PickaxeIron:2-4:1.0" } }, { "mountainsloot_ru", new List<string> { "ArmorWolfChest:2-4:1.0", "ArmorWolfLegs:2-4:1.0", "HelmetDrake:2-4:1.0", "CapeWolf:2-4:1.0", "ArmorFenringChest:2-4:1.0", "ArmorFenringLegs:2-4:1.0", "HelmetFenring:2-4:1.0", "ShieldSilver:2-4:1.0", "BowDraugrFang:2-4:1.0", "SpearWolfFang:2-4:1.0", "SwordSilver:2-4:1.0", "KnifeSilver:2-4:1.0", "BattleaxeCrystal:2-4:1.0", "MaceSilver:2-4:1.0", "FistFenrirClaw:2-4:1.0" } }, { "plainsloot_ru", new List<string> { "ArmorPaddedCuirass:2-4:1.0", "ArmorPaddedGreaves:2-4:1.0", "HelmetPadded:2-4:1.0", "CapeLinen:2-4:1.0", "AxeBlackMetal:2-4:1.0", "AtgeirBlackmetal:2-4:1.0", "KnifeBlackMetal:2-4:1.0", "MaceNeedle:2-4:1.0", "ShieldBlackmetal:2-4:1.0", "ShieldBlackmetalTower:2-4:1.0", "SwordBlackmetal:2-4:1.0" } }, { "mistlandsloot_ru", new List<string> { "ArmorCarapaceChest:2-4:1.0", "ArmorCarapaceLegs:2-4:1.0", "HelmetCarapace:2-4:1.0", "HelmetMage:2-4:1.0", "ArmorMageChest:2-4:1.0", "ArmorMageLegs:2-4:1.0", "CapeFeather:2-4:1.0", "AxeJotunBane:2-4:1.0", "BowSpineSnap:2-4:1.0", "AtgeirHimminAfl:2-4:1.0", "KnifeSkollAndHati:2-4:1.0", "SledgeDemolisher:2-4:1.0", "SwordMistwalker:2-4:1.0", "THSwordKrom:2-4:1.0", "CrossbowArbalest:2-4:1.0", "ShieldCarapace:2-4:1.0", "ShieldCarapaceBuckler:2-4:1.0", "StaffFireball:2-4:1.0", "StaffIceShards:2-4:1.0", "StaffShield:2-4:1.0", "StaffSkeleton:2-4:1.0", "PickaxeBlackMetal:2-4:1.0" } }, { "ashlandsloot_ru", new List<string> { "CapeAsksvin:2-4:1.0", "CapeAsh:2-4:1.0", "AxeBerzerkr:2-4:1.0", "MaceEldner:2-4:1.0", "SwordNiedhogg:2-4:1.0", "THSwordSlayer:2-4:1.0", "SpearSplitner:2-4:1.0", "ShieldFlametal:2-4:1.0", "ShieldFlametalTower:2-4:1.0", "BowAshlands:2-4:1.0", "CrossbowRipper:2-4:1.0", "StaffLightning:2-4:1.0", "StaffGreenRoots:2-4:1.0", "StaffClusterbomb:2-4:1.0", "StaffRedTroll:2-4:1.0", "ArmorMageChest_Ashlands:2-4:1.0", "ArmorMageLegs_Ashlands:2-4:1.0", "HelmetMage_Ashlands:2-4:1.0", "ArmorAshlandsMediumChest:2-4:1.0", "ArmorAshlandsMediumlegs:2-4:1.0", "HelmetAshlandsMediumHood:2-4:1.0", "HelmetFlametal:2-4:1.0", "ArmorFlametalChest:2-4:1.0", "ArmorFlametalLegs:2-4:1.0" } } }, ChestEnemyMap = new Dictionary<string, List<string>> { { "meadowsloot_ru", new List<string> { "Greyling", "Boar", "Neck", "Deer" } }, { "blackforestloot_ru", new List<string> { "Greydwarf", "Greydwarf_Elite", "Greydwarf_Shaman", "Skeleton_Hildir", "Troll", "Eikthyr", "Ghost" } }, { "swamploot_ru", new List<string> { "Draugr", "Draugr_Elite", "Wraith", "Serpent", "gd_king", "Abomination" } }, { "mountainsloot_ru", new List<string> { "Wolf", "Drake", "Fenring", "StoneGolem", "Bonemass", "Fenring_Cultist_Hildir", "Fenring_Cultist" } }, { "plainsloot_ru", new List<string> { "Goblin", "GoblinBrute", "BlobTar", "GoblinShaman", "Deathsquito", "Dragon", "GoblinBrute_Hildir", "Lox" } }, { "mistlandsloot_ru", new List<string> { "Gjall", "Seeker", "SeekerBrute", "GoblinKing", "Dverger" } }, { "ashlandsloot_ru", new List<string> { "Charred_Archer", "Charred_Mage", "Charred_Melee", "Charred_Twitcher", "Morgen", "BonemawSerpent", "FallenValkyrie", "Volture", "piece_Charred_Balista", "SeekerQueen", "Fader", "Charred_Melee_Dyrnwyn", "Asksvin" } } } }; ConvertYamlConfig(yamlConfig); SaveYamlConfig(yamlConfig); } private void SaveYamlConfig(YamlConfig config) { try { ISerializer serializer = new SerializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); string contents = serializer.Serialize(config); File.WriteAllText(ConfigFilePath, contents); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"YAML configuration saved successfully"); } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error saving YAML configuration: " + ex.Message)); } } [return: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] private static LootEntry ParseLootEntry(string entryString) { try { string[] array = entryString.Trim().Split(new char[1] { ':' }); string itemName = array[0]; string[] array2 = array[1].Split(new char[1] { '-' }); int num = int.Parse(array2[0]); int maxQuality = ((array2.Length > 1) ? int.Parse(array2[1]) : num); float weight = ((array.Length > 2) ? float.Parse(array[2]) : 1f); return new LootEntry { ItemName = itemName, MinQuality = num, MaxQuality = maxQuality, Weight = weight }; } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error parsing loot entry '" + entryString + "': " + ex.Message)); return null; } } } [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(1)] [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] public class ValhalLootManager : MonoBehaviour { [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] private class BiomeConfig { public string[] Resources { get; set; } = Array.Empty<string>(); public string[] CraftingStations { get; set; } = Array.Empty<string>(); } [CompilerGenerated] private sealed class <InitializeWhenReady>d__22 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] private object <>2__current; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] public ValhalLootManager <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] [return: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] [return: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] get { return <>2__current; } } [DebuggerHidden] public <InitializeWhenReady>d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Waiting for game systems to be ready before initializing ValhalLoot..."); <>2__current = (object)new WaitUntil((Func<bool>)(() => (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)ObjectDB.instance != (Object)null && (Object)(object)ZNetScene.instance != (Object)null)); <>1__state = 1; return true; case 1: <>1__state = -1; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Game systems ready"); if (Localization.instance != null && !Localization.instance.m_translations.ContainsKey("valhalloot_received")) { Localization.instance.AddWord("valhalloot_received", "You received a ValhalLoot chest!"); Localization.instance.AddWord("valhalloot_dropped", "A ValhalLoot chest was dropped nearby (inventory full)"); } <>4__this._isInitialized = true; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"ValhalLoot Manager fully initialized and ready"); <>4__this.BuildDynamicChestLootFromObjectDB(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <VerifyAndFixRegistration>d__31 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] private object <>2__current; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(new byte[] { 0, 1, 1 })] public Dictionary<string, GameObject> loadedPrefabs; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] public ValhalLootManager <>4__this; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(new byte[] { 0, 1, 1 })] private Dictionary<string, GameObject>.Enumerator <>s__1; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(new byte[] { 0, 1, 1 })] private KeyValuePair<string, GameObject> <kvp>5__2; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] private string <prefabName>5__3; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] private GameObject <prefab>5__4; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] private GameObject <verifyPrefab>5__5; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(new byte[] { 0, 1, 1 })] private Dictionary<string, GameObject>.Enumerator <>s__6; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(new byte[] { 0, 1, 1 })] private KeyValuePair<string, GameObject> <kvp>5__7; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] private string <prefabName>5__8; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] private GameObject <verifyPrefab>5__9; object IEnumerator<object>.Current { [DebuggerHidden] [return: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] [return: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] get { return <>2__current; } } [DebuggerHidden] public <VerifyAndFixRegistration>d__31(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>s__1 = default(Dictionary<string, GameObject>.Enumerator); <kvp>5__2 = default(KeyValuePair<string, GameObject>); <prefabName>5__3 = null; <prefab>5__4 = null; <verifyPrefab>5__5 = null; <>s__6 = default(Dictionary<string, GameObject>.Enumerator); <kvp>5__7 = default(KeyValuePair<string, GameObject>); <prefabName>5__8 = null; <verifyPrefab>5__9 = null; <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(2f); <>1__state = 1; return true; case 1: <>1__state = -1; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Verifying prefab registration and applying fallback if needed"); if ((Object)(object)ObjectDB.instance == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)"ObjectDB.instance is null during verification"); return false; } <>s__1 = loadedPrefabs.GetEnumerator(); try { while (<>s__1.MoveNext()) { <kvp>5__2 = <>s__1.Current; <prefabName>5__3 = <kvp>5__2.Key; <prefab>5__4 = <kvp>5__2.Value; <verifyPrefab>5__5 = ObjectDB.instance.GetItemPrefab(<prefabName>5__3); if ((Object)(object)<verifyPrefab>5__5 != (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("SUCCESS: Verified " + <prefabName>5__3 + " exists in ObjectDB")); } else { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)("FAILED: " + <prefabName>5__3 + " not found in ObjectDB after registration attempts")); } <prefabName>5__3 = null; <prefab>5__4 = null; <verifyPrefab>5__5 = null; <kvp>5__2 = default(KeyValuePair<string, GameObject>); } } finally { ((IDisposable)<>s__1).Dispose(); } <>s__1 = default(Dictionary<string, GameObject>.Enumerator); <>s__6 = loadedPrefabs.GetEnumerator(); try { while (<>s__6.MoveNext()) { <kvp>5__7 = <>s__6.Current; <prefabName>5__8 = <kvp>5__7.Key; <verifyPrefab>5__9 = ObjectDB.instance.GetItemPrefab(<prefabName>5__8); if ((Object)(object)<verifyPrefab>5__9 != (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("FINAL CHECK: " + <prefabName>5__8 + " exists in ObjectDB")); } else { ValhalLootPlugin.ValhalLootLogger.LogError((object)("FINAL CHECK FAILED: " + <prefabName>5__8 + " still not in ObjectDB!")); } <prefabName>5__8 = null; <verifyPrefab>5__9 = null; <kvp>5__7 = default(KeyValuePair<string, GameObject>); } } finally { ((IDisposable)<>s__6).Dispose(); } <>s__6 = default(Dictionary<string, GameObject>.Enumerator); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] private static ValhalLootManager _instance; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] private ValhalLootConfig _config = null; private bool _isInitialized = false; private Dictionary<string, GameObject> _biomePrefabs = new Dictionary<string, GameObject>(); public Dictionary<string, string> _biomeToPrefabMap = new Dictionary<string, string> { { "Meadows", "meadowsloot_ru" }, { "BlackForest", "blackforestloot_ru" }, { "Swamp", "swamploot_ru" }, { "Mountain", "mountainsloot_ru" }, { "Plains", "plainsloot_ru" }, { "Mistlands", "mistlandsloot_ru" }, { "Ashlands", "ashlandsloot_ru" } }; private readonly Dictionary<string, string> _chestPrefabToBiome = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "meadowsloot_ru", "Meadows" }, { "blackforestloot_ru", "BlackForest" }, { "swamploot_ru", "Swamp" }, { "mountainsloot_ru", "Mountain" }, { "plainsloot_ru", "Plains" }, { "mistlandsloot_ru", "Mistlands" }, { "ashlandsloot_ru", "Ashlands" } }; private static readonly Dictionary<string, BiomeConfig> _biomeConfigs = new Dictionary<string, BiomeConfig>(StringComparer.OrdinalIgnoreCase) { { "Meadows", new BiomeConfig { Resources = new string[5] { "leather", "deer hide", "flint", "wood", "resin" }, CraftingStations = new string[2] { "workbench", "$piece_workbench" } } }, { "BlackForest", new BiomeConfig { Resources = new string[5] { "bronze", "copper", "tin", "core wood", "troll hide" }, CraftingStations = new string[2] { "forge", "$piece_forge" } } }, { "Swamp", new BiomeConfig { Resources = new string[5] { "iron", "ancient bark", "root", "guck", "chain" }, CraftingStations = new string[2] { "forge", "$piece_forge" } } }, { "Mountain", new BiomeConfig { Resources = new string[5] { "silver", "wolf pelt", "wolf fang", "obsidian", "dragon tear" }, CraftingStations = new string[2] { "forge", "$piece_forge" } } }, { "Plains", new BiomeConfig { Resources = new string[5] { "black metal", "linen thread", "needle", "lox pelt", "barley" }, CraftingStations = new string[4] { "forge", "$piece_forge", "artisan table", "$piece_artisanstation" } } }, { "Mistlands", new BiomeConfig { Resources = new string[6] { "carapace", "refined eitr", "yggdrasil wood", "scale hide", "bilebag", "mandible" }, CraftingStations = new string[4] { "black forge", "$piece_blackforge", "galdr table", "$piece_galdrtable" } } }, { "Ashlands", new BiomeConfig { Resources = new string[4] { "flametal", "asksvin hide", "primal lava", "charred bone" }, CraftingStations = new string[2] { "black forge", "$piece_blackforge" } } } }; private static readonly HashSet<string> _itemBlacklist = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "butcher knife", "deer" }; public static ValhalLootManager Instance => _instance; public ValhalLootConfig Config { get { return _config; } set { _config = value; } } public void Awake() { if ((Object)(object)_instance == (Object)null) { _instance = this; } else if ((Object)(object)_instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"ValhalLoot Manager awakening"); AddChestLocalizations(); PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable; } private void AddChestLocalizations() { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Adding chest item localizations"); Dictionary<string, string> dictionary = new Dictionary<string, string> { { "item_meadowsloot_ru", "Meadows Treasure Chest" }, { "item_meadowsloot_ru_description", "A chest containing treasures from the Meadows. Right-click to open." }, { "item_blackforestloot_ru", "Black Forest Treasure Chest" }, { "item_blackforestloot_ru_description", "A chest containing treasures from the Black Forest. Right-click to open." }, { "item_swamploot_ru", "Swamp Treasure Chest" }, { "item_swamploot_ru_description", "A chest containing treasures from the Swamp. Right-click to open." }, { "item_mountainsloot_ru", "Mountain Treasure Chest" }, { "item_mountainsloot_ru_description", "A chest containing treasures from the Mountains. Right-click to open." }, { "item_plainsloot_ru", "Plains Treasure Chest" }, { "item_plainsloot_ru_description", "A chest containing treasures from the Plains. Right-click to open." }, { "item_mistlandsloot_ru", "Mistlands Treasure Chest" }, { "item_mistlandsloot_ru_description", "A chest containing treasures from the Mistlands. Right-click to open." }, { "item_ashlandsloot_ru", "Ashlands Treasure Chest" }, { "item_ashlandsloot_ru_description", "A chest containing treasures from the Ashlands. Right-click to open." } }; try { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; localization.AddTranslation(ref text, dictionary); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$"Added {dictionary.Count} chest localizations to Jotunn"); } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)("Could not add Jotunn localizations in Awake: " + ex.Message)); } } private void OnVanillaPrefabsAvailable() { try { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Registering chest items with Jotunn"); AddLocalizationsToValheim(); RegisterChestPrefabs(); } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error in OnVanillaPrefabsAvailable: " + ex.Message)); } } private void AddLocalizationsToValheim() { if (Localization.instance == null) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"Localization.instance is null, cannot add chest localizations"); return; } Dictionary<string, string> dictionary = new Dictionary<string, string> { { "item_meadowsloot_ru", "Meadows Treasure Chest" }, { "item_meadowsloot_ru_description", "A chest containing treasures from the Meadows. Right-click to open." }, { "item_blackforestloot_ru", "Black Forest Treasure Chest" }, { "item_blackforestloot_ru_description", "A chest containing treasures from the Black Forest. Right-click to open." }, { "item_swamploot_ru", "Swamp Treasure Chest" }, { "item_swamploot_ru_description", "A chest containing treasures from the Swamp. Right-click to open." }, { "item_mountainsloot_ru", "Mountain Treasure Chest" }, { "item_mountainsloot_ru_description", "A chest containing treasures from the Mountains. Right-click to open." }, { "item_plainsloot_ru", "Plains Treasure Chest" }, { "item_plainsloot_ru_description", "A chest containing treasures from the Plains. Right-click to open." }, { "item_mistlandsloot_ru", "Mistlands Treasure Chest" }, { "item_mistlandsloot_ru_description", "A chest containing treasures from the Mistlands. Right-click to open." }, { "item_ashlandsloot_ru", "Ashlands Treasure Chest" }, { "item_ashlandsloot_ru_description", "A chest containing treasures from the Ashlands. Right-click to open." } }; foreach (KeyValuePair<string, string> item in dictionary) { Localization.instance.AddWord("$" + item.Key, item.Value); } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$"Added {dictionary.Count} chest localizations to Valheim's Localization.instance"); } private void RegisterChestPrefabs() { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) try { AssetBundle val = null; val = ((IEnumerable<AssetBundle>)Resources.FindObjectsOfTypeAll<AssetBundle>()).FirstOrDefault((Func<AssetBundle, bool>)([<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(0)] (AssetBundle a) => ((Object)a).name == "lootbundle_ru")); if ((Object)(object)val == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)"Failed to load lootbundle_ru asset bundle"); return; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Successfully loaded asset bundle: " + ((Object)val).name)); Sprite val2 = val.LoadAsset<Sprite>("valhalloot_ru_icon"); if ((Object)(object)val2 == (Object)null) { Sprite[] array = val.LoadAllAssets<Sprite>(); if (array != null && array.Length != 0) { val2 = array[0]; } else { Texture2D val3 = new Texture2D(1, 1); val3.SetPixel(0, 0, Color.white); val3.Apply(); val2 = Sprite.Create(val3, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f)); } } string[] array2 = new string[7] { "meadowsloot_ru", "blackforestloot_ru", "swamploot_ru", "mountainsloot_ru", "plainsloot_ru", "mistlandsloot_ru", "ashlandsloot_ru" }; int num = 0; string[] array3 = array2; foreach (string text in array3) { try { string text2 = text; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Loading prefab from asset bundle: " + text2)); GameObject val4 = val.LoadAsset<GameObject>(text2); if ((Object)(object)val4 == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)("Could not find prefab " + text)); continue; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Successfully loaded prefab for " + text)); if (_chestPrefabToBiome.TryGetValue(text, out var value)) { _biomePrefabs[value] = val4; } CreateJotunnCustomItem(val4, val2, text); num++; } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error registering prefab " + text + ": " + ex.Message)); } } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$"Registered {num} chest prefabs"); } catch (Exception ex2) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error in RegisterChestPrefabs: " + ex2.Message + "\n" + ex2.StackTrace)); } } public void ProcessChestUse(Player player, ItemData item) { if ((Object)(object)player == (Object)null || item == null) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"ProcessChestUse called with null player or item"); return; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Player " + player.GetPlayerName() + " used ValhalLoot chest")); if ((Object)(object)ValhalLootUI.Instance != (Object)null) { ValhalLootUI.Instance.ShowLootSelection(item); ((Humanoid)player).GetInventory().RemoveItem(item, 1); } } public string GetChestPrefabName(ItemData chestItem) { if (chestItem == null) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"Cannot get prefab name for null chest item"); return "meadowsloot_ru"; } GameObject dropPrefab = chestItem.m_dropPrefab; string text = ((dropPrefab != null) ? ((Object)dropPrefab).name : null) ?? ""; if (string.IsNullOrEmpty(text)) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"Chest item has no prefab name"); return "meadowsloot_ru"; } return text; } public void Initialize(ValhalLootConfig config) { Config = config; ((MonoBehaviour)this).StartCoroutine(InitializeWhenReady()); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"ValhalLoot Manager initialization started"); } [IteratorStateMachine(typeof(<InitializeWhenReady>d__22))] private IEnumerator InitializeWhenReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <InitializeWhenReady>d__22(0) { <>4__this = this }; } private bool IsCombatItem(SharedData shared) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 if (shared == null) { return false; } ItemType itemType = shared.m_itemType; return (int)itemType == 3 || (int)itemType == 14 || (int)itemType == 22 || (int)itemType == 4 || (int)itemType == 5 || (int)itemType == 7 || (int)itemType == 11 || (int)itemType == 6 || (int)itemType == 17 || (int)itemType == 12; } private void BuildDynamicChestLootFromObjectDB() { try { if (Config == null) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"[RECIPE LOOT] Cannot build dynamic loot: Config is null"); return; } if ((Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_recipes == null) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"[RECIPE LOOT] Cannot build dynamic loot: ObjectDB.instance or recipes is null"); return; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$"[RECIPE LOOT] Starting Recipe-based loot generation. Found {ObjectDB.instance.m_recipes.Count} total recipes."); Config.ChestLoot.Clear(); Dictionary<Recipe, string> dictionary = new Dictionary<Recipe, string>(); string[] array = new string[7] { "Ashlands", "Mistlands", "Plains", "Mountain", "Swamp", "BlackForest", "Meadows" }; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; string[] array2 = array; foreach (string text in array2) { if (!_biomeConfigs.TryGetValue(text, out var value)) { continue; } if (!_biomeToPrefabMap.TryGetValue(text, out var value2)) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)("[RECIPE LOOT] No chest prefab mapped for biome '" + text + "'")); continue; } List<LootEntry> list = new List<LootEntry>(); foreach (Recipe recipe in ObjectDB.instance.m_recipes) { num++; if ((Object)(object)recipe == (Object)null || (Object)(object)recipe.m_item == (Object)null || !recipe.m_enabled || dictionary.ContainsKey(recipe)) { continue; } ItemDrop item = recipe.m_item; if ((Object)(object)item == (Object)null || item.m_itemData == null || item.m_itemData.m_shared == null) { continue; } SharedData shared = item.m_itemData.m_shared; if (IsItemBlacklisted(((Object)((Component)recipe.m_item).gameObject).name, shared.m_name)) { num3++; continue; } if (!IsCombatItem(shared)) { num4++; continue; } bool flag = RecipeMatchesResources(recipe, value.Resources); bool flag2 = RecipeMatchesCraftingStation(recipe, value.CraftingStations); string text2 = ((Object)((Component)recipe.m_item).gameObject).name.ToLower(); bool flag3 = text2.Contains("blackmetal") || text2.Contains("sledge") || text2.Contains("flametal") || text2.Contains("carapace"); if (flag && flag2) { int num5 = Mathf.Max(1, shared.m_maxQuality); int minQuality = ((num5 < 2) ? 1 : 2); LootEntry item2 = new LootEntry { ItemName = ((Object)((Component)recipe.m_item).gameObject).name, MinQuality = minQuality, MaxQuality = num5, Weight = 1f, Recipe = recipe }; list.Add(item2); dictionary[recipe] = value2; num2++; } } if (list.Count > 0) { Config.ChestLoot[value2] = list; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$"[RECIPE LOOT] Biome '{text}' (chest '{value2}'): {list.Count} recipes assigned"); } else { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)("[RECIPE LOOT] Biome '" + text + "' has no matching recipes!")); } } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"[RECIPE LOOT] Recipe-based loot generation complete:"); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$" Total recipes scanned: {num}"); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$" Recipes assigned to chests: {num2}"); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$" Skipped (blacklisted): {num3}"); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$" Skipped (non-combat): {num4}"); } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error building Recipe-based chest loot tables: " + ex.Message + "\n" + ex.StackTrace)); } } private bool RecipeMatchesResources(Recipe recipe, string[] biomeResources) { if (recipe.m_resources == null || recipe.m_resources.Length == 0) { return false; } Requirement[] resources = recipe.m_resources; foreach (Requirement val in resources) { if ((Object)(object)val.m_resItem == (Object)null) { continue; } string text = ((Object)val.m_resItem).name.ToLower(); string text2 = Localization.instance.Localize(val.m_resItem.m_itemData.m_shared.m_name).ToLower(); foreach (string text3 in biomeResources) { string text4 = text3.ToLower(); bool flag = text == text4 || text2 == text4; bool flag2 = text.Contains(" " + text4 + " ") || text.StartsWith(text4 + " ") || text.EndsWith(" " + text4) || text2.Contains(" " + text4 + " ") || text2.StartsWith(text4 + " ") || text2.EndsWith(" " + text4); if (flag || flag2) { return true; } } } return false; } private bool RecipeMatchesCraftingStation(Recipe recipe, string[] biomeCraftingStations) { if ((Object)(object)recipe.m_craftingStation == (Object)null) { return false; } string text = ((Object)recipe.m_craftingStation).name.ToLower(); string text2 = Localization.instance.Localize(recipe.m_craftingStation.m_name).ToLower(); foreach (string text3 in biomeCraftingStations) { string value = text3.ToLower(); if (text.Contains(value) || text2.Contains(value)) { return true; } } return false; } private bool IsItemBlacklisted(string prefabName, string localizedName) { if (_itemBlacklist.Contains(prefabName.ToLower())) { return true; } string item = Localization.instance.Localize(localizedName).ToLower(); if (_itemBlacklist.Contains(item)) { return true; } return false; } private string NormalizeEnemyName(string name) { if (string.IsNullOrEmpty(name)) { return string.Empty; } string text = name.Replace("(Clone)", "").Trim(); return text.ToLowerInvariant(); } public void RegisterRPCs(ZRoutedRpc rpc) { //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) try { AssetBundle val = null; val = ((IEnumerable<AssetBundle>)Resources.FindObjectsOfTypeAll<AssetBundle>()).FirstOrDefault((Func<AssetBundle, bool>)([<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(0)] (AssetBundle a) => ((Object)a).name == "lootbundle_ru")); if ((Object)(object)val == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)"Failed to load lootbundle_ru asset bundle"); return; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Loading chest icon sprite"); Sprite val2 = val.LoadAsset<Sprite>("valhalloot_ru_icon"); if ((Object)(object)val2 == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"Could not find valhalloot_ru_icon, looking for any sprite in the bundle"); Sprite[] array = val.LoadAllAssets<Sprite>(); if (array != null && array.Length != 0) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$"Found {array.Length} sprites in the bundle, using the first one"); val2 = array[0]; } else { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"No sprites found in bundle, creating placeholder sprite"); Texture2D val3 = new Texture2D(1, 1); val3.SetPixel(0, 0, Color.white); val3.Apply(); val2 = Sprite.Create(val3, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f)); } } string[] array2 = new string[7] { "meadowsloot_ru", "blackforestloot_ru", "swamploot_ru", "mountainsloot_ru", "plainsloot_ru", "mistlandsloot_ru", "ashlandsloot_ru" }; Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>(); string[] array3 = array2; foreach (string text in array3) { string text2 = "assets/ruijven/valhalloot/" + text + ".prefab"; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Loading prefab directly from asset bundle: " + text2)); GameObject val4 = val.LoadAsset<GameObject>(text2); if ((Object)(object)val4 == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Failed to load prefab " + text2 + " from asset bundle")); continue; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Successfully loaded prefab for " + text)); dictionary[text] = val4; try { EnsureItemDropComponent(val4); new Item(val4, false); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Registered " + text + " with custom ItemManager")); } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error registering with custom ItemManager: " + ex.Message)); } try { CreateJotunnCustomItem(val4, val2, text); } catch (Exception ex2) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error registering with Jotunn: " + ex2.Message)); } } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Adding localization for chest items and UI elements"); Dictionary<string, string> dictionary2 = new Dictionary<string, string> { { "valhalloot_ui_title", "ValhalLoot Treasure" }, { "valhalloot_ui_description", "Select your reward" }, { "valhalloot_ui_select", "Claim" }, { "valhalloot_ui_close", "Close" }, { "valhalloot_drop_title", "Drop Loot Chest?" }, { "valhalloot_drop_message", "If you throw this Loot Chest away, you will not be able to reclaim it." }, { "valhalloot_drop_confirm", "Okay" }, { "valhalloot_drop_cancel", "Cancel" }, { "valhalloot_inventory_full", "Inventory full! Cannot receive loot chest." }, { "valhalloot_received", "Received a loot chest!" }, { "item_meadowsloot_ru", "Meadows Treasure Chest" }, { "item_meadowsloot_ru_description", "A chest containing treasures from the Meadows. Right-click to open." }, { "item_blackforestloot_ru", "Black Forest Treasure Chest" }, { "item_blackforestloot_ru_description", "A chest containing treasures from the Black Forest. Right-click to open." }, { "item_swamploot_ru", "Swamp Treasure Chest" }, { "item_swamploot_ru_description", "A chest containing treasures from the Swamp. Right-click to open." }, { "item_mountainsloot_ru", "Mountain Treasure Chest" }, { "item_mountainsloot_ru_description", "A chest containing treasures from the Mountains. Right-click to open." }, { "item_plainsloot_ru", "Plains Treasure Chest" }, { "item_plainsloot_ru_description", "A chest containing treasures from the Plains. Right-click to open." }, { "item_mistlandsloot_ru", "Mistlands Treasure Chest" }, { "item_mistlandsloot_ru_description", "A chest containing treasures from the Mistlands. Right-click to open." }, { "item_ashlandsloot_ru", "Ashlands Treasure Chest" }, { "item_ashlandsloot_ru_description", "A chest containing treasures from the Ashlands. Right-click to open." } }; CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text3 = "English"; localization.AddTranslation(ref text3, dictionary2); if (Localization.instance != null) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Adding translations to Valheim Localization system"); foreach (KeyValuePair<string, string> item in dictionary2) { Localization.instance.AddWord("$" + item.Key, item.Value); } } else { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"Valheim Localization instance not available, translations may not work properly"); } ((MonoBehaviour)this).StartCoroutine(VerifyAndFixRegistration(dictionary)); PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable; } catch (Exception ex3) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error registering chest items: " + ex3.Message)); ValhalLootPlugin.ValhalLootLogger.LogError((object)("Stack trace: " + ex3.StackTrace)); } } private void CreateJotunnCustomItem(GameObject prefab, Sprite iconSprite, string chestPrefabName) { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Expected O, but got Unknown //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Expected O, but got Unknown //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Expected O, but got Unknown //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)prefab == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Cannot create CustomItem: prefab is null for " + chestPrefabName)); return; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Creating Jotunn CustomItem for " + chestPrefabName)); ItemDrop val = prefab.GetComponent<ItemDrop>(); if ((Object)(object)val == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("ItemDrop component missing on " + ((Object)prefab).name + ", adding it")); try { val = prefab.AddComponent<ItemDrop>(); if ((Object)(object)val == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Failed to add ItemDrop component to " + ((Object)prefab).name)); return; } val.m_itemData = new ItemData(); val.m_itemData.m_shared = new SharedData(); } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Exception adding ItemDrop component: " + ex.Message + "\n" + ex.StackTrace)); return; } } if (val.m_itemData == null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("ItemDrop.m_itemData is null on " + ((Object)prefab).name)); val.m_itemData = new ItemData(); } if (val.m_itemData.m_shared == null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("ItemDrop.m_itemData.m_shared is null on " + ((Object)prefab).name)); val.m_itemData.m_shared = new SharedData(); } CustomItem val2 = null; try { val2 = new CustomItem(prefab, true); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("CustomItem created successfully for " + ((Object)prefab).name)); } catch (Exception ex2) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Failed to create CustomItem: " + ex2.Message + "\n" + ex2.StackTrace)); return; } if (val2 == null || (Object)(object)val2.ItemDrop == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("CustomItem or its ItemDrop is null for " + ((Object)prefab).name)); return; } SharedData shared = val2.ItemDrop.m_itemData.m_shared; shared.m_name = "$item_" + ((Object)prefab).name; shared.m_description = "$item_" + ((Object)prefab).name + "_description"; shared.m_maxQuality = 1; shared.m_maxStackSize = 20; shared.m_equipDuration = 0.2f; shared.m_variants = 1; shared.m_itemType = (ItemType)2; shared.m_animationState = (AnimationState)1; shared.m_questItem = true; shared.m_useDurability = false; shared.m_attack = new Attack(); shared.m_secondaryAttack = new Attack(); shared.m_damages = default(DamageTypes); shared.m_damagesPerLevel = default(DamageTypes); shared.m_damageModifiers = new List<DamageModPair>(); if ((Object)(object)iconSprite != (Object)null) { shared.m_icons = (Sprite[])(object)new Sprite[1] { iconSprite }; } else { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)("No icon sprite provided for " + chestPrefabName + ", creating placeholder")); Texture2D val3 = new Texture2D(1, 1); val3.SetPixel(0, 0, Color.white); val3.Apply(); Sprite val4 = Sprite.Create(val3, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f)); shared.m_icons = (Sprite[])(object)new Sprite[1] { val4 }; } if (val2.ItemDrop.m_itemData.m_customData == null) { val2.ItemDrop.m_itemData.m_customData = new Dictionary<string, string>(); } string key = "CustomData_ValhalLoot"; if (!val2.ItemDrop.m_itemData.m_customData.ContainsKey(key)) { val2.ItemDrop.m_itemData.m_customData[key] = "{}"; } val2.ItemDrop.m_itemData.m_customData["ChestID"] = Guid.NewGuid().ToString(); val2.ItemDrop.m_itemData.m_customData["PrefabName"] = chestPrefabName; ItemManager.Instance.AddItem(val2); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Successfully registered " + ((Object)prefab).name + " with Jotunn ItemManager")); if ((Object)(object)ObjectDB.instance != (Object)null) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(((Object)prefab).name); if (!((Object)(object)itemPrefab != (Object)null)) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("DEBUG: FAILED to find " + ((Object)prefab).name + " in ObjectDB after registration!")); } } } catch (Exception ex3) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error creating Jotunn CustomItem: " + ex3.Message)); ValhalLootPlugin.ValhalLootLogger.LogError((object)("Stack trace: " + ex3.StackTrace)); } } [IteratorStateMachine(typeof(<VerifyAndFixRegistration>d__31))] private IEnumerator VerifyAndFixRegistration(Dictionary<string, GameObject> loadedPrefabs) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <VerifyAndFixRegistration>d__31(0) { <>4__this = this, loadedPrefabs = loadedPrefabs }; } private void RegisterStatusEffect(StatusEffect statusEffect) { if ((Object)(object)statusEffect != (Object)null && (Object)(object)ObjectDB.instance != (Object)null && !Object.op_Implicit((Object)(object)ObjectDB.instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode(((Object)statusEffect).name)))) { ObjectDB.instance.m_StatusEffects.Add(statusEffect); } } private void EnsureItemDropComponent(GameObject prefab) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown ItemDrop val = prefab.GetComponent<ItemDrop>(); if ((Object)(object)val == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("ItemDrop component missing on " + ((Object)prefab).name + ", adding it")); val = prefab.AddComponent<ItemDrop>(); } if (val.m_itemData == null) { val.m_itemData = new ItemData(); } if (val.m_itemData.m_shared == null) { val.m_itemData.m_shared = new SharedData(); } SharedData shared = val.m_itemData.m_shared; shared.m_name = "$item_" + ((Object)prefab).name; shared.m_description = "$item_" + ((Object)prefab).name + "_description"; shared.m_maxQuality = 1; shared.m_maxStackSize = 20; shared.m_equipDuration = 0.2f; shared.m_variants = 1; shared.m_itemType = (ItemType)2; shared.m_animationState = (AnimationState)1; shared.m_questItem = true; shared.m_useDurability = false; } [return: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] private Player GetPlayerByID(string playerID) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(playerID) || (Object)(object)ZNet.instance == (Object)null) { return null; } long result; bool flag = long.TryParse(playerID, out result); List<ZNetPeer> peers = ZNet.instance.GetPeers(); foreach (ZNetPeer item in peers) { GameObject val = ZNetScene.instance.FindInstance(item.m_characterID); if ((Object)(object)val != (Object)null) { Player component = val.GetComponent<Player>(); if ((Object)(object)component != (Object)null && ((flag && component.GetPlayerID() == result) || (!flag && component.GetPlayerID().ToString() == playerID))) { return component; } } } if ((Object)(object)Player.m_localPlayer != (Object)null && ((flag && Player.m_localPlayer.GetPlayerID() == result) || (!flag && Player.m_localPlayer.GetPlayerID().ToString() == playerID))) { return Player.m_localPlayer; } return null; } public bool ShouldDropChest(Character enemy, Player killer) { if ((Object)(object)enemy == (Object)null || (Object)(object)killer == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"ShouldDropChest called with null enemy or killer"); return false; } if (!_isInitialized) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)("ValhalLootManager not fully initialized when checking drop for " + enemy.m_name + ". Checking if we can proceed anyway.")); if (Config == null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)"Cannot proceed with drop check: Config is null"); return false; } } string prefabName = Utils.GetPrefabName(((Component)enemy).gameObject); string text = NormalizeEnemyName(prefabName); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Normalized enemy prefab name from " + prefabName + " to " + text)); if (enemy.IsBoss()) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Enemy " + text + " is a boss")); string enemyChestPrefab = GetEnemyChestPrefab(enemy); if (string.IsNullOrEmpty(enemyChestPrefab)) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Boss " + text + " not found in any chest mapping, skipping drop")); return false; } float value = Config.BossDropChance.Value; float value2 = Random.value; bool flag = value2 <= value; string text2 = killer.GetPlayerID().ToString(); string playerName = killer.GetPlayerName(); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$"Boss drop roll for {text} (killed by {playerName}): {value2} vs chance {value}, shouldDrop: {flag}"); return flag; } List<string> list = new List<string> { "Skeleton_Hildir", "Fenring_Cultist_Hildir", "GoblinBrute_Hildir", "Charred_Melee_Dyrnwyn" }; if (list.Contains(text)) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Enemy " + text + " is in miniboss list")); string enemyChestPrefab2 = GetEnemyChestPrefab(enemy); if (string.IsNullOrEmpty(enemyChestPrefab2)) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Miniboss " + text + " not found in any chest mapping, skipping drop")); return false; } float value3 = Config.MinibossDropChance.Value; float value4 = Random.value; bool flag2 = value4 <= value3; string text3 = killer.GetPlayerID().ToString(); string playerName2 = killer.GetPlayerName(); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$"Miniboss drop roll for {text} (killed by {playerName2}): {value4} vs chance {value3}, shouldDrop: {flag2}"); return flag2; } string enemyChestPrefab3 = GetEnemyChestPrefab(enemy); if (!string.IsNullOrEmpty(enemyChestPrefab3)) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Enemy " + text + " is in chest-enemy mapping for " + enemyChestPrefab3)); float value5 = Config.CreatureDropChance.Value; float value6 = Random.value; bool flag3 = value6 <= value5; string text4 = killer.GetPlayerID().ToString(); string playerName3 = killer.GetPlayerName(); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)$"Regular creature drop roll for {text} (killed by {playerName3}): {value6} vs chance {value5}, shouldDrop: {flag3}"); return flag3; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Enemy " + text + " is not in any chest mapping, skipping drop")); return false; } public string GetEnemyChestPrefab(Character enemy) { if ((Object)(object)enemy == (Object)null) { return string.Empty; } try { string prefabName = Utils.GetPrefabName(((Component)enemy).gameObject); string text = NormalizeEnemyName(prefabName); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Mapping enemy: prefab=" + prefabName + ", normalized=" + text)); if (Config.EnemyToChestMap.TryGetValue(text, out var value)) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Enemy '" + text + "' directly mapped to chest '" + value + "'")); return value; } foreach (KeyValuePair<string, List<string>> item in Config.ChestEnemyMap) { string key = item.Key; List<string> value2 = item.Value; foreach (string item2 in value2) { if (text.Equals(item2, StringComparison.OrdinalIgnoreCase)) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Enemy '" + text + "' mapped to chest '" + key + "' via ChestEnemyMap match with '" + item2 + "'")); return key; } } } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Enemy '" + text + "' not found in any chest mapping, no chest will drop")); return string.Empty; } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error in GetEnemyChestPrefab: " + ex.Message)); return string.Empty; } } public void GiveChestToPlayer(Player player, string chestName) { try { if ((Object)(object)player == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)"Cannot give chest to null player"); return; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)"Player inventory is null"); return; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Requested chest: '" + chestName + "'")); if (string.IsNullOrEmpty(chestName) || (Object)(object)ObjectDB.instance == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)"Invalid chest name or ObjectDB not initialized"); return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(chestName); if ((Object)(object)itemPrefab == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Prefab for '" + chestName + "' not found in ObjectDB")); return; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Using chest prefab: " + ((Object)itemPrefab).name)); ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("ItemDrop component not found on chest prefab " + ((Object)itemPrefab).name)); return; } ItemData val; try { val = component.m_itemData.Clone(); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Successfully cloned ItemData"); val.m_shared.m_maxStackSize = 50; val.m_shared.m_weight = 0f; val.m_stack = 1; } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error cloning ItemData: " + ex.Message + "\n" + ex.StackTrace)); return; } if (!inventory.CanAddItem(val, -1)) { ((Character)player).Message((MessageType)2, "$valhalloot_inventory_full", 0, (Sprite)null); ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Could not give chest to player " + player.GetPlayerName() + ": Inventory full")); return; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Adding chest to player inventory"); if (inventory.AddItem(val)) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Chest added to player inventory successfully"); ((Character)player).Message((MessageType)2, "$valhalloot_received", 0, (Sprite)null); } else { ValhalLootPlugin.ValhalLootLogger.LogError((object)"Failed to add chest to inventory despite CanAddItem check"); ((Character)player).Message((MessageType)2, "$valhalloot_inventory_full", 0, (Sprite)null); } } catch (Exception ex2) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error giving chest to player: " + ex2.Message)); ValhalLootPlugin.ValhalLootLogger.LogError((object)("Stack trace: " + ex2.StackTrace)); } } } [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(1)] public class LootChestDropDialog : MonoBehaviour { [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] private static LootChestDropDialog _instance; private bool _isVisible = false; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] private Player _player; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(2)] private ItemData _item; private Rect _windowRect = new Rect((float)(Screen.width / 2 - 250), (float)(Screen.height / 2 - 100), 500f, 200f); private int _windowId = 6789; private GUIStyle _titleStyle = new GUIStyle(); private GUIStyle _textStyle = new GUIStyle(); private GUIStyle _buttonStyle = new GUIStyle(); private void Awake() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown _instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); _titleStyle = new GUIStyle(); _titleStyle.fontSize = 18; _titleStyle.fontStyle = (FontStyle)1; _titleStyle.normal.textColor = Color.white; _titleStyle.alignment = (TextAnchor)4; _textStyle = new GUIStyle(); _textStyle.fontSize = 14; _textStyle.normal.textColor = Color.white; _textStyle.alignment = (TextAnchor)4; _textStyle.wordWrap = true; _buttonStyle = new GUIStyle(GUI.skin.button); _buttonStyle.fontSize = 14; _buttonStyle.padding = new RectOffset(10, 10, 5, 5); } public static void ShowDropConfirmation(Player player, ItemData item) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown try { if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("LootChestDropDialog"); _instance = val.AddComponent<LootChestDropDialog>(); } _instance._player = player; _instance._item = item; _instance._isVisible = true; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Showing loot chest drop confirmation dialog"); } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error showing drop confirmation dialog: " + ex.Message)); } } private void OnGUI() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (_isVisible) { _windowRect = GUI.Window(_windowId, _windowRect, new WindowFunction(DrawWindow), ""); } } private void DrawWindow(int windowId) { string text = Localization.instance.Localize("$valhalloot_drop_title"); string text2 = Localization.instance.Localize("$valhalloot_drop_message"); string text3 = Localization.instance.Localize("$valhalloot_drop_confirm"); string text4 = Localization.instance.Localize("$valhalloot_drop_cancel"); if (string.IsNullOrEmpty(text)) { text = "Drop Loot Chest?"; } if (string.IsNullOrEmpty(text2)) { text2 = "If you throw this Loot Chest away, you will not be able to reclaim it."; } if (string.IsNullOrEmpty(text3)) { text3 = "Okay"; } if (string.IsNullOrEmpty(text4)) { text4 = "Cancel"; } GUILayout.Space(20f); GUILayout.Label(text, _titleStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(20f); GUILayout.Label(text2, _textStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(30f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); if (GUILayout.Button(text3, _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) })) { if ((Object)(object)_player != (Object)null && _item != null) { PerformDrop(_player, _item); } else { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"Cannot drop item: player or item is null"); } _isVisible = false; } GUILayout.Space(20f); if (GUILayout.Button(text4, _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) })) { _isVisible = false; } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUI.DragWindow(); } private static void PerformDrop(Player player, ItemData item) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) try { Inventory inventory = ((Humanoid)player).GetInventory(); inventory.RemoveItem(item); Vector3 val = ((Component)player).transform.position + ((Component)player).transform.forward + ((Component)player).transform.up; Quaternion identity = Quaternion.identity; ItemDrop component = Object.Instantiate<GameObject>(item.m_dropPrefab, val, identity).GetComponent<ItemDrop>(); component.m_itemData = item.Clone(); Rigidbody componentInChildren = ((Component)component).GetComponentInChildren<Rigidbody>(); if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.velocity = (((Component)player).transform.forward + Vector3.up) * 5f; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Player " + player.GetPlayerName() + " dropped loot chest after confirmation")); } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error dropping loot chest: " + ex.Message)); } } } public static class ValhalLootPatches { [HarmonyPatch(typeof(Character), "OnDeath")] [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(1)] [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] public static class Character_OnDeath_Patch { private static readonly FieldInfo Character_m_nview_Field = typeof(Character).GetField("m_nview", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo Character_m_lastHit_Field = typeof(Character).GetField("m_lastHit", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static void Postfix(Character __instance) { try { if ((Object)(object)__instance != (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Character death detected: " + __instance.m_name)); if (__instance.IsPlayer()) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Skipping player death"); return; } ZNetView characterNView = GetCharacterNView(__instance); if ((Object)(object)characterNView == (Object)null || !characterNView.IsValid()) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Warning: " + __instance.m_name + " has invalid ZDO but continuing with drop check")); } else if (!characterNView.IsOwner()) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Skipping " + __instance.m_name + " death: Not the owner")); return; } Player killingPlayer = GetKillingPlayer(__instance); if ((Object)(object)killingPlayer == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Skipping " + __instance.m_name + " death: No killer found")); return; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)(__instance.m_name + " was killed by player " + killingPlayer.GetPlayerName())); if ((Object)(object)ValhalLootManager.Instance == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"ValhalLootManager not initialized when processing creature death"); return; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Checking if " + __instance.m_name + " should drop a chest for " + killingPlayer.GetPlayerName())); if (ValhalLootManager.Instance.ShouldDropChest(__instance, killingPlayer)) { string enemyChestPrefab = ValhalLootManager.Instance.GetEnemyChestPrefab(__instance); if (string.IsNullOrEmpty(enemyChestPrefab)) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)("No chest prefab mapping found for " + __instance.m_name + ", skipping drop")); return; } ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Giving " + enemyChestPrefab + " chest to player " + killingPlayer.GetPlayerName() + " from " + __instance.m_name)); ValhalLootManager.Instance.GiveChestToPlayer(killingPlayer, enemyChestPrefab); } else { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("No chest will be given to player " + killingPlayer.GetPlayerName() + " from " + __instance.m_name)); } } else { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"Character death detected but instance is null"); } } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error in Character.OnDeath patch: " + ex.Message)); ValhalLootPlugin.ValhalLootLogger.LogError((object)("Stack trace: " + ex.StackTrace)); } } private static Player GetKillingPlayer(Character character) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)character == (Object)null) { return null; } HitData characterLastHit = GetCharacterLastHit(character); if (characterLastHit != null) { Character attacker = characterLastHit.GetAttacker(); if ((Object)(object)attacker != (Object)null && attacker.IsPlayer()) { return (Player)(object)((attacker is Player) ? attacker : null); } } List<Player> allPlayers = Player.GetAllPlayers(); Player result = null; float num = 50f; foreach (Player item in allPlayers) { if ((Object)(object)item != (Object)null) { float num2 = Vector3.Distance(((Component)character).transform.position, ((Component)item).transform.position); if (num2 < num) { result = item; num = num2; } } } return result; } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error determining killing player: " + ex.Message)); return null; } } private static ZNetView GetCharacterNView(Character character) { if ((Object)(object)character == (Object)null || Character_m_nview_Field == null) { return null; } object? value = Character_m_nview_Field.GetValue(character); return (ZNetView)((value is ZNetView) ? value : null); } private static HitData GetCharacterLastHit(Character character) { if ((Object)(object)character == (Object)null || Character_m_lastHit_Field == null) { return null; } object? value = Character_m_lastHit_Field.GetValue(character); return (HitData)((value is HitData) ? value : null); } } [HarmonyPatch(typeof(ItemData), "IsEquipable")] public static class ItemData_IsEquipable_Patch { [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(1)] private static void Postfix(ItemData __instance, ref bool __result) { if (__instance != null && __instance.m_shared.m_name.Contains("valhalloot")) { __result = true; } } } [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(1)] [HarmonyPatch(typeof(Humanoid), "UseItem")] public static class Humanoid_UseItem_Patch { private static bool Prefix(Humanoid __instance, ItemData item) { try { if (item != null) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { string key = "CustomData_ValhalLoot"; if (item.m_customData != null && item.m_customData.ContainsKey(key)) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"ValhalLoot chest used via Jotunn custom data"); OnChestItemUsed(item, val); return false; } if (item.m_shared.m_name != null && (item.m_shared.m_name.Contains("valhalloot") || item.m_shared.m_name.Contains("loot_ru"))) { ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"ValhalLoot chest used via name detection"); OnChestItemUsed(item, val); return false; } } } return true; } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error in Humanoid.UseItem patch: " + ex.Message)); return true; } } private static void OnChestItemUsed(ItemData item, Player player) { try { ValhalLootPlugin.ValhalLootLogger.LogDebug((object)("ValhalLoot chest used by " + player.GetPlayerName())); if ((Object)(object)ValhalLootUI.Instance == (Object)null) { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"ValhalLootUI not initialized when using chest item"); } else if ((Object)(object)ValhalLootManager.Instance != (Object)null) { ValhalLootManager.Instance.ProcessChestUse(player, item); } else { ValhalLootPlugin.ValhalLootLogger.LogWarning((object)"ValhalLootManager not initialized when using chest item"); } } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error processing chest item use: " + ex.Message)); } } } } [HarmonyPatch(typeof(Humanoid), "DropItem")] public static class Player_DropItem_Patch { [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(1)] private static bool Prefix(Humanoid __instance, Inventory inventory, ItemData item, int amount, ref bool __result) { try { if (item != null) { bool flag = false; string key = "CustomData_ValhalLoot"; if (item.m_customData != null && item.m_customData.ContainsKey(key)) { flag = true; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Intercepted drop of loot chest item via Jotunn custom data"); } else if (item.m_shared != null && item.m_shared.m_name != null && (item.m_shared.m_name.Contains("loot_ru") || item.m_shared.m_name.Contains("valhalloot"))) { flag = true; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)("Intercepted drop of loot chest item via name detection: " + item.m_shared.m_name)); } if (flag) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { LootChestDropDialog.ShowDropConfirmation(val, item); __result = true; return false; } } } return true; } catch (Exception ex) { ValhalLootPlugin.ValhalLootLogger.LogError((object)("Error in Player.DropItem patch: " + ex.Message)); return true; } } } [<022029f3-5fce-4252-8684-e6648986aff8>NullableContext(1)] [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] public class ValhalLootUI : MonoBehaviour { [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] private class ItemSlot { public GameObject Container = null; public Image Background = null; public Image Icon = null; public Text NameText = null; public Text QualityText = null; public Button SelectButton = null; public EventTrigger EventTrigger = null; public int SlotIndex; } [CompilerGenerated] private sealed class <InitializeAndShowLoot>d__27 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] private object <>2__current; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] public ItemData chestItem; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] public string prefabNameOverride; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] public ValhalLootUI <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] [return: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] [return: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] get { return <>2__current; } } [DebuggerHidden] public <InitializeAndShowLoot>d__27(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Starting UI initialization before showing loot"); if (!<>4__this._isInitialized || (Object)(object)<>4__this._uiPanel == (Object)null) { <>4__this.CreateUI(); <>4__this._isInitialized = true; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Created UI in InitializeAndShowLoot"); } <>4__this._chestItem = chestItem; <>4__this._currentChestPrefabName = <>4__this.GetChestPrefabNameWithFallbacks(chestItem, prefabNameOverride); <>4__this.GenerateLootOptions(<>4__this._currentChestPrefabName); <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this.UpdateUIElements(); if ((Object)(object)<>4__this._uiPanel != (Object)null) { <>4__this._uiPanel.SetActive(true); <>4__this._isVisible = true; GUIManager.BlockInput(true); } else { ValhalLootPlugin.ValhalLootLogger.LogError((object)"UI panel is null when trying to show it in InitializeAndShowLoot"); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <InitializeWhenReady>d__21 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] private object <>2__current; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] public ValhalLootUI <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] [return: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] [return: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] get { return <>2__current; } } [DebuggerHidden] public <InitializeWhenReady>d__21(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"Waiting for dependencies to be ready"); <>2__current = (object)new WaitUntil((Func<bool>)(() => (Object)(object)Player.m_localPlayer != (Object)null)); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = (object)new WaitUntil((Func<bool>)(() => GUIManager.Instance != null && (Object)(object)GUIManager.CustomGUIFront != (Object)null)); <>1__state = 2; return true; case 2: <>1__state = -1; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"All dependencies ready, creating UI"); <>4__this.CreateUI(); <>4__this._isInitialized = true; ValhalLootPlugin.ValhalLootLogger.LogInfo((object)"ValhalLoot UI fully initialized"); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <RetryGenerateLootOptions>d__31 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] private object <>2__current; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] public string chestPrefabName; [<6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] public ValhalLootUI <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] [return: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] [return: <6c1629e0-990f-46fb-933a-fb94e8696503>Nullable(0)] get { return <>2__current; } } [DebuggerHidden] public <RetryGenerateLootOptions>d__31(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknow