Please disclose if any significant portion of your mod was created 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 Drop That v3.1.4
Valheim.DropThat.dll
Decompiled 3 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.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CreatureLevelControl; using DropThat.Caches; using DropThat.Commands; using DropThat.Configuration; using DropThat.Configuration.Sync; using DropThat.Core; using DropThat.Core.Configuration; using DropThat.Core.Patches; using DropThat.Creature; using DropThat.Creature.DamageRecords; using DropThat.Creature.StatusRecords; using DropThat.Debugging; using DropThat.Drop; using DropThat.Drop.CharacterDropSystem; using DropThat.Drop.CharacterDropSystem.Caches; using DropThat.Drop.CharacterDropSystem.Conditions; using DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific.CLLC; using DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific.SpawnThat; using DropThat.Drop.CharacterDropSystem.Configuration; using DropThat.Drop.CharacterDropSystem.Configuration.Toml; using DropThat.Drop.CharacterDropSystem.Debug; using DropThat.Drop.CharacterDropSystem.Managers; using DropThat.Drop.CharacterDropSystem.Models; using DropThat.Drop.CharacterDropSystem.Patches; using DropThat.Drop.CharacterDropSystem.Services; using DropThat.Drop.CharacterDropSystem.Sync; using DropThat.Drop.DropTableSystem; using DropThat.Drop.DropTableSystem.Conditions; using DropThat.Drop.DropTableSystem.Conditions.ModSpecific.CLLC; using DropThat.Drop.DropTableSystem.Conditions.ModSpecific.SpawnThat; using DropThat.Drop.DropTableSystem.Configuration; using DropThat.Drop.DropTableSystem.Configuration.Toml; using DropThat.Drop.DropTableSystem.Debug; using DropThat.Drop.DropTableSystem.Managers; using DropThat.Drop.DropTableSystem.Models; using DropThat.Drop.DropTableSystem.Patches; using DropThat.Drop.DropTableSystem.Services; using DropThat.Drop.DropTableSystem.Sync; using DropThat.Drop.Options; using DropThat.Drop.Options.Modifiers; using DropThat.Drop.Options.Modifiers.ModEpicLoot; using DropThat.Integrations; using DropThat.Integrations.CllcIntegration; using DropThat.Integrations.EpicLootIntegration; using DropThat.Locations; using DropThat.Locations.Sync; using DropThat.Utilities; using DropThat.Utilities.Valheim; using EpicLoot; using EpicLoot.Data; using EpicLoot.LegendarySystem; using HarmonyLib; using Microsoft.CodeAnalysis; using ThatCore.Cache; using ThatCore.Config; using ThatCore.Config.Toml; using ThatCore.Config.Toml.Mapping; using ThatCore.Config.Toml.Parsers; using ThatCore.Config.Toml.Schema; using ThatCore.Config.Toml.Writers; using ThatCore.Extensions; using ThatCore.Lifecycle; using ThatCore.Lifecycle.Patches; using ThatCore.Logging; using ThatCore.Models; using ThatCore.Network; using ThatCore.Utilities.Files; using ThatCore.Utilities.Valheim; using UnityEngine; using Valheim.DropThat.Drop.DropTableSystem.Patches; 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.Callbacks; 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: AssemblyMetadata("RepositoryUrl", "https://github.com/ASharpPen/Valheim.SpawnThat")] [assembly: AssemblyTitle("Valheim.DropThat")] [assembly: AssemblyProduct("Valheim.DropThat")] [assembly: AssemblyInformationalVersion("3.1.4+06158da09d571592e8f64611d9d09ed4d138b8ef")] [assembly: AssemblyFileVersion("3.1.4.0")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCompany("A Sharp Pen")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: InternalsVisibleTo("Valheim.DropThat.Tests")] [assembly: AssemblyDescription("Valheim mod and tool for configuring loot drops.")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.1.4.0")] [module: <20da67ff-5d3f-4fc3-8c8a-7ca14c3b52f9>RefSafetyRules(11)] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<9291b86b-d23c-4f75-adf6-281ae3aea255>Embedded] internal sealed class <9291b86b-d23c-4f75-adf6-281ae3aea255>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] [CompilerGenerated] [<9291b86b-d23c-4f75-adf6-281ae3aea255>Embedded] internal sealed class <20da67ff-5d3f-4fc3-8c8a-7ca14c3b52f9>RefSafetyRulesAttribute : Attribute { public readonly int Version; public <20da67ff-5d3f-4fc3-8c8a-7ca14c3b52f9>RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Valheim.DropThat.Drop.DropTableSystem.Patches { [HarmonyPatch(typeof(MineRock5))] internal static class Patch_MineRock5_Fix_Naming { private static string _originalPrefabName { get; set; } [HarmonyPatch("Awake")] private static void Prefix(MineRock5 __instance) { if (((Object)(object)__instance).IsNotNull() && ((Object)(object)((Component)__instance).gameObject).IsNotNull()) { _originalPrefabName = ((Object)((Component)__instance).gameObject).name; } } [HarmonyPatch("Awake")] private static void Postfix(MineRock5 __instance) { if (((Object)(object)__instance).IsNotNull() && ((Object)(object)((Component)__instance).gameObject).IsNotNull() && _originalPrefabName != null) { ((Object)((Component)__instance).gameObject).name = _originalPrefabName; } } } } namespace DropThat { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("asharppen.valheim.drop_that", "Drop That!", "3.1.4")] public sealed class DropThatPlugin : BaseUnityPlugin { public const string ModId = "asharppen.valheim.drop_that"; public const string PluginName = "Drop That!"; public const string Version = "3.1.4"; private void Awake() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0030: Expected O, but got Unknown Log.SetLogger(new BepInExLogger(((BaseUnityPlugin)this).Logger)); GeneralConfigManager.Load(); Harmony val = new Harmony("asharppen.valheim.drop_that"); PatchCore(val); PatchCharacterDrop(val); PatchDropTableSystem(val); Startup.SetupServices(); } private static void PatchCore(Harmony harmony) { harmony.ApplyPatches(); harmony.PatchAll(typeof(Lifecycle_Patches)); harmony.PatchAll(typeof(Patch_WriteLocationsToFile)); } private static void PatchCharacterDrop(Harmony harmony) { harmony.PatchAll(typeof(Patch_Character_RecordHit)); harmony.PatchAll(typeof(Patch_CharacterDrop_ConfigureDroplist)); harmony.PatchAll(typeof(Patch_TrackDrops)); if (!InstallationManager.StarLevelSystemInstalled) { harmony.PatchAll(typeof(Patch_CharacterDrop_ConfigureDroppedItems)); } } private static void PatchDropTableSystem(Harmony harmony) { harmony.PatchAll(typeof(Patch_WriteDebugFiles)); harmony.PatchAll(typeof(Patch_Logistics.Patch_Container)); harmony.PatchAll(typeof(Patch_Logistics.Patch_DropOnDestroyed)); harmony.PatchAll(typeof(Patch_Logistics.Patch_LootSpawner)); harmony.PatchAll(typeof(Patch_Logistics.Patch_TreeBase)); harmony.PatchAll(typeof(Patch_Logistics.Patch_TreeLog)); harmony.PatchAll(typeof(Patch_Logistics.Patch_MineRock)); harmony.PatchAll(typeof(Patch_Logistics.Patch_MineRock5)); harmony.PatchAll(typeof(Patch_MineRock5_Fix_Naming)); harmony.PatchAll(typeof(Patch_RollDrops)); if (!InstallationManager.StarLevelSystemInstalled) { harmony.PatchAll(typeof(Patch_ModifyInstantiatedDrops.Patch_DropOnDestroyed_OnDestroyed)); harmony.PatchAll(typeof(Patch_ModifyInstantiatedDrops.Patch_LootSpawner_UpdateSpawner)); harmony.PatchAll(typeof(Patch_ModifyInstantiatedDrops.Patch_TreeLog_Destroy)); harmony.PatchAll(typeof(Patch_ModifyInstantiatedDrops.Patch_TreeBase_RPC_Damage)); harmony.PatchAll(typeof(Patch_ModifyInstantiatedDrops.Patch_MineRock_RPC_Hit)); harmony.PatchAll(typeof(Patch_ModifyInstantiatedDrops.Patch_MineRock5_DamageArea)); } } } internal static class Startup { public static void SetupServices() { LifecycleManager.OnLateInit += LoadConfigs; LifecycleManager.OnNewConnection += SyncManager.SetupConfigSyncForPeer; GeneralConfigStartup.Setup(); CharacterDropSystemStartup.Setup(); DropTableSystemStartup.Setup(); LocationSyncManager.Configure(); LoadCommands(); } private static void LoadConfigs() { Log.Development?.Log("Loading configs: " + LifecycleManager.GameState); GameState gameState = LifecycleManager.GameState; if ((gameState == GameState.Singleplayer || gameState == GameState.DedicatedServer) ? true : false) { DropSystemConfigManager.LoadConfigs(); } } private static void LoadCommands() { ReloadConfigsCommand.Register(); WriteLoadedDropTablesCommand.Register(); WriteSchemaCommand.Register(); } } } namespace DropThat.Utilities { internal static class HashSetExtensions { public static void AddNullSafe<T>(this HashSet<T> set, T candidate) where T : class { if (set != null && candidate != null) { set.Add(candidate); } } } internal static class ListExtensions { public static void AddNullSafe<T>(this List<T> list, T candidate) where T : class { if (list != null && candidate != null) { list.Add(candidate); } } } internal static class ReflectionUtils { private static MethodInfo InstantiateGameObject; private static MethodInfo ListGameObjectMoveNext; public static MethodInfo InstantiateGameObjectMethod => InstantiateGameObject ?? (InstantiateGameObject = (from x in typeof(Object).GetMethods(BindingFlags.Static | BindingFlags.Public) where x.Name.Equals("Instantiate") select x into m where m.IsGenericMethod select m).First((MethodInfo m) => m.ContainsGenericParameters && m.GetParameters().Length == 3 && m.GetParameters()[2].ParameterType == typeof(Quaternion)).GetGenericMethodDefinition().MakeGenericMethod(typeof(GameObject))); public static MethodInfo ListGameObjectMoveNextMethod => ListGameObjectMoveNext ?? (ListGameObjectMoveNext = typeof(List<GameObject>.Enumerator).GetMethod("MoveNext")); } public static class StringExtensions { private static char[] Comma = new char[1] { ',' }; public static List<string> SplitBy(this string value, char splitChar, bool toUpper = false) { string[] array = value.Split(new char[1] { splitChar }, StringSplitOptions.RemoveEmptyEntries); if (array == null || array.Length == 0) { return new List<string>(); } return array.Select((string x) => Clean(x, toUpper)).ToList(); } public static List<string> SplitByComma(this string value, bool toUpper = false) { string[] array = value.Split(Comma, StringSplitOptions.RemoveEmptyEntries); if (array == null || array.Length == 0) { return new List<string>(); } return array.Select((string x) => Clean(x, toUpper)).ToList(); } private static string Clean(string x, bool toUpper) { string text = x.Trim(); if (toUpper) { return text.ToUpperInvariant(); } return text; } public static bool TryConvertToEnum<T>(this IEnumerable<string> strings, out List<T> enums) where T : struct { enums = new List<T>(); foreach (string @string in strings) { if (Enum.TryParse<T>(@string, ignoreCase: true, out var result)) { enums.Add(result); continue; } return false; } return true; } } } namespace DropThat.Utilities.Valheim { internal static class BiomeExtensions { public static string GetNames(this Biome biome) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return biome.Split().Join(); } } public static class HitDataExtensions { public static DamageType GetCombinedDamageType(this HitData hit) { //IL_0001: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) DamageType val = (DamageType)0; if (hit.m_damage.m_blunt > 0f) { val = (DamageType)(val | 1); } if (hit.m_damage.m_slash > 0f) { val = (DamageType)(val | 2); } if (hit.m_damage.m_pierce > 0f) { val = (DamageType)(val | 4); } if (hit.m_damage.m_chop > 0f) { val = (DamageType)(val | 8); } if (hit.m_damage.m_pickaxe > 0f) { val = (DamageType)(val | 0x10); } if (hit.m_damage.m_fire > 0f) { val = (DamageType)(val | 0x20); } if (hit.m_damage.m_frost > 0f) { val = (DamageType)(val | 0x40); } if (hit.m_damage.m_lightning > 0f) { val = (DamageType)(val | 0x80); } if (hit.m_damage.m_poison > 0f) { val = (DamageType)(val | 0x100); } if (hit.m_damage.m_spirit > 0f) { val = (DamageType)(val | 0x200); } return val; } } public static class ZdoExtensions { private const string Prefix = "DropThat_"; private static readonly int _spawnBiomeHash = StringExtensionMethods.GetStableHashCode("DropThat_spawn-biome"); private static readonly int _spawnPositionHash = StringExtensionMethods.GetStableHashCode("DropThat_spawn-position"); public static Biome? GetSpawnBiome(this ZDO zdo) { int @int = zdo.GetInt(_spawnBiomeHash, -1); if (@int < 0) { return null; } return (Biome)@int; } public static void SetSpawnBiome(this ZDO zdo, Biome? biome) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected I4, but got Unknown if (!biome.HasValue || biome < 0) { zdo.RemoveInt(_spawnBiomeHash); } else { zdo.Set(_spawnBiomeHash, (int)biome.Value, false); } } public static Vector3? GetSpawnPosition(this ZDO zdo) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) Vector3 value2 = default(Vector3); if (ZDOExtraData.s_vec3.TryGetValue(zdo.m_uid, out var value) && value.TryGetValue(_spawnPositionHash, ref value2)) { return value2; } return null; } public static void SetSpawnPosition(this ZDO zdo, Vector3? value) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!value.HasValue) { zdo.RemoveInt(_spawnPositionHash); } else { zdo.Set(_spawnPositionHash, value.Value); } } } } namespace DropThat.Locations { public static class LocationHelper { private static Dictionary<Vector2i, SimpleLocation> _simpleLocationsByZone { get; set; } static LocationHelper() { LifecycleManager.OnWorldInit += delegate { _simpleLocationsByZone = null; }; } internal static void SetLocations(IEnumerable<SimpleLocation> locations) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (_simpleLocationsByZone == null) { _simpleLocationsByZone = new Dictionary<Vector2i, SimpleLocation>(); } foreach (SimpleLocation location in locations) { _simpleLocationsByZone[location.ZonePosition] = location; } } public static SimpleLocation FindLocation(Vector3 position) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if (((Object)(object)ZoneSystem.instance).IsNull()) { Log.Warning?.Log("Attempting to retrieve location before ZoneSystem is initialized."); return null; } Vector2i zone = ZoneSystem.GetZone(position); if (((Object)(object)ZoneSystem.instance).IsNotNull() && (ZoneSystem.instance.m_locationInstances?.Count ?? 0) > 0 && ZoneSystem.instance.m_locationInstances.TryGetValue(zone, out var value)) { return new SimpleLocation { LocationName = (value.m_location?.m_prefabName ?? ""), Position = value.m_position, ZonePosition = zone }; } if (_simpleLocationsByZone != null && _simpleLocationsByZone.TryGetValue(zone, out var value2)) { return value2; } return null; } } public sealed class SimpleLocation { public Vector3 Position; public Vector2i ZonePosition; public string LocationName; } } namespace DropThat.Locations.Sync { internal static class LocationSyncManager { public static void Configure() { SyncManager.RegisterSyncHandlers("RPC_DropThat_ReceiveSimpleLocations", GenerateMessage, RPC_DropThat_ReceiveSimpleLocations); } private static IMessage GenerateMessage() { return new SimpleLocationMessage(); } private static void RPC_DropThat_ReceiveSimpleLocations(ZRpc rpc, ZPackage package) { try { IncomingMessageService.ReceiveMessageAsync<SimpleLocationMessage>(package); } catch (Exception e) { Log.Error?.Log("Error while attempting to receive locations package.", e); } } } internal sealed class SimpleLocationMessage : IMessage { public string[] LocationNames; public SimpleLocationDTO[] Locations; public void Initialize() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) Dictionary<Vector2i, LocationInstance> locationInstances = ZoneSystem.instance.m_locationInstances; Dictionary<string, ushort> dictionary = new Dictionary<string, ushort>(); List<string> list = new List<string>(); List<SimpleLocationDTO> list2 = new List<SimpleLocationDTO>(); foreach (KeyValuePair<Vector2i, LocationInstance> item in locationInstances) { string prefabName = item.Value.m_location.m_prefabName; ushort num; if (dictionary.TryGetValue(item.Value.m_location.m_prefabName, out var value)) { num = value; } else { list.Add(prefabName); num = (ushort)(list.Count - 1); dictionary.Add(prefabName, num); } list2.Add(new SimpleLocationDTO(item.Key, num)); } LocationNames = list.ToArray(); Locations = list2.ToArray(); Log.Trace?.Log($"Packed {LocationNames.Length} location names"); Log.Trace?.Log($"Packed {Locations.Length} locations"); } public void AfterUnpack() { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) Log.Trace?.Log($"Unpacking {LocationNames.Length} location names"); Log.Trace?.Log($"Unpacking {Locations.Length} locations"); List<SimpleLocation> list = new List<SimpleLocation>(Locations.Length); SimpleLocationDTO[] locations = Locations; Vector2i val = default(Vector2i); for (int i = 0; i < locations.Length; i++) { SimpleLocationDTO simpleLocationDTO = locations[i]; ((Vector2i)(ref val))..ctor(simpleLocationDTO.X, simpleLocationDTO.Y); list.Add(new SimpleLocation { LocationName = LocationNames[simpleLocationDTO.Location], Position = ZoneSystem.GetZonePos(val), ZonePosition = val }); } LocationHelper.SetLocations(list); } } public struct SimpleLocationDTO { public int X; public int Y; public ushort Location; public SimpleLocationDTO(Vector2i pos, ushort location) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) X = pos.x; Y = pos.y; Location = location; } } } namespace DropThat.Integrations { public static class InstallationManager { public static bool EpicLootInstalled { get; } = (object)Type.GetType("EpicLoot.EpicLoot, EpicLoot") != null; public static bool RRRInstalled { get; } = (object)Type.GetType("RRRCore.Plugin, RRRCore") != null; public static bool SpawnThatInstalled { get; } = Chainloader.PluginInfos.ContainsKey("asharppen.valheim.spawn_that"); public static bool CLLCInstalled { get; } = (object)Type.GetType("CreatureLevelControl.API, CreatureLevelControl") != null; public static bool StarLevelSystemInstalled { get; } = (object)Type.GetType("StarLevelSystem.StarLevelSystem,StarLevelSystem") != null; } } namespace DropThat.Integrations.EpicLootIntegration { internal static class ItemRoller { internal static bool TryRollMagic(ItemData itemData, Vector3 dropPos, ItemRollParameters parameters) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (!EpicLoot.CanBeMagicItem(itemData)) { Log.Development?.Log("Item '" + itemData.m_shared.m_name + "' can't be made magic."); return false; } Rarity rarity = ItemService.RollRarity(parameters); Log.Development?.Log($"Item '{itemData.m_shared.m_name}' rolled rarity '{rarity}'."); switch (rarity) { case Rarity.None: return false; case Rarity.Unique: return ItemService.TryMakeUnique(itemData, parameters); default: { ItemRarity? val = ItemService.RarityToItemRarity(rarity); if (val.HasValue) { ItemService.MakeMagic(val.Value, itemData, dropPos); return true; } return false; } } } } internal sealed class ItemRollParameters { public float RarityWeightNone { get; set; } public float RarityWeightMagic { get; set; } public float RarityWeightRare { get; set; } public float RarityWeightEpic { get; set; } public float RarityWeightLegendary { get; set; } public float RarityWeightUnique { get; set; } public List<string> UniqueIds { get; set; } } internal static class ItemService { public static bool TryMakeUnique(ItemData itemData, ItemRollParameters parameters) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown if (parameters.UniqueIds == null || parameters.UniqueIds.Count == 0) { return false; } string text = parameters.UniqueIds[Random.Range(0, parameters.UniqueIds.Count)]; LegendaryInfo val = default(LegendaryInfo); if (!UniqueLegendaryHelper.TryGetLegendaryInfo(text, ref val)) { Log.Warning?.Log("Attempted to roll Epic Loot unique legendary with id '" + text + "' but was unable to find matching info registered in Epic Loot."); return false; } MagicItem val2 = new MagicItem { Rarity = (ItemRarity)3, LegendaryID = val.ID, DisplayName = val.Name }; if (!val.Requirements.CheckRequirements(itemData, val2, (string)null, true, false, false)) { Log.Warning?.Log("Attempted to roll Epic Loot unique legendary with id '" + text + "' but requirements were not met. Skipping."); return false; } if (val.IsSetItem) { val2.SetID = UniqueLegendaryHelper.GetSetForLegendaryItem(val); } if ((val.GuaranteedMagicEffects?.Count ?? 0) > 0) { foreach (GuaranteedMagicEffect guaranteedMagicEffect in val.GuaranteedMagicEffects) { if (MagicItemEffectDefinitions.AllDefinitions.TryGetValue(guaranteedMagicEffect.Type, out var value)) { MagicItemEffect item = LootRoller.RollEffect(value, (ItemRarity)3, guaranteedMagicEffect.Values, 1f); val2.Effects.Add(item); continue; } Log.Warning?.Log("Unable to find a guaranteed Epic Loot magic effect '" + guaranteedMagicEffect.Type + "' while rolling unique legendary with id '" + text + "'. Skipping effect."); } } int num = LootRoller.RollEffectCountPerRarity((ItemRarity)3) - val2.Effects.Count; if (num > 0) { List<MagicItemEffectDefinition> availableEffects = MagicItemEffectDefinitions.GetAvailableEffects(itemData, val2, -1, true, false, false); for (int i = 0; i < num; i++) { MagicItemEffect item2 = LootRoller.RollEffect(RollWeightedEffect(availableEffects, removeSelected: false), (ItemRarity)3, (ValueDef)null, 1f); val2.Effects.Add(item2); } } ItemExtensions.Data(itemData).GetOrCreate<MagicItemComponent>("").SetMagicItem(val2); LootRoller.InitializeMagicItem(itemData); return true; } public static void MakeMagic(ItemRarity rarity, ItemData itemData, Vector3 position) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) MagicItemComponent orCreate = ItemExtensions.Data(itemData).GetOrCreate<MagicItemComponent>(""); float luckFactor = LootRoller.GetLuckFactor(position); MagicItem val = LootRoller.RollMagicItem(rarity, itemData, luckFactor, 1f); Log.Development?.Log("\t" + GeneralExtensions.Join<MagicItemEffect>((IEnumerable<MagicItemEffect>)val.Effects, (Func<MagicItemEffect, string>)((MagicItemEffect x) => x.EffectType), ", ")); orCreate.SetMagicItem(val); LootRoller.InitializeMagicItem(itemData); } private static MagicItemEffectDefinition RollWeightedEffect(List<MagicItemEffectDefinition> magicEffects, bool removeSelected) { float num = magicEffects.Sum((MagicItemEffectDefinition x) => x.SelectionWeight); float num2 = Random.Range(0f, num); float num3 = 0f; for (int i = 0; i < magicEffects.Count; i++) { MagicItemEffectDefinition val = magicEffects[i]; num3 += val.SelectionWeight; if (num2 <= num3) { if (removeSelected) { magicEffects.RemoveAt(i); } return val; } } return magicEffects.Last(); } public static Rarity RollRarity(ItemRollParameters parameters) { float num = parameters.RarityWeightNone + parameters.RarityWeightMagic + parameters.RarityWeightRare + parameters.RarityWeightEpic + parameters.RarityWeightLegendary + parameters.RarityWeightUnique; float num2 = Random.Range(0f, num); double num3 = 0.0; num3 += (double)parameters.RarityWeightUnique; if (parameters.RarityWeightUnique > 0f && (double)num2 <= num3) { return Rarity.Unique; } num3 += (double)parameters.RarityWeightLegendary; if (parameters.RarityWeightLegendary > 0f && (double)num2 <= num3) { return Rarity.Legendary; } num3 += (double)parameters.RarityWeightEpic; if (parameters.RarityWeightEpic > 0f && (double)num2 <= num3) { return Rarity.Epic; } num3 += (double)parameters.RarityWeightRare; if (parameters.RarityWeightRare > 0f && (double)num2 <= num3) { return Rarity.Rare; } num3 += (double)parameters.RarityWeightMagic; if (parameters.RarityWeightMagic > 0f && (double)num2 <= num3) { return Rarity.Magic; } return Rarity.None; } public static ItemRarity? RarityToItemRarity(Rarity rarity) { return rarity switch { Rarity.None => null, Rarity.Magic => (ItemRarity)0, Rarity.Rare => (ItemRarity)1, Rarity.Epic => (ItemRarity)2, Rarity.Legendary => (ItemRarity)3, Rarity.Unique => (ItemRarity)3, _ => null, }; } } internal enum Rarity { None, Magic, Rare, Epic, Legendary, Unique } } namespace DropThat.Integrations.CllcIntegration { public enum CllcBossAffix { None, Reflective, Shielded, Mending, Summoner, Elementalist, Enraged, Twin } internal static class CllcBossAffixExtensions { public static BossAffix Convert(this CllcBossAffix affix) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) return (BossAffix)(affix switch { CllcBossAffix.Reflective => 1, CllcBossAffix.Shielded => 2, CllcBossAffix.Mending => 3, CllcBossAffix.Summoner => 4, CllcBossAffix.Elementalist => 5, CllcBossAffix.Enraged => 6, CllcBossAffix.Twin => 7, _ => 0, }); } } public enum CllcCreatureExtraEffect { None, Aggressive, Quick, Regenerating, Curious, Splitting, Armored } internal static class CllcCreatureExtraEffectExtensions { public static CreatureExtraEffect Convert(this CllcCreatureExtraEffect extraEffect) { //IL_0023: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //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_003b: Unknown result type (might be due to invalid IL or missing references) return (CreatureExtraEffect)(extraEffect switch { CllcCreatureExtraEffect.Aggressive => 1, CllcCreatureExtraEffect.Quick => 2, CllcCreatureExtraEffect.Regenerating => 3, CllcCreatureExtraEffect.Curious => 4, CllcCreatureExtraEffect.Splitting => 5, CllcCreatureExtraEffect.Armored => 6, _ => 0, }); } } public enum CllcCreatureInfusion { None, Lightning, Fire, Frost, Poison, Chaos, Spirit } internal static class CllcCreatureInfusionExtensions { public static CreatureInfusion Convert(this CllcCreatureInfusion infusion) { //IL_0023: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //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_003b: Unknown result type (might be due to invalid IL or missing references) return (CreatureInfusion)(infusion switch { CllcCreatureInfusion.Lightning => 1, CllcCreatureInfusion.Fire => 2, CllcCreatureInfusion.Frost => 3, CllcCreatureInfusion.Poison => 4, CllcCreatureInfusion.Chaos => 5, CllcCreatureInfusion.Spirit => 6, _ => 0, }); } } } namespace DropThat.Drop { internal sealed class DropSystemConfigCollection : IDropSystemConfigCollection { private Dictionary<Type, IDropSystemConfig> _dropSystemConfigs = new Dictionary<Type, IDropSystemConfig>(); public List<IDropSystemConfig> GetDropSystemConfigs() { return _dropSystemConfigs.Values.ToList(); } public TDropSystemConfig GetDropSystemConfig<TDropSystemConfig>() where TDropSystemConfig : IDropSystemConfig, new() { Type typeFromHandle = typeof(TDropSystemConfig); TDropSystemConfig val; if (_dropSystemConfigs.TryGetValue(typeFromHandle, out var value)) { val = (TDropSystemConfig)value; } else { val = new TDropSystemConfig(); _dropSystemConfigs[typeFromHandle] = val; } return val; } internal void Build() { foreach (IDropSystemConfig value in _dropSystemConfigs.Values) { try { value.Build(); } catch (Exception e) { Log.Error?.Log("Error during build of drop config " + value?.GetType()?.Name, e); } } } } public static class DropSystemConfigManager { public static event Action<IDropSystemConfigCollection> OnConfigure; internal static event Action<IDropSystemConfigCollection> OnConfigureLate; internal static event Action OnConfigsLoadedEarly; public static event Action OnConfigsLoaded; internal static void ConfigsLoaded() { Log.Trace?.Log("Running OnConfigsLoaded actions."); DropSystemConfigManager.OnConfigsLoadedEarly.Raise("Error during configs loaded event."); DropSystemConfigManager.OnConfigsLoaded.Raise("Error during configs loaded event."); } internal static void LoadConfigs() { Log.Trace?.Log("Loading configs."); DropSystemConfigCollection dropSystemConfigCollection = new DropSystemConfigCollection(); DropSystemConfigManager.OnConfigure.Raise(dropSystemConfigCollection); DropSystemConfigManager.OnConfigureLate.Raise(dropSystemConfigCollection); dropSystemConfigCollection.Build(); ConfigsLoaded(); } } public interface IDropSystemConfig { void Build(); } public interface IDropSystemConfigCollection { List<IDropSystemConfig> GetDropSystemConfigs(); TDropSystemConfig GetDropSystemConfig<TDropSystemConfig>() where TDropSystemConfig : IDropSystemConfig, new(); } } namespace DropThat.Drop.Options { public interface IHaveItemModifiers { ICollection<IItemModifier> ItemModifiers { get; } } public interface IItemModifier { void Modify(ItemModifierContext<GameObject> drop); void Modify(ItemModifierContext<ItemData> drop); bool IsPointless(); } public static class IItemModifierExtensions { public static T GetOrDefault<T>(this ICollection<IItemModifier> modifiers) { return modifiers.OfType<T>().FirstOrDefault(); } } public sealed class ItemModifierContext<T> where T : class { public T Item { get; set; } public Vector3 Position { get; set; } } } namespace DropThat.Drop.Options.Modifiers { public sealed class ModifierDurability : IItemModifier { public float? Durability { get; set; } public bool IsPointless() { if (Durability.HasValue) { return Durability < 0f; } return true; } public void Modify(ItemModifierContext<GameObject> drop) { if (Durability.HasValue && !(Durability < 0f)) { ItemDrop val = ComponentCache.Get<ItemDrop>(drop.Item); if (!((Object)(object)val).IsNull()) { Log.Trace?.Log($"Setting durability of item '{((Object)val).name}' to {Durability}."); val.m_itemData.m_durability = Durability.Value; } } } public void Modify(ItemModifierContext<ItemData> drop) { if (Durability.HasValue && !(Durability < 0f)) { Log.Trace?.Log($"Setting durability of item '{((Object)drop.Item.m_dropPrefab).name}' to {Durability}."); drop.Item.m_durability = Durability.Value; } } } public sealed class ModifierQualityLevel : IItemModifier { public int? QualityLevel { get; set; } public bool IsPointless() { if (QualityLevel.HasValue) { return QualityLevel <= 0; } return true; } public void Modify(ItemModifierContext<GameObject> drop) { if (!IsPointless()) { ItemDrop val = ComponentCache.Get<ItemDrop>(drop.Item); if (!((Object)(object)val).IsNull()) { Log.Trace?.Log($"Setting quality level of item '{((Object)val).name}' to {QualityLevel}."); val.m_itemData.m_quality = QualityLevel.Value; } } } public void Modify(ItemModifierContext<ItemData> drop) { if (!IsPointless()) { Log.Trace?.Log($"Setting quality level of item '{((Object)drop.Item.m_dropPrefab).name}' to {QualityLevel}."); drop.Item.m_quality = QualityLevel.Value; } } } } namespace DropThat.Drop.Options.Modifiers.ModEpicLoot { public sealed class ModifierEpicLootItem : IItemModifier { public float? RarityWeightNone { get; set; } public float? RarityWeightMagic { get; set; } public float? RarityWeightRare { get; set; } public float? RarityWeightEpic { get; set; } public float? RarityWeightLegendary { get; set; } public float? RarityWeightUnique { get; set; } public List<string> UniqueIds { get; set; } public bool IsPointless() { if (RarityWeightNone + RarityWeightMagic + RarityWeightRare + RarityWeightEpic + RarityWeightLegendary + RarityWeightUnique == 0f) { return (UniqueIds?.Count ?? 0) == 0; } return false; } public void Modify(ItemModifierContext<GameObject> drop) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)drop.Item).IsNull() && !IsPointless()) { ItemDrop val = ComponentCache.Get<ItemDrop>(drop.Item); if (ItemRoller.TryRollMagic(val.m_itemData, ((Component)val).transform.position, new ItemRollParameters { RarityWeightNone = RarityWeightNone.GetValueOrDefault(), RarityWeightMagic = RarityWeightMagic.GetValueOrDefault(), RarityWeightRare = RarityWeightRare.GetValueOrDefault(), RarityWeightEpic = RarityWeightEpic.GetValueOrDefault(), RarityWeightLegendary = RarityWeightLegendary.GetValueOrDefault(), RarityWeightUnique = RarityWeightUnique.GetValueOrDefault(), UniqueIds = (UniqueIds ?? new List<string>(0)) })) { val.Save(); } } } public void Modify(ItemModifierContext<ItemData> drop) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (drop?.Item != null && !IsPointless()) { ItemRoller.TryRollMagic(drop.Item, drop.Position, new ItemRollParameters { RarityWeightNone = RarityWeightNone.GetValueOrDefault(), RarityWeightMagic = RarityWeightMagic.GetValueOrDefault(), RarityWeightRare = RarityWeightRare.GetValueOrDefault(), RarityWeightEpic = RarityWeightEpic.GetValueOrDefault(), RarityWeightLegendary = RarityWeightLegendary.GetValueOrDefault(), RarityWeightUnique = RarityWeightUnique.GetValueOrDefault(), UniqueIds = UniqueIds }); } } } } namespace DropThat.Drop.DropTableSystem { internal sealed class DropTableSystemConfiguration : IDropSystemConfig { private Dictionary<string, DropTableBuilder> _builders = new Dictionary<string, DropTableBuilder>(); private bool _finalized; public DropTableBuilder GetBuilder(string name) { if (_finalized) { throw new InvalidOperationException("Collection is finalized. Builders cannot be retrieved or modified after build."); } if (_builders.TryGetValue(name, out var value)) { Log.Trace?.Log("Potentially conflicting configurations for droptable '" + name + "'."); return value; } return _builders[name] = new DropTableBuilder(name, this); } public void Build() { if (_finalized) { Log.Warning?.Log("Attempting to build character drop configs that have already been finalized. Ignoring request."); return; } _finalized = true; DropTableTemplateManager.ResetTemplates(_builders.Values.Select((DropTableBuilder x) => x.Build())); } } internal static class DropTableSystemStartup { public static void Setup() { DropTableConfigSyncManager.Configure(); DropSystemConfigManager.OnConfigureLate += LoadFileConfigs; DropThat.Drop.DropTableSystem.Debug.DebugWriter.Configure(); } private static void LoadFileConfigs(IDropSystemConfigCollection configCollection) { DropThat.Drop.DropTableSystem.Configuration.Toml.ConfigurationFileManager.LoadConfigs(configCollection.GetDropSystemConfig<DropTableSystemConfiguration>()); } } } namespace DropThat.Drop.DropTableSystem.Sync { internal sealed class DropTableConfigMessage : IMessage { public Dictionary<string, DropTableTemplate> Templates { get; set; } public void Initialize() { Templates = new Dictionary<string, DropTableTemplate>(DropTableTemplateManager.Templates); Log.Debug?.Log("Packaged DropTable configurations: " + $"{Templates.Values.Sum((DropTableTemplate x) => x.Drops.Count)} drops for {Templates.Count} drop tables"); } public void AfterUnpack() { if (Templates == null) { Dictionary<string, DropTableTemplate> dictionary2 = (Templates = new Dictionary<string, DropTableTemplate>(0)); } DropTableTemplateManager.ResetTemplates(Templates.Values); Log.Debug?.Log("Unpacked DropTable configurations: " + $"{Templates.Values.Sum((DropTableTemplate x) => x.Drops.Count)} drops for {Templates.Count} drop tables"); } } internal static class DropTableConfigSyncManager { public static void Configure() { SyncManager.RegisterSyncHandlers("RPC_DropThat_ReceiveDropTableDropConfigs", GenerateMessage, RPC_DropThat_ReceiveDropTableDropConfigs); RegisterSyncedTypes(); } private static IMessage GenerateMessage() { return new DropTableConfigMessage(); } private static void RPC_DropThat_ReceiveDropTableDropConfigs(ZRpc rpc, ZPackage package) { try { IncomingMessageService.ReceiveMessageAsync<DropTableConfigMessage>(package); } catch (Exception e) { Log.Error?.Log("Error while attempting to receive DropTable config package.", e); } } private static void RegisterSyncedTypes() { ThatCore.Network.Serializer serializer = SerializerManager.GetSerializer<DropTableConfigMessage>(); serializer.RegisterType(typeof(DropThat.Drop.DropTableSystem.Conditions.ModSpecific.CLLC.ConditionWorldLevelMax)); serializer.RegisterType(typeof(DropThat.Drop.DropTableSystem.Conditions.ModSpecific.CLLC.ConditionWorldLevelMin)); serializer.RegisterType(typeof(DropThat.Drop.DropTableSystem.Conditions.ModSpecific.SpawnThat.ConditionTemplateId)); serializer.RegisterType(typeof(ConditionAltitudeMax)); serializer.RegisterType(typeof(ConditionAltitudeMin)); serializer.RegisterType(typeof(DropThat.Drop.DropTableSystem.Conditions.ConditionBiome)); serializer.RegisterType(typeof(ConditionDaytimeNotAfternoon)); serializer.RegisterType(typeof(ConditionDaytimeNotDay)); serializer.RegisterType(typeof(ConditionDaytimeNotNight)); serializer.RegisterType(typeof(DropThat.Drop.DropTableSystem.Conditions.ConditionDistanceToCenterMax)); serializer.RegisterType(typeof(DropThat.Drop.DropTableSystem.Conditions.ConditionDistanceToCenterMin)); serializer.RegisterType(typeof(DropThat.Drop.DropTableSystem.Conditions.ConditionEnvironments)); serializer.RegisterType(typeof(ConditionGlobalKeysAll)); serializer.RegisterType(typeof(DropThat.Drop.DropTableSystem.Conditions.ConditionGlobalKeysAny)); serializer.RegisterType(typeof(ConditionGlobalKeysNotAll)); serializer.RegisterType(typeof(DropThat.Drop.DropTableSystem.Conditions.ConditionGlobalKeysNotAny)); serializer.RegisterType(typeof(DropThat.Drop.DropTableSystem.Conditions.ConditionLocation)); serializer.RegisterType(typeof(DropThat.Drop.DropTableSystem.Conditions.ConditionNotBiome)); serializer.RegisterType(typeof(DropThat.Drop.DropTableSystem.Conditions.ConditionNotEnvironments)); serializer.RegisterType(typeof(DropThat.Drop.DropTableSystem.Conditions.ConditionNotLocation)); serializer.RegisterType(typeof(ConditionNotWithinCircle)); serializer.RegisterType(typeof(ConditionWithinCircle)); serializer.RegisterType(typeof(ModifierEpicLootItem)); serializer.RegisterType(typeof(ModifierDurability)); serializer.RegisterType(typeof(ModifierQualityLevel)); } } } namespace DropThat.Drop.DropTableSystem.Services { internal static class ConfigureDropTableService { public static void ConfigureTable(DropTable table, DropTableTemplate template) { if (template.DropMin.HasValue) { table.m_dropMin = template.DropMin.Value; } if (template.DropMax.HasValue) { table.m_dropMax = template.DropMax.Value; } if (template.DropChance.HasValue) { table.m_dropChance = template.DropChance.Value; } if (template.DropOnlyOnce.HasValue) { table.m_oneOfEach = template.DropOnlyOnce.Value; } } public static List<DropTableDrop> CreateDropList(DropTable table, DropTableTemplate template) { //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) List<DropData> list = table.m_drops ?? new List<DropData>(); List<DropTableDrop> list2 = list.Select((DropData x, int i) => new DropTableDrop { DropTableIndex = i, CurrentIndex = i, DropData = x, TableData = table }).ToList(); Log.Trace?.Log("Configuring drops for " + template.PrefabName + ":"); foreach (KeyValuePair<int, DropTableDropTemplate> item in template.Drops.OrderBy((KeyValuePair<int, DropTableDropTemplate> x) => x.Key)) { if (item.Value.TemplateEnabled.HasValue && item.Value.TemplateEnabled == false) { continue; } if (item.Key < list2.Count && item.Key >= 0) { string cleanedName = ((Object)(object)list[item.Key].m_item).GetCleanedName(); if (!string.IsNullOrEmpty(item.Value.PrefabName) && cleanedName == template.PrefabName) { Log.Trace?.Log($"\t'{item.Key}:{cleanedName}'."); } else { Log.Trace?.Log($"\t'{item.Key}:{cleanedName}' -> '{item.Value.PrefabName}'."); } DropTableDrop dropTableDrop = list2[item.Key]; dropTableDrop.DropData = ConfigureDrop(list[item.Key], template, item.Value); dropTableDrop.TableTemplate = template; dropTableDrop.DropTemplate = item.Value; } else if (item.Value.Enabled != false) { Log.Trace?.Log("Inserting drop '" + item.Value.PrefabName + "'."); if (TryCreateDrop(template, item.Value, out var drop)) { list2.Add(new DropTableDrop { DropTableIndex = list2.Count, CurrentIndex = list2.Count, DropData = drop, TableData = table, DropTemplate = item.Value, TableTemplate = template }); } } } return list2; } internal static bool TryCreateDrop(DropTableTemplate tableTemplate, DropTableDropTemplate dropTemplate, out DropData drop) { //IL_0003: 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_0026: Unknown result type (might be due to invalid IL or missing references) drop = new DropData { m_stackMax = 1, m_stackMin = 1, m_weight = 1f }; if (!string.IsNullOrWhiteSpace(dropTemplate.PrefabName)) { GameObject prefab = ZNetScene.instance.GetPrefab(dropTemplate.PrefabName); if (prefab == null) { Log.Warning?.Log("Unable to find prefab '" + dropTemplate.PrefabName + "' " + $"for config '{tableTemplate.PrefabName}.{dropTemplate.Id}'. Disabling config."); dropTemplate.TemplateEnabled = false; return false; } drop.m_item = prefab; } if (dropTemplate.AmountMin.HasValue) { drop.m_stackMin = dropTemplate.AmountMin.Value; } if (dropTemplate.AmountMax.HasValue) { drop.m_stackMax = dropTemplate.AmountMax.Value; } if (dropTemplate.Weight.HasValue) { drop.m_weight = dropTemplate.Weight.Value; } if (dropTemplate.DisableResourceModifierScaling.HasValue) { drop.m_dontScale = dropTemplate.DisableResourceModifierScaling.Value; } return true; } internal static DropData ConfigureDrop(DropData drop, DropTableTemplate tableTemplate, DropTableDropTemplate dropTemplate) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrWhiteSpace(dropTemplate.PrefabName)) { GameObject prefab = ZNetScene.instance.GetPrefab(dropTemplate.PrefabName); if (prefab == null) { Log.Warning?.Log("Unable to find prefab '" + dropTemplate.PrefabName + "' " + $"for config '{tableTemplate.PrefabName}.{dropTemplate.Id}'. Disabling config."); dropTemplate.TemplateEnabled = false; return drop; } drop.m_item = prefab; } if (dropTemplate.AmountMin.HasValue) { drop.m_stackMin = dropTemplate.AmountMin.Value; } if (dropTemplate.AmountMax.HasValue) { drop.m_stackMax = dropTemplate.AmountMax.Value; } if (dropTemplate.Weight.HasValue) { drop.m_weight = dropTemplate.Weight.Value; } if (dropTemplate.DisableResourceModifierScaling.HasValue) { drop.m_dontScale = dropTemplate.DisableResourceModifierScaling.Value; } return drop; } } internal static class DropRollerService { public static List<DropTableDrop> RollDrops(DropTable dropTable, GameObject source, List<DropTableDrop> drops) { //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) if (Random.value > dropTable.m_dropChance) { Log.Trace?.Log("DropTable chance rolled too high. Nothing will be dropped for '" + ((Object)(object)source).GetCleanedName() + "'."); return new List<DropTableDrop>(0); } List<DropTableDrop> possibleDrops = GetPossibleDrops(drops, source); if (Log.TraceEnabled) { Log.Trace?.Log("Possible drops: "); foreach (DropTableDrop drop in drops) { int num = ((drop.DropTemplate != null) ? drop.DropTemplate.Id : drop.DropTableIndex); Log.Trace?.Log($"\t{num}: {((Object)drop.DropData.m_item).name}"); } } float num2 = possibleDrops.Sum((DropTableDrop x) => x.DropData.m_weight); int num3 = Random.Range(dropTable.m_dropMin, dropTable.m_dropMax + 1); Log.Trace?.Log($"Rolling drops {num3} times (from possible range {dropTable.m_dropMin} to {dropTable.m_dropMax})."); List<DropTableDrop> list = new List<DropTableDrop>(num3); for (int i = 0; i < num3; i++) { float num4 = Random.Range(0f, num2); float num5 = 0f; for (int j = 0; j < possibleDrops.Count; j++) { DropTableDrop dropTableDrop = possibleDrops[j]; num5 += dropTableDrop.DropData.m_weight; if (num4 <= num5) { list.Add(dropTableDrop); if (dropTable.m_oneOfEach) { possibleDrops.RemoveAt(j); num2 -= dropTableDrop.DropData.m_weight; } break; } } } return list; } private static List<DropTableDrop> GetPossibleDrops(List<DropTableDrop> drops, GameObject source) { //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) List<DropTableDrop> list = new List<DropTableDrop>(); for (int i = 0; i < drops.Count; i++) { DropTableDrop drop = drops[i]; if (drop.DropTemplate != null) { if (drop.DropTemplate.Enabled == false) { Log.Trace?.Log($"Filtering drop '{drop.TableTemplate.PrefabName}.{drop.DropTemplate.Id}' " + "due to not being enabled."); continue; } DropThat.Drop.DropTableSystem.Models.DropContext dropContext = new DropThat.Drop.DropTableSystem.Models.DropContext(source, drop.TableData, drop.DropData) { DropConfig = drop.DropTemplate, DropTableConfig = drop.TableTemplate }; if (drop.DropTemplate.Conditions.All(delegate(DropThat.Drop.DropTableSystem.Conditions.IDropCondition cond) { try { bool result = cond.IsValid(dropContext); Log.Trace?.Log($"Filtering drop '{drop.TableTemplate.PrefabName}.{drop.DropTemplate.Id}' " + "due to invalid condition '" + cond?.GetType()?.Name + "'."); return result; } catch (Exception e) { Log.Error?.Log("Error while attempting to check condition '" + cond?.GetType()?.Name + "' " + $"for config '{drop.TableTemplate.PrefabName}.{drop.DropTemplate.Id}'. " + "Condition will be ignored", e); return true; } })) { list.Add(new DropTableDrop { CurrentIndex = i, DropTableIndex = drop.DropTableIndex, TableData = drop.TableData, DropData = drop.DropData, TableTemplate = drop.TableTemplate, DropTemplate = drop.DropTemplate }); } } else { list.Add(new DropTableDrop { CurrentIndex = i, DropTableIndex = drop.DropTableIndex, TableData = drop.TableData, DropData = drop.DropData }); } } return list; } } internal static class DropScalerService { private static readonly ItemData[] Item = (ItemData[])(object)new ItemData[1]; public static GameObject[] ScaleDropsAsGameObjects(DropTableDrop drop) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) int num = CalculateAmount(drop); GameObject[] array = (GameObject[])(object)new GameObject[num]; for (int i = 0; i < num; i++) { GameObject item = drop.DropData.m_item; array[i] = item; } return array; } public static ICollection<ItemData> ScaleDropsAsItemData(GameObject source, DropTableDrop drop) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ItemDrop val = ComponentCache.Get<ItemDrop>(drop.DropData.m_item); if (((Object)(object)val).IsNull()) { return Array.Empty<ItemData>(); } int num = CalculateAmount(drop); int maxStackSize = val.m_itemData.m_shared.m_maxStackSize; if (num > maxStackSize) { int num2 = Mathf.CeilToInt((float)num / (float)maxStackSize); List<ItemData> list = new List<ItemData>(num2); int num3 = num; for (int i = 0; i < num2; i++) { int num4 = Math.Min(num3, maxStackSize); ItemData item = CreateItemDataDrop(source, drop, val, num4); list.Add(item); num3 -= num4; } return list; } Item[0] = CreateItemDataDrop(source, drop, val, num); return Item; } private static ItemData CreateItemDataDrop(GameObject source, DropTableDrop drop, ItemDrop itemDrop, int amount) { //IL_000e: 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) ItemData val = itemDrop.m_itemData.Clone(); val.m_dropPrefab = drop.DropData.m_item; val.m_stack = amount; if (drop.DropTemplate != null) { ItemModifierContext<ItemData> drop2 = new ItemModifierContext<ItemData> { Item = val, Position = source.transform.position }; foreach (IItemModifier itemModifier in drop.DropTemplate.ItemModifiers) { try { itemModifier.Modify(drop2); } catch (Exception e) { Log.Error?.Log("Error while attempting to apply modifier '" + itemModifier.GetType().Name + "' " + $"to '{drop.TableTemplate.PrefabName}.{drop.DropTemplate.Id}'.", e); } } } return val; } public static int CalculateAmount(DropTableDrop drop) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) int num = Math.Max(1, drop.DropData.m_stackMin); int num2 = drop.DropData.m_stackMax + 1; int num3 = Random.Range(num, num2); if (drop.DropData.m_dontScale) { return num3; } float num4 = (float)num3 * Game.m_resourceRate; float num5 = num4 % 1f; int num6 = (int)num4; if (num5 > 0.001f && num5 <= Random.Range(0f, 1f)) { num6++; } return num6; } } internal static class DropTableCompiler { public static List<DropTableTemplate> CompileAllDrops(bool applyTemplate = true) { if (((Object)(object)ZNetScene.instance).IsNull()) { throw new InvalidOperationException("Too early. Trying to get expected drops before ZnetScene is instantiated."); } List<DropTableTemplate> list = new List<DropTableTemplate>(); foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { if (((Object)(object)prefab).IsNotNull() && TryCompileDrops(prefab, applyTemplate, out var compiledDrops)) { list.Add(compiledDrops); } } return list; } public static bool TryCompileDrops(string prefabName, bool applyTemplate, out DropTableTemplate compiledDrops) { if (((Object)(object)ZNetScene.instance).IsNull()) { throw new InvalidOperationException("Too early. Trying to get expected drops before ZnetScene is instantiated."); } GameObject prefab = ZNetScene.instance.GetPrefab(prefabName); if (((Object)(object)prefab).IsNull()) { compiledDrops = null; return false; } return TryCompileDrops(prefab, applyTemplate, out compiledDrops); } public static bool TryCompileDrops(GameObject prefab, bool applyTemplate, out DropTableTemplate compiledDrops) { DropTable val = null; Container val2 = default(Container); DropOnDestroyed val3 = default(DropOnDestroyed); LootSpawner val4 = default(LootSpawner); TreeBase val5 = default(TreeBase); TreeLog val6 = default(TreeLog); MineRock val7 = default(MineRock); MineRock5 val8 = default(MineRock5); if (prefab.TryGetComponent<Container>(ref val2)) { val = val2.m_defaultItems; } else if (prefab.TryGetComponent<DropOnDestroyed>(ref val3)) { val = val3.m_dropWhenDestroyed; } else if (prefab.TryGetComponent<LootSpawner>(ref val4)) { val = val4.m_items; } else if (prefab.TryGetComponent<TreeBase>(ref val5)) { val = val5.m_dropWhenDestroyed; } else if (prefab.TryGetComponent<TreeLog>(ref val6)) { val = val6.m_dropWhenDestroyed; } else if (prefab.TryGetComponent<MineRock>(ref val7)) { val = val7.m_dropItems; } else if (prefab.TryGetComponent<MineRock5>(ref val8)) { val = val8.m_dropItems; } if (val == null) { compiledDrops = null; return false; } compiledDrops = CompileDrops(((Object)(object)prefab).GetCleanedName(), applyTemplate, val); return true; } private static DropTableTemplate CompileDrops(string prefabName, bool applyTemplate, DropTable table) { Dictionary<int, DropTableDropTemplate> drops = table.m_drops?.Select((DropData x, int i) => new DropTableDropTemplate { Id = i, PrefabName = ((Object)(object)x.m_item).GetCleanedName(), AmountMin = x.m_stackMin, AmountMax = x.m_stackMax, Weight = x.m_weight, DisableResourceModifierScaling = x.m_dontScale }).ToDictionary((DropTableDropTemplate x) => x.Id) ?? new Dictionary<int, DropTableDropTemplate>(); DropTableTemplate dropTableTemplate = new DropTableTemplate { PrefabName = prefabName, DropChance = table.m_dropChance, DropMin = table.m_dropMin, DropMax = table.m_dropMax, DropOnlyOnce = table.m_oneOfEach, Drops = drops }; if (!applyTemplate || !DropTableTemplateManager.TryGetTemplate(prefabName, out var template)) { return dropTableTemplate; } foreach (KeyValuePair<int, DropTableDropTemplate> item in template.Drops.OrderBy((KeyValuePair<int, DropTableDropTemplate> x) => x.Key)) { DropTableDropTemplate value = item.Value; if (value.TemplateEnabled != false) { if (dropTableTemplate.Drops.TryGetValue(item.Key, out var value2)) { value2.PrefabName = value.PrefabName ?? value2.PrefabName; value2.Enabled = value.Enabled ?? value2.Enabled; value2.AmountMin = value.AmountMin ?? value2.AmountMin; value2.AmountMax = value.AmountMax ?? value2.AmountMax; value2.Weight = value.Weight ?? value2.Weight; value2.DisableResourceModifierScaling = value.DisableResourceModifierScaling ?? value2.DisableResourceModifierScaling; value2.ItemModifiers = value.ItemModifiers.ToList(); value2.Conditions = value.Conditions.ToList(); } else if (value.Enabled != false) { dropTableTemplate.Drops[item.Key] = new DropTableDropTemplate { Id = item.Key, PrefabName = value.PrefabName, AmountMin = value.AmountMin, AmountMax = value.AmountMax, Weight = value.Weight, DisableResourceModifierScaling = value.DisableResourceModifierScaling, ItemModifiers = value.ItemModifiers.ToList(), Conditions = value.Conditions.ToList() }; } } } return dropTableTemplate; } } } namespace DropThat.Drop.DropTableSystem.Patches { internal static class Patch_Logistics { [HarmonyPatch(typeof(Container))] internal static class Patch_Container { [HarmonyPatch("Awake")] [HarmonyPrefix] private static void Init(Container __instance) { DropTableSessionManager.Initialize((MonoBehaviour)(object)__instance, __instance.m_defaultItems); } [HarmonyPatch("AddDefaultItems")] [HarmonyPrefix] private static void Begin(Container __instance) { DropTableSessionManager.StartSession((MonoBehaviour)(object)__instance); } [HarmonyPostfix] [HarmonyPatch("AddDefaultItems")] private static void End() { DropTableSessionManager.EndSession(); } } [HarmonyPatch(typeof(DropOnDestroyed))] internal static class Patch_DropOnDestroyed { [HarmonyPostfix] [HarmonyPatch("Awake")] private static void Init(DropOnDestroyed __instance) { DropTableSessionManager.Initialize((MonoBehaviour)(object)__instance, __instance.m_dropWhenDestroyed); } [HarmonyPrefix] [HarmonyPatch("OnDestroyed")] private static void Begin(DropOnDestroyed __instance) { DropTableSessionManager.StartSession((MonoBehaviour)(object)__instance); } [HarmonyPatch("OnDestroyed")] [HarmonyPostfix] private static void End() { DropTableSessionManager.EndSession(); } } [HarmonyPatch(typeof(LootSpawner))] internal static class Patch_LootSpawner { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void Init(LootSpawner __instance) { DropTableSessionManager.Initialize((MonoBehaviour)(object)__instance, __instance.m_items); } [HarmonyPrefix] [HarmonyPatch("UpdateSpawner")] private static void Begin(LootSpawner __instance) { DropTableSessionManager.StartSession((MonoBehaviour)(object)__instance); } [HarmonyPostfix] [HarmonyPatch("UpdateSpawner")] private static void End() { DropTableSessionManager.EndSession(); } } [HarmonyPatch(typeof(TreeBase))] internal static class Patch_TreeBase { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void Init(TreeBase __instance) { DropTableSessionManager.Initialize((MonoBehaviour)(object)__instance, __instance.m_dropWhenDestroyed); } [HarmonyPatch("RPC_Damage")] [HarmonyPrefix] private static void Begin(TreeBase __instance) { DropTableSessionManager.StartSession((MonoBehaviour)(object)__instance); } [HarmonyPatch("RPC_Damage")] [HarmonyPostfix] private static void End() { DropTableSessionManager.EndSession(); } } [HarmonyPatch(typeof(TreeLog))] internal static class Patch_TreeLog { [HarmonyPostfix] [HarmonyPatch("Awake")] private static void Init(TreeLog __instance) { DropTableSessionManager.Initialize((MonoBehaviour)(object)__instance, __instance.m_dropWhenDestroyed); } [HarmonyPrefix] [HarmonyPatch("Destroy")] private static void Begin(TreeLog __instance) { DropTableSessionManager.StartSession((MonoBehaviour)(object)__instance); } [HarmonyPatch("Destroy")] [HarmonyPostfix] private static void End() { DropTableSessionManager.EndSession(); } } [HarmonyPatch(typeof(MineRock))] internal static class Patch_MineRock { [HarmonyPatch("Start")] [HarmonyPostfix] private static void Init(MineRock __instance) { DropTableSessionManager.Initialize((MonoBehaviour)(object)__instance, __instance.m_dropItems); } [HarmonyPatch("RPC_Hit")] [HarmonyPrefix] private static void Begin(MineRock __instance) { DropTableSessionManager.StartSession((MonoBehaviour)(object)__instance); } [HarmonyPatch("RPC_Hit")] [HarmonyPostfix] private static void End() { DropTableSessionManager.EndSession(); } } [HarmonyPatch(typeof(MineRock5))] internal static class Patch_MineRock5 { [HarmonyPriority(300)] [HarmonyPostfix] [HarmonyPatch("Awake")] private static void Init(MineRock5 __instance) { DropTableSessionManager.Initialize((MonoBehaviour)(object)__instance, __instance.m_dropItems); } [HarmonyPrefix] [HarmonyPatch("DamageArea")] private static void Begin(MineRock5 __instance) { DropTableSessionManager.StartSession((MonoBehaviour)(object)__instance); } [HarmonyPostfix] [HarmonyPatch("DamageArea")] private static void End() { DropTableSessionManager.EndSession(); } } } [HarmonyPatch] internal static class Patch_ModifyInstantiatedDrops { [HarmonyPatch(typeof(DropOnDestroyed))] internal static class Patch_DropOnDestroyed_OnDestroyed { [HarmonyPatch("OnDestroyed")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions) { return instructions.InsertDropManagementInstructions<DropOnDestroyed>(); } } [HarmonyPatch(typeof(LootSpawner))] internal static class Patch_LootSpawner_UpdateSpawner { [HarmonyPatch("UpdateSpawner")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions) { return instructions.InsertDropManagementInstructions<LootSpawner>(); } } [HarmonyPatch(typeof(TreeLog))] internal static class Patch_TreeLog_Destroy { [HarmonyPatch("Destroy")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown CodeInstruction instruction; return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)GetDropListMethod, (string)null) }).MatchEndForward((CodeMatch[])(object)new CodeMatch[1] { CodeMatch.op_Implicit(OpCodes.Ldc_I4_0) }).Advance(1) .GetInstruction(out instruction) .MatchForward(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)ReflectionUtils.InstantiateGameObjectMethod, (string)null) }) .Advance(1) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { instruction.GetLdlocFromStLoc() }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<GameObject, int, GameObject>>((Func<GameObject, int, GameObject>)ModifyInstantiatedObjectDrop) }) .InstructionEnumeration(); } } [HarmonyPatch(typeof(TreeBase))] internal static class Patch_TreeBase_RPC_Damage { [HarmonyTranspiler] [HarmonyPatch("RPC_Damage")] private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions) { return instructions.InsertDropManagementInstructions<TreeBase>(); } } [HarmonyPatch(typeof(MineRock))] internal static class Patch_MineRock_RPC_Hit { private static int LoopIndex; private static void InitLoopIndex() { LoopIndex = -1; } private static void IncrementLoopIndex() { LoopIndex++; } private static GameObject ModifyInstantiatedObjectDrop(GameObject obj) { DropTableSessionManager.ModifyDrop(obj, LoopIndex); return obj; } [HarmonyPatch("RPC_Hit")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).Start().InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Action>((Action)InitLoopIndex) }).MatchForward(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)ReflectionUtils.InstantiateGameObjectMethod, (string)null) }) .Advance(1) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<GameObject, GameObject>>((Func<GameObject, GameObject>)ModifyInstantiatedObjectDrop) }) .MatchEndForward((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)ReflectionUtils.ListGameObjectMoveNextMethod, (string)null) }) .Advance(1) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Action>((Action)IncrementLoopIndex) }) .InstructionEnumeration(); } } [HarmonyPatch(typeof(MineRock5))] internal static class Patch_MineRock5_DamageArea { private static int LoopIndex; private static void InitLoopIndex() { LoopIndex = -1; } private static void IncrementLoopIndex() { LoopIndex++; } private static GameObject ModifyInstantiatedObjectDrop(GameObject obj) { DropTableSessionManager.ModifyDrop(obj, LoopIndex); return obj; } [HarmonyPatch("DamageArea")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).Start().InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Action>((Action)InitLoopIndex) }).MatchForward(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)ReflectionUtils.InstantiateGameObjectMethod, (string)null) }) .Advance(1) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<GameObject, GameObject>>((Func<GameObject, GameObject>)ModifyInstantiatedObjectDrop) }) .MatchEndForward((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)ReflectionUtils.ListGameObjectMoveNextMethod, (string)null) }) .Advance(1) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Action>((Action)IncrementLoopIndex) }) .InstructionEnumeration(); } } private static MethodInfo GetDropListMethod = AccessTools.Method(typeof(DropTable), "GetDropList", (Type[])null, (Type[])null); private static IEnumerable<CodeInstruction> InsertDropManagementInstructions<T>(this IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown CodeInstruction instruction; return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)ReflectionUtils.InstantiateGameObjectMethod, (string)null) }).Advance(-4).GetInstruction(out instruction) .MatchForward(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)ReflectionUtils.InstantiateGameObjectMethod, (string)null) }) .Advance(1) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { instruction }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<GameObject, int, GameObject>>((Func<GameObject, int, GameObject>)ModifyInstantiatedObjectDrop) }) .InstructionEnumeration(); } private static GameObject ModifyInstantiatedObjectDrop(GameObject obj, int index) { DropTableSessionManager.ModifyDrop(obj, index); return obj; } } [HarmonyPatch] internal static class Patch_RollDrops { [HarmonyPriority(0)] [HarmonyPatch(typeof(DropTable), "GetDropListItems")] [HarmonyPrefix] private static bool DropListItemsOverhaul(DropTable __instance, ref List<ItemData> __result) { try { if (DropTableSessionManager.HasChanges()) { __result = DropTableSessionManager.GenerateItemDrops(__instance); return false; } } catch (Exception e) { Log.Error?.Log("Error while attempting to generate drops. Running vanilla code instead.", e); } return true; } [HarmonyPrefix] [HarmonyPatch(typeof(DropTable), "GetDropList", new Type[] { typeof(int) })] [HarmonyPriority(0)] private static bool DropListOverhaul(DropTable __instance, ref List<GameObject> __result) { try { if (DropTableSessionManager.HasChanges()) { __result = DropTableSessionManager.GenerateDrops(__instance); return false; } } catch (Exception e) { Log.Error?.Log("Error while attempting to generate drops. Running vanilla code instead.", e); } return true; } } } namespace DropThat.Drop.DropTableSystem.Models { public sealed class DropContext { private Vector3? _pos; public GameObject DropTableSource { get; set; } public DropTable DropTable { get; set; } public DropData Drop { get; set; } public DropTableTemplate DropTableConfig { get; set; } public DropTableDropTemplate DropConfig { get; set; } public Vector3 Pos { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) Vector3 valueOrDefault = _pos.GetValueOrDefault(); if (!_pos.HasValue) { valueOrDefault = DropTableSource.transform.position; _pos = valueOrDefault; return valueOrDefault; } return valueOrDefault; } } public DropContext(GameObject dropTableSource, DropTable dropTable, DropData drop) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) DropTableSource = dropTableSource; DropTable = dropTable; Drop = drop; } } internal sealed class DropLink { public DropTableTemplate Table { get; set; } public DropTableDropTemplate Drop { get; set; } } public sealed class DropTableDrop { public int DropTableIndex { get; set; } public int CurrentIndex { get; set; } public DropTable TableData { get; set; } public DropData DropData { get; set; } public DropTableTemplate TableTemplate { get; set; } public DropTableDropTemplate DropTemplate { get; set; } } public sealed class DropTableDropTemplate : IHaveItemModifiers, DropThat.Drop.DropTableSystem.Conditions.IHaveDropConditions { public ICollection<DropThat.Drop.DropTableSystem.Conditions.IDropCondition> Conditions { get; set; } = new List<DropThat.Drop.DropTableSystem.Conditions.IDropCondition>(); public ICollection<IItemModifier> ItemModifiers { get; set; } = new List<IItemModifier>(); public int Id { get; set; } public string PrefabName { get; set; } [DefaultValue(true)] public bool? Enabled { get; set; } = true; [DefaultValue(true)] public bool? TemplateEnabled { get; set; } = true; public int? AmountMin { get; set; } public int? AmountMax { get; set; } public float? Weight { get; set; } public bool? DisableResourceModifierScaling { get; set; } } public sealed class DropTableTemplate { public string PrefabName { get; set; } public Dictionary<int, DropTableDropTemplate> Drops { get; set; } = new Dictionary<int, DropTableDropTemplate>(); public int? DropMin { get; set; } public int? DropMax { get; set; } public float? DropChance { get; set; } public bool? DropOnlyOnce { get; set; } } } namespace DropThat.Drop.DropTableSystem.Managers { public static class DropTableManager { private static Dictionary<string, DropTableTemplate> Cache { get; } private static Dictionary<string, DropTableTemplate> CacheConfigured { get; } private static bool CachedAll { get; set; } private static bool CachedConfigured { get; set; } static DropTableManager() { Cache = new Dictionary<string, DropTableTemplate>(); CacheConfigured = new Dictionary<string, DropTableTemplate>(); DropSystemConfigManager.OnConfigsLoadedEarly += delegate { Cache.Clear(); CacheConfigured.Clear(); CachedAll = false; CachedConfigured = false; }; } public static List<DropTableTemplate> CompileAllPrefabDrops() { if (CachedAll) { return Cache.Values.ToList(); } foreach (DropTableTemplate item in DropThat.Drop.DropTableSystem.Services.DropTableCompiler.CompileAllDrops()) { Cache[item.PrefabName] = item; } CachedAll = true; return Cache.Values.ToList(); } public static List<DropTableTemplate> CompiledConfiguredPrefabDrops() { if (CachedConfigured) { return CacheConfigured.Values.ToList(); } foreach (string key in DropTableTemplateManager.Templates.Keys) { if (DropThat.Drop.DropTableSystem.Services.DropTableCompiler.TryCompileDrops(key, applyTemplate: true, out var compiledDrops)) { Cache[key] = compiledDrops; CacheConfigured[key] = compiledDrops; } } CachedConfigured = true; return CacheConfigured.Values.ToList(); } public static bool TryCompileDrops(string prefabName, out DropTableTemplate compiledDrops) { if (Cache.TryGetValue(prefabName, out compiledDrops)) { return true; } if (DropThat.Drop.DropTableSystem.Services.DropTableCompiler.TryCompileDrops(prefabName, applyTemplate: true, out compiledDrops)) { Cache[prefabName] = compiledDrops; return true; } return false; } public static List<DropTableTemplate> CompileWithoutTemplates() { return DropThat.Drop.DropTableSystem.Services.DropTableCompiler.CompileAllDrops(applyTemplate: false); } public static bool TryCompileWithoutTemplates(string prefabName, out DropTableTemplate compiledDrops) { if (DropThat.Drop.DropTableSystem.Services.DropTableCompiler.TryCompileDrops(prefabName, applyTemplate: false, out compiledDrops)) { return true; } return false; } } public static class DropTableSessionManager { private class DropSession { public DropTableTemplate Template { get; set; } public List<DropTableDrop> Table { get; set; } } internal static ManagedCache<GameObject> DropTableInstances { get; } = new ManagedCache<GameObject>(); private static ManagedCache<DropSession> Sessions { get; } = new ManagedCache<DropSession>(); private static MonoBehaviour SessionEntity { get; set; } private static List<DropTableDrop> SessionDrops { get; set; } public static void Initialize(MonoBehaviour source, DropTable dropTable) { try { if (dropTable == null || ((Object)(object)source).IsNull()) { Log.Development?.Log("DropTable or Source is null"); return; } DropTableInstances.Set((Object)(object)((Component)source).gameObject, ((Component)source).gameObject); if (DropTableTemplateManager.TryGetTemplate(((Object)(object)source).GetCleanedName(), out var template)) { Sessions.Set((Object)(object)source, new DropSession { Template = template, Table = PrepareTable(dropTable, template) }); } } catch (Exception e) { Log.Error?.Log("Error while attempting to initialize DropTable configuration.", e); } } public static bool HasChanges() { DropSession value; if (((Object)(object)SessionEntity).IsNotNull()) { return Sessions.TryGet((Object)(object)SessionEntity, out value); } return false; } public static void StartSession(MonoBehaviour source) { SessionEntity = source; } public static List<ItemData> GenerateItemDrops(DropTable dropTable) { //IL_011d: Unknown result type (might be due to invalid IL or missing references) if (dropTable == null) { return new List<ItemData>(); } if (((Object)(object)SessionEntity).IsNull()) { return new List<ItemData>(); } DropSession value; List<DropTableDrop> list = (Sessions.TryGet((Object)(object)SessionEntity, out value) ? value.Table : null); if (list == null) { Log.Warning?.Log(((Object)(object)SessionEntity).GetCleanedName() + ": Attempted to generate drops without having prepared DropTable. Attempting recovery, but something is wrong."); if (DropTableTemplateManager.TryGetTemplate(((Object)(object)SessionEntity).GetCleanedName(), out var template)) { ManagedCache<DropSession> sessions = Sessions; MonoBehaviour sessionEntity = SessionEntity; DropSession obj = new DropSession { Template = template }; list = (obj.Table = PrepareTable(dropTable, template)); sessions.Set((Object)(object)sessionEntity, obj); } else { list = PrepareTable(dropTable, new DropTableTemplate()); } } List<DropTableDrop> list3 = DropRollerService.RollDrops(dropTable, ((Component)SessionEntity).gameObject, list); if (Log.TraceEnabled) { Log.Trace?.Log($"{((Object)(object)SessionEntity).GetCleanedName()}: Dropping {list3.Count} items"); foreach (DropTableDrop item in list3) { Log.Trace?.Log("\t" + ((Object)item.DropData.m_item).name); } } return (from x in list3.SelectMany((DropTableDrop drop) => DropScalerService.ScaleDropsAsItemData(((Component)SessionEntity).gameObject, drop)) where x != null select x).ToList(); } public static List<GameObject> GenerateDrops(DropTable dropTable) { //IL_015c: Unknown result type (might be due to invalid IL or missing references) if (dropTable == null) { return new List<GameObject>(); } if (((Object)(object)SessionEntity).IsNull()) { return new List<GameObject>(); } DropSession value; List<DropTableDrop> list = (Sessions.TryGet((Object)(object)SessionEntity, out value) ? value.Table : null); if (list == null) { Log.Warning?.Log(((Object)(object)SessionEntity).GetCleanedName() + ": Attempted to generate drops without having prepared DropTable. Attempting recovery, but something is wrong."); if (DropTableTemplateManager.TryGetTemplate(((Object)(object)SessionEntity).GetCleanedName(), out var template)) { ManagedCache<DropSession> sessions = Sessions; MonoBehaviour sessionEntity = SessionEntity; DropSession obj = new DropSession { Template = template }; list = (obj.Table = PrepareTable(dropTable, template)); sessions.Set((Object)(object)sessionEntity, obj); } else { list = PrepareTable(dropTable, new DropTableTemplate()); } } List<DropTableDrop> list3 = DropRollerService.RollDrops(dropTable, ((Component)SessionEntity).gameObject, list); List<GameObject> result = (from x in list3.SelectMany(DropScalerService.ScaleDropsAsGameObjects) where ((Object)(object)x).IsNotNull() select x).ToList(); if (Log.TraceEnabled) { Log.Trace?.Log($"Dropping {list3.Count} items:"); foreach (DropTableDrop item in list3) { Log.Trace?.Log("\t" + ((Object)item.DropData.m_item).name); } } SessionDrops = list3; return result; } private static List<DropTableDrop> PrepareTable(DropTable dropTable, DropTableTemplate template) { ConfigureDropTableService.ConfigureTable(dropTable, template); return ConfigureDropTableService.CreateDropList(dropTable, template); } public static void ModifyDrop(GameObject drop, int index) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) try { if (index < 0 || !(index < SessionDrops?.Count)) { return; } DropTableDrop dropTableDrop = SessionDrops[index]; ItemModifierContext<GameObject> dropContext = new ItemModifierContext<GameObject> { Item = drop, Position = drop.transform.position }; dropTableDrop.DropTemplate?.ItemModifiers?.ForEach(delegate(IItemModifier modifier) { try { modifier.Modify(dropContext); } catch (Exception e2) { Log.Error?.Log($"Error while attempting to apply modifier '{modifier.GetType().Name}' to drop '{drop}'. Skipping modifier.", e2); } }); } catch (Exception e) { Log.Error?.Log($"Error while preparing to modify drop '{drop}'. Skipping modifiers.", e); } } public static void EndSession() { try { SessionEntity = null; SessionDrops = null; } catch (Exception e) { Log.Error?.Log("Error while cleaning up DropTable.", e); } } } public static class DropTableTemplateManager { internal static Dictionary<string, DropTableTemplate> Templates { get; set; } static DropTableTemplateManager() { Templates = new Dictionary<string, DropTableTemplate>(); LifecycleManager.SubscribeToWorldInit(delegate { Templates = new Dictionary<string, DropTableTemplate>(); }); } public static void SetTemplate(string prefabName, DropTableTemplate template) { Templates[prefabName] = template; } public static List<DropTableTemplate> GetTemplates() { return Templates.Values.ToList(); } public static DropTableTemplate GetTemplate(string prefabName) { if (prefabName != null && Templates.TryGetValue(prefabName, out var value)) { return value; } return null; } public static bool TryGetTemplate(string prefabName, out DropTableTemplate template) { if (prefabName != null) { return Templates.TryGetValue(prefabName, out template); } template = null; return false; } public static bool TryGetTemplate(string prefabName, int id, out DropTableDropTemplate dropTemplate) { if (prefabName != null && Templates.TryGetValue(prefabName, out var value)) { return value.Drops.TryGetValue(id, out dropTemplate); } dropTemplate = null; return false; } internal static void ResetTemplates(IEnumerable<DropTableTemplate> templates) { Log.Development?.Log("Resetting DropTable templates"); Templates = templates.ToDictionary((DropTableTemplate x) => x.PrefabName); ZNetView val = default(ZNetView); foreach (GameObject value in DropTableSessionManager.DropTableInstances.Values) { if (((Object)(object)value).IsNotNull() && value.TryGetComponent<ZNetView>(ref val)) { ZDO zDO = val.GetZDO(); if (zDO != null) { val.ResetZDO(); Object.Destroy((Object)(object)((Component)val).gameObject); ZNetScene.instance.m_instances.Remove(zDO); } } } } } } namespace DropThat.Drop.DropTableSystem.Debug { internal static class DebugWriter { private static bool Spawned; private static bool ConfigsLoaded; public static void Configure() { LifecycleManager.OnWorldInit += delegate { Spawned = false; ConfigsLoaded = false; }; LifecycleManager.OnFindSpawnPointFirstTime += delegate { Spawned = true; TryWriteFiles(); }; DropSystemConfigManager.OnConfigsLoaded += delegate { ConfigsLoaded = true; TryWriteFiles(); }; static void TryWriteFiles() { if (Spawned && ConfigsLoaded) { if ((bool)GeneralConfigManager.Config?.WriteLoadedDropTableDropsToFile) { WriteLoadedDropTablesToDisk(); } if ((bool)GeneralConfigManager.Config?.WriteDropTablesToFileAfterChanges) { WriteExpectedPostChangesToDisk(); } } } } public static void WriteLoadedDropTablesToDisk() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) DebugFileWriter.WriteFile(TomlConfigWriter.WriteToString(DropThat.Drop.DropTableSystem.Configuration.Toml.ConfigurationFileManager.ConfigMapper.MapToConfigFromTemplates(DropTableTemplateManager.Templates.Values), new TomlWriterSettings { FileName = "drop_that.drop_table.loaded.cfg", Header = string.Format("# This file was auto-generated by Drop That {0} at {1}, with Valheim '{2}.{3}.{4}'.\n", "3.1.4", DateTimeOffset.UtcNow.ToString("u"), Version.CurrentVersion.m_major, Version.CurrentVersion.m_minor, Version.CurrentVersion.m_patch) + "# The entries listed here were generated from the internally loaded DropTable configurations.\n# This is intended to reveal the state of Drop That, after loading configs from all sources, and before applying them to their respective target drop tables.\n# This file is not scanned by Drop That, and any changes done will therefore have no effect. Copy sections into a DropTable config in the configs folder if you want to change things." }), "drop_that.drop_table.loaded.cfg", "loaded DropTable configs"); } public static void WriteExpectedPostChangesToDisk() { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) Log.Development?.Log("Attempting to write post changes for " + ZNetScene.instance.m_prefabs.Count + " prefabs"); List<DropTableTemplate> list = DropTableManager.CompileAllPrefabDrops(); Log.Development?.Log("Compiled post changes for " + list.Count + " drop tables"); DebugFileWriter.WriteFile(TomlConfigWriter.WriteToString(DropThat.Drop.DropTableSystem.Configuration.Toml.ConfigurationFileManager.ConfigMapper.MapToConfigFromTemplates(list), new TomlWriterSettings { FileName = "drop_that.drop_table.after_changes.cfg", Header = string.Format("# This file was auto-generated by Drop That {0} at {1}, with Valheim '{2}.{3}.{4}'.\n", "3.1.4", DateTimeOffset.UtcNow.ToString("u"), Version.CurrentVersion.m_major, Version.CurrentVersion.m_minor, Version.CurrentVersion.m_patch) + "# The file is intended for debugging and investigating the drops from entities with a DropTable (the name of the drop tables mostly used by objects and chests).\n# The entries listed here show the expected result of applying the loaded Drop That configs. This will include any unchanged drops.\n# Note, the actual dropping is calculated for each entity at run-time, so this file might not perfectly reflect the game state.\n# This file is not scanned by Drop That, and any changes done will therefore have no effect. Copy sections into a DropTable config in the configs folder if you want to change things.# See https://github.com/ASharpPen/Valheim.DropThat/wiki/DropTable-Configuration for additional details." }), "drop_that.drop_table.after_changes.cfg", "expected drop tables after applying changes"); } } internal static class DropTableDataWriter { private static string GetData(MonoBehaviour source, DropTable dropTable, string[] additionalHeaders) { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); string cleanedName = ((Object)(object)((Component)source).gameObject).GetCleanedName(); if (string.IsNullOrWhiteSpace(cleanedName)) { return ""; } stringBuilder.AppendLine(); stringBuilder.AppendLine("## DropTable Source: " + ((object)source).GetType().Name + "; " + GeneralExtensions.Join<string>((IEnumerable<string>)additionalHeaders, (Func<string, string>)null, "; ")); stringBuilder.AppendLine("[" + cleanedName + "]"); stringBuilder.AppendLine("DropChance=" + (dropTable.m_dropChance * 100f).ToString(CultureInfo.InvariantCulture)); stringBuilder.AppendLine($"DropOnlyOnce={dropTable.m_oneOfEach}"); stringBuilder.AppendLine($"DropMin={dropTable.m_dropMin}"); stringBuilder.AppendLine($"DropMax={dropTable.m_dropMax}"); for (int i = 0; i < dropTable.m_drops.Count; i++) { DropData val = dropTable.m_drops[i]; stringBuilder.AppendLine(); stringBuilder.AppendLine($"[{cleanedName}.{i}]"); stringBuilder.AppendLine("PrefabName=" + (((Object)(object)val.m_item).IsNotNull() ? ((Object)val.m_item).name : "")); stringBuilder.AppendLine("Weight=" + val.m_weight.ToString(CultureInfo.InvariantCulture)); stringBuilder.AppendLine($"AmountMin={val.m_stackMin}"); stringBuilder.AppendLine($"AmountMax={val.m_stackMax}"); stringBuilder.AppendLine($"DisableResourceModifierScaling={val.m_dontScale}"); } return stringBuilder.ToString(); } internal static void PrintDungeonDropTables() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) IOrderedEnumerable<ZoneLocation> orderedEnumerable = from x in ZoneSystem.instance.m_locations where x.m_enable orderby x.m_biome, x.m_prefabName select x; List<string> list = new List<string>(); foreach (ZoneLocation item in orderedEnumerable) { item.m_prefab.Load(); GameObject asset = item.m_prefab.Asset; if (((Object)(object)asset).IsNull()) { continue; } DungeonGenerator[] componentsInChildren = asset.GetComponentsInChildren<DungeonGenerator>(); if (componentsInChildren == null || componentsInChildren.Length == 0) { continue; } DungeonGenerator[] array = componentsInChildren; foreach (DungeonGenerator dungeon in array) { List<Room> list2 = (from x in DungeonDB.GetRooms().Select(delegate(RoomData x) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) x.m_prefab.Load(); return x.RoomInPrefab; }) where ((Object)(object)x).IsNotNull() && (Theme)(x.m_theme & dungeon.m_themes) == x.m_theme select x).ToList(); if (list2 == null || list2.Count == 0) { continue; } foreach (Room item2 in list2) { list.AddRange(Extract(((Component)item2).gameObject, "Biome: " + item.m_biome.GetNames(), "Location: " + item.m_prefabName, $"Room Theme: {item2.m_theme}", "Room: " + ((Object)ite