Decompiled source of Drop That v3.0.8

Valheim.DropThat.dll

Decompiled 2 months ago
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.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.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.Services;
using DropThat.Drop.DropTableSystem.Sync;
using DropThat.Drop.DropTableSystem.Wrapper;
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.Logging;
using ThatCore.Models;
using ThatCore.Network;
using ThatCore.Utilities.Files;
using ThatCore.Utilities.Valheim;
using UnityEngine;
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.0.8+0714bff64a7e2425d8d1406f09ff30c963f6956b")]
[assembly: AssemblyFileVersion("3.0.8.0")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCompany("A Sharp Pen")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[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.0.8.0")]
[module: <9fb87ba0-860c-4572-b5f6-594aee2312aa>RefSafetyRules(11)]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<2e6916aa-1633-4c40-9a23-e008455862f5>Embedded]
	internal sealed class <2e6916aa-1633-4c40-9a23-e008455862f5>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	[<2e6916aa-1633-4c40-9a23-e008455862f5>Embedded]
	internal sealed class <9fb87ba0-860c-4572-b5f6-594aee2312aa>RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public <9fb87ba0-860c-4572-b5f6-594aee2312aa>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 (ThatCore.Extensions.UnityObjectExtensions.IsNotNull((Object)(object)__instance) && ThatCore.Extensions.UnityObjectExtensions.IsNotNull((Object)(object)((Component)__instance).gameObject))
			{
				_originalPrefabName = ((Object)((Component)__instance).gameObject).name;
			}
		}

		[HarmonyPatch("Awake")]
		private static void Postfix(MineRock5 __instance)
		{
			if (ThatCore.Extensions.UnityObjectExtensions.IsNotNull((Object)(object)__instance) && ThatCore.Extensions.UnityObjectExtensions.IsNotNull((Object)(object)((Component)__instance).gameObject) && _originalPrefabName != null)
			{
				((Object)((Component)__instance).gameObject).name = _originalPrefabName;
			}
		}
	}
}
namespace DropThat
{
	[BepInPlugin("asharppen.valheim.drop_that", "Drop That!", "3.0.8")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class DropThatPlugin : BaseUnityPlugin
	{
		public const string ModId = "asharppen.valheim.drop_that";

		public const string PluginName = "Drop That!";

		public const string Version = "3.0.8";

		private void Awake()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Log.SetLogger(new BepInExLogger(((BaseUnityPlugin)this).Logger));
			GeneralConfigManager.Load();
			new Harmony("asharppen.valheim.drop_that").PatchAll();
			Startup.SetupServices();
		}
	}
	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;

		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 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;
		}
	}
	public static class UnityObjectExtensions
	{
		private static Regex NameRegex = new Regex("^[^$(]*(?=$|[(])", RegexOptions.Compiled);

		public static bool IsNull(this Object obj)
		{
			if (obj == (Object)null || !Object.op_Implicit(obj))
			{
				return true;
			}
			return false;
		}

		public static bool IsNotNull(this Object obj)
		{
			if (obj != (Object)null && Object.op_Implicit(obj))
			{
				return true;
			}
			return false;
		}

		public static string GetCleanedName(this Object obj, bool toUpper = false)
		{
			if (obj.IsNull())
			{
				return null;
			}
			string text = obj.name.Split(new char[1] { '(' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault()?.Trim();
			if (!string.IsNullOrWhiteSpace(text))
			{
				return text;
			}
			return obj.name;
		}
	}
}
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 (DropThat.Utilities.UnityObjectExtensions.IsNull((Object)(object)ZoneSystem.instance))
			{
				Log.Warning?.Log("Attempting to retrieve location before ZoneSystem is initialized.");
				return null;
			}
			Vector2i zone = ZoneSystem.GetZone(position);
			if (DropThat.Utilities.UnityObjectExtensions.IsNotNull((Object)(object)ZoneSystem.instance) && (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;

	}
}
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))
			{
				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);
						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);
				for (int i = 0; i < num; i++)
				{
					MagicItemEffect item2 = LootRoller.RollEffect(RollWeightedEffect(availableEffects, removeSelected: false), (ItemRarity)3, (ValueDef)null);
					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);
			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 (!ThatCore.Extensions.UnityObjectExtensions.IsNull((Object)(object)val))
				{
					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 (!ThatCore.Extensions.UnityObjectExtensions.IsNull((Object)(object)val))
				{
					Log.Trace?.Log($"Setting quality level of item '{((Object)val).name}' to {QualityLevel}.");
					val.m_itemData.m_durability = 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 (!ThatCore.Extensions.UnityObjectExtensions.IsNull((Object)(object)drop.Item) && !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.Wrapper
{
	internal sealed class WrapperCache
	{
		public WrapperComponent Wrapper { get; set; }

		public GameObject Wrapped { get; set; }

		public bool Unwrapped { get; set; }

		internal static ManagedCache<WrapperCache> Cache { get; } = new ManagedCache<WrapperCache>();


		internal static Dictionary<int, WrapperCache> CacheById { get; } = new Dictionary<int, WrapperCache>();


		internal static bool TryGet(GameObject key, out WrapperCache cache)
		{
			if (Cache.TryGet((Object)(object)key, out cache))
			{
				return true;
			}
			return false;
		}

		internal static bool TryGet(int instanceId, out WrapperCache cache)
		{
			if (CacheById.TryGetValue(instanceId, out cache))
			{
				return true;
			}
			return false;
		}

		internal static void Set(WrapperComponent wrapper, GameObject wrapped, bool unwrapped = false)
		{
			WrapperCache value = new WrapperCache
			{
				Wrapper = wrapper,
				Wrapped = wrapped,
				Unwrapped = unwrapped
			};
			Cache.Set((Object)(object)((Component)wrapper).gameObject, value);
			CacheById[wrapper.SourceId] = value;
		}

		internal static void CleanUp(int instanceId)
		{
			CacheById.Remove(instanceId);
		}
	}
	public sealed class WrapperComponent : MonoBehaviour
	{
		public DropTableDrop Drop;

		public int SourceId;

		public void Start()
		{
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (WrapperCache.TryGet(((Component)this).gameObject, out var cache))
				{
					if (cache.Unwrapped)
					{
						Log.Development?.Log("Destroying succesfully unwrapped wrapper.");
						WrapperCache.CleanUp(SourceId);
					}
					else
					{
						Log.Development?.Log($"Wrapper of '{((Object)cache.Wrapper).name}' was not unwrapped. Has cache '{cache != null}' and wrapper instance '{((Object)((Component)this).gameObject).GetInstanceID()}'");
					}
					return;
				}
				Log.Development?.Log($"Searching for cached wrapper: {SourceId}");
				if (WrapperCache.TryGet(SourceId, out cache))
				{
					Drop = cache.Wrapper.Drop;
					WrapperCache.CleanUp(SourceId);
					Log.Development?.Log($"Found original cached wrapper: {SourceId}");
				}
				GameObject val = Drop?.DropData.m_item;
				if (ThatCore.Extensions.UnityObjectExtensions.IsNull((Object)(object)val))
				{
					string cleanedName = ThatCore.Extensions.UnityObjectExtensions.GetCleanedName((Object)(object)((Component)this).gameObject);
					Log.Development?.Log("No stored drop reference for wrapper '" + cleanedName + "'.");
					val = ZNetScene.instance.GetPrefab(cleanedName);
				}
				if (ThatCore.Extensions.UnityObjectExtensions.IsNull((Object)(object)val))
				{
					Log.Development?.Log($"Unable to find prefab for wrapper '{((Object)this).name}'. Has cache: {cache != null}");
					return;
				}
				Vector3 position = ((Component)this).gameObject.transform.position;
				DropTableSessionManager.UnwrapDrop(((Component)this).gameObject);
				Log.Development?.Log($"Dummy object '{((Object)((Component)this).gameObject).name}' instantiated. Creating real object instead at '{position}'. Has cache '{cache != null}' and wrapper instance '{((Object)((Component)this).gameObject).GetInstanceID()}'");
				GameObject actualDrop = Object.Instantiate<GameObject>(val, position, ((Component)this).gameObject.transform.rotation);
				if (Drop?.DropTemplate == null)
				{
					return;
				}
				ItemModifierContext<GameObject> dropContext = new ItemModifierContext<GameObject>
				{
					Item = actualDrop,
					Position = actualDrop.transform.position
				};
				Drop.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 '" + ((Object)actualDrop).name + "'. Skipping modifier.", e2);
					}
				});
			}
			catch (Exception e)
			{
				WrapperCache.CleanUp(SourceId);
				Log.Error?.Log("Error during Wrapper.Start", e);
			}
			finally
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	public static class WrapperGameObjectExtensions
	{
		public static WrapperComponent Wrap(this GameObject gameObject)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (WrapperCache.TryGet(gameObject, out var cache))
			{
				return cache.Wrapper;
			}
			GameObject val = new GameObject(((Object)gameObject).name);
			WrapperComponent wrapperComponent = val.AddComponent<WrapperComponent>();
			wrapperComponent.SourceId = ((Object)val).GetInstanceID();
			WrapperCache.Set(wrapperComponent, gameObject);
			return wrapperComponent;
		}

		public static GameObject Unwrap(this GameObject gameObject)
		{
			if (ThatCore.Extensions.UnityObjectExtensions.IsNull((Object)(object)gameObject))
			{
				return gameObject;
			}
			if (WrapperCache.TryGet(gameObject, out var cache))
			{
				Log.Development?.Log("Unwrapped '" + ((Object)cache.Wrapped).name + "'");
				cache.Unwrapped = true;
				return cache.Wrapped;
			}
			return gameObject;
		}
	}
}
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(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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: 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();
			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 = DropThat.Utilities.UnityObjectExtensions.GetCleanedName((Object)(object)list[item.Key].m_item);
					if (!string.IsNullOrEmpty(item.Value.PrefabName) && cleanedName == template.PrefabName)
					{
						Log.Trace?.Log($"Configuring existing drop '{item.Key}:{cleanedName}'.");
					}
					else
					{
						Log.Trace?.Log($"Configuring and changing existing drop '{item.Key}:{cleanedName}' to {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 '" + DropThat.Utilities.UnityObjectExtensions.GetCleanedName((Object)(object)source) + "'.");
				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 val = drop.DropData.m_item;
				if (drop.DropTemplate != null)
				{
					WrapperComponent wrapperComponent = val.Wrap();
					wrapperComponent.Drop = drop;
					val = ((Component)wrapperComponent).gameObject;
				}
				array[i] = val;
			}
			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 (ThatCore.Extensions.UnityObjectExtensions.IsNull((Object)(object)val))
			{
				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 (ThatCore.Extensions.UnityObjectExtensions.IsNull((Object)(object)ZNetScene.instance))
			{
				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 (ThatCore.Extensions.UnityObjectExtensions.IsNotNull((Object)(object)prefab) && TryCompileDrops(prefab, applyTemplate, out var compiledDrops))
				{
					list.Add(compiledDrops);
				}
			}
			return list;
		}

		public static bool TryCompileDrops(string prefabName, bool applyTemplate, out DropTableTemplate compiledDrops)
		{
			if (ThatCore.Extensions.UnityObjectExtensions.IsNull((Object)(object)ZNetScene.instance))
			{
				throw new InvalidOperationException("Too early. Trying to get expected drops before ZnetScene is instantiated.");
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(prefabName);
			if (ThatCore.Extensions.UnityObjectExtensions.IsNull((Object)(object)prefab))
			{
				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(ThatCore.Extensions.UnityObjectExtensions.GetCleanedName((Object)(object)prefab), 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 = ThatCore.Extensions.UnityObjectExtensions.GetCleanedName((Object)(object)x.m_item),
				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
						{
							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
{
	[HarmonyPatch]
	internal static class Patch_Init
	{
		[HarmonyPatch(typeof(Container))]
		internal static class Patch_Container_Awake_InitDropContext
		{
			[HarmonyPatch("Awake")]
			[HarmonyPrefix]
			private static void SetLink(Container __instance)
			{
				DropTableSessionManager.Initialize((MonoBehaviour)(object)__instance, __instance.m_defaultItems);
			}
		}

		[HarmonyPatch(typeof(DropOnDestroyed))]
		internal static class Patch_DropOnDestroyed_Awake_InitDropContext
		{
			[HarmonyPatch("Awake")]
			[HarmonyPostfix]
			private static void SetLink(DropOnDestroyed __instance)
			{
				DropTableSessionManager.Initialize((MonoBehaviour)(object)__instance, __instance.m_dropWhenDestroyed);
			}
		}

		[HarmonyPatch(typeof(LootSpawner))]
		internal static class Patch_LootSpawner_Awake_InitDropContext
		{
			[HarmonyPatch("Awake")]
			[HarmonyPostfix]
			private static void SetLink(LootSpawner __instance)
			{
				DropTableSessionManager.Initialize((MonoBehaviour)(object)__instance, __instance.m_items);
			}
		}

		[HarmonyPatch(typeof(TreeBase))]
		internal static class Patch_TreeBase_Awake_InitDropContext
		{
			[HarmonyPatch("Awake")]
			[HarmonyPostfix]
			private static void SetLink(TreeBase __instance)
			{
				DropTableSessionManager.Initialize((MonoBehaviour)(object)__instance, __instance.m_dropWhenDestroyed);
			}
		}

		[HarmonyPatch(typeof(TreeLog))]
		internal static class Patch_TreeLog_Awake_InitDropContext
		{
			[HarmonyPostfix]
			[HarmonyPatch("Awake")]
			private static void SetLink(TreeLog __instance)
			{
				DropTableSessionManager.Initialize((MonoBehaviour)(object)__instance, __instance.m_dropWhenDestroyed);
			}
		}

		[HarmonyPatch(typeof(MineRock))]
		internal static class Patch_MineRock_Awake_InitDropContext
		{
			[HarmonyPostfix]
			[HarmonyPatch("Start")]
			private static void SetLink(MineRock __instance)
			{
				DropTableSessionManager.Initialize((MonoBehaviour)(object)__instance, __instance.m_dropItems);
			}
		}

		[HarmonyPatch(typeof(MineRock5))]
		internal static class Patch_MineRock5_Awake_InitDropContext
		{
			[HarmonyPatch("Awake")]
			[HarmonyPostfix]
			private static void SetLink(MineRock5 __instance)
			{
				DropTableSessionManager.Initialize((MonoBehaviour)(object)__instance, __instance.m_dropItems);
			}
		}
	}
	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();
			}
		}

		[HarmonyPatch(typeof(LootSpawner))]
		internal static class Patch_LootSpawner_UpdateSpawner
		{
			[HarmonyPatch("UpdateSpawner")]
			[HarmonyTranspiler]
			private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions)
			{
				return instructions.InsertDropManagementInstructions();
			}
		}

		[HarmonyPatch(typeof(TreeLog))]
		internal static class Patch_TreeLog_Destroy
		{
			[HarmonyPatch("Destroy")]
			[HarmonyTranspiler]
			private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions)
			{
				return instructions.InsertDropManagementInstructions();
			}
		}

		[HarmonyPatch(typeof(TreeBase))]
		internal static class Patch_TreeBase_RPC_Damage
		{
			[HarmonyPatch("RPC_Damage")]
			[HarmonyTranspiler]
			private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions)
			{
				return instructions.InsertDropManagementInstructions();
			}
		}

		[HarmonyPatch(typeof(MineRock))]
		internal static class Patch_MineRock_RPC_Hit
		{
			[HarmonyPatch("RPC_Hit")]
			[HarmonyTranspiler]
			private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions)
			{
				return instructions.InsertDropManagementInstructions();
			}
		}

		[HarmonyPatch(typeof(MineRock5))]
		internal static class Patch_MineRock5_DamageArea
		{
			[HarmonyTranspiler]
			[HarmonyPatch("DamageArea")]
			private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions)
			{
				return instructions.InsertDropManagementInstructions();
			}
		}

		private static IEnumerable<CodeInstruction> InsertDropManagementInstructions(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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Call, (object)ReflectionUtils.InstantiateGameObjectMethod, (string)null)
			}).Advance(-2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<GameObject, GameObject>>((Func<GameObject, GameObject>)DropTableSessionManager.UnwrapDrop) })
				.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]
				{
					new CodeInstruction(OpCodes.Dup, (object)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Action<GameObject>>((Action<GameObject>)DropTableSessionManager.ModifyInstantiatedDrop) })
				.InstructionEnumeration();
		}
	}
	[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(__instance))
				{
					__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;
		}

		[HarmonyPatch(typeof(DropTable), "GetDropList", new Type[] { typeof(int) })]
		[HarmonyPriority(0)]
		[HarmonyPrefix]
		private static bool DropListOverhaul(DropTable __instance, ref List<GameObject> __result)
		{
			try
			{
				if (DropTableSessionManager.HasChanges(__instance))
				{
					__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;
		}
	}
	internal static class DropTableSessionManager
	{
		private static GameObject _currentWrapped;

		public static ManagedCache<GameObject> DropTableInstances { get; } = new ManagedCache<GameObject>();


		private static ConditionalWeakTable<DropTable, GameObject> SourceLinkTable { get; } = new ConditionalWeakTable<DropTable, GameObject>();


		private static ConditionalWeakTable<DropTable, DropTableTemplate> TemplateLinkTable { get; } = new ConditionalWeakTable<DropTable, DropTableTemplate>();


		private static ConditionalWeakTable<DropTable, List<DropTableDrop>> DropsByTable { get; } = new ConditionalWeakTable<DropTable, List<DropTableDrop>>();


		public static void Initialize(MonoBehaviour source, DropTable dropTable)
		{
			try
			{
				GameObject value;
				if (dropTable == null || ThatCore.Extensions.UnityObjectExtensions.IsNull((Object)(object)source))
				{
					Log.Development?.Log("DropTable or Source is null");
				}
				else if (!SourceLinkTable.TryGetValue(dropTable, out value))
				{
					DropTableInstances.Set((Object)(object)((Component)source).gameObject, ((Component)source).gameObject);
					SourceLinkTable.Add(dropTable, ((Component)source).gameObject);
					if (DropTableTemplateManager.TryGetTemplate(ThatCore.Extensions.UnityObjectExtensions.GetCleanedName((Object)(object)source), out var template))
					{
						TemplateLinkTable.Remove(dropTable);
						TemplateLinkTable.Add(dropTable, template);
						PrepareTable(dropTable);
					}
				}
			}
			catch (Exception e)
			{
				Log.Error?.Log("Error while attempting to store reference from drop table to its source.", e);
			}
		}

		public static bool HasChanges(DropTable dropTable)
		{
			DropTableTemplate value;
			return TemplateLinkTable.TryGetValue(dropTable, out value);
		}

		public static List<ItemData> GenerateItemDrops(DropTable dropTable)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			if (dropTable == null)
			{
				return new List<ItemData>();
			}
			if (!DropsByTable.TryGetValue(dropTable, out var value))
			{
				Log.Warning?.Log("Attempted to generate drops without having prepared DropTable. Attempting recovery, but something is wrong.");
				value = PrepareTable(dropTable);
			}
			if (!SourceLinkTable.TryGetValue(dropTable, out var source))
			{
				return new List<ItemData>();
			}
			List<DropTableDrop> list = DropRollerService.RollDrops(dropTable, source, value);
			if (Log.TraceEnabled)
			{
				Log.Trace?.Log($"Dropping {list.Count} items:");
				foreach (DropTableDrop item in list)
				{
					Log.Trace?.Log("\t" + ((Object)item.DropData.m_item).name);
				}
			}
			return (from x in list.SelectMany((DropTableDrop drop) => DropScalerService.ScaleDropsAsItemData(source, drop))
				where x != null
				select x).ToList();
		}

		public static List<GameObject> GenerateDrops(DropTable dropTable)
		{
			if (dropTable == null)
			{
				return new List<GameObject>();
			}
			if (!DropsByTable.TryGetValue(dropTable, out var value))
			{
				Log.Warning?.Log("Attempted to generate drops without having prepared DropTable. Attempting recovery, but something is wrong.");
				value = PrepareTable(dropTable);
			}
			if (!SourceLinkTable.TryGetValue(dropTable, out var value2))
			{
				return new List<GameObject>();
			}
			return (from x in DropRollerService.RollDrops(dropTable, value2, value).SelectMany(DropScalerService.ScaleDropsAsGameObjects)
				where x != null
				select x).ToList();
		}

		private static List<DropTableDrop> PrepareTable(DropTable dropTable)
		{
			if (!TemplateLinkTable.TryGetValue(dropTable, out var value))
			{
				Log.Warning?.Log("Attempted to generate drops without having template linked to DropTable.");
				return new List<DropTableDrop>(0);
			}
			ConfigureDropTableService.ConfigureTable(dropTable, value);
			List<DropTableDrop> list = ConfigureDropTableService.CreateDropList(dropTable, value);
			DropsByTable.Remove(dropTable);
			DropsByTable.Add(dropTable, list);
			return list;
		}

		public static GameObject UnwrapDrop(GameObject wrappedDrop)
		{
			try
			{
				_currentWrapped = wrappedDrop;
				return wrappedDrop.Unwrap();
			}
			catch (Exception e)
			{
				Log.Error?.Log("Error while attempting to unwrap drop", e);
				return wrappedDrop;
			}
		}

		public static void ModifyInstantiatedDrop(GameObject drop)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!WrapperCache.TryGet(_currentWrapped, out var cache) || cache.Wrapper.Drop?.DropTemplate == null)
				{
					return;
				}
				ItemModifierContext<GameObject> dropContext = new ItemModifierContext<GameObject>
				{
					Item = drop,
					Position = drop.transform.position
				};
				cache.Wrapper.Drop.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 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 (ThatCore.Extensions.UnityObjectExtensions.IsNotNull((Object)(object)value) && 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.0.8", 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.0.8", 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 = DropThat.Utilities.UnityObjectExtensions.GetCleanedName((Object)(object)((Component)source).gameObject);
			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=" + (DropThat.Utilities.UnityObjectExtensions.IsNotNull((Object)(object)val.m_item) ? ((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 (DropThat.Utilities.UnityObjectExtensions.IsNull((Object)(object)asset))
				{
					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 DropThat.Utilities.UnityObjectExtensions.IsNotNull((Object)(object)x) && (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)item2).name));
					}
				}
			}
			PrintDebugFile.PrintFile(list, "drop_that.drop_table.dungeons.txt", "drop tables for dungeons");
		}

		internal static void PrintLocationDropTables()
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			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 (!DropThat.Utilities.UnityObjectExtensions.IsNull((Object)(object)asset))
				{
					list.AddRange(Extract(asset, "Biome: " + item.m_biome.GetNames(), "Location: " + item.m_prefabName));
				}
			}
			PrintDebugFile.PrintFile(list, "drop_that.drop_table.locations.txt", "drop tables for locations");
		}

		internal static void PrintPrefabDropTables()
		{
			List<string> list = new List<string>();
			foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
			{
				list.AddRange(Extract(prefab));
			}
			PrintDebugFile.PrintFile(list, "drop_that.drop_table.prefabs.txt", "drop tables for prefabs");
		}

		private static List<string> Extract(GameObject prefab, params string[] additionalHeaders)
		{
			List<string> list = new List<string>();
			Container componentInChildren = prefab.GetComponentInChildren<Container>();
			if (DropThat.Utilities.UnityObjectExtensions.IsNotNull((Object)(object)componentInChildren) && Object.op_Implicit((Object)(object)componentInChildren))
			{
				list.Add(GetData((MonoBehaviour)(object)componentInChildren, componentInChildren.m_defaultItems, additionalHeaders));
			}
			DropOnDestroyed componentInChildren2 = prefab.GetComponentInChildren<DropOnDestroyed>();
			if (DropThat.Utilities.UnityObjectExtensions.IsNotNull((Object)(object)componentInChildren2) && Object.op_Implicit((Object)(object)componentInChildren2))
			{
				list.Add(GetData((MonoBehaviour)(object)componentInChildren2, componentInChildren2.m_dropWhenDestroyed, additionalHeaders));
			}
			LootSpawner componentInChildren3 = prefab.GetComponentInChildren<LootSpawner>();
			if (DropThat.Utilities.UnityObjectExtensions.IsNotNull((Object)(object)componentInChildren3) && Object.op_Implicit((Object)(object)componentInChildren3))
			{
				list.Add(GetData((MonoBehaviour)(object)componentInChildren3, componentInChildren3.m_items, additionalHeaders));
			}
			TreeBase componentInChildren4 = prefab.GetComponentInChildren<TreeBase>();
			if (DropThat.Utilities.UnityObjectExtensions.IsNotNull((Object)(object)componentInChildren4) && Object.op_Implicit((Object)(object)componentInChildren4))
			{
				list.Add(GetData((MonoBehaviour)(object)componentInChildren4, componentInChildren4.m_dropWhenDestroyed, additionalHeaders));
			}
			TreeLog componentInChildren5 = prefab.GetComponentInChildren<TreeLog>();
			if (DropThat.Utilities.UnityObjectExtensions.IsNotNull((Object)(object)componentInChildren5) && Object.op_Implicit((Object)(object)componentInChildren5))
			{
				list.Add(GetData((MonoBehaviour)(object)componentInChildren5, componentInChildren5.m_dropWhenDestroyed, additionalHeaders));
			}
			MineRock componentInChildren6 = prefab.GetCompo