Decompiled source of TuckMyChooksIn v1.1.1

plugins/TuckMyChooksIn.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TuckMyChooksIn")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+52e01f41167f74e9be2c5be814fc0ad6e10c7558")]
[assembly: AssemblyProduct("TuckMyChooksIn")]
[assembly: AssemblyTitle("TuckMyChooksIn")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace TuckMyChooksIn;

public class ChickenBed : MonoBehaviour, Hoverable, Interactable
{
	private struct HuddleInfo
	{
		public Character hen;

		public MonsterAI ai;
	}

	public static readonly List<ChickenBed> AllBeds = new List<ChickenBed>();

	public Transform m_spawnPoint;

	private ZNetView m_nview;

	private Coroutine m_tuckCoroutine;

	private float m_originalWalkSpeed;

	public static int s_pendingTucks = 0;

	private static readonly List<HuddleInfo> s_huddlers = new List<HuddleInfo>();

	public static float s_sleepBlockStart = 0f;

	public MonsterAI OccupantAI { get; set; }

	public Character Occupant { get; set; }

	public bool IsOccupied
	{
		get
		{
			if ((Object)(object)Occupant != (Object)null)
			{
				return (Object)(object)OccupantAI != (Object)null;
			}
			return false;
		}
	}

	internal static void AddHuddler(Character hen, MonsterAI ai, ChickenBed nearestBed)
	{
		s_huddlers.Add(new HuddleInfo
		{
			hen = hen,
			ai = ai
		});
		ai.SetFollowTarget(((Component)nearestBed).gameObject);
		((MonoBehaviour)nearestBed).StartCoroutine(nearestBed.HuddleAndSleep(hen, ai));
	}

	private IEnumerator HuddleAndSleep(Character hen, MonsterAI ai)
	{
		float timeout = 20f;
		float elapsed = 0f;
		while (elapsed < timeout)
		{
			if ((Object)(object)hen == (Object)null || (Object)(object)ai == (Object)null)
			{
				yield break;
			}
			if (Vector3.Distance(((Component)hen).transform.position, ((Component)this).transform.position) <= 3f)
			{
				break;
			}
			elapsed += Time.deltaTime;
			yield return null;
		}
		if ((Object)(object)hen == (Object)null || (Object)(object)ai == (Object)null)
		{
			yield break;
		}
		ZNetView component = ((Component)hen).GetComponent<ZNetView>();
		if ((Object)(object)component != (Object)null && component.IsValid())
		{
			Animator componentInChildren = ((Component)hen).GetComponentInChildren<Animator>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.SetBool("sleeping", true);
			}
			component.GetZDO().Set(ZDOVars.s_sleeping, true);
		}
		Plugin.Log.LogInfo((object)"Huddler settled near bed.");
	}

	private void Awake()
	{
		m_nview = ((Component)this).GetComponent<ZNetView>();
		if ((Object)(object)m_spawnPoint == (Object)null)
		{
			m_spawnPoint = ((Component)this).transform;
		}
		AllBeds.Add(this);
	}

	private void OnDestroy()
	{
		AllBeds.Remove(this);
	}

	public Vector3 GetSleepPoint()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		return m_spawnPoint.position;
	}

	public string GetHoverText()
	{
		if (IsOccupied)
		{
			return Occupant.GetHoverName() + " is tucked in <3";
		}
		return "Chicken Bed (vacant)";
	}

	public string GetHoverName()
	{
		return "Chicken Bed";
	}

	public bool Interact(Humanoid user, bool hold, bool alt)
	{
		if (hold)
		{
			return false;
		}
		if (IsOccupied)
		{
			((Character)user).Message((MessageType)2, "A chook is sleeping here!", 0, (Sprite)null);
		}
		else
		{
			((Character)user).Message((MessageType)2, "This chicken bed is vacant.", 0, (Sprite)null);
		}
		return false;
	}

	public bool UseItem(Humanoid user, ItemData item)
	{
		return false;
	}

	public void TuckIn(Character hen, MonsterAI ai)
	{
		Occupant = hen;
		OccupantAI = ai;
		if (!((Object)(object)hen == (Object)null) && !((Object)(object)ai == (Object)null))
		{
			if (s_pendingTucks == 0)
			{
				s_sleepBlockStart = Time.time;
			}
			s_pendingTucks++;
			m_tuckCoroutine = ((MonoBehaviour)this).StartCoroutine(WaitAndSleep(hen, ai));
		}
	}

	private IEnumerator WaitAndSleep(Character hen, MonsterAI ai)
	{
		m_originalWalkSpeed = hen.m_walkSpeed;
		hen.m_walkSpeed = hen.m_runSpeed * 2f;
		ai.SetFollowTarget(((Component)this).gameObject);
		float timeout = 20f;
		float elapsed = 0f;
		while (elapsed < timeout)
		{
			if ((Object)(object)hen == (Object)null || (Object)(object)ai == (Object)null)
			{
				yield break;
			}
			if (Vector3.Distance(((Component)hen).transform.position, ((Component)this).transform.position) <= 3f)
			{
				break;
			}
			elapsed += Time.deltaTime;
			yield return null;
		}
		if ((Object)(object)hen == (Object)null || (Object)(object)ai == (Object)null)
		{
			yield break;
		}
		hen.m_walkSpeed = m_originalWalkSpeed;
		ai.SetFollowTarget(((Component)this).gameObject);
		((Component)hen).transform.position = GetSleepPoint();
		((Component)hen).transform.rotation = m_spawnPoint.rotation;
		ZNetView component = ((Component)hen).GetComponent<ZNetView>();
		if ((Object)(object)component != (Object)null && component.IsValid())
		{
			Animator componentInChildren = ((Component)hen).GetComponentInChildren<Animator>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.SetBool("sleeping", true);
			}
			component.GetZDO().Set(ZDOVars.s_sleeping, true);
		}
		Plugin.Log.LogInfo((object)$"Chook tucked in at {GetSleepPoint()}!");
		s_pendingTucks = Mathf.Max(0, s_pendingTucks - 1);
		m_tuckCoroutine = null;
	}

	public void WakeUp()
	{
		if (m_tuckCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(m_tuckCoroutine);
			m_tuckCoroutine = null;
			s_pendingTucks = Mathf.Max(0, s_pendingTucks - 1);
			if ((Object)(object)Occupant != (Object)null)
			{
				Occupant.m_walkSpeed = m_originalWalkSpeed;
			}
		}
		if ((Object)(object)Occupant != (Object)null && (Object)(object)OccupantAI != (Object)null)
		{
			OccupantAI.SetFollowTarget((GameObject)null);
			ZNetView component = ((Component)Occupant).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid())
			{
				Animator componentInChildren = ((Component)Occupant).GetComponentInChildren<Animator>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.SetBool("sleeping", false);
				}
				component.GetZDO().Set(ZDOVars.s_sleeping, false);
			}
			Plugin.Log.LogInfo((object)"Chook woke up!");
		}
		Vacate();
	}

	public void Vacate()
	{
		Occupant = null;
		OccupantAI = null;
	}

	public static List<ChickenBed> GetVacantBeds()
	{
		List<ChickenBed> list = new List<ChickenBed>();
		foreach (ChickenBed allBed in AllBeds)
		{
			if ((Object)(object)allBed != (Object)null && !allBed.IsOccupied)
			{
				list.Add(allBed);
			}
		}
		return list;
	}

	public static void WakeAllChickens()
	{
		if (s_huddlers.Count <= 0 && !AllBeds.Exists((ChickenBed b) => (Object)(object)b != (Object)null && b.IsOccupied))
		{
			return;
		}
		foreach (ChickenBed allBed in AllBeds)
		{
			if ((Object)(object)allBed != (Object)null && allBed.IsOccupied)
			{
				allBed.WakeUp();
			}
		}
		foreach (HuddleInfo s_huddler in s_huddlers)
		{
			if ((Object)(object)s_huddler.hen == (Object)null || (Object)(object)s_huddler.ai == (Object)null)
			{
				continue;
			}
			s_huddler.ai.SetFollowTarget((GameObject)null);
			ZNetView component = ((Component)s_huddler.hen).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid())
			{
				Animator componentInChildren = ((Component)s_huddler.hen).GetComponentInChildren<Animator>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.SetBool("sleeping", false);
				}
				component.GetZDO().Set(ZDOVars.s_sleeping, false);
			}
		}
		s_huddlers.Clear();
	}
}
[HarmonyPatch(typeof(Player), "AttachStart")]
public static class PlayerAttachStartPatch
{
	private struct HenInfo
	{
		public Character character;

		public MonsterAI ai;
	}

	private static readonly HashSet<string> HenPrefabs = new HashSet<string> { "Hen", "Chicken", "hen", "chicken" };

	private static void Postfix(Player __instance, bool isBed)
	{
		if (isBed && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			Plugin.Log.LogInfo((object)"Player got into bed — time to tuck some chooks in!");
			TuckChickensIn();
		}
	}

	private static void TuckChickensIn()
	{
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Unknown result type (might be due to invalid IL or missing references)
		int num = ZNet.instance.GetNrOfPlayers();
		if (num < 1)
		{
			num = 1;
		}
		List<HenInfo> list = FindTamedHens();
		if (list.Count == 0)
		{
			Plugin.Log.LogInfo((object)"No tamed chooks found nearby.");
			return;
		}
		int num2 = Mathf.Max(1, Mathf.CeilToInt((float)list.Count / (float)num));
		int num3 = CountPlayersInBed();
		int num4 = Mathf.Min(list.Count, num2 * num3);
		int num5 = ChickenBed.AllBeds.Count((ChickenBed b) => (Object)(object)b != (Object)null && b.IsOccupied);
		int num6 = num4 - num5;
		if (num6 <= 0)
		{
			Plugin.Log.LogInfo((object)$"Already enough chooks tucked in ({num5}/{num4}).");
			return;
		}
		List<ChickenBed> vacantBeds = ChickenBed.GetVacantBeds();
		if (vacantBeds.Count == 0)
		{
			Plugin.Log.LogInfo((object)"No vacant chicken beds available!");
			return;
		}
		HashSet<Character> tuckedHens = new HashSet<Character>();
		foreach (ChickenBed allBed in ChickenBed.AllBeds)
		{
			if ((Object)(object)allBed != (Object)null && (Object)(object)allBed.Occupant != (Object)null)
			{
				tuckedHens.Add(allBed.Occupant);
			}
		}
		List<HenInfo> list2 = list.Where((HenInfo h) => !tuckedHens.Contains(h.character)).ToList();
		int num7 = 0;
		for (int i = 0; i < num6 && i < vacantBeds.Count && i < list2.Count; i++)
		{
			HenInfo henInfo = list2[i];
			ChickenBed chickenBed = FindClosestBed(((Component)henInfo.character).transform.position, vacantBeds);
			if ((Object)(object)chickenBed == (Object)null)
			{
				break;
			}
			vacantBeds.Remove(chickenBed);
			chickenBed.TuckIn(henInfo.character, henInfo.ai);
			num7++;
		}
		Plugin.Log.LogInfo((object)$"Tucked {num7} chooks into bed! (total: {num5 + num7}/{list.Count})");
		List<ChickenBed> list3 = ChickenBed.AllBeds.FindAll((ChickenBed b) => (Object)(object)b != (Object)null);
		if (list3.Count <= 0)
		{
			return;
		}
		int num8 = 0;
		for (int j = num7; j < list2.Count; j++)
		{
			HenInfo henInfo2 = list2[j];
			ChickenBed chickenBed2 = FindClosestBed(((Component)henInfo2.character).transform.position, list3);
			if (!((Object)(object)chickenBed2 == (Object)null))
			{
				ChickenBed.AddHuddler(henInfo2.character, henInfo2.ai, chickenBed2);
				num8++;
			}
		}
		if (num8 > 0)
		{
			Plugin.Log.LogInfo((object)$"Sent {num8} bedless chooks to huddle near the nearest bed.");
		}
	}

	private static List<HenInfo> FindTamedHens()
	{
		List<HenInfo> list = new List<HenInfo>();
		foreach (Character allCharacter in Character.GetAllCharacters())
		{
			if (!((Object)(object)allCharacter == (Object)null) && !allCharacter.IsPlayer() && allCharacter.IsTamed() && IsHenPrefab(((Object)((Component)allCharacter).gameObject).name))
			{
				MonsterAI component = ((Component)allCharacter).GetComponent<MonsterAI>();
				if (!((Object)(object)component == (Object)null))
				{
					list.Add(new HenInfo
					{
						character = allCharacter,
						ai = component
					});
				}
			}
		}
		return list;
	}

	private static bool IsHenPrefab(string name)
	{
		string text = name.ToLowerInvariant();
		if (!text.Contains("hen"))
		{
			return text.Contains("chicken");
		}
		return true;
	}

	private static int CountPlayersInBed()
	{
		int num = 0;
		foreach (ZDO allCharacterZDO in ZNet.instance.GetAllCharacterZDOS())
		{
			if (allCharacterZDO.GetBool(ZDOVars.s_inBed, false))
			{
				num++;
			}
		}
		return num;
	}

	private static ChickenBed FindClosestBed(Vector3 pos, List<ChickenBed> beds)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		ChickenBed result = null;
		float num = float.MaxValue;
		foreach (ChickenBed bed in beds)
		{
			if (!((Object)(object)bed == (Object)null))
			{
				float num2 = Vector3.Distance(pos, bed.GetSleepPoint());
				if (num2 < num)
				{
					num = num2;
					result = bed;
				}
			}
		}
		return result;
	}
}
[HarmonyPatch(typeof(Game), "EverybodyIsTryingToSleep")]
public static class GameEverybodyIsTryingSleepPatch
{
	private static bool Prepare()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Invalid comparison between Unknown and I4
		return (int)SystemInfo.graphicsDeviceType != 4;
	}

	private static void Postfix(ref bool __result)
	{
		if (__result && ChickenBed.s_pendingTucks > 0)
		{
			if (Time.time - ChickenBed.s_sleepBlockStart < 20f)
			{
				__result = false;
			}
			else
			{
				ChickenBed.s_pendingTucks = 0;
			}
		}
	}
}
[HarmonyPatch(typeof(Game), "SleepStop")]
public static class GameSleepStopPatch
{
	private static bool Prepare()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Invalid comparison between Unknown and I4
		return (int)SystemInfo.graphicsDeviceType != 4;
	}

	private static void Postfix()
	{
		Plugin.Log.LogInfo((object)"Morning! Waking up the chooks.");
		ChickenBed.WakeAllChickens();
	}
}
[HarmonyPatch(typeof(Player), "AttachStop")]
public static class PlayerAttachStopPatch
{
	private static void Postfix(Player __instance)
	{
		if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			Plugin.Log.LogInfo((object)"Player got out of bed — waking chooks.");
			ChickenBed.WakeAllChickens();
		}
	}
}
[BepInPlugin("tuckmychooksin", "TuckMyChooksIn", "1.1.1")]
public class Plugin : BaseUnityPlugin
{
	public const string PluginGUID = "tuckmychooksin";

	public const string PluginName = "TuckMyChooksIn";

	public const string PluginVersion = "1.1.1";

	internal static ManualLogSource Log;

	internal static Plugin Instance;

	private Harmony _harmony;

	private void Awake()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		Instance = this;
		_harmony = new Harmony("tuckmychooksin");
		_harmony.PatchAll();
		Log.LogInfo((object)"TuckMyChooksIn v1.1.1 loaded. Time to tuck those chooks in!");
	}

	private void OnDestroy()
	{
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}
}
[HarmonyPatch(typeof(ZNetScene), "OnDestroy")]
public static class ZNetSceneDestroyPatch
{
	private static void Prefix(ZNetScene __instance)
	{
		if ((Object)(object)PrefabSetup.s_prefabTemplate != (Object)null)
		{
			__instance.m_prefabs.Remove(PrefabSetup.s_prefabTemplate);
		}
	}
}
[HarmonyPatch(typeof(ZNetScene), "Awake")]
public static class PrefabSetup
{
	private const string ChickenBedName = "piece_chickenbed";

	private const float BedScale = 0.35f;

	internal static GameObject s_prefabTemplate;

	private static void Postfix(ZNetScene __instance)
	{
		CreateChickenBedPrefab(__instance);
	}

	private static void CreateChickenBedPrefab(ZNetScene zns)
	{
		//IL_00de: 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_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Expected O, but got Unknown
		if ((Object)(object)zns.GetPrefab("piece_chickenbed") != (Object)null)
		{
			return;
		}
		if ((Object)(object)s_prefabTemplate != (Object)null)
		{
			zns.m_prefabs.Add(s_prefabTemplate);
			Dictionary<int, GameObject> value = Traverse.Create((object)zns).Field("m_namedPrefabs").GetValue<Dictionary<int, GameObject>>();
			if (value != null)
			{
				value[StringExtensionMethods.GetStableHashCode("piece_chickenbed")] = s_prefabTemplate;
			}
			Plugin.Log.LogInfo((object)"Chicken bed re-registered with new ZNetScene.");
			return;
		}
		GameObject val = FindBedPrefab(zns);
		if ((Object)(object)val == (Object)null)
		{
			Plugin.Log.LogWarning((object)"Could not find a bed prefab to clone for the chicken bed!");
			return;
		}
		Plugin.Log.LogInfo((object)("Cloning bed prefab '" + ((Object)val).name + "' for chicken bed."));
		bool activeSelf = val.activeSelf;
		val.SetActive(false);
		GameObject val2 = Object.Instantiate<GameObject>(val);
		val.SetActive(activeSelf);
		((Object)val2).name = "piece_chickenbed";
		val2.transform.localScale = Vector3.one * 0.35f;
		Bed component = val2.GetComponent<Bed>();
		if ((Object)(object)component != (Object)null)
		{
			Transform spawnPoint = component.m_spawnPoint;
			Object.DestroyImmediate((Object)(object)component);
			val2.AddComponent<ChickenBed>().m_spawnPoint = spawnPoint;
		}
		else
		{
			val2.AddComponent<ChickenBed>();
		}
		Piece component2 = val2.GetComponent<Piece>();
		if ((Object)(object)component2 != (Object)null)
		{
			component2.m_name = "$piece_chickenbed";
			component2.m_description = "$piece_chickenbed_desc";
			component2.m_category = (PieceCategory)4;
			GameObject prefab = zns.GetPrefab("Wood");
			component2.m_resources = (Requirement[])(object)((!((Object)(object)prefab != (Object)null)) ? new Requirement[0] : new Requirement[1]
			{
				new Requirement
				{
					m_resItem = prefab.GetComponent<ItemDrop>(),
					m_amount = 1,
					m_recover = true
				}
			});
		}
		val2.SetActive(true);
		ZNetView component3 = val2.GetComponent<ZNetView>();
		if ((Object)(object)component3 != (Object)null)
		{
			ZDO zDO = component3.GetZDO();
			if (zDO != null)
			{
				component3.ResetZDO();
				Traverse.Create((object)zns).Field("m_instances").GetValue<Dictionary<ZDO, ZNetView>>()?.Remove(zDO);
				ZDOMan.instance.DestroyZDO(zDO);
				Plugin.Log.LogInfo((object)"Cleaned up spurious ZDO from chicken bed template.");
			}
		}
		ChickenBed component4 = val2.GetComponent<ChickenBed>();
		if ((Object)(object)component4 != (Object)null)
		{
			ChickenBed.AllBeds.Remove(component4);
		}
		zns.m_prefabs.Add(val2);
		Dictionary<int, GameObject> value2 = Traverse.Create((object)zns).Field("m_namedPrefabs").GetValue<Dictionary<int, GameObject>>();
		if (value2 != null)
		{
			value2[StringExtensionMethods.GetStableHashCode("piece_chickenbed")] = val2;
		}
		Object.DontDestroyOnLoad((Object)(object)val2);
		s_prefabTemplate = val2;
		AddToHammer(zns, val2);
		RegisterLocalization();
		Plugin.Log.LogInfo((object)"Chicken bed prefab created and registered!");
	}

	private static GameObject FindBedPrefab(ZNetScene zns)
	{
		string[] array = new string[3] { "bed", "piece_bed02", "piece_bed01" };
		foreach (string text in array)
		{
			GameObject prefab = zns.GetPrefab(text);
			if ((Object)(object)prefab != (Object)null)
			{
				return prefab;
			}
		}
		foreach (GameObject prefab2 in zns.m_prefabs)
		{
			if ((Object)(object)prefab2 != (Object)null && (Object)(object)prefab2.GetComponent<Bed>() != (Object)null)
			{
				return prefab2;
			}
		}
		return null;
	}

	private static void AddToHammer(ZNetScene zns, GameObject chickenBed)
	{
		GameObject prefab = zns.GetPrefab("Hammer");
		if ((Object)(object)prefab == (Object)null)
		{
			Plugin.Log.LogWarning((object)"Could not find Hammer prefab!");
			return;
		}
		ItemDrop component = prefab.GetComponent<ItemDrop>();
		if ((Object)(object)component == (Object)null)
		{
			Plugin.Log.LogWarning((object)"Hammer has no ItemDrop component!");
			return;
		}
		PieceTable buildPieces = component.m_itemData.m_shared.m_buildPieces;
		if ((Object)(object)buildPieces == (Object)null)
		{
			Plugin.Log.LogWarning((object)"Hammer has no PieceTable!");
			return;
		}
		buildPieces.m_pieces.Add(chickenBed);
		Plugin.Log.LogInfo((object)"Chicken bed added to hammer build menu.");
	}

	private static void RegisterLocalization()
	{
		Localization instance = Localization.instance;
		if (instance != null)
		{
			Dictionary<string, string> value = Traverse.Create((object)instance).Field("m_translations").GetValue<Dictionary<string, string>>();
			if (value == null)
			{
				Plugin.Log.LogWarning((object)"Could not access localisation translations.");
				return;
			}
			value["piece_chickenbed"] = "Chicken Bed";
			value["piece_chickenbed_desc"] = "A tiny bed for your chooks. They'll tuck themselves in when you go to sleep!";
		}
	}
}
[HarmonyPatch(typeof(Player), "OnSpawned")]
public static class PlayerSpawnPatch
{
	private static void Postfix(Player __instance)
	{
		Traverse.Create((object)__instance).Method("UpdateAvailablePiecesList", Array.Empty<object>()).GetValue();
	}
}