Decompiled source of Drop That v2.3.13

Valheim.DropThat.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
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 EpicLoot;
using EpicLoot.Data;
using EpicLoot.LegendarySystem;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using Valheim.DropThat.Caches;
using Valheim.DropThat.Configuration;
using Valheim.DropThat.Configuration.ConfigTypes;
using Valheim.DropThat.Core;
using Valheim.DropThat.Core.Configuration;
using Valheim.DropThat.Core.Network;
using Valheim.DropThat.Creature.DamageRecords;
using Valheim.DropThat.Creature.StatusRecords;
using Valheim.DropThat.Debugging;
using Valheim.DropThat.Drop.CharacterDropSystem.Caches;
using Valheim.DropThat.Drop.CharacterDropSystem.Conditions;
using Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific;
using Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific.CLLC;
using Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific.SpawnThat;
using Valheim.DropThat.Drop.CharacterDropSystem.Models;
using Valheim.DropThat.Drop.CharacterDropSystem.Modifiers;
using Valheim.DropThat.Drop.CharacterDropSystem.Modifiers.ModSpecific;
using Valheim.DropThat.Drop.CharacterDropSystem.Modifiers.ModSpecific.ModEpicLoot;
using Valheim.DropThat.Drop.CharacterDropSystem.Services;
using Valheim.DropThat.Drop.DropTableSystem.Caches;
using Valheim.DropThat.Drop.DropTableSystem.Conditions;
using Valheim.DropThat.Drop.DropTableSystem.Conditions.ModSpecific;
using Valheim.DropThat.Drop.DropTableSystem.Conditions.ModSpecific.ModCLLC;
using Valheim.DropThat.Drop.DropTableSystem.Managers;
using Valheim.DropThat.Drop.DropTableSystem.Modifiers;
using Valheim.DropThat.Drop.DropTableSystem.Modifiers.ModSpecific.ModEpicLoot;
using Valheim.DropThat.Drop.DropTableSystem.Wrapper;
using Valheim.DropThat.Integrations;
using Valheim.DropThat.Integrations.EpicLootIntegration;
using Valheim.DropThat.Locations;
using Valheim.DropThat.Reset;
using Valheim.DropThat.Utilities;
using Valheim.DropThat.Utilities.Valheim;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("A Sharp Pen")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Valheim mod and tool for configuring loot drops.")]
[assembly: AssemblyFileVersion("2.3.13.0")]
[assembly: AssemblyInformationalVersion("2.3.13+780bf6647f512c07461ae8296b24713e31979865")]
[assembly: AssemblyProduct("Valheim.DropThat")]
[assembly: AssemblyTitle("Valheim.DropThat")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ASharpPen/Valheim.SpawnThat")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.3.13.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Valheim.DropThat
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("asharppen.valheim.drop_that", "Drop That!", "2.3.13")]
	public class DropThatPlugin : BaseUnityPlugin
	{
		public const string ModId = "asharppen.valheim.drop_that";

		public const string PluginName = "Drop That!";

		public const string Version = "2.3.13";

		private void Awake()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Log.Logger = ((BaseUnityPlugin)this).Logger;
			ConfigurationManager.LoadGeneralConfigurations();
			new Harmony("asharppen.valheim.drop_that").PatchAll();
			NetworkSetup.SetupNetworking();
		}
	}
}
namespace Valheim.DropThat.Utilities
{
	public static class CodeMatcherExtensions
	{
		public static CodeMatcher GetPosition(this CodeMatcher codeMatcher, out int position)
		{
			position = codeMatcher.Pos;
			return codeMatcher;
		}

		internal static CodeMatcher Print(this CodeMatcher codeMatcher, int before, int after)
		{
			return codeMatcher;
		}
	}
	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.StartsWith("Instantiate")
			select x into m
			where m.IsGenericMethod
			select m).First((MethodInfo m) => m.ContainsGenericParameters && m.GetParameters().Length == 3).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 Valheim.DropThat.Utilities.Valheim
{
	public static class BiomeExtensions
	{
		public static string GetNames(this Biome biome)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			List<string> list = new List<string>();
			foreach (Biome value in Enum.GetValues(typeof(Biome)))
			{
				Biome val = value;
				if ((int)val != 0 && (biome & val) > 0)
				{
					list.Add(((object)(Biome)(ref val)).ToString());
				}
			}
			return GeneralExtensions.Join<string>((IEnumerable<string>)list, (Func<string, string>)null, ", ");
		}
	}
	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;
		}
	}
}
namespace Valheim.DropThat.Reset
{
	public static class StateResetter
	{
		private static HashSet<Action> OnResetActions = new HashSet<Action>();

		public static void Subscribe(Action onReset)
		{
			OnResetActions.Add(onReset);
		}

		public static void Unsubscribe(Action onReset)
		{
			OnResetActions.Remove(onReset);
		}

		public static void Reset()
		{
			Log.LogDebug("Resetting mod state.");
			foreach (Action onResetAction in OnResetActions)
			{
				onResetAction();
			}
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "OnWorldStart")]
	public static class WorldStartPatch
	{
		[HarmonyPatch("OnWorldStart")]
		[HarmonyPrefix]
		private static void ResetState()
		{
			Log.LogDebug("OnWorldStart - Resetting configurations");
			StateResetter.Reset();
			ConfigurationManager.LoadAll();
		}

		[HarmonyPatch("JoinServer")]
		[HarmonyPrefix]
		private static void ResetStateMultiplayer()
		{
			Log.LogDebug("JoinServer - Resetting configurations");
			StateResetter.Reset();
		}

		[HarmonyPatch("ParseServerArguments")]
		[HarmonyPrefix]
		private static void ResetStateServer()
		{
			Log.LogDebug("ParseServerArguments - Resetting configurations");
			StateResetter.Reset();
			ConfigurationManager.LoadAllCharacterDropConfigurations();
			ConfigurationManager.LoadAllCharacterDropLists();
			ConfigurationManager.LoadAllDropTableConfigurations();
			ConfigurationManager.LoadAllDropTableLists();
		}
	}
}
namespace Valheim.DropThat.Locations
{
	public static class LocationHelper
	{
		private static Dictionary<Vector2i, SimpleLocation> _simpleLocationsByZone { get; set; }

		static LocationHelper()
		{
			StateResetter.Subscribe(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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			if (((Object)(object)ZoneSystem.instance).IsNull())
			{
				Log.LogWarning("Attempting to retrieve location before ZoneSystem is initialized.");
				return null;
			}
			Vector2i zone = ZoneSystem.instance.GetZone(position);
			if (((Object)(object)ZoneSystem.instance).IsNotNull() && (ZoneSystem.instance.m_locationInstances?.Count ?? 0) > 0 && ZoneSystem.instance.m_locationInstances.TryGetValue(zone, out var value))
			{
				return new SimpleLocation
				{
					LocationName = (value.m_location?.m_prefabName ?? ""),
					Position = value.m_position,
					ZonePosition = zone
				};
			}
			if (_simpleLocationsByZone != null && _simpleLocationsByZone.TryGetValue(zone, out var value2))
			{
				return value2;
			}
			return null;
		}
	}
	[HarmonyPatch(typeof(ZoneSystem))]
	internal static class Patch_ZoneSystem_Start_PrintLocations
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void PrintLocations(ZoneSystem __instance)
		{
			if (__instance.m_locations != null && (bool)ConfigurationManager.GeneralConfig.WriteLocationsToFile)
			{
				LocationsFileWriter.WriteToList(__instance.m_locations);
			}
		}
	}
	public class SimpleLocation
	{
		public Vector3 Position;

		public Vector2i ZonePosition;

		public string LocationName;
	}
	[Serializable]
	internal class SimpleLocationPackage : CompressedPackage
	{
		public string[] LocationNames;

		public SimpleLocationDTO[] Locations;

		protected override void BeforePack()
		{
			//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.LogTrace($"Packed {LocationNames.Length} location names");
			Log.LogTrace($"Packed {Locations.Length} locations");
		}

		protected override void AfterUnpack(object responseObject)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			if (responseObject is SimpleLocationPackage)
			{
				Log.LogTrace($"Unpacking {LocationNames.Length} location names");
				Log.LogTrace($"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.PositionX, simpleLocationDTO.PositionY);
					list.Add(new SimpleLocation
					{
						LocationName = LocationNames[simpleLocationDTO.Location],
						Position = ZoneSystem.instance.GetZonePos(val),
						ZonePosition = val
					});
				}
				LocationHelper.SetLocations(list);
			}
		}
	}
	[Serializable]
	public struct SimpleLocationDTO
	{
		public int PositionX;

		public int PositionY;

		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)
			PositionX = pos.x;
			PositionY = pos.y;
			Location = location;
		}
	}
	[HarmonyPatch(typeof(ZNet))]
	public static class ZoneSystemMultiplayerPatch
	{
		private static bool HaveReceivedLocations;

		static ZoneSystemMultiplayerPatch()
		{
			StateResetter.Subscribe(delegate
			{
				HaveReceivedLocations = false;
			});
		}

		[HarmonyPatch("OnNewConnection")]
		[HarmonyPostfix]
		private static void TransferLocationData(ZNet __instance, ZNetPeer peer)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			if (ZNet.instance.IsServer())
			{
				Log.LogDebug("Registering server RPC for sending location data on request from client.");
				peer.m_rpc.Register("RPC_RequestLocationsDropThat", new Method(RPC_RequestLocationsDropThat));
				return;
			}
			Log.LogDebug("Registering client RPC for receiving location data from server.");
			peer.m_rpc.Register<ZPackage>("RPC_ReceiveLocationsDropThat", (Action<ZRpc, ZPackage>)RPC_ReceiveLocationsDropThat);
			Log.LogDebug("Requesting location data from server.");
			peer.m_rpc.Invoke("RPC_RequestLocationsDropThat", Array.Empty<object>());
		}

		private static void RPC_RequestLocationsDropThat(ZRpc rpc)
		{
			try
			{
				if (!ZNet.instance.IsServer())
				{
					Log.LogWarning("Non-server instance received request for location data. Ignoring request.");
					return;
				}
				Log.LogInfo("Sending location data.");
				if (ZoneSystem.instance.m_locationInstances == null)
				{
					Log.LogWarning("Unable to get locations from zonesystem to send to client.");
					return;
				}
				ZPackage package = new SimpleLocationPackage().Pack();
				DataTransferService.Service.AddToQueue(package, "RPC_ReceiveLocationsDropThat", rpc);
				Log.LogInfo("Finished sending locations package.");
			}
			catch (Exception e)
			{
				Log.LogError("Unexpected error while attempting to create and send locations package from server to client.", e);
			}
		}

		private static void RPC_ReceiveLocationsDropThat(ZRpc rpc, ZPackage pkg)
		{
			Log.LogDebug("Received locations package.");
			try
			{
				if (HaveReceivedLocations)
				{
					Log.LogDebug("Already received locations previously. Skipping.");
					return;
				}
				CompressedPackage.Unpack(pkg);
				HaveReceivedLocations = true;
				Log.LogInfo("Successfully received and unpacked locations package.");
			}
			catch (Exception e)
			{
				Log.LogError("Error while attempting to read received locations package.", e);
			}
		}
	}
}
namespace Valheim.DropThat.Integrations
{
	public static class InstallationManager
	{
		private static bool? _epicLootInstalled;

		private static bool? _rrrInstalled;

		public static bool EpicLootInstalled
		{
			get
			{
				bool valueOrDefault = _epicLootInstalled.GetValueOrDefault();
				if (!_epicLootInstalled.HasValue)
				{
					valueOrDefault = (object)Type.GetType("EpicLoot.EpicLoot, EpicLoot") != null;
					_epicLootInstalled = valueOrDefault;
					return valueOrDefault;
				}
				return valueOrDefault;
			}
		}

		public static bool RRRInstalled
		{
			get
			{
				bool valueOrDefault = _rrrInstalled.GetValueOrDefault();
				if (!_rrrInstalled.HasValue)
				{
					valueOrDefault = (object)Type.GetType("RRRCore.Plugin, RRRCore") != null;
					_rrrInstalled = valueOrDefault;
					return valueOrDefault;
				}
				return valueOrDefault;
			}
		}
	}
}
namespace Valheim.DropThat.Integrations.EpicLootIntegration
{
	internal static class ItemRoller
	{
		internal static bool TryRollMagic(ItemData itemData, Vector3 dropPos, ItemRollParameters parameters)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (!EpicLoot.CanBeMagicItem(itemData))
			{
				return false;
			}
			Rarity rarity = ItemService.RollRarity(parameters);
			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 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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.LogWarning("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.LogWarning("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.LogWarning("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 magicItem = LootRoller.RollMagicItem(rarity, itemData, luckFactor);
			orCreate.SetMagicItem(magicItem);
			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 Valheim.DropThat.Drop.DropTableSystem
{
	public class DropModificationContext
	{
		public class CachedComponent<T> where T : Component
		{
			private T Component;

			private GameObject Source;

			private bool HasChecked;

			public CachedComponent(GameObject gameObject)
			{
				Source = gameObject;
			}

			public static implicit operator T(CachedComponent<T> cache)
			{
				if (!cache.HasChecked)
				{
					cache.Component = cache.Source.GetComponent<T>();
					cache.HasChecked = true;
				}
				return cache.Component;
			}
		}

		public GameObject Drop { get; }

		public DropTemplate Template { get; }

		public CachedComponent<ItemDrop> ItemDrop { get; }

		public DropModificationContext(GameObject drop, DropTemplate template)
		{
			Drop = drop;
			Template = template;
			ItemDrop = new CachedComponent<ItemDrop>(drop);
		}
	}
	public class DropSourceTemplateLink
	{
		public GameObject Source;

		public DropTableEntityConfiguration EntityConfig;
	}
	public class DropTemplate
	{
		public DropTableEntityConfiguration EntityConfig { get; set; }

		public DropTableItemConfiguration Config { get; set; }

		public List<IDropTableCondition> Conditions { get; set; } = new List<IDropTableCondition>();


		public List<IDropTableModifier> Modifiers { get; set; } = new List<IDropTableModifier>();


		public DropData Drop { get; set; }
	}
	internal static class DropTableManager
	{
		private static readonly ItemData[] Item = (ItemData[])(object)new ItemData[1];

		public static List<ItemData> GetItemDrops(DropTable dropTable, DropSourceTemplateLink context)
		{
			return GetDrops(dropTable, context, ConvertTemplateToItem);
		}

		public static List<GameObject> GetDrops(DropTable dropTable, DropSourceTemplateLink context)
		{
			return GetDrops(dropTable, context, ConvertTemplateToDrop);
		}

		private static List<T> GetDrops<T>(DropTable dropTable, DropSourceTemplateLink context, Func<DropTemplate, IEnumerable<T>> DropConverter) where T : class
		{
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			List<DropTemplate> possibleDrops = DropConfigManager.GetPossibleDrops(context, dropTable);
			if (possibleDrops.Count == 0)
			{
				return new List<T>(0);
			}
			DropTableEntityConfiguration entityConfig = context.EntityConfig;
			if ((entityConfig == null) ? (Random.value > dropTable.m_dropChance) : (Random.value > (float)entityConfig.SetDropChance / 100f))
			{
				return new List<T>(0);
			}
			List<DropTemplate> templates = new List<DropTemplate>(possibleDrops);
			templates = DropConditionManager.Filter(context, templates);
			float num = templates.Sum((DropTemplate x) => x.Drop.m_weight);
			int num2 = ((entityConfig == null) ? Random.Range(dropTable.m_dropMin, dropTable.m_dropMax + 1) : Random.Range((int)entityConfig.SetDropMin, (int)entityConfig.SetDropMax + 1));
			bool flag = ((entityConfig == null) ? dropTable.m_oneOfEach : ((bool)entityConfig.SetDropOnlyOnce));
			List<T> list = new List<T>(num2);
			for (int i = 0; i < num2; i++)
			{
				float num3 = Random.Range(0f, num);
				float num4 = 0f;
				try
				{
					bool flag2 = false;
					foreach (DropTemplate item in templates)
					{
						num4 += item.Drop.m_weight;
						if (num3 <= num4)
						{
							list.AddRange(DropConverter(item));
							if (flag)
							{
								templates.Remove(item);
								num -= item.Drop.m_weight;
							}
							flag2 = true;
							break;
						}
					}
					if (!flag2 && templates.Count > 0)
					{
						list.AddRange(DropConverter(templates.First()));
					}
				}
				catch (Exception e)
				{
					Log.LogWarning("Error while rolling drop. Skipping roll\n", e);
				}
			}
			return list;
		}

		private static IEnumerable<ItemData> ConvertTemplateToItem(DropTemplate template)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ItemData val = template.Drop.m_item.GetComponent<ItemDrop>().m_itemData.Clone();
				int num = CalculateAmount(template);
				ConfigurationEntry<int> configurationEntry;
				ConfigurationEntry<float> configurationEntry2;
				if (num > val.m_shared.m_maxStackSize)
				{
					int num2 = Mathf.CeilToInt((float)num / (float)val.m_shared.m_maxStackSize);
					List<ItemData> list = new List<ItemData>(num2);
					int num3 = num;
					for (int i = 0; i < num2; i++)
					{
						ItemData val2 = template.Drop.m_item.GetComponent<ItemDrop>().m_itemData.Clone();
						int num4 = Math.Min(num3, val.m_shared.m_maxStackSize);
						val2.m_dropPrefab = template.Drop.m_item.Wrap();
						val2.m_stack = num4;
						configurationEntry = template.Config?.SetQualityLevel;
						val2.m_quality = ((configurationEntry == null) ? 1 : ((int)configurationEntry));
						configurationEntry2 = template.Config?.SetDurability;
						val2.m_durability = ((((configurationEntry2 != null) ? ((float)configurationEntry2) : (-1f)) >= 0f) ? ((float)template.Config.SetDurability) : val2.m_durability);
						DropTemplateCache.RegisterTemplate(val2, template);
						DropTemplateCache.RegisterTemplate(val2.m_dropPrefab, template);
						list.Add(val2);
						num3 -= num4;
					}
					return list;
				}
				val.m_dropPrefab = template.Drop.m_item.Wrap();
				val.m_stack = num;
				configurationEntry = template.Config?.SetQualityLevel;
				val.m_quality = ((configurationEntry == null) ? 1 : ((int)configurationEntry));
				configurationEntry2 = template.Config?.SetDurability;
				val.m_durability = ((((configurationEntry2 != null) ? ((float)configurationEntry2) : (-1f)) >= 0f) ? ((float)template.Config.SetDurability) : val.m_durability);
				DropTemplateCache.RegisterTemplate(val, template);
				DropTemplateCache.RegisterTemplate(val.m_dropPrefab, template);
				Item[0] = val;
				return Item;
			}
			catch (Exception e)
			{
				Log.LogError("Error while attempting to prepare new item data", e);
				return Enumerable.Empty<ItemData>();
			}
		}

		private static IEnumerable<GameObject> ConvertTemplateToDrop(DropTemplate template)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = template.Drop.m_item.Wrap();
			DropTemplateCache.RegisterTemplate(val, template);
			int num = CalculateAmount(template);
			GameObject[] array = (GameObject[])(object)new GameObject[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = val;
			}
			return array;
		}

		private static int CalculateAmount(DropTemplate template)
		{
			//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, template.Drop.m_stackMin);
			int num2 = template.Drop.m_stackMax + 1;
			int num3 = Random.Range(num, num2);
			if (template.Drop.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;
		}
	}
}
namespace Valheim.DropThat.Drop.DropTableSystem.Wrapper
{
	internal class WrapperCache
	{
		public GameObject Wrapper { get; set; }

		public GameObject Wrapped { get; set; }

		public bool Unwrapped { get; set; }

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


		internal static WrapperCache Get(GameObject go)
		{
			if (Cache.TryGet((Object)(object)go, out var value))
			{
				return value;
			}
			return null;
		}

		internal static void SetStatus(GameObject wrapper, bool unwrapped = false)
		{
			if (Cache.TryGet((Object)(object)wrapper, out var value))
			{
				value.Unwrapped = unwrapped;
			}
		}

		internal static void Set(GameObject wrapper, GameObject wrapped, bool unwrapped = false)
		{
			Cache.Set((Object)(object)wrapper, new WrapperCache
			{
				Wrapper = wrapper,
				Wrapped = wrapped,
				Unwrapped = unwrapped
			});
		}
	}
	public class WrapperComponent : MonoBehaviour
	{
		public void Start()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				WrapperCache wrapperCache = WrapperCache.Get(((Component)this).gameObject);
				if ((wrapperCache == null || !wrapperCache.Unwrapped) && wrapperCache == null)
				{
					string cleanedName = ((Object)(object)((Component)this).gameObject).GetCleanedName();
					GameObject prefab = ZNetScene.instance.GetPrefab(cleanedName);
					if (((Object)(object)prefab).IsNotNull())
					{
						Vector3 position = ((Component)this).gameObject.transform.position;
						Object.Instantiate<GameObject>(prefab, position, ((Component)this).gameObject.transform.rotation);
					}
				}
			}
			catch (Exception e)
			{
				Log.LogError("Error during Wrapper.Start", e);
			}
			finally
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	public static class WrapperGameObjectExtensions
	{
		public static GameObject Wrap(this GameObject gameObject)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0025: Expected O, but got Unknown
			if (WrapperCache.Get(gameObject) != null)
			{
				return gameObject;
			}
			GameObject val = new GameObject(((Object)gameObject).name);
			val.AddComponent<WrapperComponent>();
			WrapperCache.Set(val, gameObject);
			return val;
		}

		public static GameObject Unwrap(this GameObject gameObject)
		{
			if ((Object)(object)gameObject == (Object)null || !Object.op_Implicit((Object)(object)gameObject))
			{
				return gameObject;
			}
			WrapperCache wrapperCache = WrapperCache.Get(gameObject);
			if (wrapperCache != null)
			{
				wrapperCache.Unwrapped = true;
				return wrapperCache.Wrapped;
			}
			return gameObject;
		}
	}
}
namespace Valheim.DropThat.Drop.DropTableSystem.Patches
{
	internal static class Patch_DropSourceLink
	{
		[HarmonyPatch(typeof(Container))]
		internal static class Patch_Container_Awake_InitDropContext
		{
			[HarmonyPatch("Awake")]
			[HarmonyPrefix]
			private static void SetLink(Container __instance)
			{
				CreateLink(__instance.m_defaultItems, ((Component)__instance).gameObject);
			}
		}

		[HarmonyPatch(typeof(DropOnDestroyed))]
		internal static class Patch_DropOnDestroyed_Awake_InitDropContext
		{
			[HarmonyPatch("Awake")]
			[HarmonyPostfix]
			private static void SetLink(DropOnDestroyed __instance)
			{
				CreateLink(__instance.m_dropWhenDestroyed, ((Component)__instance).gameObject);
			}
		}

		[HarmonyPatch(typeof(LootSpawner))]
		internal static class Patch_LootSpawner_Awake_InitDropContext
		{
			[HarmonyPatch("Awake")]
			[HarmonyPostfix]
			private static void SetLink(LootSpawner __instance)
			{
				CreateLink(__instance.m_items, ((Component)__instance).gameObject);
			}
		}

		[HarmonyPatch(typeof(TreeBase))]
		internal static class Patch_TreeBase_Awake_InitDropContext
		{
			[HarmonyPatch("Awake")]
			[HarmonyPostfix]
			private static void SetLink(TreeBase __instance)
			{
				CreateLink(__instance.m_dropWhenDestroyed, ((Component)__instance).gameObject);
			}
		}

		[HarmonyPatch(typeof(TreeLog))]
		internal static class Patch_TreeLog_Awake_InitDropContext
		{
			[HarmonyPatch("Awake")]
			[HarmonyPostfix]
			private static void SetLink(TreeLog __instance)
			{
				CreateLink(__instance.m_dropWhenDestroyed, ((Component)__instance).gameObject);
			}
		}

		[HarmonyPatch(typeof(MineRock))]
		internal static class Patch_MineRock_Awake_InitDropContext
		{
			[HarmonyPatch("Start")]
			[HarmonyPostfix]
			private static void SetLink(MineRock __instance)
			{
				CreateLink(__instance.m_dropItems, ((Component)__instance).gameObject);
			}
		}

		[HarmonyPatch(typeof(MineRock5))]
		internal static class Patch_MineRock5_Awake_InitDropContext
		{
			[HarmonyPatch("Start")]
			[HarmonyPostfix]
			private static void SetLink(MineRock5 __instance)
			{
				CreateLink(__instance.m_dropItems, ((Component)__instance).gameObject);
			}
		}

		private static void CreateLink(DropTable dropTable, GameObject source)
		{
			try
			{
				if (dropTable == null || source == null)
				{
					return;
				}
				DropSourceTemplateLink dropSourceTemplateLink = new DropSourceTemplateLink
				{
					Source = source
				};
				string cleanedName = ((Object)(object)source).GetCleanedName();
				if (string.IsNullOrWhiteSpace(cleanedName))
				{
					return;
				}
				if (ConfigurationManager.DropTableConfigs == null)
				{
					Log.LogDebug($"{source} woke before configs were loaded. Skipping config for '{source}'");
					return;
				}
				if (ConfigurationManager.DropTableConfigs.TryGet(cleanedName, out var value))
				{
					dropSourceTemplateLink.EntityConfig = value;
				}
				DropLinkCache.SetLink(dropTable, dropSourceTemplateLink);
			}
			catch (Exception e)
			{
				Log.LogError("Error while attempting to create associate drop table for object with config.", e);
			}
		}
	}
	[HarmonyPatch(typeof(DropTable))]
	internal static class Patch_DropTable_GetDrops_Overhaul
	{
		[HarmonyPatch("GetDropListItems")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> DropListItemsOverhaul(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			Label label = default(Label);
			return new CodeMatcher(instructions, generator).Start().InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null)
			}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Patch_DropTable_GetDrops_Overhaul), "GetDropListItems", (Type[])null, (Type[])null))
			})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ret, (object)null)
				})
				.CreateLabel(ref label)
				.Start()
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Patch_DropTable_GetDrops_Overhaul), "UseOriginal", (Type[])null, (Type[])null))
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Brtrue, (object)label)
				})
				.InstructionEnumeration();
		}

		[HarmonyPatch("GetDropList", new Type[] { typeof(int) })]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> DropListOverhaul(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			Label label = default(Label);
			return new CodeMatcher(instructions, generator).Start().InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null)
			}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldarg_1, (object)null)
			})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Patch_DropTable_GetDrops_Overhaul), "GetDropList", (Type[])null, (Type[])null))
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ret, (object)null)
				})
				.CreateLabel(ref label)
				.Start()
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Patch_DropTable_GetDrops_Overhaul), "UseOriginal", (Type[])null, (Type[])null))
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Brtrue, (object)label)
				})
				.InstructionEnumeration();
		}

		private static bool UseOriginal(DropTable dropTable)
		{
			return DropLinkCache.GetLink(dropTable)?.EntityConfig == null;
		}

		private static List<ItemData> GetDropListItems(DropTable dropTable)
		{
			try
			{
				DropSourceTemplateLink link = DropLinkCache.GetLink(dropTable);
				if (DropConfigManager.GetPossibleDrops(link, dropTable).Count == 0)
				{
					return new List<ItemData>(0);
				}
				return DropTableManager.GetItemDrops(dropTable, link);
			}
			catch (Exception e)
			{
				Log.LogError("Error during calculation of item drops", e);
				return new List<ItemData>(0);
			}
		}

		private static List<GameObject> GetDropList(DropTable dropTable, int dropCount)
		{
			try
			{
				DropSourceTemplateLink link = DropLinkCache.GetLink(dropTable);
				if (DropConfigManager.GetPossibleDrops(link, dropTable).Count == 0)
				{
					return new List<GameObject>(0);
				}
				return DropTableManager.GetDrops(dropTable, link);
			}
			catch (Exception e)
			{
				Log.LogError("Error during calculation of item drops", e);
				return new List<GameObject>(0);
			}
		}
	}
	[HarmonyPatch(typeof(MineRock5))]
	internal static class Patch_MineRock5_Fix_Naming
	{
		private static string _originalPrefabName { get; set; }

		[HarmonyPatch("Start")]
		private static void Prefix(MineRock5 __instance)
		{
			if (((Object)(object)__instance).IsNotNull() && ((Object)(object)((Component)__instance).gameObject).IsNotNull())
			{
				_originalPrefabName = ((Object)((Component)__instance).gameObject).name;
			}
		}

		[HarmonyPatch("Start")]
		private static void Postfix(MineRock5 __instance)
		{
			if (((Object)(object)__instance).IsNotNull() && ((Object)(object)((Component)__instance).gameObject).IsNotNull() && _originalPrefabName != null)
			{
				((Object)((Component)__instance).gameObject).name = _originalPrefabName;
			}
		}
	}
	internal static class Patch_OnDrop
	{
		[HarmonyPatch(typeof(Container))]
		internal static class Patch_Container_AddDefaultItems
		{
			[HarmonyPatch("AddDefaultItems")]
			[HarmonyTranspiler]
			private static IEnumerable<CodeInstruction> InsertItemManagement(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_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Expected O, but got Unknown
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Expected O, but got Unknown
				return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AddItemToInventory, (string)null)
				}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null)
				}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Patch_OnDrop), "ModifyContainerItem", (Type[])null, (Type[])null))
				})
					.InstructionEnumeration();
			}
		}

		[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
		{
			[HarmonyPatch("DamageArea")]
			[HarmonyTranspiler]
			private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions)
			{
				return instructions.InsertDropManagementInstructions();
			}
		}

		private static MethodInfo DropInstantiation = ReflectionUtils.InstantiateGameObjectMethod;

		private static MethodInfo AddItemToInventory = AccessTools.Method(typeof(Inventory), "AddItem", new Type[1] { typeof(ItemData) }, (Type[])null);

		private static MethodInfo UnwrapDropMethod = AccessTools.Method(typeof(Patch_OnDrop), "UnwrapDrop", (Type[])null, (Type[])null);

		private static MethodInfo ModifyDropMethod = AccessTools.Method(typeof(Patch_OnDrop), "ModifyDrop", (Type[])null, (Type[])null);

		private static GameObject _currentWrapped;

		private static ItemData _currentItem;

		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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Call, (object)DropInstantiation, (string)null)
			}).Advance(-2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Call, (object)UnwrapDropMethod)
			})
				.MatchForward(true, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Call, (object)DropInstantiation, (string)null)
				})
				.Advance(1)
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Dup, (object)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)ModifyDropMethod)
				})
				.InstructionEnumeration();
		}

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

		private static void ModifyDrop(GameObject drop)
		{
			try
			{
				DropTemplate template = DropTemplateCache.GetTemplate(_currentWrapped);
				if (template == null)
				{
					return;
				}
				DropModificationContext context = new DropModificationContext(drop, template);
				foreach (IDropTableModifier modifier in template.Modifiers)
				{
					try
					{
						modifier.Modify(context);
					}
					catch (Exception e)
					{
						Log.LogError($"Error while attempting to apply modifier '{modifier.GetType().Name}' to drop '{drop}'. Skipping modifier.", e);
					}
				}
			}
			catch (Exception e2)
			{
				Log.LogError($"Error while preparing to modify drop '{drop}'. Skipping modifiers.", e2);
			}
			_currentWrapped = null;
		}

		private static ItemData ModifyContainerItem(ItemData item, Container container)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				item.m_dropPrefab = item.m_dropPrefab.Unwrap();
				DropTemplate template = DropTemplateCache.GetTemplate(item);
				if (template == null)
				{
					return item;
				}
				foreach (IDropTableModifier modifier in template.Modifiers)
				{
					try
					{
						modifier.Modify(ref item, template, ((Component)container).transform.position);
					}
					catch (Exception e)
					{
						Log.LogError("Error while attempting to apply modifier '" + modifier.GetType().Name + "' to drop '" + ((Object)item.m_dropPrefab).name + "'. Skipping modifier.", e);
					}
				}
			}
			catch (Exception e2)
			{
				Log.LogError("Error while preparing to modify drop '" + ((Object)item.m_dropPrefab).name + "'. Skipping modifiers.", e2);
			}
			return item;
		}

		private static void RememberCurrentItem(ItemData itemData)
		{
			_currentItem = itemData;
		}
	}
}
namespace Valheim.DropThat.Drop.DropTableSystem.Modifiers
{
	public interface IDropTableModifier
	{
		void Modify(DropModificationContext context);

		void Modify(ref ItemData drop, DropTemplate template, Vector3 position);
	}
	public class ModifierSetDurability : IDropTableModifier
	{
		private static ModifierSetDurability _instance;

		public static ModifierSetDurability Instance => _instance ?? (_instance = new ModifierSetDurability());

		public void Modify(DropModificationContext context)
		{
			ConfigurationEntry<float> configurationEntry = context.Template?.Config?.SetDurability;
			float num = ((configurationEntry != null) ? ((float)configurationEntry) : (-1f));
			if (!(num < 0f))
			{
				ItemDrop val = context.ItemDrop;
				if (val != null)
				{
					Log.LogTrace($"Setting durability of item '{context.Drop}' to {num}");
					val.m_itemData.m_durability = num;
				}
			}
		}

		public void Modify(ref ItemData drop, DropTemplate template, Vector3 position)
		{
			ConfigurationEntry<float> configurationEntry = template.Config?.SetDurability;
			float num = ((configurationEntry != null) ? ((float)configurationEntry) : (-1f));
			if (!(num < 0f))
			{
				drop.m_durability = num;
			}
		}
	}
	public class ModifierSetQualityLevel : IDropTableModifier
	{
		private static ModifierSetQualityLevel _instance;

		public static ModifierSetQualityLevel Instance => _instance ?? (_instance = new ModifierSetQualityLevel());

		public void Modify(DropModificationContext context)
		{
			ConfigurationEntry<int> configurationEntry = context.Template?.Config?.SetQualityLevel;
			int num = ((configurationEntry != null) ? ((int)configurationEntry) : 0);
			if (num > 0)
			{
				ItemDrop val = context.ItemDrop;
				if (val != null)
				{
					Log.LogTrace($"Setting level of item '{context.Drop}' to {num}");
					val.m_itemData.m_quality = num;
				}
			}
		}

		public void Modify(ref ItemData drop, DropTemplate template, Vector3 position)
		{
			ConfigurationEntry<int> configurationEntry = template.Config?.SetQualityLevel;
			int num = ((configurationEntry != null) ? ((int)configurationEntry) : 0);
			if (num > 0)
			{
				drop.m_quality = num;
			}
		}
	}
}
namespace Valheim.DropThat.Drop.DropTableSystem.Modifiers.ModSpecific.ModEpicLoot
{
	internal class ModifierMagicItem : IDropTableModifier
	{
		private static ModifierMagicItem _instance;

		public static ModifierMagicItem Instance => _instance ?? (_instance = new ModifierMagicItem());

		public void Modify(DropModificationContext context)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (!InstallationManager.EpicLootInstalled)
			{
				return;
			}
			EpicLootItemConfiguration config = GetConfig(context.Template);
			if (config != null)
			{
				ItemDrop val = context.ItemDrop;
				if (!((Object)(object)val).IsNull() && ItemRoller.TryRollMagic(val.m_itemData, ((Component)val).transform.position, new ItemRollParameters
				{
					RarityWeightNone = config.RarityWeightNone,
					RarityWeightMagic = config.RarityWeightMagic,
					RarityWeightRare = config.RarityWeightRare,
					RarityWeightEpic = config.RarityWeightEpic,
					RarityWeightLegendary = config.RarityWeightLegendary,
					RarityWeightUnique = config.RarityWeightUnique,
					UniqueIds = config.UniqueIDs.Value.SplitByComma()
				}))
				{
					val.Save();
				}
			}
		}

		public void Modify(ref ItemData drop, DropTemplate template, Vector3 position)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (InstallationManager.EpicLootInstalled)
			{
				EpicLootItemConfiguration config = GetConfig(template);
				if (config != null && drop != null)
				{
					ItemRoller.TryRollMagic(drop, position, new ItemRollParameters
					{
						RarityWeightNone = config.RarityWeightNone,
						RarityWeightMagic = config.RarityWeightMagic,
						RarityWeightRare = config.RarityWeightRare,
						RarityWeightEpic = config.RarityWeightEpic,
						RarityWeightLegendary = config.RarityWeightLegendary,
						RarityWeightUnique = config.RarityWeightUnique,
						UniqueIds = config.UniqueIDs.Value.SplitByComma()
					});
				}
			}
		}

		private EpicLootItemConfiguration GetConfig(DropTemplate template)
		{
			if (template == null)
			{
				return null;
			}
			if (template.Config.TryGet("EpicLoot", out var value) && value is EpicLootItemConfiguration result)
			{
				return result;
			}
			return null;
		}
	}
}
namespace Valheim.DropThat.Drop.DropTableSystem.Managers
{
	internal static class DropConditionManager
	{
		public static List<DropTemplate> Filter(DropSourceTemplateLink context, List<DropTemplate> templates)
		{
			return templates.Where(delegate(DropTemplate template)
			{
				try
				{
					if ((template?.Conditions?.Count).GetValueOrDefault() == 0)
					{
						return true;
					}
					return !template.Conditions.Any(delegate(IDropTableCondition x)
					{
						try
						{
							return x?.ShouldFilter(context, template) ?? true;
						}
						catch (Exception e2)
						{
							Log.LogError($"Error while attempting to check condition '{x?.GetType()?.Name}' for '{template.Config.PrefabName}'. Condition will be ignored", e2);
							return true;
						}
					});
				}
				catch (Exception e)
				{
					Log.LogError($"Error while attempting to check conditions for '{template?.Config?.PrefabName}'. Conditions will be ignored", e);
					return true;
				}
			}).ToList();
		}
	}
	internal static class DropConfigManager
	{
		private static Dictionary<int, List<DropTemplate>> TemplateCache { get; set; }

		private static GeneralConfiguration GeneralConfig => ConfigurationManager.GeneralConfig;

		static DropConfigManager()
		{
			TemplateCache = new Dictionary<int, List<DropTemplate>>();
			StateResetter.Subscribe(delegate
			{
				TemplateCache = new Dictionary<int, List<DropTemplate>>();
			});
		}

		public static List<DropTemplate> GetPossibleDrops(DropSourceTemplateLink context, DropTable dropTable)
		{
			int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)context.Source).name);
			if (TemplateCache.TryGetValue(stableHashCode, out var value))
			{
				return new List<DropTemplate>(value);
			}
			List<DropTemplate> list = PrepareDrops(context, dropTable);
			TemplateCache[stableHashCode] = new List<DropTemplate>(list);
			return list;
		}

		private static List<DropTemplate> PrepareDrops(DropSourceTemplateLink context, DropTable dropTable)
		{
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			List<DropTemplate> list = new List<DropTemplate>();
			string text = context.EntityConfig?.UseDropList?.Value;
			DropTableListConfiguration dropTableListConfiguration = null;
			if (!string.IsNullOrWhiteSpace(text) && ConfigurationManager.DropTableLists != null && ConfigurationManager.DropTableLists.TryGet(text, out var value))
			{
				dropTableListConfiguration = value;
			}
			bool flag = false;
			if ((bool)GeneralConfig.ClearAllExistingDropTables)
			{
				goto IL_0133;
			}
			if ((bool)GeneralConfig.ClearAllExistingDropTablesWhenModified)
			{
				DropTableEntityConfiguration entityConfig = context.EntityConfig;
				if ((entityConfig != null && entityConfig.Subsections?.Any((KeyValuePair<string, DropTableItemConfiguration> x) => x.Value.EnableConfig) == true) || (dropTableListConfiguration != null && dropTableListConfiguration.Subsections?.Any((KeyValuePair<string, DropTableItemConfiguration> x) => x.Value.EnableConfig) == true))
				{
					goto IL_0133;
				}
			}
			goto IL_0136;
			IL_0133:
			flag = true;
			goto IL_0136;
			IL_0136:
			if (!flag)
			{
				foreach (DropData drop in dropTable.m_drops)
				{
					if (!(drop.m_weight <= 0f))
					{
						list.Add(new DropTemplate
						{
							Drop = drop
						});
					}
				}
			}
			if (context.EntityConfig == null)
			{
				return list;
			}
			foreach (DropTableItemConfiguration item in MergeAndOrder(dropTableListConfiguration, context.EntityConfig))
			{
				InsertDrop(list, item, context.EntityConfig);
			}
			return list;
		}

		private static void InsertDrop(List<DropTemplate> drops, DropTableItemConfiguration itemConfig, DropTableEntityConfiguration entityConfig)
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			if (!itemConfig.EnableConfig || (float)itemConfig.SetTemplateWeight <= 0f)
			{
				return;
			}
			GameObject val = ObjectDB.instance.GetItemPrefab(itemConfig.PrefabName.Value);
			if (((Object)(object)val).IsNull())
			{
				val = ZNetScene.instance.GetPrefab(itemConfig.PrefabName.Value);
			}
			if (((Object)(object)val).IsNull())
			{
				Log.LogWarning("Unable to find prefab '" + itemConfig.PrefabName.Value + "' for '" + itemConfig.SectionKey + "'.");
				return;
			}
			DropTemplate item = new DropTemplate
			{
				Drop = new DropData
				{
					m_item = val,
					m_weight = itemConfig.SetTemplateWeight,
					m_stackMin = itemConfig.SetAmountMin,
					m_stackMax = itemConfig.SetAmountMax,
					m_dontScale = itemConfig.DisableResourceModifierScaling
				},
				Conditions = ExtractConditions(itemConfig),
				Modifiers = ExtractModifiers(itemConfig),
				Config = itemConfig,
				EntityConfig = entityConfig
			};
			if ((bool)GeneralConfig.AlwaysAppendCharacterDrops)
			{
				drops.Add(item);
				return;
			}
			int index = itemConfig.Index;
			if (drops.Count > index && index >= 0)
			{
				drops.RemoveAt(index);
			}
			if (index >= 0 && index <= drops.Count)
			{
				drops.Insert(index, item);
			}
			else
			{
				drops.Add(item);
			}
		}

		private static List<IDropTableCondition> ExtractConditions(DropTableItemConfiguration config)
		{
			List<IDropTableCondition> list = new List<IDropTableCondition>();
			list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Conditions.ConditionBiome.Instance);
			list.AddNullSafe(ConditionAltitude.Instance);
			list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Conditions.ConditionDaytime.Instance);
			list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Conditions.ConditionEnvironments.Instance);
			list.AddNullSafe(ConditionGlobalKeysRequired.Instance);
			list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Conditions.ConditionLocation.Instance);
			list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Conditions.ConditionDistanceToCenter.Instance);
			list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Conditions.ModSpecific.ConditionLoaderCLLC.ConditionWorldLevel);
			return list;
		}

		private static List<IDropTableModifier> ExtractModifiers(DropTableItemConfiguration config)
		{
			List<IDropTableModifier> list = new List<IDropTableModifier>();
			list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Modifiers.ModifierSetQualityLevel.Instance);
			if (InstallationManager.EpicLootInstalled && config.TryGet("EpicLoot", out var value) && value is EpicLootItemConfiguration)
			{
				list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Modifiers.ModSpecific.ModEpicLoot.ModifierMagicItem.Instance);
			}
			list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Modifiers.ModifierSetDurability.Instance);
			return list;
		}

		private static IEnumerable<DropTableItemConfiguration> MergeAndOrder(DropTableListConfiguration list, DropTableEntityConfiguration entity)
		{
			Dictionary<int, DropTableItemConfiguration> dictionary = new Dictionary<int, DropTableItemConfiguration>();
			if (list != null)
			{
				foreach (DropTableItemConfiguration value in list.Subsections.Values)
				{
					if ((bool)value.EnableConfig)
					{
						dictionary[value.Index] = value;
					}
				}
			}
			if (entity != null)
			{
				foreach (DropTableItemConfiguration value2 in entity.Subsections.Values)
				{
					if ((bool)value2.EnableConfig)
					{
						dictionary[value2.Index] = value2;
					}
				}
			}
			return dictionary.Values.OrderBy((DropTableItemConfiguration x) => x.Index);
		}
	}
}
namespace Valheim.DropThat.Drop.DropTableSystem.Debug
{
	[HarmonyPatch(typeof(DungeonDB))]
	internal static class Patch_DungeonDB_Start
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void WriteDropTableData()
		{
			if ((bool)ConfigurationManager.GeneralConfig?.WriteDropTablesToFiles)
			{
				DropTableDataWriter.PrintDungeonDropTables();
			}
		}
	}
	[HarmonyPatch(typeof(ZoneSystem))]
	internal static class Patch_ZoneSystem_Start
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void WriteDropTableData()
		{
			if ((bool)ConfigurationManager.GeneralConfig?.WriteDropTablesToFiles)
			{
				DropTableDataWriter.PrintPrefabDropTables();
				DropTableDataWriter.PrintLocationDropTables();
			}
		}
	}
	internal static class DropTableDataWriter
	{
		private static string GetData(MonoBehaviour source, DropTable dropTable, string[] additionalHeaders)
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			string cleanedName = ((Object)(object)((Component)source).gameObject).GetCleanedName();
			if (string.IsNullOrWhiteSpace(cleanedName))
			{
				return "";
			}
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("## DropTable Source: " + ((object)source).GetType().Name + "; " + GeneralExtensions.Join<string>((IEnumerable<string>)additionalHeaders, (Func<string, string>)null, "; "));
			stringBuilder.AppendLine("[" + cleanedName + "]");
			stringBuilder.AppendLine("SetDropChance = " + (dropTable.m_dropChance * 100f).ToString(CultureInfo.InvariantCulture));
			stringBuilder.AppendLine(string.Format("{0} = {1}", "SetDropOnlyOnce", dropTable.m_oneOfEach));
			stringBuilder.AppendLine(string.Format("{0} = {1}", "SetDropMin", dropTable.m_dropMin));
			stringBuilder.AppendLine(string.Format("{0} = {1}", "SetDropMax", dropTable.m_dropMax));
			for (int i = 0; i < dropTable.m_drops.Count; i++)
			{
				DropData val = dropTable.m_drops[i];
				stringBuilder.AppendLine();
				stringBuilder.AppendLine($"[{cleanedName}.{i}]");
				stringBuilder.AppendLine("PrefabName = " + (((Object)(object)val.m_item).IsNotNull() ? ((Object)val.m_item).name : ""));
				stringBuilder.AppendLine("SetTemplateWeight = " + val.m_weight.ToString(CultureInfo.InvariantCulture));
				stringBuilder.AppendLine(string.Format("{0} = {1}", "SetAmountMin", val.m_stackMin));
				stringBuilder.AppendLine(string.Format("{0} = {1}", "SetAmountMax", val.m_stackMax));
				stringBuilder.AppendLine(string.Format("{0} = {1}", "DisableResourceModifierScaling", val.m_dontScale));
			}
			return stringBuilder.ToString();
		}

		internal static void PrintDungeonDropTables()
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			IOrderedEnumerable<ZoneLocation> orderedEnumerable = from x in ZoneSystem.instance.m_locations
				where x.m_enable
				orderby x.m_biome, x.m_prefabName
				select x;
			List<string> list = new List<string>();
			foreach (ZoneLocation item in orderedEnumerable)
			{
				item.m_prefab.Load();
				GameObject asset = item.m_prefab.Asset;
				if (((Object)(object)asset).IsNull())
				{
					continue;
				}
				DungeonGenerator[] componentsInChildren = asset.GetComponentsInChildren<DungeonGenerator>();
				if (componentsInChildren == null || componentsInChildren.Length == 0)
				{
					continue;
				}
				DungeonGenerator[] array = componentsInChildren;
				foreach (DungeonGenerator dungeon in array)
				{
					List<Room> list2 = (from x in DungeonDB.GetRooms().Select(delegate(RoomData x)
						{
							//IL_0006: Unknown result type (might be due to invalid IL or missing references)
							x.m_prefab.Load();
							return x.RoomInPrefab;
						})
						where ((Object)(object)x).IsNotNull() && (Theme)(x.m_theme & dungeon.m_themes) == x.m_theme
						select x).ToList();
					if (list2 == null || list2.Count == 0)
					{
						continue;
					}
					foreach (Room item2 in list2)
					{
						list.AddRange(Extract(((Component)item2).gameObject, "Biome: " + item.m_biome.GetNames(), "Location: " + item.m_prefabName, $"Room Theme: {item2.m_theme}", "Room: " + ((Object)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 (!((Object)(object)asset).IsNull())
				{
					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 (((Object)(object)componentInChildren).IsNotNull() && Object.op_Implicit((Object)(object)componentInChildren))
			{
				list.Add(GetData((MonoBehaviour)(object)componentInChildren, componentInChildren.m_defaultItems, additionalHeaders));
			}
			DropOnDestroyed componentInChildren2 = prefab.GetComponentInChildren<DropOnDestroyed>();
			if (((Object)(object)componentInChildren2).IsNotNull() && Object.op_Implicit((Object)(object)componentInChildren2))
			{
				list.Add(GetData((MonoBehaviour)(object)componentInChildren2, componentInChildren2.m_dropWhenDestroyed, additionalHeaders));
			}
			LootSpawner componentInChildren3 = prefab.GetComponentInChildren<LootSpawner>();
			if (((Object)(object)componentInChildren3).IsNotNull() && Object.op_Implicit((Object)(object)componentInChildren3))
			{
				list.Add(GetData((MonoBehaviour)(object)componentInChildren3, componentInChildren3.m_items, additionalHeaders));
			}
			TreeBase componentInChildren4 = prefab.GetComponentInChildren<TreeBase>();
			if (((Object)(object)componentInChildren4).IsNotNull() && Object.op_Implicit((Object)(object)componentInChildren4))
			{
				list.Add(GetData((MonoBehaviour)(object)componentInChildren4, componentInChildren4.m_dropWhenDestroyed, additionalHeaders));
			}
			TreeLog componentInChildren5 = prefab.GetComponentInChildren<TreeLog>();
			if (((Object)(object)componentInChildren5).IsNotNull() && Object.op_Implicit((Object)(object)componentInChildren5))
			{
				list.Add(GetData((MonoBehaviour)(object)componentInChildren5, componentInChildren5.m_dropWhenDestroyed, additionalHeaders));
			}
			MineRock componentInChildren6 = prefab.GetComponentInChildren<MineRock>();
			if (((Object)(object)componentInChildren6).IsNotNull() && Object.op_Implicit((Object)(object)componentInChildren6))
			{
				list.Add(GetData((MonoBehaviour)(object)componentInChildren6, componentInChildren6.m_dropItems, additionalHeaders));
			}
			MineRock5 componentInChildren7 = prefab.GetComponentInChildren<MineRock5>();
			if (((Object)(object)componentInChildren7).IsNotNull() && Object.op_Implicit((Object)(object)componentInChildren7))
			{
				list.Add(GetData((MonoBehaviour)(object)componentInChildren7, componentInChildren7.m_dropItems, additionalHeaders));
			}
			return list;
		}
	}
}
namespace Valheim.DropThat.Drop.DropTableSystem.Conditions
{
	public class ConditionAltitude : IDropTableCondition
	{
		private static ConditionAltitude _instance;

		public static ConditionAltitude Instance => _instance ?? (_instance = new ConditionAltitude());

		public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template)
		{
			//IL_000c: 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)
			if (IsValid(context.Source.transform.position, template?.Config))
			{
				return false;
			}
			Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due being outside required altitude.");
			return true;
		}

		public bool IsValid(Vector3 position, DropTableItemConfiguration config)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (config == null)
			{
				return true;
			}
			float num = position.y - ZoneSystem.instance.m_waterLevel;
			if (num < (float)config.ConditionAltitudeMin)
			{
				return false;
			}
			if (num > (float)config.ConditionAltitudeMax)
			{
				return false;
			}
			return true;
		}
	}
	public class ConditionBiome : IDropTableCondition
	{
		private static ConditionBiome _instance;

		public static ConditionBiome Instance => _instance ?? (_instance = new ConditionBiome());

		public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template)
		{
			//IL_000c: 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)
			if (IsValid(context.Source.transform.position, template?.Config))
			{
				return false;
			}
			Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due being outside required biome.");
			return true;
		}

		public bool IsValid(Vector3 position, DropTableItemConfiguration config)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (config == null)
			{
				return true;
			}
			if (string.IsNullOrWhiteSpace(config.ConditionBiomes.Value))
			{
				return true;
			}
			List<string> source = config.ConditionBiomes.Value.SplitByComma(toUpper: true);
			Biome val = Heightmap.FindBiome(position);
			string currentBiomeCleaned = ((object)(Biome)(ref val)).ToString().ToUpperInvariant();
			return source.Any((string x) => x == currentBiomeCleaned);
		}
	}
	public class ConditionDaytime : IDropTableCondition
	{
		private static ConditionDaytime _instance;

		public static ConditionDaytime Instance => _instance ?? (_instance = new ConditionDaytime());

		public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (IsValid(template?.Config))
			{
				return false;
			}
			Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due being outside allowed time of day.");
			return true;
		}

		public bool IsValid(DropTableItemConfiguration config)
		{
			if (config == null)
			{
				return true;
			}
			EnvMan instance = EnvMan.instance;
			if ((bool)config.ConditionNotDay && instance.IsDay())
			{
				return false;
			}
			if ((bool)config.ConditionNotAfternoon && instance.IsAfternoon())
			{
				return false;
			}
			if ((bool)config.ConditionNotNight && instance.IsNight())
			{
				return false;
			}
			return true;
		}
	}
	public class ConditionDistanceToCenter : IDropTableCondition
	{
		private static ConditionDistanceToCenter _instance;

		public static ConditionDistanceToCenter Instance => _instance ?? (_instance = new ConditionDistanceToCenter());

		public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template)
		{
			//IL_000c: 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)
			if (IsValid(context.Source.transform.position, template?.Config))
			{
				return false;
			}
			Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due not being within required distance to center of map.");
			return true;
		}

		public bool IsValid(Vector3 position, DropTableItemConfiguration config)
		{
			if (config == null)
			{
				return true;
			}
			float magnitude = ((Vector3)(ref position)).magnitude;
			if (magnitude < config.ConditionDistanceToCenterMin.Value)
			{
				return false;
			}
			if (config.ConditionDistanceToCenterMax.Value > 0f && magnitude > config.ConditionDistanceToCenterMax.Value)
			{
				return false;
			}
			return true;
		}
	}
	public class ConditionEnvironments : IDropTableCondition
	{
		private static ConditionEnvironments _instance;

		public static ConditionEnvironments Instance => _instance ?? (_instance = new ConditionEnvironments());

		public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (IsValid(template.Config))
			{
				return false;
			}
			Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due to current environment.");
			return true;
		}

		public bool IsValid(DropTableItemConfiguration config)
		{
			if (string.IsNullOrEmpty(config.ConditionEnvironments.Value))
			{
				return true;
			}
			EnvMan instance = EnvMan.instance;
			string currentEnv = instance.GetCurrentEnvironment().m_name.Trim().ToUpperInvariant();
			List<string> list = config.ConditionEnvironments.Value.SplitByComma(toUpper: true);
			if (list.Count == 0)
			{
				return true;
			}
			if (list.Any((string x) => x == currentEnv))
			{
				return true;
			}
			return false;
		}
	}
	public class ConditionGlobalKeysRequired : IDropTableCondition
	{
		private static ConditionGlobalKeysRequired _instance;

		public static ConditionGlobalKeysRequired Instance => _instance ?? (_instance = new ConditionGlobalKeysRequired());

		public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (IsValid(template.Config))
			{
				return false;
			}
			Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due to not finding required global key.");
			return true;
		}

		public bool IsValid(DropTableItemConfiguration config)
		{
			if (string.IsNullOrEmpty(config.ConditionGlobalKeys.Value))
			{
				return true;
			}
			List<string> list = config.ConditionGlobalKeys.Value.SplitByComma();
			if (list.Count == 0)
			{
				return true;
			}
			if (list.Any((string x) => ZoneSystem.instance.GetGlobalKey(x)))
			{
				return true;
			}
			return false;
		}
	}
	public class ConditionLocation : IDropTableCondition
	{
		private static ConditionLocation _instance;

		public static ConditionLocation Instance => _instance ?? (_instance = new ConditionLocation());

		public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template)
		{
			//IL_000c: 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)
			if (IsValid(context.Source.transform.position, template.Config))
			{
				return false;
			}
			Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due to not being in required location.");
			return true;
		}

		public bool IsValid(Vector3 position, DropTableItemConfiguration config)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrWhiteSpace(config?.ConditionLocations?.Value))
			{
				return true;
			}
			List<string> list = config.ConditionLocations.Value.SplitByComma(toUpper: true);
			if (list.Count == 0)
			{
				return true;
			}
			SimpleLocation simpleLocation = LocationHelper.FindLocation(position);
			string currentLocationName = simpleLocation.LocationName.Trim().ToUpperInvariant();
			return list.Any((string x) => x == currentLocationName);
		}
	}
	public interface IDropTableCondition
	{
		bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template);
	}
}
namespace Valheim.DropThat.Drop.DropTableSystem.Conditions.ModSpecific
{
	internal static class ConditionLoaderCLLC
	{
		public static bool InstalledCLLC { get; } = (object)Type.GetType("CreatureLevelControl.API, CreatureLevelControl") != null;


		public static Valheim.DropThat.Drop.DropTableSystem.Conditions.ModSpecific.ModCLLC.ConditionWorldLevel ConditionWorldLevel
		{
			get
			{
				if (!InstalledCLLC)
				{
					return null;
				}
				return Valheim.DropThat.Drop.DropTableSystem.Conditions.ModSpecific.ModCLLC.ConditionWorldLevel.Instance;
			}
		}
	}
}
namespace Valheim.DropThat.Drop.DropTableSystem.Conditions.ModSpecific.ModCLLC
{
	public class ConditionWorldLevel : IDropTableCondition
	{
		private static ConditionWorldLevel _instance;

		public static ConditionWorldLevel Instance => _instance ?? (_instance = new ConditionWorldLevel());

		public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (IsValid(template?.Config))
			{
				return false;
			}
			Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due to not being within required CLLC world level.");
			return true;
		}

		public bool IsValid(DropTableItemConfiguration itemConfig)
		{
			if (itemConfig == null)
			{
				return true;
			}
			if (itemConfig.TryGet("CreatureLevelAndLootControl", out var value) && value is DropTableModConfigCLLC dropTableModConfigCLLC)
			{
				int worldLevel = API.GetWorldLevel();
				if (worldLevel < (int)dropTableModConfigCLLC.ConditionWorldLevelMin)
				{
					return false;
				}
				if ((int)dropTableModConfigCLLC.ConditionWorldLevelMax > 0 && worldLevel > (int)dropTableModConfigCLLC.ConditionWorldLevelMax)
				{
					return false;
				}
			}
			return true;
		}
	}
}
namespace Valheim.DropThat.Drop.DropTableSystem.Caches
{
	internal static class DropLinkCache
	{
		private static ConditionalWeakTable<DropTable, DropSourceTemplateLink> LinkTable = new ConditionalWeakTable<DropTable, DropSourceTemplateLink>();

		public static DropSourceTemplateLink GetLink(DropTable key)
		{
			if (LinkTable.TryGetValue(key, out var value))
			{
				return value;
			}
			return null;
		}

		public static void SetLink(DropTable key, DropSourceTemplateLink context)
		{
			if (context != null)
			{
				LinkTable.Add(key, context);
			}
		}
	}
	internal class DropTemplateCache
	{
		private static ManagedCache<DropTemplate> DropTemplates { get; } = new ManagedCache<DropTemplate>();


		private static ConditionalWeakTable<ItemData, DropTemplateCache> ItemTemplates { get; } = new ConditionalWeakTable<ItemData, DropTemplateCache>();


		public DropTemplate Template { get; set; }

		public static void RegisterTemplate(GameObject drop, DropTemplate template)
		{
			DropTemplates.Set((Object)(object)drop, template);
		}

		public static void RegisterTemplate(ItemData item, DropTemplate template)
		{
			ItemTemplates.GetOrCreateValue(item).Template = template;
		}

		public static DropTemplate GetTemplate(ItemData item)
		{
			if (ItemTemplates.TryGetValue(item, out var value))
			{
				return value.Template;
			}
			return null;
		}

		public static DropTemplate GetTemplate(GameObject drop)
		{
			if (DropTemplates.TryGet((Object)(object)drop, out var value))
			{
				return value;
			}
			return null;
		}
	}
}
namespace Valheim.DropThat.Drop.CharacterDropSystem
{
	public class ConditionChecker
	{
		private HashSet<ICondition> OnStartConditions;

		private HashSet<ICondition> OnDeathConditions;

		private static ConditionChecker _instance;

		public static ConditionChecker Instance => _instance ?? (_instance = new ConditionChecker());

		private ConditionChecker()
		{
			StateResetter.Subscribe(delegate
			{
				_instance = null;
			});
			OnStartConditions = new HashSet<ICondition>();
			OnStartConditions.AddNullSafe(ConditionInventory.Instance);
			OnStartConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ConditionLocation.Instance);
			OnStartConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ConditionDistanceToCenter.Instance);
			OnStartConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ConditionBiome.Instance);
			OnDeathConditions = new HashSet<ICondition>();
			OnDeathConditions.AddNullSafe(ConditionCreatureState.Instance);
			OnDeathConditions.AddNullSafe(ConditionLoaderSpawnThat.ConditionTemplateId);
			OnDeathConditions.AddNullSafe(ConditionFaction.Instance);
			OnDeathConditions.AddNullSafe(ConditionNotFaction.Instance);
			OnDeathConditions.AddNullSafe(ConditionKilledByDamageType.Instance);
			OnDeathConditions.AddNullSafe(ConditionKilledBySkillType.Instance);
			OnDeathConditions.AddNullSafe(ConditionKilledWithStatus.Instance);
			OnDeathConditions.AddNullSafe(ConditionKilledWithStatuses.Instance);
			OnDeathConditions.AddNullSafe(ConditionKilledByEntityType.Instance);
			OnDeathConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ConditionEnvironments.Instance);
			OnDeathConditions.AddNullSafe(ConditionGlobalKeys.Instance);
			OnDeathConditions.AddNullSafe(ConditionLevel.Instance);
			OnDeathConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ConditionDaytime.Instance);
			OnDeathConditions.AddNullSafe(ConditionHitByEntityTypeRecently.Instance);
			OnDeathConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific.ConditionLoaderCLLC.ConditionBossAffix);
			OnDeathConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific.ConditionLoaderCLLC.ConditionInfusion);
			OnDeathConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific.ConditionLoaderCLLC.ConditionCreatureExtraEffect);
			OnDeathConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific.ConditionLoaderCLLC.ConditionWorldLevel);
		}

		public static List<Drop> FilterOnStart(CharacterDrop characterDrop)
		{
			try
			{
				return Instance.Filter(characterDrop, Instance.OnStartConditions);
			}
			catch (Exception e)
			{
				Log.LogError("Error while attempting to run OnStart conditions. Skipping filtering.", e);
				return characterDrop.m_drops;
			}
		}

		public static List<Drop> FilterOnDeath(CharacterDrop characterDrop)
		{
			try
			{
				return Instance.Filter(characterDrop, Instance.OnDeathConditions);
			}
			catch (Exception e)
			{
				Log.LogError("Error while attempting to run OnDeath conditions. Skipping filtering.", e);
				return characterDrop.m_drops;
			}
		}

		public List<Drop> Filter(CharacterDrop characterDrop, IEnumerable<ICondition> conditions)
		{
			List<Drop> list = new List<Drop>();
			foreach (Drop drop in characterDrop.m_drops)
			{
				DropExtended dropExtended = DropExtended.GetExtension(drop);
				if (dropExtended == null)
				{
					list.Add(drop);
				}
				else if (!conditions.Any((ICondition x) => x?.ShouldFilter(drop, dropExtended, characterDrop) ?? false))
				{
					list.Add(drop);
				}
			}
			return list;
		}
	}
	public class DropContext
	{
		public GameObject Item { get; set; }

		public DropExtended Extended { get; set; }

		public Vector3 Pos { get; set; }
	}
	public class DropModificationManager
	{
		private HashSet<IDropModifier> DropModifiers = new HashSet<IDropModifier>();

		private static DropModificationManager _instance;

		public static DropModificationManager Instance => _instance ?? (_instance = new DropModificationManager());

		private DropModificationManager()
		{
			StateResetter.Subscribe(delegate
			{
				_instance = null;
			});
			DropModifiers.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Modifiers.ModifierSetQualityLevel.Instance);
			DropModifiers.AddNullSafe(ModifierLoaderEpicLoot.MagicItem);
			DropModifiers.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Modifiers.ModifierSetDurability.Instance);
		}

		public void ApplyModifications(GameObject item, DropExtended extended, Vector3 pos)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (item == null || extended == null)
			{
				return;
			}
			DropContext context = new DropContext
			{
				Item = item,
				Extended = extended,
				Pos = pos
			};
			foreach (IDropModifier dropModifier in DropModifiers)
			{
				try
				{
					dropModifier?.Modify(context);
				}
				catch (Exception e)
				{
					Log.LogError("Error while attempting to modify item drop " + ((Object)item).name, e);
				}
			}
		}
	}
}
namespace Valheim.DropThat.Drop.CharacterDropSystem.Services
{
	internal static class MobDropInitializationService
	{
		public static IEnumerable<CharacterDropItemConfiguration> PrepareInsertion(CharacterDropListConfiguration listConfig, CharacterDropMobConfiguration mobConfig)
		{
			Dictionary<int, CharacterDropItemConfiguration> dictionary = new Dictionary<int, CharacterDropItemConfiguration>();
			if (listConfig != null)
			{
				foreach (CharacterDropItemConfiguration value in listConfig.Subsections.Values)
				{
					if ((bool)value.EnableConfig)
					{
						dictionary[value.Index] = value;
					}
				}
			}
			if (mobConfig != null)
			{
				foreach (CharacterDropItemConfiguration value2 in mobConfig.Subsections.Values)
				{
					if ((bool)value2.EnableConfig)
					{
						dictionary[value2.Index] = value2;
					}
				}
			}
			return dictionary.Values.OrderBy((CharacterDropItemConfiguration x) => x.Index);
		}
	}
}
namespace Valheim.DropThat.Drop.CharacterDropSystem.Patches
{
	[HarmonyPatch(typeof(CharacterDrop))]
	public static class Patch_CharacterDrop_DropItems
	{
		private class LoopCounter
		{
			private static ConditionalWeakTable<object, LoopCounter> LoopCounterTable = new ConditionalWeakTable<object, LoopCounter>();

			public int Count;

			public static void Increment(object obj)
			{
				LoopCounterTable.GetOrCreateValue(obj).Count++;
			}

			public static void Increment(object obj, int count)
			{
				LoopCounterTable.GetOrCreateValue(obj).Count += count;
			}

			public static int GetCount(object obj)
			{
				if (LoopCounterTable.TryGetValue(obj, out var value))
				{
					return value.Count;
				}
				return 0;
			}
		}

		private static MethodInfo OnSpawnedItemMethod = AccessTools.Method(typeof(Patch_CharacterDrop_DropItems), "OnSpawnedItem", new Type[3]
		{
			typeof(GameObject),
			typeof(List<KeyValuePair<GameObject, int>>),
			typeof(Vector3)
		}, (Type[])null);

		private static MethodInfo AfterSpawnedItemMethod = AccessTools.Method(typeof(Patch_CharacterDrop_DropItems), "AfterSpawnedItem", (Type[])null, (Type[])null);

		[HarmonyPatch("DropItems")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> HookSpawnedItem(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldloc_3, (object)null, (string)null)
			}).Advance(3).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldloc_S, (object)5)
			})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_1, (object)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)OnSpawnedItemMethod)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldloc_S, (object)5)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldloc_2, (object)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AfterSpawnedItemMethod)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Stloc_2, (object)null)
				})
				.InstructionEnumeration();
		}

		private static int AfterSpawnedItem(GameObject item, List<KeyValuePair<GameObject, int>> drops, int index)
		{
			int num = index;
			try
			{
				int itemCount = LoopCounter.GetCount(drops) - 1;
				int index2 = GetIndex(drops, itemCount);
				if (index2 >= drops.Count)
				{
					return num;
				}
				KeyValuePair<GameObject, int> keyValuePair = drops[index2];
				bool flag = false;
				if (keyValuePair.Value > 1)
				{
					if ((bool)ConfigurationManager.GeneralConfig.AlwaysAutoStack)
					{
						flag = true;
					}
					else
					{
						DropExtended drop = TempDropListCache.GetDrop(drops, index2);
						if