Decompiled source of Dragon Keep v1.0.0

plugins/RavenwoodDragonKeep/DragonKeep.dll

Decompiled 12 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace DragonKeep;

public class CustomChildDoor : MonoBehaviour, Hoverable, Interactable
{
	public string m_name = "door";

	public string m_doorID = "";

	public ItemDrop m_keyItem;

	public bool m_canNotBeClosed;

	public bool m_invertedOpenClosedText;

	public bool m_checkGuardStone = true;

	public bool m_disableManualInteract;

	public GameObject m_openEnable;

	public EffectList m_openEffects = new EffectList();

	public EffectList m_closeEffects = new EffectList();

	public EffectList m_lockedEffects = new EffectList();

	public ZNetView m_rootZNetView;

	public Component m_animator;

	public string m_animatorStateParameter = "state";

	private ZNetView m_nview;

	private CustomDoorSound m_doorSound;

	private uint m_lastDataRevision = uint.MaxValue;

	private string m_stateKey;

	private string m_rpcName;

	private string m_autoRpcName;

	private string m_registeredRpcName;

	private string m_registeredAutoRpcName;

	private static Type localizationType;

	private static FieldInfo localizationInstanceField;

	private static MethodInfo localizationLocalizeMethod;

	private void Awake()
	{
		if ((Object)(object)m_rootZNetView != (Object)null && !string.IsNullOrEmpty(m_doorID))
		{
			InitializeAfterConfiguration();
		}
	}

	public void InitializeAfterConfiguration()
	{
		if (string.IsNullOrEmpty(m_doorID))
		{
			m_doorID = BuildDoorID();
		}
		m_stateKey = "CustomChildDoor_" + m_doorID + "_state";
		m_rpcName = "CustomChildDoor_" + m_doorID + "_UseDoor";
		m_autoRpcName = "CustomChildDoor_" + m_doorID + "_AutoSetDoor";
		if ((Object)(object)m_animator == (Object)null)
		{
			m_animator = FindAnimatorComponent(((Component)this).gameObject);
		}
		ZNetView val = (((Object)(object)m_rootZNetView != (Object)null) ? m_rootZNetView : ((Component)this).GetComponentInParent<ZNetView>());
		if ((Object)(object)m_nview != (Object)(object)val)
		{
			m_nview = val;
			m_registeredRpcName = null;
			m_registeredAutoRpcName = null;
		}
		if ((Object)(object)m_nview == (Object)null)
		{
			Debug.LogWarning((object)("[CustomChildDoor] No root ZNetView found for door: " + ((Object)this).name));
			return;
		}
		if (m_registeredRpcName != m_rpcName)
		{
			m_nview.Register<bool>(m_rpcName, (Action<long, bool>)RPC_UseDoor);
			m_registeredRpcName = m_rpcName;
		}
		if (m_registeredAutoRpcName != m_autoRpcName)
		{
			m_nview.Register<int>(m_autoRpcName, (Action<long, int>)RPC_AutoSetDoor);
			m_registeredAutoRpcName = m_autoRpcName;
		}
		if (!((MonoBehaviour)this).IsInvoking("UpdateState"))
		{
			((MonoBehaviour)this).InvokeRepeating("UpdateState", 0f, 0.2f);
		}
	}

	private string BuildDoorID()
	{
		string text = ((Object)this).name;
		Transform parent = ((Component)this).transform.parent;
		while ((Object)(object)parent != (Object)null)
		{
			text = ((Object)parent).name + "_" + text;
			if ((Object)(object)((Component)parent).GetComponent<ZNetView>() != (Object)null)
			{
				break;
			}
			parent = parent.parent;
		}
		return SanitizeKey(text);
	}

	private string SanitizeKey(string value)
	{
		if (string.IsNullOrEmpty(value))
		{
			return "Door";
		}
		return value.Replace(" ", "_").Replace("/", "_").Replace("\\", "_")
			.Replace("(", "_")
			.Replace(")", "_")
			.Replace("[", "_")
			.Replace("]", "_")
			.Replace(".", "_")
			.Replace("-", "_");
	}

	private bool IsValid()
	{
		return (Object)(object)m_nview != (Object)null && m_nview.IsValid() && m_nview.GetZDO() != null;
	}

	private int GetState()
	{
		if (!IsValid())
		{
			return 0;
		}
		return m_nview.GetZDO().GetInt(m_stateKey, 0);
	}

	private void SetSavedState(int state)
	{
		if (IsValid())
		{
			m_nview.GetZDO().Set(m_stateKey, state);
		}
	}

	private void UpdateState()
	{
		if (IsValid())
		{
			uint dataRevision = m_nview.GetZDO().DataRevision;
			if (m_lastDataRevision != dataRevision)
			{
				m_lastDataRevision = dataRevision;
				SetState(GetState());
			}
		}
	}

	private void SetState(int state)
	{
		if ((Object)(object)m_animator != (Object)null)
		{
			int animatorInteger = GetAnimatorInteger(m_animator, m_animatorStateParameter);
			if (animatorInteger != state)
			{
				if (state != 0)
				{
					GetDoorSound().PlayOpen();
				}
				else
				{
					GetDoorSound().PlayClose();
				}
				SetAnimatorInteger(m_animator, m_animatorStateParameter, state);
			}
		}
		if ((Object)(object)m_openEnable != (Object)null)
		{
			m_openEnable.SetActive(state != 0);
		}
	}

	public void SetDoorSound(CustomDoorSound doorSound)
	{
		m_doorSound = doorSound;
		if ((Object)(object)m_doorSound != (Object)null)
		{
			m_doorSound.Configure(this);
		}
	}

	private CustomDoorSound GetDoorSound()
	{
		if ((Object)(object)m_doorSound == (Object)null)
		{
			m_doorSound = ((Component)this).GetComponent<CustomDoorSound>();
		}
		if ((Object)(object)m_doorSound == (Object)null)
		{
			m_doorSound = ((Component)this).gameObject.AddComponent<CustomDoorSound>();
		}
		m_doorSound.Configure(this);
		return m_doorSound;
	}

	private bool CanInteract()
	{
		if (!IsValid())
		{
			return false;
		}
		if ((Object)(object)m_animator == (Object)null)
		{
			return false;
		}
		if (((Object)(object)m_keyItem != (Object)null || m_canNotBeClosed) && GetState() != 0)
		{
			return false;
		}
		return !IsAnimatorInTransition(m_animator);
	}

	public void AutoSetDoorState(bool open)
	{
		if (!IsValid())
		{
			return;
		}
		int num = (open ? 1 : 0);
		if (GetState() != num)
		{
			if (string.IsNullOrEmpty(m_autoRpcName))
			{
				m_autoRpcName = "CustomChildDoor_" + m_doorID + "_AutoSetDoor";
			}
			m_nview.InvokeRPC(m_autoRpcName, new object[1] { num });
		}
	}

	private void RPC_AutoSetDoor(long uid, int wantedState)
	{
		if (IsValid())
		{
			wantedState = ((wantedState != 0) ? 1 : 0);
			if (GetState() != wantedState)
			{
				SetSavedState(wantedState);
				UpdateState();
			}
		}
	}

	public string GetHoverText()
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		if (m_disableManualInteract)
		{
			return "";
		}
		string cleanDoorName = GetCleanDoorName();
		if (!IsValid())
		{
			return "";
		}
		if (m_canNotBeClosed && !CanInteract())
		{
			return "";
		}
		if (m_checkGuardStone && !PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false))
		{
			return cleanDoorName + "\n[<color=yellow><b>E</b></color>] No access";
		}
		if (!CanInteract())
		{
			return cleanDoorName;
		}
		string text = ((GetState() == 0) ? (m_invertedOpenClosedText ? "Close" : "Open") : (m_invertedOpenClosedText ? "Open" : "Close"));
		return cleanDoorName + "\n[<color=yellow><b>E</b></color>] " + text;
	}

	private string GetCleanDoorName()
	{
		if (string.IsNullOrEmpty(m_name))
		{
			return CleanDoorName(((Object)this).name);
		}
		return CleanDoorName(m_name);
	}

	private static string CleanDoorName(string value)
	{
		if (string.IsNullOrEmpty(value))
		{
			return "Door";
		}
		if (value == "MainGate")
		{
			return "Main Gate";
		}
		if (value == "Roof_Door")
		{
			return "Roof Door";
		}
		return value.Replace("_", " ");
	}

	public string GetHoverName()
	{
		if (m_disableManualInteract)
		{
			return "";
		}
		return GetCleanDoorName();
	}

	public bool Interact(Humanoid character, bool hold, bool alt)
	{
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		if (m_disableManualInteract)
		{
			return false;
		}
		if (hold)
		{
			return false;
		}
		if (!CanInteract())
		{
			return false;
		}
		if (m_checkGuardStone && !PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false))
		{
			return true;
		}
		if ((Object)(object)m_keyItem != (Object)null)
		{
			if (!HaveKey(character))
			{
				m_lockedEffects.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1);
				if (Game.m_worldLevel > 0 && HaveKey(character, matchWorldLevel: false))
				{
					((Character)character).Message((MessageType)2, Localize("$msg_ng_the_x") + m_keyItem.m_itemData.m_shared.m_name + Localize("$msg_ng_x_is_too_low"), 0, (Sprite)null);
				}
				else
				{
					((Character)character).Message((MessageType)2, Localize("$msg_door_needkey", m_keyItem.m_itemData.m_shared.m_name), 0, (Sprite)null);
				}
				return true;
			}
			((Character)character).Message((MessageType)2, Localize("$msg_door_usingkey", m_keyItem.m_itemData.m_shared.m_name), 0, (Sprite)null);
		}
		Vector3 val = ((Component)character).transform.position - ((Component)this).transform.position;
		Vector3 normalized = ((Vector3)(ref val)).normalized;
		Game.instance.IncrementPlayerStat((PlayerStatType)((GetState() == 0) ? 74 : 75), 1f);
		Open(normalized);
		return true;
	}

	private void Open(Vector3 userDirection)
	{
		//IL_0017: 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)
		if (IsValid())
		{
			bool flag = Vector3.Dot(((Component)this).transform.forward, userDirection) < 0f;
			m_nview.InvokeRPC(m_rpcName, new object[1] { flag });
		}
	}

	public bool UseItem(Humanoid user, ItemData item)
	{
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: 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)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		if (m_disableManualInteract)
		{
			return false;
		}
		if ((Object)(object)m_keyItem == (Object)null)
		{
			return false;
		}
		if (m_keyItem.m_itemData.m_shared.m_name != item.m_shared.m_name)
		{
			return false;
		}
		if (!CanInteract())
		{
			return false;
		}
		if (m_checkGuardStone && !PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false))
		{
			return true;
		}
		((Character)user).Message((MessageType)2, Localize("$msg_door_usingkey", m_keyItem.m_itemData.m_shared.m_name), 0, (Sprite)null);
		Vector3 val = ((Component)user).transform.position - ((Component)this).transform.position;
		Vector3 normalized = ((Vector3)(ref val)).normalized;
		Open(normalized);
		return true;
	}

	private bool HaveKey(Humanoid player, bool matchWorldLevel = true)
	{
		if ((Object)(object)m_keyItem == (Object)null)
		{
			return true;
		}
		return player.GetInventory().HaveItem(m_keyItem.m_itemData.m_shared.m_name, matchWorldLevel);
	}

	private void RPC_UseDoor(long uid, bool forward)
	{
		if (CanInteract())
		{
			if (GetState() == 0)
			{
				SetSavedState(forward ? 1 : (-1));
			}
			else
			{
				SetSavedState(0);
			}
			UpdateState();
		}
	}

	public static Component FindAnimatorComponent(GameObject owner)
	{
		if ((Object)(object)owner == (Object)null)
		{
			return null;
		}
		Component[] componentsInChildren = owner.GetComponentsInChildren<Component>(true);
		Component[] array = componentsInChildren;
		foreach (Component val in array)
		{
			if (!((Object)(object)val == (Object)null))
			{
				Type type = ((object)val).GetType();
				if (type.Name == "Animator" || type.FullName == "UnityEngine.Animator")
				{
					return val;
				}
			}
		}
		return null;
	}

	private static int GetAnimatorInteger(Component animator, string parameterName)
	{
		if ((Object)(object)animator == (Object)null || string.IsNullOrEmpty(parameterName))
		{
			return int.MinValue;
		}
		try
		{
			MethodInfo method = ((object)animator).GetType().GetMethod("GetInteger", new Type[1] { typeof(string) });
			if (method == null)
			{
				return int.MinValue;
			}
			return (method.Invoke(animator, new object[1] { parameterName }) is int num) ? num : int.MinValue;
		}
		catch
		{
			return int.MinValue;
		}
	}

	private static void SetAnimatorInteger(Component animator, string parameterName, int value)
	{
		if ((Object)(object)animator == (Object)null || string.IsNullOrEmpty(parameterName))
		{
			return;
		}
		try
		{
			MethodInfo method = ((object)animator).GetType().GetMethod("SetInteger", new Type[2]
			{
				typeof(string),
				typeof(int)
			});
			if (method != null)
			{
				method.Invoke(animator, new object[2] { parameterName, value });
			}
		}
		catch
		{
		}
	}

	private static bool IsAnimatorInTransition(Component animator)
	{
		if ((Object)(object)animator == (Object)null)
		{
			return false;
		}
		try
		{
			MethodInfo method = ((object)animator).GetType().GetMethod("IsInTransition", new Type[1] { typeof(int) });
			if (method == null)
			{
				return false;
			}
			object obj = method.Invoke(animator, new object[1] { 0 });
			bool flag = default(bool);
			int num;
			if (obj is bool)
			{
				flag = (bool)obj;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}
		catch
		{
			return false;
		}
	}

	private static string Localize(string text, params object[] args)
	{
		if (string.IsNullOrEmpty(text))
		{
			return text;
		}
		try
		{
			EnsureLocalizationReflection();
			object obj = ((localizationInstanceField != null) ? localizationInstanceField.GetValue(null) : null);
			if (obj == null || localizationLocalizeMethod == null)
			{
				return FormatFallback(text, args);
			}
			if (args != null && args.Length != 0)
			{
				try
				{
					return (localizationLocalizeMethod.Invoke(obj, new object[2] { text, args }) as string) ?? FormatFallback(text, args);
				}
				catch
				{
					return (localizationLocalizeMethod.Invoke(obj, new object[1] { text }) as string) ?? FormatFallback(text, args);
				}
			}
			return (localizationLocalizeMethod.Invoke(obj, new object[1] { text }) as string) ?? text;
		}
		catch
		{
			return FormatFallback(text, args);
		}
	}

	private static void EnsureLocalizationReflection()
	{
		if (localizationType != null)
		{
			return;
		}
		Assembly assembly = typeof(Game).Assembly;
		localizationType = assembly.GetType("Localization");
		if (localizationType == null)
		{
			return;
		}
		localizationInstanceField = localizationType.GetField("instance", BindingFlags.Static | BindingFlags.Public);
		MethodInfo[] methods = localizationType.GetMethods(BindingFlags.Instance | BindingFlags.Public);
		foreach (MethodInfo methodInfo in methods)
		{
			if (!(methodInfo.Name != "Localize"))
			{
				ParameterInfo[] parameters = methodInfo.GetParameters();
				if (parameters.Length >= 1 && parameters[0].ParameterType == typeof(string))
				{
					localizationLocalizeMethod = methodInfo;
					break;
				}
			}
		}
	}

	private static string FormatFallback(string text, object[] args)
	{
		if (args == null || args.Length == 0)
		{
			return text;
		}
		try
		{
			return string.Format(text, args);
		}
		catch
		{
			return text;
		}
	}
}
public class CustomDoorSound : MonoBehaviour
{
	[SerializeField]
	private EffectList m_openEffects = new EffectList();

	[SerializeField]
	private EffectList m_closeEffects = new EffectList();

	private bool m_warnedMissingOpenSfx;

	private bool m_warnedMissingCloseSfx;

	public void Configure(EffectList openEffects, EffectList closeEffects)
	{
		//IL_0007: 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)
		m_openEffects = (EffectList)(((object)openEffects) ?? ((object)new EffectList()));
		m_closeEffects = (EffectList)(((object)closeEffects) ?? ((object)new EffectList()));
	}

	public void Configure(CustomChildDoor door)
	{
		Configure(((Object)(object)door != (Object)null) ? door.m_openEffects : null, ((Object)(object)door != (Object)null) ? door.m_closeEffects : null);
	}

	public void PlayOpen()
	{
		PlayEffects(m_openEffects, opening: true);
	}

	public void PlayClose()
	{
		PlayEffects(m_closeEffects, opening: false);
	}

	private static bool HasEffects(EffectList effects)
	{
		return effects != null && effects.m_effectPrefabs != null && effects.m_effectPrefabs.Length != 0;
	}

	private void PlayEffects(EffectList effects, bool opening)
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		string action = (opening ? "OPEN" : "CLOSE");
		if (!HasEffects(effects))
		{
			WarnMissingSound(opening);
		}
		else if (IsBundledSmallDoorSound(effects))
		{
			PlayBundledSmallDoorClips(effects, action, opening);
		}
		else
		{
			effects.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1);
		}
	}

	private static bool IsBundledSmallDoorSound(EffectList effects)
	{
		if (!HasEffects(effects))
		{
			return false;
		}
		for (int i = 0; i < effects.m_effectPrefabs.Length; i++)
		{
			EffectData val = effects.m_effectPrefabs[i];
			if (val != null && !((Object)(object)val.m_prefab == (Object)null))
			{
				string name = ((Object)val.m_prefab).name;
				if (name == "sfx_door_open" || name == "sfx_door_close")
				{
					return true;
				}
			}
		}
		return false;
	}

	private void PlayBundledSmallDoorClips(EffectList effects, string action, bool opening)
	{
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Invalid comparison between Unknown and I4
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Expected O, but got Unknown
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		bool flag = false;
		for (int i = 0; i < effects.m_effectPrefabs.Length; i++)
		{
			EffectData val = effects.m_effectPrefabs[i];
			if (val == null || !val.m_enabled || (Object)(object)val.m_prefab == (Object)null)
			{
				continue;
			}
			ZSFX[] componentsInChildren = val.m_prefab.GetComponentsInChildren<ZSFX>(true);
			foreach (ZSFX val2 in componentsInChildren)
			{
				if ((Object)(object)val2 == (Object)null || val2.m_audioClips == null || val2.m_audioClips.Length == 0)
				{
					continue;
				}
				AudioClip val3 = val2.m_audioClips[Random.Range(0, val2.m_audioClips.Length)];
				if (!((Object)(object)val3 == (Object)null))
				{
					if ((int)val3.loadState == 0)
					{
						val3.LoadAudioData();
					}
					GameObject val4 = new GameObject("DragonKeep_" + action + "_DoorSound");
					val4.transform.position = ((Component)this).transform.position;
					AudioSource val5 = val4.AddComponent<AudioSource>();
					val5.playOnAwake = false;
					val5.loop = false;
					val5.spatialBlend = 1f;
					val5.rolloffMode = (AudioRolloffMode)0;
					val5.minDistance = 5f;
					val5.maxDistance = 50f;
					val5.dopplerLevel = 0f;
					val5.volume = 1f;
					val5.pitch = 1f;
					val5.clip = val3;
					val5.Play();
					float num = Mathf.Max(1f, val3.length + 0.25f);
					Object.Destroy((Object)(object)val4, num);
					flag = true;
				}
			}
		}
		if (!flag)
		{
			WarnMissingSound(opening);
		}
	}

	private void WarnMissingSound(bool opening)
	{
		if (opening)
		{
			if (!m_warnedMissingOpenSfx)
			{
				m_warnedMissingOpenSfx = true;
				Debug.LogWarning((object)("[DragonKeep] Door open SFX was not found for: " + ((Object)this).name));
			}
		}
		else if (!m_warnedMissingCloseSfx)
		{
			m_warnedMissingCloseSfx = true;
			Debug.LogWarning((object)("[DragonKeep] Door close SFX was not found for: " + ((Object)this).name));
		}
	}
}
[BepInPlugin("DragonKeep", "Ravenwood Dragon Keep", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class DragonKeep : BaseUnityPlugin
{
	public const string PluginGUID = "DragonKeep";

	public const string PluginName = "Ravenwood Dragon Keep";

	public const string PluginVersion = "1.0.0";

	internal static ConfigFile ModConfig;

	private AssetBundle dragonPenBundle;

	private void Awake()
	{
		//IL_0011: 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)
		ModConfig = ((BaseUnityPlugin)this).Config;
		new Harmony("DragonKeep").PatchAll();
		string resourcePath = "DragonKeep.dragonpen";
		dragonPenBundle = EmbeddedAssetBundleLoader.LoadBundle(resourcePath);
		if ((Object)(object)dragonPenBundle == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"Failed to load embedded AssetBundle: dragonpen");
			return;
		}
		foreach (string allCategory in DragonKingdomRegistrar.GetAllCategories())
		{
			PieceManager.Instance.AddPieceCategory(allCategory);
		}
		PrefabManager.OnPrefabsRegistered += delegate
		{
			DragonKingdomRegistrar.RegisterAllPieces(dragonPenBundle);
		};
	}
}
public static class EmbeddedAssetBundleLoader
{
	public static AssetBundle LoadBundle(string resourcePath)
	{
		Assembly executingAssembly = Assembly.GetExecutingAssembly();
		using Stream stream = executingAssembly.GetManifestResourceStream(resourcePath);
		if (stream == null)
		{
			Debug.LogError((object)("AssetBundle resource not found: " + resourcePath));
			return null;
		}
		byte[] array = new byte[stream.Length];
		stream.Read(array, 0, array.Length);
		return AssetBundle.LoadFromMemory(array);
	}
}
public class DragonKeepRemovalEffects : MonoBehaviour
{
	public EffectList m_destroyedEffect = new EffectList();

	public GameObject[] m_fragmentRoots = (GameObject[])(object)new GameObject[0];

	public bool m_createFragments = true;

	private bool effectsPlayed;

	public void Play()
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		if (effectsPlayed)
		{
			return;
		}
		effectsPlayed = true;
		EffectList destroyedEffect = m_destroyedEffect;
		if (destroyedEffect != null)
		{
			destroyedEffect.Create(((Component)this).transform.position, ((Component)this).transform.rotation, ((Component)this).transform, 1f, -1);
		}
		if (!m_createFragments)
		{
			return;
		}
		if (m_fragmentRoots != null && m_fragmentRoots.Length != 0)
		{
			for (int i = 0; i < m_fragmentRoots.Length; i++)
			{
				GameObject val = m_fragmentRoots[i];
				if (!((Object)(object)val == (Object)null))
				{
					val.SetActive(true);
					Destructible.CreateFragments(val, false);
				}
			}
		}
		else
		{
			Destructible.CreateFragments(((Component)this).gameObject, true);
		}
	}
}
[HarmonyPatch(typeof(ZNetScene), "Destroy", new Type[] { typeof(GameObject) })]
internal static class DragonKeepZNetSceneDestroyPatch
{
	private static void Prefix(GameObject __0)
	{
		if (!((Object)(object)__0 == (Object)null))
		{
			__0.GetComponent<DragonKeepRemovalEffects>()?.Play();
		}
	}
}
public class DragonKingdomRegistration
{
	public string PrefabName;

	public string DisplayName;

	public RequirementConfig[] Requirements;

	public string Description;

	public string Category;

	public int Comfort;

	public DragonKingdomRegistration(string prefab, string display, RequirementConfig[] reqs, string desc, string cat, int comfort = 0)
	{
		PrefabName = prefab;
		DisplayName = display;
		Requirements = reqs;
		Description = desc;
		Category = cat;
		Comfort = comfort;
	}
}
public static class DragonKingdomRegistrar
{
	private static bool wasAlreadyRegistered = false;

	private const string DefaultHammerTab = "Ravenwood";

	private static ConfigEntry<string> hammerTabConfig;

	public static readonly List<DragonKingdomRegistration> AllRegistrations = new List<DragonKingdomRegistration>
	{
		new DragonKingdomRegistration("DP_DragonPen", "Dragon Pen", (RequirementConfig[])(object)new RequirementConfig[4]
		{
			new RequirementConfig("Iron", 400, 0, true),
			new RequirementConfig("RoundLog", 400, 0, true),
			new RequirementConfig("Obsidian", 400, 0, true),
			new RequirementConfig("RWc_Lion", 50, 0, true)
		}, "", "dragonkingdom"),
		new DragonKingdomRegistration("DP_DragonPen_Base", "Dragon Pen no roof", (RequirementConfig[])(object)new RequirementConfig[4]
		{
			new RequirementConfig("Iron", 400, 0, true),
			new RequirementConfig("RoundLog", 400, 0, true),
			new RequirementConfig("Obsidian", 400, 0, true),
			new RequirementConfig("RWc_Lion", 40, 0, true)
		}, "", "dragonkingdom"),
		new DragonKingdomRegistration("DP_Roof", "Dragon Pen roof", (RequirementConfig[])(object)new RequirementConfig[4]
		{
			new RequirementConfig("Bronze", 40, 0, true),
			new RequirementConfig("FineWood", 100, 0, true),
			new RequirementConfig("Crystal", 200, 0, true),
			new RequirementConfig("RWc_Bear", 40, 0, true)
		}, "", "dragonkingdom"),
		new DragonKingdomRegistration("DP_Original_Wall", "Dragon Pen Wall", (RequirementConfig[])(object)new RequirementConfig[3]
		{
			new RequirementConfig("Obsidian", 8, 0, true),
			new RequirementConfig("Stone", 8, 0, true),
			new RequirementConfig("RWc_Deer", 15, 0, true)
		}, "", "dragonkingdom"),
		new DragonKingdomRegistration("DP_Original_High_Wall", "Dragon Pen Original High Wall", (RequirementConfig[])(object)new RequirementConfig[4]
		{
			new RequirementConfig("Obsidian", 20, 0, true),
			new RequirementConfig("Stone", 20, 0, true),
			new RequirementConfig("Iron", 20, 0, true),
			new RequirementConfig("RWc_Snake", 5, 0, true)
		}, "", "dragonkingdom"),
		new DragonKingdomRegistration("DP_6m_Wall", "Dragon Pen 6m Wall", (RequirementConfig[])(object)new RequirementConfig[3]
		{
			new RequirementConfig("Obsidian", 20, 0, true),
			new RequirementConfig("Stone", 20, 0, true),
			new RequirementConfig("RWc_Deer", 50, 0, true)
		}, "", "dragonkingdom"),
		new DragonKingdomRegistration("DP_2m_Wall", "Dragon Pen Short Wall", (RequirementConfig[])(object)new RequirementConfig[3]
		{
			new RequirementConfig("Obsidian", 2, 0, true),
			new RequirementConfig("Stone", 2, 0, true),
			new RequirementConfig("RWc_Deer", 5, 0, true)
		}, "", "dragonkingdom"),
		new DragonKingdomRegistration("DP_Castle_Tower", "Dragon Pen Castle Tower", (RequirementConfig[])(object)new RequirementConfig[4]
		{
			new RequirementConfig("Obsidian", 100, 0, true),
			new RequirementConfig("Stone", 100, 0, true),
			new RequirementConfig("Crystal", 10, 0, true),
			new RequirementConfig("RWc_Snake", 20, 0, true)
		}, "", "dragonkingdom"),
		new DragonKingdomRegistration("DP_Corner_Tower", "Dragon Pen Corner Tower", (RequirementConfig[])(object)new RequirementConfig[4]
		{
			new RequirementConfig("Iron", 50, 0, true),
			new RequirementConfig("Stone", 50, 0, true),
			new RequirementConfig("RoundLog", 50, 0, true),
			new RequirementConfig("RWc_Snake", 15, 0, true)
		}, "", "dragonkingdom"),
		new DragonKingdomRegistration("DP_Corner_Piece", "Dragon Pen Corner Piece", (RequirementConfig[])(object)new RequirementConfig[2]
		{
			new RequirementConfig("Obsidian", 10, 0, true),
			new RequirementConfig("RWc_Deer", 10, 0, true)
		}, "", "dragonkingdom"),
		new DragonKingdomRegistration("DP_Corner_Piece_Small", "Dragon Pen Small Corner Piece", (RequirementConfig[])(object)new RequirementConfig[2]
		{
			new RequirementConfig("Obsidian", 5, 0, true),
			new RequirementConfig("RWc_Deer", 5, 0, true)
		}, "", "dragonkingdom"),
		new DragonKingdomRegistration("DP_Gate", "Dragon Pen Main Gate", (RequirementConfig[])(object)new RequirementConfig[4]
		{
			new RequirementConfig("Obsidian", 50, 0, true),
			new RequirementConfig("Iron", 100, 0, true),
			new RequirementConfig("RoundLog", 100, 0, true),
			new RequirementConfig("RWc_Snake", 25, 0, true)
		}, "", "dragonkingdom"),
		new DragonKingdomRegistration("DP_Throne", "Dragon Throne", (RequirementConfig[])(object)new RequirementConfig[4]
		{
			new RequirementConfig("TrophyDragonQueen", 1, 0, true),
			new RequirementConfig("TrophySerpent", 1, 0, true),
			new RequirementConfig("Bronze", 50, 0, true),
			new RequirementConfig("RWc_Bear", 100, 0, true)
		}, "", "dragonkingdom"),
		new DragonKingdomRegistration("DP_B_Throne", "Dragon Throne Large", (RequirementConfig[])(object)new RequirementConfig[4]
		{
			new RequirementConfig("TrophyDragonQueen", 1, 0, true),
			new RequirementConfig("TrophyFader", 1, 0, true),
			new RequirementConfig("Bronze", 200, 0, true),
			new RequirementConfig("RWc_Lion", 20, 0, true)
		}, "", "dragonkingdom", 1)
	};

	public static IEnumerable<string> GetAllCategories()
	{
		return AllRegistrations.Select((DragonKingdomRegistration r) => CategoryToTab(r.Category)).Distinct();
	}

	private static string CategoryToTab(string category)
	{
		string text = category.ToLower();
		if (1 == 0)
		{
		}
		string result = ((!(text == "dragonkingdom")) ? category : GetConfiguredHammerTab());
		if (1 == 0)
		{
		}
		return result;
	}

	private static string GetConfiguredHammerTab()
	{
		if (hammerTabConfig == null && DragonKeep.ModConfig != null)
		{
			hammerTabConfig = DragonKeep.ModConfig.Bind<string>("General", "Hammer Tab", "Ravenwood", "Hammer build-menu tab used for every Ravenwood Dragon Keep prefab. Restart Valheim after changing this setting.");
		}
		string text = hammerTabConfig?.Value;
		return string.IsNullOrWhiteSpace(text) ? "Ravenwood" : text.Trim();
	}

	public static void RegisterAllPieces(AssetBundle bundle)
	{
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Expected O, but got Unknown
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Expected O, but got Unknown
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Expected O, but got Unknown
		if (wasAlreadyRegistered)
		{
			return;
		}
		HashSet<string> hashSet = new HashSet<string>();
		foreach (DragonKingdomRegistration allRegistration in AllRegistrations)
		{
			RegisterPiece(bundle, allRegistration);
			hashSet.Add(allRegistration.PrefabName);
		}
		GameObject[] array = bundle.LoadAllAssets<GameObject>();
		foreach (GameObject val in array)
		{
			if (!((Object)(object)val == (Object)null) && ((Object)val).name.StartsWith("DP_") && !hashSet.Contains(((Object)val).name))
			{
				string display = ((Object)val).name.Substring(3).Replace("_", " ");
				DragonKingdomRegistration reg = new DragonKingdomRegistration(((Object)val).name, display, (RequirementConfig[])(object)new RequirementConfig[3]
				{
					new RequirementConfig("Iron", 50, 0, true),
					new RequirementConfig("Wood", 100, 0, true),
					new RequirementConfig("Resin", 40, 0, true)
				}, "", "dragonkingdom");
				RegisterPiece(bundle, reg);
				hashSet.Add(((Object)val).name);
			}
		}
		wasAlreadyRegistered = true;
	}

	private static void RegisterPiece(AssetBundle bundle, DragonKingdomRegistration reg)
	{
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Expected O, but got Unknown
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Expected O, but got Unknown
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Expected O, but got Unknown
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f4: Expected O, but got Unknown
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Expected O, but got Unknown
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0233: Unknown result type (might be due to invalid IL or missing references)
		//IL_0240: Expected O, but got Unknown
		//IL_0368: Unknown result type (might be due to invalid IL or missing references)
		//IL_036d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0379: Unknown result type (might be due to invalid IL or missing references)
		//IL_038b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0397: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a1: Expected O, but got Unknown
		//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b4: Expected O, but got Unknown
		if ((Object)(object)bundle == (Object)null)
		{
			return;
		}
		GameObject val = bundle.LoadAsset<GameObject>(reg.PrefabName);
		if (!((Object)(object)val == (Object)null))
		{
			((Object)val).name = reg.PrefabName;
			RequirementConfig[] configuredRequirements = GetConfiguredRequirements(reg);
			ZNetView val2 = val.GetComponent<ZNetView>() ?? val.AddComponent<ZNetView>();
			val2.m_persistent = true;
			val2.m_syncInitialScale = true;
			PrepareEternalBuildingPrefab(val);
			Piece val3 = val.GetComponent<Piece>() ?? val.AddComponent<Piece>();
			val3.m_name = reg.DisplayName;
			val3.m_description = reg.Description;
			val3.m_groundOnly = false;
			val3.m_canBeRemoved = true;
			ZNetScene instance = ZNetScene.instance;
			GameObject val4 = ((instance != null) ? instance.GetPrefab("vfx_Place_stone") : null);
			ZNetScene instance2 = ZNetScene.instance;
			GameObject val5 = ((instance2 != null) ? instance2.GetPrefab("sfx_build_hammer_stone") : null);
			ZNetScene instance3 = ZNetScene.instance;
			GameObject val6 = ((instance3 != null) ? instance3.GetPrefab("vfx_destroyed") : null);
			ZNetScene instance4 = ZNetScene.instance;
			GameObject val7 = ((instance4 != null) ? instance4.GetPrefab("sfx_rock_destroyed") : null);
			EffectList val8 = new EffectList();
			List<EffectData> list = new List<EffectData>();
			if ((Object)(object)val4 != (Object)null)
			{
				list.Add(new EffectData
				{
					m_prefab = val4
				});
			}
			if ((Object)(object)val5 != (Object)null)
			{
				list.Add(new EffectData
				{
					m_prefab = val5
				});
			}
			val8.m_effectPrefabs = list.ToArray();
			val3.m_placeEffect = val8;
			WearNTear component = val.GetComponent<WearNTear>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_health = 1000000f;
				component.m_noRoofWear = true;
			}
			Destructible component2 = val.GetComponent<Destructible>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.m_health = 1000000f;
			}
			TreeBase component3 = val.GetComponent<TreeBase>();
			if ((Object)(object)component3 != (Object)null)
			{
				component3.m_health = 1000000f;
				component3.m_minToolTier = 1073741823;
			}
			EffectList val9 = new EffectList();
			List<EffectData> list2 = new List<EffectData>();
			if ((Object)(object)val6 != (Object)null)
			{
				list2.Add(new EffectData
				{
					m_prefab = val6
				});
			}
			if ((Object)(object)val7 != (Object)null)
			{
				list2.Add(new EffectData
				{
					m_prefab = val7
				});
			}
			val9.m_effectPrefabs = list2.ToArray();
			DragonKeepRemovalEffects dragonKeepRemovalEffects = val.GetComponent<DragonKeepRemovalEffects>() ?? val.AddComponent<DragonKeepRemovalEffects>();
			dragonKeepRemovalEffects.m_destroyedEffect = val9;
			if ((Object)(object)component != (Object)null)
			{
				component.m_destroyedEffect = val9;
			}
			if (reg.Comfort > 0)
			{
				val3.m_comfort = reg.Comfort;
			}
			Sprite val10 = bundle.LoadAsset<Sprite>(reg.PrefabName);
			if ((Object)(object)val10 != (Object)null)
			{
				val3.m_icon = val10;
			}
			else
			{
				Debug.LogWarning((object)("[DragonKeep] Icon not found for prefab: " + reg.PrefabName));
			}
			if (reg.PrefabName == "DP_DragonPen")
			{
				ConfigureDragonPenDoors(val, val2, bundle, configureGroundDoors: true, configureRoofDoor: true);
			}
			else if (reg.PrefabName == "DP_DragonPen_Base")
			{
				ConfigureDragonPenDoors(val, val2, bundle, configureGroundDoors: true, configureRoofDoor: false);
			}
			else if (reg.PrefabName == "DP_Roof")
			{
				ConfigureDragonPenDoors(val, val2, bundle, configureGroundDoors: false, configureRoofDoor: true);
			}
			else if (reg.PrefabName == "DP_Corner_Tower")
			{
				ConfigureCornerTowerDoors(val, val2, bundle);
			}
			PieceConfig val11 = new PieceConfig
			{
				PieceTable = "Hammer",
				Category = CategoryToTab(reg.Category),
				CraftingStation = "piece_workbench",
				Requirements = configuredRequirements
			};
			PieceManager.Instance.AddPiece(new CustomPiece(val, true, val11));
		}
	}

	private static RequirementConfig[] GetConfiguredRequirements(DragonKingdomRegistration reg)
	{
		if (DragonKeep.ModConfig == null)
		{
			return reg.Requirements;
		}
		string text = FormatRequirements(reg.Requirements);
		ConfigEntry<string> val = DragonKeep.ModConfig.Bind<string>("Build Costs", reg.PrefabName, text, "Build cost format: [Valheim prefab name][amount]. Up to four requirements.");
		if (TryParseRequirements(val.Value, out var requirements))
		{
			return requirements;
		}
		Debug.LogWarning((object)("[DragonKeep] Invalid build cost for " + reg.PrefabName + ". Using the default value: " + text));
		return reg.Requirements;
	}

	private static string FormatRequirements(RequirementConfig[] requirements)
	{
		if (requirements == null || requirements.Length == 0)
		{
			return "";
		}
		return string.Join("", requirements.Select((RequirementConfig requirement) => $"[{requirement.Item}][{requirement.Amount}]"));
	}

	private static bool TryParseRequirements(string value, out RequirementConfig[] requirements)
	{
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Expected O, but got Unknown
		List<RequirementConfig> list = new List<RequirementConfig>();
		requirements = (RequirementConfig[])(object)new RequirementConfig[0];
		if (string.IsNullOrWhiteSpace(value))
		{
			return false;
		}
		int i = 0;
		while (i < value.Length)
		{
			for (; i < value.Length && char.IsWhiteSpace(value[i]); i++)
			{
			}
			if (i >= value.Length)
			{
				break;
			}
			if (value[i] != '[')
			{
				return false;
			}
			int num = value.IndexOf(']', i + 1);
			if (num < 0)
			{
				return false;
			}
			string text = value.Substring(i + 1, num - i - 1).Trim();
			for (i = num + 1; i < value.Length && char.IsWhiteSpace(value[i]); i++)
			{
			}
			if (i >= value.Length || value[i] != '[')
			{
				return false;
			}
			int num2 = value.IndexOf(']', i + 1);
			if (num2 < 0)
			{
				return false;
			}
			string s = value.Substring(i + 1, num2 - i - 1).Trim();
			if (string.IsNullOrWhiteSpace(text) || !int.TryParse(s, out var result) || result <= 0 || list.Count >= 4)
			{
				return false;
			}
			list.Add(new RequirementConfig(text, result, 0, true));
			i = num2 + 1;
		}
		if (list.Count == 0)
		{
			return false;
		}
		requirements = list.ToArray();
		return true;
	}

	private static void PrepareEternalBuildingPrefab(GameObject prefab)
	{
		HashSet<GameObject> configuredSupportColliders = CaptureConfiguredSupportColliders(prefab);
		EnsureSolidColliders(prefab);
		RemoveComponentsInChildren<Destructible>(prefab);
		RemoveComponentsInChildren<TreeLog>(prefab);
		RemoveComponentsInChildren<Plant>(prefab);
		RemoveComponentsInChildren<WearNTear>(prefab);
		RemoveComponentsInChildren<Rigidbody>(prefab);
		RemoveComponentsInChildren<TreeBase>(prefab);
		RemoveComponentsInChildren<StaticPhysics>(prefab);
		RemoveComponentsInChildren<ZSyncTransform>(prefab);
		SetLayerRecursively(prefab, "piece");
		ApplyEternalSupportColliderLayer(prefab, configuredSupportColliders);
	}

	private static HashSet<GameObject> CaptureConfiguredSupportColliders(GameObject prefab)
	{
		HashSet<GameObject> hashSet = new HashSet<GameObject>();
		if ((Object)(object)prefab == (Object)null)
		{
			return hashSet;
		}
		int num = LayerMask.NameToLayer("static_solid");
		if (num < 0)
		{
			return hashSet;
		}
		Transform[] componentsInChildren = prefab.GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)(object)prefab && ((Component)val).gameObject.layer == num)
			{
				hashSet.Add(((Component)val).gameObject);
			}
		}
		return hashSet;
	}

	private static void ApplyEternalSupportColliderLayer(GameObject prefab, HashSet<GameObject> configuredSupportColliders)
	{
		if ((Object)(object)prefab == (Object)null)
		{
			return;
		}
		int num = LayerMask.NameToLayer("static_solid");
		if (num < 0)
		{
			return;
		}
		if (configuredSupportColliders != null)
		{
			foreach (GameObject configuredSupportCollider in configuredSupportColliders)
			{
				if (!((Object)(object)configuredSupportCollider == (Object)null))
				{
					SetLayerRecursively(configuredSupportCollider, "static_solid");
					DisableRenderers(configuredSupportCollider);
					EnsureColliderTree(configuredSupportCollider);
				}
			}
		}
		Transform[] componentsInChildren = prefab.GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)(object)prefab))
			{
				string name = ((Object)val).name;
				if (string.Equals(name, "Collider", StringComparison.OrdinalIgnoreCase) || string.Equals(name, "SupportCollider", StringComparison.OrdinalIgnoreCase) || name.IndexOf("support", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("collider", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					SetLayerRecursively(((Component)val).gameObject, "static_solid");
					DisableRenderers(((Component)val).gameObject);
					EnsureColliderTree(((Component)val).gameObject);
				}
			}
		}
	}

	private static void DisableRenderers(GameObject root)
	{
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			if ((Object)(object)componentsInChildren[i] != (Object)null)
			{
				componentsInChildren[i].enabled = false;
			}
		}
	}

	private static void EnsureColliderTree(GameObject root)
	{
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		Collider[] componentsInChildren = root.GetComponentsInChildren<Collider>(true);
		foreach (Collider val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null))
			{
				val.enabled = true;
				val.isTrigger = false;
			}
		}
	}

	private static void EnsureSolidColliders(GameObject prefab)
	{
		//IL_00ac: 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_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)prefab == (Object)null)
		{
			return;
		}
		Collider[] componentsInChildren = prefab.GetComponentsInChildren<Collider>(true);
		if (componentsInChildren != null && componentsInChildren.Length != 0)
		{
			foreach (Collider val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					val.enabled = true;
					val.isTrigger = false;
				}
			}
			return;
		}
		BoxCollider val2 = prefab.GetComponent<BoxCollider>();
		if ((Object)(object)val2 == (Object)null)
		{
			val2 = prefab.AddComponent<BoxCollider>();
		}
		Renderer[] componentsInChildren2 = prefab.GetComponentsInChildren<Renderer>(true);
		if (componentsInChildren2.Length != 0)
		{
			Bounds bounds = componentsInChildren2[0].bounds;
			for (int j = 1; j < componentsInChildren2.Length; j++)
			{
				((Bounds)(ref bounds)).Encapsulate(componentsInChildren2[j].bounds);
			}
			val2.center = prefab.transform.InverseTransformPoint(((Bounds)(ref bounds)).center);
			val2.size = ((Bounds)(ref bounds)).size;
			((Collider)val2).enabled = true;
			((Collider)val2).isTrigger = false;
		}
	}

	private static void SetLayerRecursively(GameObject root, string layerName)
	{
		if ((Object)(object)root == (Object)null || string.IsNullOrWhiteSpace(layerName))
		{
			return;
		}
		int num = LayerMask.NameToLayer(layerName);
		if (num < 0)
		{
			return;
		}
		Transform[] componentsInChildren = root.GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).gameObject.layer = num;
			}
		}
	}

	private static void RemoveComponentsInChildren<T>(GameObject root) where T : Component
	{
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		T[] componentsInChildren = root.GetComponentsInChildren<T>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			if ((Object)(object)componentsInChildren[i] != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i], true);
			}
		}
	}

	private static void ConfigureDragonPenDoors(GameObject prefab, ZNetView rootZNetView, AssetBundle bundle, bool configureGroundDoors, bool configureRoofDoor)
	{
		if ((Object)(object)prefab == (Object)null || (Object)(object)rootZNetView == (Object)null)
		{
			return;
		}
		ZNetView[] componentsInChildren = prefab.GetComponentsInChildren<ZNetView>(true);
		foreach (ZNetView val in componentsInChildren)
		{
			if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)rootZNetView)
			{
				Object.DestroyImmediate((Object)(object)val, true);
			}
		}
		GameObject val2 = (((Object)(object)bundle != (Object)null) ? bundle.LoadAsset<GameObject>("sfx_M_Dragongate_Open") : null);
		GameObject val3 = (((Object)(object)bundle != (Object)null) ? bundle.LoadAsset<GameObject>("sfx_M_Dragongate_Close") : null);
		GameObject val4 = (((Object)(object)bundle != (Object)null) ? bundle.LoadAsset<GameObject>("sfx_door_open") : null);
		GameObject val5 = (((Object)(object)bundle != (Object)null) ? bundle.LoadAsset<GameObject>("sfx_door_close") : null);
		if (configureGroundDoors && (Object)(object)val2 == (Object)null)
		{
			Debug.LogWarning((object)"[DragonKeep] Missing DragonPen main gate open SFX prefab: sfx_M_Dragongate_Open");
		}
		if (configureGroundDoors && (Object)(object)val3 == (Object)null)
		{
			Debug.LogWarning((object)"[DragonKeep] Missing DragonPen main gate close SFX prefab: sfx_M_Dragongate_Close");
		}
		if ((configureGroundDoors || configureRoofDoor) && (Object)(object)val4 == (Object)null)
		{
			Debug.LogWarning((object)"[DragonKeep] Missing DragonPen small door open SFX prefab: sfx_door_open");
		}
		if ((configureGroundDoors || configureRoofDoor) && (Object)(object)val5 == (Object)null)
		{
			Debug.LogWarning((object)"[DragonKeep] Missing DragonPen small door close SFX prefab: sfx_door_close");
		}
		if (configureGroundDoors)
		{
			string[] array = new string[9] { "MainGate", "Left_F", "Right_F", "Left_B", "Right_B", "Left_F_B", "Right_F_B", "Left_B_B", "Right_B_B" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				Transform val6 = FindDeepChild(prefab.transform, text);
				if ((Object)(object)val6 == (Object)null)
				{
					Debug.LogWarning((object)("[DragonKeep] DragonPen child door not found: " + text));
				}
				else if (text == "MainGate")
				{
					ConfigureChildDoor(((Component)val6).gameObject, rootZNetView, text, val2, val3);
				}
				else
				{
					ConfigureChildDoor(((Component)val6).gameObject, rootZNetView, text, val4, val5);
				}
			}
		}
		if (!configureRoofDoor)
		{
			return;
		}
		Transform val7 = FindDeepChild(prefab.transform, "Roof_Door");
		if ((Object)(object)val7 == (Object)null)
		{
			Debug.LogWarning((object)"[DragonKeep] DragonPen roof door not found: Roof_Door");
			return;
		}
		CustomChildDoor customChildDoor = ConfigureChildDoor(((Component)val7).gameObject, rootZNetView, "Roof_Door", val4, val5);
		if ((Object)(object)customChildDoor != (Object)null)
		{
			customChildDoor.m_name = "Roof Door";
			customChildDoor.m_checkGuardStone = false;
			customChildDoor.m_disableManualInteract = true;
		}
		RoofDoorAutoOpenerInstaller.Apply(((Component)val7).gameObject, rootZNetView);
	}

	private static CustomChildDoor ConfigureChildDoor(GameObject doorObject, ZNetView rootZNetView, string doorID, GameObject openSfxPrefab, GameObject closeSfxPrefab)
	{
		if ((Object)(object)doorObject == (Object)null || (Object)(object)rootZNetView == (Object)null)
		{
			return null;
		}
		Door val = doorObject.GetComponent<Door>();
		if ((Object)(object)val == (Object)null)
		{
			val = doorObject.GetComponentInChildren<Door>(true);
		}
		CustomChildDoor customChildDoor = doorObject.GetComponent<CustomChildDoor>();
		if ((Object)(object)customChildDoor == (Object)null)
		{
			customChildDoor = doorObject.AddComponent<CustomChildDoor>();
		}
		customChildDoor.m_doorID = doorID;
		customChildDoor.m_rootZNetView = rootZNetView;
		customChildDoor.m_animator = CustomChildDoor.FindAnimatorComponent(doorObject);
		customChildDoor.m_disableManualInteract = false;
		if ((Object)(object)val != (Object)null)
		{
			customChildDoor.m_name = val.m_name;
			customChildDoor.m_keyItem = val.m_keyItem;
			customChildDoor.m_canNotBeClosed = val.m_canNotBeClosed;
			customChildDoor.m_invertedOpenClosedText = val.m_invertedOpenClosedText;
			customChildDoor.m_checkGuardStone = val.m_checkGuardStone;
			customChildDoor.m_openEnable = val.m_openEnable;
			customChildDoor.m_openEffects = val.m_openEffects;
			customChildDoor.m_closeEffects = val.m_closeEffects;
			customChildDoor.m_lockedEffects = val.m_lockedEffects;
		}
		else
		{
			customChildDoor.m_name = ((Object)doorObject).name;
		}
		if ((Object)(object)openSfxPrefab != (Object)null)
		{
			customChildDoor.m_openEffects = CreateSingleEffectList(openSfxPrefab);
		}
		if ((Object)(object)closeSfxPrefab != (Object)null)
		{
			customChildDoor.m_closeEffects = CreateSingleEffectList(closeSfxPrefab);
		}
		Door[] componentsInChildren = doorObject.GetComponentsInChildren<Door>(true);
		foreach (Door val2 in componentsInChildren)
		{
			if ((Object)(object)val2 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)val2, true);
			}
		}
		CustomDoorSound customDoorSound = doorObject.GetComponent<CustomDoorSound>();
		if ((Object)(object)customDoorSound == (Object)null)
		{
			customDoorSound = doorObject.AddComponent<CustomDoorSound>();
		}
		customDoorSound.Configure(customChildDoor.m_openEffects, customChildDoor.m_closeEffects);
		customChildDoor.SetDoorSound(customDoorSound);
		customChildDoor.InitializeAfterConfiguration();
		return customChildDoor;
	}

	private static void ConfigureCornerTowerDoors(GameObject prefab, ZNetView rootZNetView, AssetBundle bundle)
	{
		if ((Object)(object)prefab == (Object)null || (Object)(object)rootZNetView == (Object)null)
		{
			return;
		}
		ZNetView[] componentsInChildren = prefab.GetComponentsInChildren<ZNetView>(true);
		foreach (ZNetView val in componentsInChildren)
		{
			if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)rootZNetView)
			{
				Object.DestroyImmediate((Object)(object)val, true);
			}
		}
		GameObject val2 = (((Object)(object)bundle != (Object)null) ? bundle.LoadAsset<GameObject>("sfx_door_open") : null);
		GameObject val3 = (((Object)(object)bundle != (Object)null) ? bundle.LoadAsset<GameObject>("sfx_door_close") : null);
		if ((Object)(object)val2 == (Object)null)
		{
			Debug.LogWarning((object)"[DragonKeep] Missing Corner Tower door open SFX prefab: sfx_door_open");
		}
		if ((Object)(object)val3 == (Object)null)
		{
			Debug.LogWarning((object)"[DragonKeep] Missing Corner Tower door close SFX prefab: sfx_door_close");
		}
		string[] array = new string[2] { "Left_F", "Left_B" };
		string[] array2 = array;
		foreach (string text in array2)
		{
			Transform val4 = FindDeepChild(prefab.transform, text);
			if ((Object)(object)val4 == (Object)null)
			{
				Debug.LogWarning((object)("[DragonKeep] Corner Tower child door not found: " + text));
			}
			else
			{
				ConfigureChildDoor(((Component)val4).gameObject, rootZNetView, text, val2, val3);
			}
		}
	}

	private static EffectList CreateSingleEffectList(GameObject effectPrefab)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_002c: 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_0039: Expected O, but got Unknown
		EffectList val = new EffectList();
		if ((Object)(object)effectPrefab == (Object)null)
		{
			val.m_effectPrefabs = (EffectData[])(object)new EffectData[0];
			return val;
		}
		val.m_effectPrefabs = (EffectData[])(object)new EffectData[1]
		{
			new EffectData
			{
				m_prefab = effectPrefab
			}
		};
		return val;
	}

	private static GameObject GetRegisteredPrefab(string prefabName)
	{
		GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(prefabName) : null);
		if ((Object)(object)val == (Object)null && PrefabManager.Instance != null)
		{
			val = PrefabManager.Instance.GetPrefab(prefabName);
		}
		return val;
	}

	private static Transform FindDeepChild(Transform parent, string childName)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		if ((Object)(object)parent == (Object)null)
		{
			return null;
		}
		foreach (Transform item in parent)
		{
			Transform val = item;
			if (((Object)val).name == childName)
			{
				return val;
			}
			Transform val2 = FindDeepChild(val, childName);
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
		}
		return null;
	}
}
[HarmonyPatch(typeof(SE_Rested), "CalculateComfortLevel", new Type[]
{
	typeof(bool),
	typeof(Vector3)
})]
internal static class LargeDragonThroneComfortPatch
{
	private const string LargeThroneDisplayName = "Dragon Throne Large";

	private const float VanillaComfortRadius = 10f;

	private const float LargeThroneComfortRadius = 30f;

	private static readonly List<Piece> comfortPieces = new List<Piece>();

	private static void Postfix(bool inShelter, Vector3 position, ref int __result)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: 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)
		comfortPieces.Clear();
		Piece.GetAllComfortPiecesInRadius(position, 30f, comfortPieces);
		bool flag = false;
		bool flag2 = false;
		float num = 100f;
		foreach (Piece comfortPiece in comfortPieces)
		{
			if (!((Object)(object)comfortPiece == (Object)null) && comfortPiece.m_comfort > 0 && !(comfortPiece.m_name != "Dragon Throne Large"))
			{
				flag = true;
				Vector3 val = ((Component)comfortPiece).transform.position - position;
				if (((Vector3)(ref val)).sqrMagnitude <= num)
				{
					flag2 = true;
				}
			}
		}
		if (flag && !(inShelter && flag2))
		{
			__result++;
		}
	}
}
public static class RoofDoorAutoOpenerInstaller
{
	private const float AutoOpenRadius = 10f;

	private const float AutoCloseDelay = 7f;

	public static void Apply(GameObject roofDoorObject, ZNetView rootZNetView)
	{
		if (!((Object)(object)roofDoorObject == (Object)null))
		{
			RoofDoorAutoOpener roofDoorAutoOpener = roofDoorObject.GetComponent<RoofDoorAutoOpener>();
			if ((Object)(object)roofDoorAutoOpener == (Object)null)
			{
				roofDoorAutoOpener = roofDoorObject.AddComponent<RoofDoorAutoOpener>();
			}
			roofDoorAutoOpener.rootZNetView = rootZNetView;
			roofDoorAutoOpener.detectionRadius = 10f;
			roofDoorAutoOpener.closeDelay = 7f;
			roofDoorAutoOpener.customDoor = roofDoorObject.GetComponent<CustomChildDoor>();
			roofDoorAutoOpener.detectionPoint = FindDeepChild(roofDoorObject.transform, "Roof_Detection_Point");
			if ((Object)(object)roofDoorAutoOpener.detectionPoint == (Object)null)
			{
				roofDoorAutoOpener.detectionPoint = roofDoorObject.transform;
			}
		}
	}

	private static Transform FindDeepChild(Transform parent, string childName)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		if ((Object)(object)parent == (Object)null)
		{
			return null;
		}
		foreach (Transform item in parent)
		{
			Transform val = item;
			if (((Object)val).name == childName)
			{
				return val;
			}
			Transform val2 = FindDeepChild(val, childName);
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
		}
		return null;
	}
}
public class RoofDoorAutoOpener : MonoBehaviour
{
	public CustomChildDoor customDoor;

	public ZNetView rootZNetView;

	public Transform detectionPoint;

	public float detectionRadius = 10f;

	public float closeDelay = 7f;

	private const float CheckInterval = 0.25f;

	private float _nextCheckTime;

	private float _lastPlayerSeenTime = -999f;

	private bool _wantedOpen;

	private void Awake()
	{
		Refresh();
	}

	private void OnEnable()
	{
		Refresh();
	}

	private void Refresh()
	{
		if ((Object)(object)customDoor == (Object)null)
		{
			customDoor = ((Component)this).GetComponent<CustomChildDoor>();
		}
		if ((Object)(object)rootZNetView == (Object)null)
		{
			rootZNetView = ((Component)this).GetComponentInParent<ZNetView>();
		}
		if ((Object)(object)rootZNetView == (Object)null && (Object)(object)customDoor != (Object)null)
		{
			rootZNetView = customDoor.m_rootZNetView;
		}
		if ((Object)(object)detectionPoint == (Object)null)
		{
			detectionPoint = FindDeepChild(((Component)this).transform, "Roof_Detection_Point");
		}
		if ((Object)(object)detectionPoint == (Object)null)
		{
			detectionPoint = ((Component)this).transform;
		}
	}

	private void Update()
	{
		if (Time.time < _nextCheckTime)
		{
			return;
		}
		_nextCheckTime = Time.time + 0.25f;
		if ((Object)(object)customDoor == (Object)null || (Object)(object)rootZNetView == (Object)null || (Object)(object)detectionPoint == (Object)null)
		{
			Refresh();
		}
		if ((Object)(object)customDoor == (Object)null || (Object)(object)rootZNetView == (Object)null || !rootZNetView.IsValid() || rootZNetView.GetZDO() == null)
		{
			return;
		}
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null))
		{
			bool flag = IsPlayerNear(localPlayer);
			if (flag)
			{
				_lastPlayerSeenTime = Time.time;
			}
			bool flag2 = flag || Time.time - _lastPlayerSeenTime <= closeDelay;
			if (flag2 != _wantedOpen || IsDoorOpen() != flag2)
			{
				_wantedOpen = flag2;
				customDoor.AutoSetDoorState(flag2);
			}
		}
	}

	private bool IsPlayerNear(Player localPlayer)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: 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)
		if ((Object)(object)localPlayer == (Object)null)
		{
			return false;
		}
		Vector3 val = (((Object)(object)detectionPoint != (Object)null) ? detectionPoint.position : ((Component)this).transform.position);
		return Vector3.Distance(((Component)localPlayer).transform.position, val) <= detectionRadius;
	}

	private bool IsDoorOpen()
	{
		return GetDoorState() != 0;
	}

	private int GetDoorState()
	{
		if ((Object)(object)customDoor == (Object)null || (Object)(object)rootZNetView == (Object)null || !rootZNetView.IsValid() || rootZNetView.GetZDO() == null)
		{
			return 0;
		}
		return rootZNetView.GetZDO().GetInt(GetDoorStateKey(), 0);
	}

	private string GetDoorStateKey()
	{
		string text = (((Object)(object)customDoor != (Object)null && !string.IsNullOrEmpty(customDoor.m_doorID)) ? customDoor.m_doorID : "Roof_Door");
		return "CustomChildDoor_" + text + "_state";
	}

	private static Transform FindDeepChild(Transform parent, string childName)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		if ((Object)(object)parent == (Object)null)
		{
			return null;
		}
		foreach (Transform item in parent)
		{
			Transform val = item;
			if (((Object)val).name == childName)
			{
				return val;
			}
			Transform val2 = FindDeepChild(val, childName);
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
		}
		return null;
	}
}