Decompiled source of WatchEgg v1.0.4

WatchEgg.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.SceneManagement;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("WatchEgg")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WatchEgg")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("217b75f9-9ff7-4920-8cee-9e5a99f9861d")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("Sapphire009.StaminaFull", "StaminaFull", "1.0.1")]
public sealed class StaminaFull : BaseUnityPlugin
{
	[HarmonyPatch(typeof(CharacterAfflictions), "AddStatus", new Type[]
	{
		typeof(STATUSTYPE),
		typeof(float),
		typeof(bool),
		typeof(bool),
		typeof(bool)
	})]
	private static class CharacterAfflictionsAddStatusPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE __0, float __1, bool __2, bool __3, bool __4, ref bool __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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 (__1 <= 0f || !CanApplyProtection(__instance))
			{
				return true;
			}
			__result = false;
			LogBlockedStatus(__0, __1, "AddStatus");
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterAfflictions), "AdjustStatus", new Type[]
	{
		typeof(STATUSTYPE),
		typeof(float),
		typeof(bool)
	})]
	private static class CharacterAfflictionsAdjustStatusPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE __0, float __1, bool __2)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (__1 <= 0f || !CanApplyProtection(__instance))
			{
				return true;
			}
			LogBlockedStatus(__0, __1, "AdjustStatus");
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterAfflictions), "SetStatus", new Type[]
	{
		typeof(STATUSTYPE),
		typeof(float),
		typeof(bool)
	})]
	private static class CharacterAfflictionsSetStatusPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE __0, float __1, bool __2)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (!CanApplyProtection(__instance))
			{
				return true;
			}
			float currentStatus = __instance.GetCurrentStatus(__0);
			if (__1 <= currentStatus)
			{
				return true;
			}
			LogBlockedStatus(__0, __1 - currentStatus, "SetStatus");
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterAfflictions), "AddAffliction", new Type[]
	{
		typeof(Affliction),
		typeof(bool)
	})]
	private static class CharacterAfflictionsAddAfflictionPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterAfflictions __instance, Affliction __0, bool __1)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			if (!CanApplyProtection(__instance))
			{
				return true;
			}
			if (blockedAfflictionLogCount < 50)
			{
				blockedAfflictionLogCount++;
				string text = ((__0 != null) ? ((object)__0).GetType().Name : "null");
				ManualLogSource modLogger = ModLogger;
				if (modLogger != null)
				{
					string[] obj = new string[7]
					{
						"[StaminaFull] Affliction blocked ",
						$"({blockedAfflictionLogCount}/",
						$"{50}). ",
						"Affliction=",
						text,
						", Scene=",
						null
					};
					Scene activeScene = SceneManager.GetActiveScene();
					obj[6] = ((Scene)(ref activeScene)).name;
					modLogger.LogInfo((object)string.Concat(obj));
				}
			}
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterAfflictions), "AddThorn", new Type[] { typeof(Vector3) })]
	private static class CharacterAfflictionsAddThornPositionPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterAfflictions __instance, Vector3 __0)
		{
			if (!CanApplyProtection(__instance))
			{
				return true;
			}
			LogBlockedThorn();
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterAfflictions), "AddThorn", new Type[] { typeof(ushort) })]
	private static class CharacterAfflictionsAddThornIndexPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterAfflictions __instance, ushort __0)
		{
			if (!CanApplyProtection(__instance))
			{
				return true;
			}
			LogBlockedThorn();
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterAfflictions), "RPC_EnableThorn", new Type[] { typeof(int) })]
	private static class CharacterAfflictionsEnableThornPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterAfflictions __instance, int __0)
		{
			if (!CanApplyProtection(__instance))
			{
				return true;
			}
			LogBlockedThorn();
			return false;
		}
	}

	[HarmonyPatch(typeof(Character), "FixedUpdate")]
	private static class CharacterFixedUpdatePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Character __instance)
		{
			if (CanApplyProtection(__instance))
			{
				ClearAllNegativeStates(__instance);
			}
		}
	}

	public const string PluginGUID = "Sapphire009.StaminaFull";

	public const string PluginName = "StaminaFull";

	public const string PluginVersion = "1.0.1";

	private const string BuildMarker = "StatusProtection-NormalStamina-R3";

	private const int MaximumLogCount = 50;

	internal static ManualLogSource ModLogger;

	private static int blockedStatusLogCount;

	private static int blockedAfflictionLogCount;

	private static int blockedThornLogCount;

	private Harmony harmony;

	private void Awake()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		ModLogger = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("Sapphire009.StaminaFull");
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"StaminaFull 1.0.1 loaded. Build: StatusProtection-NormalStamina-R3. Complete status protection is enabled outside Airport. Original stamina consumption remains enabled.");
	}

	private void OnDestroy()
	{
		blockedStatusLogCount = 0;
		blockedAfflictionLogCount = 0;
		blockedThornLogCount = 0;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
			harmony = null;
		}
		ModLogger = null;
	}

	internal static bool IsAirportScene()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		Scene activeScene = SceneManager.GetActiveScene();
		string name = ((Scene)(ref activeScene)).name;
		if (string.IsNullOrEmpty(name))
		{
			return false;
		}
		return name.IndexOf("Airport", StringComparison.OrdinalIgnoreCase) >= 0;
	}

	internal static bool CanApplyProtection(Character character)
	{
		if ((Object)(object)character == (Object)null || !character.IsLocal || (Object)(object)character.data == (Object)null || character.refs == null || (Object)(object)character.refs.afflictions == (Object)null)
		{
			return false;
		}
		if (IsAirportScene())
		{
			return false;
		}
		return true;
	}

	internal static bool CanApplyProtection(CharacterAfflictions afflictions)
	{
		if ((Object)(object)afflictions == (Object)null)
		{
			return false;
		}
		return CanApplyProtection(afflictions.character);
	}

	internal static void ClearAllNegativeStates(Character character)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		if (!CanApplyProtection(character))
		{
			return;
		}
		CharacterAfflictions afflictions = character.refs.afflictions;
		bool flag = false;
		int numStatusTypes = CharacterAfflictions.NumStatusTypes;
		for (int i = 0; i < numStatusTypes; i++)
		{
			STATUSTYPE val = (STATUSTYPE)i;
			if (!(afflictions.GetCurrentStatus(val) <= 0f))
			{
				afflictions.SetStatus(val, 0f, false);
				flag = true;
			}
		}
		if (afflictions.isWebbed)
		{
			afflictions.SetStatus((STATUSTYPE)11, 0f, false);
			afflictions.isWebbed = false;
			flag = true;
		}
		if (flag)
		{
			afflictions.PushStatuses((Player)null);
		}
		if (afflictions.afflictionList != null && afflictions.afflictionList.Count > 0)
		{
			afflictions.ClearAllAfflictions();
		}
		if (afflictions.physicalThorns == null)
		{
			return;
		}
		for (int num = afflictions.physicalThorns.Count - 1; num >= 0; num--)
		{
			ThornOnMe val2 = afflictions.physicalThorns[num];
			if (!((Object)(object)val2 == (Object)null) && val2.stuckIn)
			{
				afflictions.RemoveThorn(val2);
			}
		}
	}

	private static void LogBlockedStatus(STATUSTYPE statusType, float amount, string source)
	{
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: 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)
		if (blockedStatusLogCount < 50)
		{
			blockedStatusLogCount++;
			ManualLogSource modLogger = ModLogger;
			if (modLogger != null)
			{
				string[] obj = new string[9]
				{
					"[StaminaFull] Status blocked ",
					$"({blockedStatusLogCount}/",
					$"{50}). ",
					$"Status={statusType}, ",
					$"Amount={amount:0.0000}, ",
					"Source=",
					source,
					", Scene=",
					null
				};
				Scene activeScene = SceneManager.GetActiveScene();
				obj[8] = ((Scene)(ref activeScene)).name;
				modLogger.LogInfo((object)string.Concat(obj));
			}
		}
	}

	private static void LogBlockedThorn()
	{
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		if (blockedThornLogCount < 50)
		{
			blockedThornLogCount++;
			ManualLogSource modLogger = ModLogger;
			if (modLogger != null)
			{
				string[] obj = new string[5]
				{
					"[StaminaFull] Thorn blocked ",
					$"({blockedThornLogCount}/",
					$"{50}). ",
					"Scene=",
					null
				};
				Scene activeScene = SceneManager.GetActiveScene();
				obj[4] = ((Scene)(ref activeScene)).name;
				modLogger.LogInfo((object)string.Concat(obj));
			}
		}
	}
}
namespace Sapphire009.WatchEgg;

[HarmonyPatch(typeof(CharacterItems), "EquipSlot")]
public static class AutoDrop
{
	[HarmonyPatch(typeof(CharacterItems), "DropItemRpc")]
	private static class DropItemRpcPatch
	{
		[HarmonyPrefix]
		private unsafe static void Prefix(CharacterItems __instance, float throwCharge, byte slotID, Vector3 spawnPos)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			Character localCharacter = Character.localCharacter;
			string text = "null";
			bool flag = false;
			if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null && (Object)(object)localCharacter.data.currentItem != (Object)null)
			{
				Item currentItem = localCharacter.data.currentItem;
				text = ((Object)((Component)currentItem).gameObject).name;
				flag = IsNestEggName(text);
			}
			string[] obj = new string[10]
			{
				"DropItemRpc CALLED | SlotID=",
				slotID.ToString(),
				" | ThrowCharge=",
				throwCharge.ToString(),
				" | SpawnPosition=",
				null,
				null,
				null,
				null,
				null
			};
			Vector3 val = spawnPos;
			obj[5] = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString();
			obj[6] = " | CurrentItem=";
			obj[7] = text;
			obj[8] = " | IsNestEgg=";
			obj[9] = flag.ToString();
			LogWarning(string.Concat(obj));
		}
	}

	public const string DeveloperName = "Sapphire009";

	public const string TargetPrefabName = "NestEgg";

	private const string LogPrefix = "[AutoDrop] ";

	private static ManualLogSource logger;

	public static void SetLogger(ManualLogSource pluginLogger)
	{
		logger = pluginLogger;
		LogInfo("AutoDrop initialized. Target prefab: NestEgg");
	}

	[HarmonyPrepare]
	private static bool Prepare()
	{
		LogInfo("PATCH READY: CharacterItems.EquipSlot");
		return true;
	}

	[HarmonyPrefix]
	private static void Prefix(CharacterItems __instance, Optionable<byte> slotID)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		LogInfo("EquipSlot PREFIX entered. | RequestedSlot=" + FormatSlot(slotID));
		if ((Object)(object)__instance == (Object)null)
		{
			LogError("CharacterItems instance is null.");
			return;
		}
		Character localCharacter = Character.localCharacter;
		if ((Object)(object)localCharacter == (Object)null)
		{
			LogWarning("Character.localCharacter is null.");
			return;
		}
		if (localCharacter.refs == null || (Object)(object)localCharacter.refs.items == (Object)null)
		{
			LogWarning("Local CharacterItems reference is null.");
			return;
		}
		if ((Object)(object)localCharacter.refs.items != (Object)(object)__instance)
		{
			LogInfo("Non-local CharacterItems ignored.");
			return;
		}
		if ((Object)(object)localCharacter.data == (Object)null)
		{
			LogWarning("Character.data is null.");
			return;
		}
		if ((Object)(object)localCharacter.player == (Object)null)
		{
			LogWarning("Character.player is null.");
			return;
		}
		if (slotID.IsNone)
		{
			LogInfo("Requested slot is None. Ignored.");
			return;
		}
		if (__instance.currentSelectedSlot.IsNone)
		{
			LogWarning("CurrentSelectedSlot is None.");
			return;
		}
		byte value = __instance.currentSelectedSlot.Value;
		byte value2 = slotID.Value;
		if (value == value2)
		{
			LogInfo("Same slot selected. Ignored. | Slot=" + value);
			return;
		}
		Item currentItem = localCharacter.data.currentItem;
		if ((Object)(object)currentItem == (Object)null)
		{
			LogWarning("Current held Item is null.");
			return;
		}
		ItemSlot itemSlot = localCharacter.player.GetItemSlot(value);
		if (itemSlot == null)
		{
			LogError("Current ItemSlot is null. | SlotID=" + value);
			return;
		}
		string text = NormalizePrefabName(((Object)((Component)currentItem).gameObject).name);
		string text2 = (itemSlot.IsEmpty() ? string.Empty : NormalizePrefabName(itemSlot.GetPrefabName()));
		string text3 = ((currentItem.UIData != null) ? currentItem.UIData.itemName : "UIData null");
		bool flag = IsNestEggName(text);
		bool flag2 = IsNestEggName(text2);
		LogInfo("Detection result | CurrentSlot=" + value + " | RequestedSlot=" + value2 + " | HeldObject=" + text + " | SlotPrefab=" + text2 + " | UIItemName=" + text3 + " | HeldIsNestEgg=" + flag + " | SlotIsNestEgg=" + flag2);
		if (!flag && !flag2)
		{
			LogInfo("Current item is not NestEgg.");
			return;
		}
		if (currentItem.UIData == null)
		{
			LogError("NestEgg detected, but currentItem.UIData is null.");
			return;
		}
		bool canPocket = currentItem.UIData.canPocket;
		bool canDrop = currentItem.UIData.canDrop;
		currentItem.UIData.canPocket = false;
		currentItem.UIData.canDrop = true;
		Item prefab = itemSlot.prefab;
		if ((Object)(object)prefab != (Object)null && prefab.UIData != null)
		{
			prefab.UIData.canPocket = false;
			prefab.UIData.canDrop = true;
		}
		LogWarning("NEST EGG CONFIRMED. Auto-drop setting applied. | canPocket: " + canPocket + " -> " + currentItem.UIData.canPocket + " | canDrop: " + canDrop + " -> " + currentItem.UIData.canDrop);
	}

	[HarmonyPostfix]
	private static void Postfix(CharacterItems __instance, Optionable<byte> slotID)
	{
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		Character localCharacter = Character.localCharacter;
		string text = "null";
		if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null && (Object)(object)localCharacter.data.currentItem != (Object)null)
		{
			text = ((Object)((Component)localCharacter.data.currentItem).gameObject).name;
		}
		LogInfo("EquipSlot POSTFIX | RequestedSlot=" + FormatSlot(slotID) + " | CurrentItemAfter=" + text);
	}

	private static bool IsNestEggName(string objectName)
	{
		return string.Equals(NormalizePrefabName(objectName), "NestEgg", StringComparison.OrdinalIgnoreCase);
	}

	private static string NormalizePrefabName(string objectName)
	{
		if (string.IsNullOrEmpty(objectName))
		{
			return string.Empty;
		}
		string text = objectName.Trim();
		while (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase))
		{
			text = text.Substring(0, text.Length - "(Clone)".Length).Trim();
		}
		return text;
	}

	private static string FormatSlot(Optionable<byte> slotID)
	{
		if (slotID.IsSome)
		{
			return slotID.Value.ToString();
		}
		return "None";
	}

	private static void LogInfo(string message)
	{
		if (logger != null)
		{
			logger.LogInfo((object)("[AutoDrop] " + message));
		}
	}

	private static void LogWarning(string message)
	{
		if (logger != null)
		{
			logger.LogWarning((object)("[AutoDrop] " + message));
		}
	}

	private static void LogError(string message)
	{
		if (logger != null)
		{
			logger.LogError((object)("[AutoDrop] " + message));
		}
	}
}
[DisallowMultipleComponent]
public sealed class BrighteningEgg : MonoBehaviour
{
	[HarmonyPatch(typeof(Item), "Awake")]
	private static class ItemAwakePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Item __instance)
		{
			if (IsNestEgg(__instance) && !((Object)(object)((Component)__instance).GetComponent<BrighteningEgg>() != (Object)null))
			{
				((Component)__instance).gameObject.AddComponent<BrighteningEgg>();
			}
		}
	}

	public const string DeveloperName = "Sapphire009";

	public const string TargetPrefabName = "NestEgg";

	private const string LogPrefix = "[BrighteningEgg] ";

	private const float MaximumMarkerSize = 34f;

	private const float MinimumMarkerSize = 23f;

	private const float NearDistance = 4f;

	private const float FarDistance = 120f;

	private const float ScreenEdgeMargin = 40f;

	private const float BottomScreenMargin = 72f;

	private const float LabelWidth = 100f;

	private const float LabelHeight = 30f;

	private const float LabelSpacing = 3f;

	private const float BaseLightIntensity = 2.3f;

	private const float LightPulseAmount = 0.55f;

	private const float LightPulseSpeed = 2.2f;

	private const float LightRange = 4.5f;

	private const float CameraSearchInterval = 1f;

	private static readonly Color MarkerColor = new Color(1f, 0.72f, 0.08f, 1f);

	private static readonly Color MarkerCenterColor = new Color(1f, 0.95f, 0.45f, 1f);

	private static readonly Color LabelColor = new Color(1f, 0.86f, 0.2f, 1f);

	private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.BrighteningEgg");

	private static Texture2D circleTexture;

	private Item item;

	private GameObject lightObject;

	private Light eggLight;

	private Camera cachedCamera;

	private float nextCameraSearchTime;

	private GUIStyle labelStyle;

	private GUIStyle labelShadowStyle;

	private int cachedFontSize = -1;

	private void Awake()
	{
		item = ((Component)this).GetComponent<Item>();
		if (!IsNestEgg(item))
		{
			((Behaviour)this).enabled = false;
			return;
		}
		CreateCircleTexture();
		CreateEggLight();
		Logger.LogInfo((object)("[BrighteningEgg] Always-visible marker attached. | Object=" + ((Object)((Component)item).gameObject).name));
	}

	private void Update()
	{
		if (!((Object)(object)item == (Object)null))
		{
			UpdateEggLight();
		}
	}

	private void OnGUI()
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: 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_008b: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		if (!((Behaviour)this).enabled || (Object)(object)item == (Object)null || !((Component)this).gameObject.activeInHierarchy || IsHeldByLocalPlayer())
		{
			return;
		}
		Camera viewCamera = GetViewCamera();
		if (!((Object)(object)viewCamera == (Object)null))
		{
			Vector3 val = CalculateWorldMarkerPosition();
			Vector3 val2 = viewCamera.WorldToScreenPoint(val);
			if (!(val2.z <= 0f))
			{
				float x = val2.x;
				float num = (float)Screen.height - val2.y;
				x = Mathf.Clamp(x, 40f, (float)Screen.width - 40f);
				num = Mathf.Clamp(num, 40f, (float)Screen.height - 72f);
				float num2 = Vector3.Distance(((Component)viewCamera).transform.position, val);
				float num3 = Mathf.InverseLerp(4f, 120f, num2);
				float markerSize = Mathf.Lerp(34f, 23f, num3);
				DrawMarker(x, num, markerSize);
				DrawEggLabel(x, num, markerSize);
			}
		}
	}

	private static void DrawMarker(float centerX, float centerY, float markerSize)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)circleTexture == (Object)null))
		{
			Color color = GUI.color;
			float num = markerSize + 7f;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(centerX - num * 0.5f, centerY - num * 0.5f, num, num);
			GUI.color = new Color(0f, 0f, 0f, 0.88f);
			GUI.DrawTexture(val, (Texture)(object)circleTexture, (ScaleMode)0, true);
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(centerX - markerSize * 0.5f, centerY - markerSize * 0.5f, markerSize, markerSize);
			GUI.color = MarkerColor;
			GUI.DrawTexture(val2, (Texture)(object)circleTexture, (ScaleMode)0, true);
			float num2 = markerSize * 0.35f;
			Rect val3 = default(Rect);
			((Rect)(ref val3))..ctor(centerX - num2 * 0.5f, centerY - num2 * 0.5f, num2, num2);
			GUI.color = MarkerCenterColor;
			GUI.DrawTexture(val3, (Texture)(object)circleTexture, (ScaleMode)0, true);
			GUI.color = color;
		}
	}

	private void DrawEggLabel(float centerX, float centerY, float markerSize)
	{
		//IL_0051: 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_0075: 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_0098: Unknown result type (might be due to invalid IL or missing references)
		int fontSize = Mathf.RoundToInt(Mathf.Clamp(markerSize * 0.68f, 16f, 23f));
		PrepareLabelStyles(fontSize);
		float num = centerX - 50f;
		float num2 = centerY + markerSize * 0.5f + 3f;
		Rect val = default(Rect);
		((Rect)(ref val))..ctor(num, num2, 100f, 30f);
		DrawLabelShadow(val, -2f, 0f);
		DrawLabelShadow(val, 2f, 0f);
		DrawLabelShadow(val, 0f, -2f);
		DrawLabelShadow(val, 0f, 2f);
		GUI.Label(val, "Egg", labelStyle);
	}

	private void DrawLabelShadow(Rect originalRect, float offsetX, float offsetY)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		Rect val = default(Rect);
		((Rect)(ref val))..ctor(((Rect)(ref originalRect)).x + offsetX, ((Rect)(ref originalRect)).y + offsetY, ((Rect)(ref originalRect)).width, ((Rect)(ref originalRect)).height);
		GUI.Label(val, "Egg", labelShadowStyle);
	}

	private void PrepareLabelStyles(int fontSize)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		//IL_008f: 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_00ab: Expected O, but got Unknown
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		if (labelStyle == null || labelShadowStyle == null || cachedFontSize != fontSize)
		{
			cachedFontSize = fontSize;
			labelStyle = new GUIStyle(GUI.skin.label);
			labelStyle.alignment = (TextAnchor)1;
			labelStyle.fontSize = fontSize;
			labelStyle.fontStyle = (FontStyle)1;
			labelStyle.wordWrap = false;
			labelStyle.clipping = (TextClipping)0;
			labelStyle.normal.textColor = LabelColor;
			labelShadowStyle = new GUIStyle(labelStyle);
			labelShadowStyle.normal.textColor = new Color(0f, 0f, 0f, 1f);
		}
	}

	private Camera GetViewCamera()
	{
		if ((Object)(object)cachedCamera != (Object)null && ((Behaviour)cachedCamera).isActiveAndEnabled)
		{
			return cachedCamera;
		}
		if (Time.unscaledTime < nextCameraSearchTime)
		{
			return null;
		}
		nextCameraSearchTime = Time.unscaledTime + 1f;
		Camera main = Camera.main;
		if ((Object)(object)main != (Object)null && ((Behaviour)main).isActiveAndEnabled)
		{
			cachedCamera = main;
			return cachedCamera;
		}
		Camera[] allCameras = Camera.allCameras;
		foreach (Camera val in allCameras)
		{
			if (!((Object)(object)val == (Object)null) && ((Behaviour)val).isActiveAndEnabled)
			{
				cachedCamera = val;
				return cachedCamera;
			}
		}
		return null;
	}

	private Vector3 CalculateWorldMarkerPosition()
	{
		//IL_000d: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: 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_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//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_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
		bool flag = false;
		Bounds val = default(Bounds);
		foreach (Renderer val2 in componentsInChildren)
		{
			if ((Object)(object)val2 == (Object)null || !val2.enabled)
			{
				continue;
			}
			Bounds bounds = val2.bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			if (!(((Vector3)(ref size)).sqrMagnitude <= 0.0001f))
			{
				if (!flag)
				{
					val = bounds;
					flag = true;
				}
				else
				{
					((Bounds)(ref val)).Encapsulate(bounds);
				}
			}
		}
		if (!flag)
		{
			return ((Component)this).transform.position + Vector3.up * 0.65f;
		}
		float num = Mathf.Clamp(((Bounds)(ref val)).extents.y * 0.35f, 0.12f, 0.45f);
		return new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).max.y + num, ((Bounds)(ref val)).center.z);
	}

	private void CreateEggLight()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		lightObject = new GameObject("WatchEgg_NestEgg_AlwaysLight");
		lightObject.transform.SetParent(((Component)this).transform, false);
		lightObject.transform.localPosition = CalculateLightLocalPosition();
		lightObject.transform.localRotation = Quaternion.identity;
		eggLight = lightObject.AddComponent<Light>();
		eggLight.type = (LightType)2;
		eggLight.color = MarkerColor;
		eggLight.intensity = 2.3f;
		eggLight.range = 4.5f;
		eggLight.shadows = (LightShadows)0;
		eggLight.renderMode = (LightRenderMode)0;
		eggLight.bounceIntensity = 0f;
	}

	private void UpdateEggLight()
	{
		if (!((Object)(object)eggLight == (Object)null) && !((Object)(object)lightObject == (Object)null))
		{
			if (!lightObject.activeSelf)
			{
				lightObject.SetActive(true);
			}
			float num = (Mathf.Sin(Time.unscaledTime * 2.2f) + 1f) * 0.5f;
			eggLight.intensity = 2.3f + num * 0.55f;
		}
	}

	private Vector3 CalculateLightLocalPosition()
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: 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)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: 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_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
		if (componentsInChildren == null || componentsInChildren.Length == 0)
		{
			return Vector3.zero;
		}
		bool flag = false;
		Bounds val = default(Bounds);
		foreach (Renderer val2 in componentsInChildren)
		{
			if ((Object)(object)val2 == (Object)null || !val2.enabled)
			{
				continue;
			}
			Bounds bounds = val2.bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			if (!(((Vector3)(ref size)).sqrMagnitude <= 0.0001f))
			{
				if (!flag)
				{
					val = bounds;
					flag = true;
				}
				else
				{
					((Bounds)(ref val)).Encapsulate(bounds);
				}
			}
		}
		if (!flag)
		{
			return Vector3.zero;
		}
		return ((Component)this).transform.InverseTransformPoint(((Bounds)(ref val)).center);
	}

	private bool IsHeldByLocalPlayer()
	{
		Character localCharacter = Character.localCharacter;
		if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null)
		{
			return false;
		}
		return localCharacter.IsLocal && (Object)(object)localCharacter.data.currentItem == (Object)(object)item;
	}

	private static void CreateCircleTexture()
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)circleTexture != (Object)null)
		{
			return;
		}
		circleTexture = new Texture2D(64, 64, (TextureFormat)4, false);
		((Object)circleTexture).name = "WatchEgg_AlwaysVisibleCircle";
		((Texture)circleTexture).wrapMode = (TextureWrapMode)1;
		((Texture)circleTexture).filterMode = (FilterMode)1;
		((Object)circleTexture).hideFlags = (HideFlags)61;
		Color[] array = (Color[])(object)new Color[4096];
		Vector2 val = default(Vector2);
		((Vector2)(ref val))..ctor(31.5f, 31.5f);
		float num = 30.08f;
		for (int i = 0; i < 64; i++)
		{
			for (int j = 0; j < 64; j++)
			{
				float num2 = Vector2.Distance(new Vector2((float)j, (float)i), val);
				float num3 = Mathf.Clamp01((num - num2) * 0.8f);
				array[i * 64 + j] = new Color(1f, 1f, 1f, num3);
			}
		}
		circleTexture.SetPixels(array);
		circleTexture.Apply(false, true);
	}

	private void OnDestroy()
	{
		if ((Object)(object)lightObject != (Object)null)
		{
			Object.Destroy((Object)(object)lightObject);
			lightObject = null;
		}
		eggLight = null;
		cachedCamera = null;
	}

	public static bool IsNestEgg(Item targetItem)
	{
		if ((Object)(object)targetItem == (Object)null)
		{
			return false;
		}
		return IsNestEggName(((Object)((Component)targetItem).gameObject).name);
	}

	public static bool IsNestEggName(string objectName)
	{
		return string.Equals(NormalizePrefabName(objectName), "NestEgg", StringComparison.OrdinalIgnoreCase);
	}

	private static string NormalizePrefabName(string objectName)
	{
		if (string.IsNullOrEmpty(objectName))
		{
			return string.Empty;
		}
		string text = objectName.Trim();
		while (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase))
		{
			text = text.Substring(0, text.Length - "(Clone)".Length).Trim();
		}
		return text;
	}
}
[DisallowMultipleComponent]
public sealed class CountUI : MonoBehaviour
{
	[HarmonyPatch(typeof(CharacterSpawner), "Update")]
	private static class CharacterSpawnerUpdatePatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			EnsureCountUIExists();
		}
	}

	public const string DeveloperName = "Sapphire009";

	private const string LogPrefix = "[CountUI] ";

	private const float ReferenceScreenHeight = 1080f;

	private const float ReferenceWidth = 360f;

	private const float ReferenceHeight = 48f;

	private const float ReferenceBottomMargin = 115f;

	private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.CountUI");

	private static CountUI instance;

	private GUIStyle textStyle;

	private GUIStyle shadowStyle;

	private int cachedFontSize = -1;

	private void Awake()
	{
		if ((Object)(object)instance != (Object)null && (Object)(object)instance != (Object)(object)this)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		instance = this;
		Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		Logger.LogInfo((object)"[CountUI] Broken egg counter UI created.");
	}

	private void OnDestroy()
	{
		if ((Object)(object)instance == (Object)(object)this)
		{
			instance = null;
		}
	}

	private void OnGUI()
	{
		//IL_00c2: 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)
		if (ShouldDisplay())
		{
			PrepareStyles();
			float num = Mathf.Clamp((float)Screen.height / 1080f, 0.75f, 1.5f);
			float num2 = 360f * num;
			float num3 = 48f * num;
			float num4 = ((float)Screen.width - num2) * 0.5f;
			float num5 = (float)Screen.height - 115f * num - num3;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(num4, num5, num2, num3);
			string text = "BROKEN EGGS : " + EggCheckpoint.BrokenEggCount;
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 2f * num, ((Rect)(ref val)).y + 2f * num, ((Rect)(ref val)).width, ((Rect)(ref val)).height);
			GUI.Label(val2, text, shadowStyle);
			GUI.Label(val, text, textStyle);
		}
	}

	private static bool ShouldDisplay()
	{
		Character localCharacter = Character.localCharacter;
		if ((Object)(object)localCharacter == (Object)null || !localCharacter.IsLocal)
		{
			return false;
		}
		if (!EggCheckpoint.HasCheckpoint && EggCheckpoint.BrokenEggCount <= 0)
		{
			return false;
		}
		return true;
	}

	private void PrepareStyles()
	{
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Expected O, but got Unknown
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Expected O, but got Unknown
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		int num = Mathf.RoundToInt(Mathf.Clamp((float)Screen.height / 1080f * 26f, 19f, 34f));
		if (textStyle == null || shadowStyle == null || cachedFontSize != num)
		{
			cachedFontSize = num;
			textStyle = new GUIStyle(GUI.skin.label);
			textStyle.alignment = (TextAnchor)4;
			textStyle.fontSize = num;
			textStyle.fontStyle = (FontStyle)1;
			textStyle.normal.textColor = Color.white;
			textStyle.wordWrap = false;
			textStyle.clipping = (TextClipping)0;
			shadowStyle = new GUIStyle(textStyle);
			shadowStyle.normal.textColor = new Color(0f, 0f, 0f, 0.9f);
		}
	}

	private static void EnsureCountUIExists()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		if (!((Object)(object)instance != (Object)null))
		{
			GameObject val = new GameObject("WatchEgg_BrokenEgg_CountUI");
			val.AddComponent<CountUI>();
		}
	}
}
[DisallowMultipleComponent]
public sealed class EggCheckpoint : MonoBehaviour
{
	[HarmonyPatch(typeof(Item), "Awake")]
	private static class ItemAwakePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Item __instance)
		{
			if (IsNestEgg(__instance) && !((Object)(object)((Component)__instance).GetComponent<EggCheckpoint>() != (Object)null))
			{
				((Component)__instance).gameObject.AddComponent<EggCheckpoint>();
			}
		}
	}

	[HarmonyPatch(typeof(Breakable), "Break")]
	private static class BreakableBreakPatch
	{
		[HarmonyPrefix]
		private static void Prefix(Breakable __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			Item val = ((Component)__instance).GetComponent<Item>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)__instance).GetComponentInParent<Item>();
			}
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)__instance).GetComponentInChildren<Item>(true);
			}
			if (IsNestEgg(val))
			{
				int item = ((!((Object)(object)((MonoBehaviourPun)val).photonView != (Object)null) || ((MonoBehaviourPun)val).photonView.ViewID <= 0) ? ((Object)((Component)val).gameObject).GetInstanceID() : ((MonoBehaviourPun)val).photonView.ViewID);
				if (!CountedBrokenViewIds.Contains(item))
				{
					CountedBrokenViewIds.Add(item);
					BrokenEggCount++;
					Logger.LogWarning((object)("[EggCheckpoint] NestEgg broken. | BrokenCount=" + BrokenEggCount + " | EggID=" + item));
				}
			}
		}
	}

	public const string DeveloperName = "Sapphire009";

	public const string TargetPrefabName = "NestEgg";

	public const float TargetCheckpointDistance = 50f;

	private const float TargetCheckpointDistanceSquared = 2500f;

	private const float MinimumGroundNormalY = 0.55f;

	private const float GroundCastStartHeight = 2.5f;

	private const float GroundCastDistance = 6f;

	private const float InitialGroundCastDistance = 12f;

	private const float GroundCastRadius = 0.18f;

	private const float GroundSurfacePadding = 0.015f;

	private const float MaximumEggGroundDistanceFromHolder = 1.6f;

	private const string LogPrefix = "[EggCheckpoint] ";

	private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.EggCheckpoint");

	private static readonly HashSet<int> CountedBrokenViewIds = new HashSet<int>();

	private static int activeSceneHandle = int.MinValue;

	private Item item;

	private Quaternion eggRestRotation;

	private float pivotToEggBottom = 0.2f;

	public static bool HasCheckpoint { get; private set; }

	public static Vector3 CheckpointPosition { get; private set; }

	public static Quaternion CheckpointRotation { get; private set; }

	public static int CheckpointNumber { get; private set; }

	public static int BrokenEggCount { get; private set; }

	public static float DistanceFromLastCheckpoint { get; private set; }

	private void Awake()
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		ResetStaticDataWhenSceneChanged();
		item = ((Component)this).GetComponent<Item>();
		if (!IsNestEgg(item))
		{
			((Behaviour)this).enabled = false;
			return;
		}
		eggRestRotation = ((Component)this).transform.rotation;
		CacheEggBottomOffset();
		CacheInitialCheckpoint();
		Logger.LogInfo((object)("[EggCheckpoint] Attached to " + ((Object)((Component)item).gameObject).name + " | Radius=" + 50f + " | DistanceMode=EggToCheckpoint3DSphere | MustBeHeld=True"));
	}

	private void Update()
	{
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Invalid comparison between Unknown and I4
		//IL_00f1: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		ResetStaticDataWhenSceneChanged();
		if ((Object)(object)item == (Object)null)
		{
			return;
		}
		if (!HasCheckpoint)
		{
			CacheInitialCheckpoint();
			if (!HasCheckpoint)
			{
				DistanceFromLastCheckpoint = 0f;
				return;
			}
		}
		Vector3 val = ((Component)this).transform.position - CheckpointPosition;
		float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
		DistanceFromLastCheckpoint = Mathf.Sqrt(sqrMagnitude);
		if (sqrMagnitude < 2500f || (int)item.itemState != 1 || (Object)(object)item.holderCharacter == (Object)null)
		{
			return;
		}
		Character holderCharacter = item.holderCharacter;
		if (IsHolderOnSafeGround(holderCharacter) && TryGetSafeHeldEggPosition(holderCharacter, out var result))
		{
			Vector3 val2 = result - CheckpointPosition;
			if (!(((Vector3)(ref val2)).sqrMagnitude < 2500f))
			{
				SaveCheckpoint(result);
			}
		}
	}

	private bool TryGetSafeHeldEggPosition(Character holder, out Vector3 result)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//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_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: 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_008c: 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)
		result = Vector3.zero;
		if (!IsHolderOnSafeGround(holder))
		{
			return false;
		}
		if (TryCastGroundBelowHeldEgg(holder, out var groundHit))
		{
			result = ((RaycastHit)(ref groundHit)).point + Vector3.up * (pivotToEggBottom + 0.015f);
			return true;
		}
		if (!TryCastGroundAtHolder(holder, out groundHit))
		{
			return false;
		}
		result = ((RaycastHit)(ref groundHit)).point + Vector3.up * (pivotToEggBottom + 0.015f);
		return true;
	}

	private static bool IsHolderOnSafeGround(Character holder)
	{
		if ((Object)(object)holder == (Object)null || (Object)(object)holder.data == (Object)null)
		{
			return false;
		}
		if (!holder.data.isGrounded)
		{
			return false;
		}
		if (holder.data.isClimbing || holder.data.isRopeClimbing || holder.data.isVineClimbing)
		{
			return false;
		}
		if (holder.data.dead || holder.data.fullyPassedOut)
		{
			return false;
		}
		if (holder.data.groundNormal.y < 0.55f)
		{
			return false;
		}
		return true;
	}

	private bool TryCastGroundBelowHeldEgg(Character holder, out RaycastHit groundHit)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: 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)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: 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_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		groundHit = default(RaycastHit);
		if ((Object)(object)holder == (Object)null || (Object)(object)holder.data == (Object)null)
		{
			return false;
		}
		Vector3 groundPos = holder.data.groundPos;
		Vector3 val = default(Vector3);
		((Vector3)(ref val))..ctor(((Component)this).transform.position.x, groundPos.y + 2.5f, ((Component)this).transform.position.z);
		if (!Physics.SphereCast(val, 0.18f, Vector3.down, ref groundHit, 6f, LayerMask.op_Implicit(HelperFunctions.GetMask((LayerType)1)), (QueryTriggerInteraction)1))
		{
			return false;
		}
		if (((RaycastHit)(ref groundHit)).normal.y < 0.55f)
		{
			return false;
		}
		Vector3 val2 = ((RaycastHit)(ref groundHit)).point - groundPos;
		val2.y = 0f;
		return ((Vector3)(ref val2)).sqrMagnitude <= 2.5600002f;
	}

	private static bool TryCastGroundAtHolder(Character holder, out RaycastHit groundHit)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: 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)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		groundHit = default(RaycastHit);
		if ((Object)(object)holder == (Object)null || (Object)(object)holder.data == (Object)null)
		{
			return false;
		}
		Vector3 val = holder.data.groundPos + Vector3.up * 2.5f;
		if (!Physics.SphereCast(val, 0.18f, Vector3.down, ref groundHit, 6f, LayerMask.op_Implicit(HelperFunctions.GetMask((LayerType)1)), (QueryTriggerInteraction)1))
		{
			return false;
		}
		return ((RaycastHit)(ref groundHit)).normal.y >= 0.55f;
	}

	private bool TryGetGroundPositionBelowEgg(float castDistance, out Vector3 result)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: 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_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: 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)
		//IL_002b: 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_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: 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)
		result = Vector3.zero;
		Vector3 val = ((Component)this).transform.position + Vector3.up * 2.5f;
		RaycastHit val2 = default(RaycastHit);
		if (!Physics.SphereCast(val, 0.18f, Vector3.down, ref val2, castDistance, LayerMask.op_Implicit(HelperFunctions.GetMask((LayerType)1)), (QueryTriggerInteraction)1))
		{
			return false;
		}
		if (((RaycastHit)(ref val2)).normal.y < 0.55f)
		{
			return false;
		}
		result = ((RaycastHit)(ref val2)).point + Vector3.up * (pivotToEggBottom + 0.015f);
		return true;
	}

	private unsafe void SaveCheckpoint(Vector3 newCheckpointPosition)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: 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)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		Vector3 checkpointPosition = CheckpointPosition;
		float num = Vector3.Distance(checkpointPosition, newCheckpointPosition);
		CheckpointPosition = newCheckpointPosition;
		CheckpointRotation = eggRestRotation;
		HasCheckpoint = true;
		CheckpointNumber++;
		DistanceFromLastCheckpoint = 0f;
		ManualLogSource logger = Logger;
		string[] obj = new string[10]
		{
			"[EggCheckpoint] New held-egg checkpoint saved. | Number=",
			CheckpointNumber.ToString(),
			" | Distance=",
			num.ToString(),
			" | PreviousPosition=",
			null,
			null,
			null,
			null,
			null
		};
		Vector3 val = checkpointPosition;
		obj[5] = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString();
		obj[6] = " | NewPosition=";
		obj[7] = ((object)CheckpointPosition/*cast due to .constrained prefix*/).ToString();
		obj[8] = " | Holder=";
		obj[9] = GetCharacterName(((Object)(object)item != (Object)null) ? item.holderCharacter : null);
		logger.LogWarning((object)string.Concat(obj));
	}

	private void CacheInitialCheckpoint()
	{
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: 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)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Invalid comparison between Unknown and I4
		if (!HasCheckpoint && (TryGetGroundPositionBelowEgg(12f, out var result) || ((Object)(object)item != (Object)null && (int)item.itemState == 1 && (Object)(object)item.holderCharacter != (Object)null && TryGetSafeHeldEggPosition(item.holderCharacter, out result))))
		{
			CheckpointPosition = result;
			CheckpointRotation = eggRestRotation;
			HasCheckpoint = true;
			CheckpointNumber = 1;
			DistanceFromLastCheckpoint = 0f;
			Logger.LogWarning((object)("[EggCheckpoint] Initial checkpoint cached. | Position=" + ((object)CheckpointPosition/*cast due to .constrained prefix*/).ToString()));
		}
	}

	private void CacheEggBottomOffset()
	{
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: 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_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//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_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: 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_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true);
		float num = float.PositiveInfinity;
		bool flag = false;
		Vector3 size;
		foreach (Collider val in componentsInChildren)
		{
			if ((Object)(object)val == (Object)null || !val.enabled || val.isTrigger)
			{
				continue;
			}
			Bounds bounds = val.bounds;
			size = ((Bounds)(ref bounds)).size;
			if (!(((Vector3)(ref size)).sqrMagnitude <= 0.0001f))
			{
				if (((Bounds)(ref bounds)).min.y < num)
				{
					num = ((Bounds)(ref bounds)).min.y;
				}
				flag = true;
			}
		}
		if (!flag)
		{
			Renderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren2)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				Bounds bounds2 = val2.bounds;
				size = ((Bounds)(ref bounds2)).size;
				if (!(((Vector3)(ref size)).sqrMagnitude <= 0.0001f))
				{
					if (((Bounds)(ref bounds2)).min.y < num)
					{
						num = ((Bounds)(ref bounds2)).min.y;
					}
					flag = true;
				}
			}
		}
		if (!flag)
		{
			pivotToEggBottom = 0.2f;
			return;
		}
		float num2 = ((Component)this).transform.position.y - num;
		if (num2 <= 0.01f || num2 >= 3f)
		{
			pivotToEggBottom = 0.2f;
		}
		else
		{
			pivotToEggBottom = num2;
		}
	}

	public static bool TryGetCheckpoint(out Vector3 position, out Quaternion rotation)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: 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)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		position = CheckpointPosition;
		rotation = CheckpointRotation;
		return HasCheckpoint;
	}

	public static void ResetCheckpoint()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		HasCheckpoint = false;
		CheckpointPosition = Vector3.zero;
		CheckpointRotation = Quaternion.identity;
		CheckpointNumber = 0;
		BrokenEggCount = 0;
		DistanceFromLastCheckpoint = 0f;
		CountedBrokenViewIds.Clear();
	}

	private static void ResetStaticDataWhenSceneChanged()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		Scene activeScene = SceneManager.GetActiveScene();
		if (activeSceneHandle != ((Scene)(ref activeScene)).handle)
		{
			activeSceneHandle = ((Scene)(ref activeScene)).handle;
			ResetCheckpoint();
			Logger.LogInfo((object)("[EggCheckpoint] Scene changed. Checkpoint data reset. | Scene=" + ((Scene)(ref activeScene)).name));
		}
	}

	public static bool IsNestEgg(Item targetItem)
	{
		if ((Object)(object)targetItem == (Object)null)
		{
			return false;
		}
		return IsNestEggName(((Object)((Component)targetItem).gameObject).name);
	}

	public static bool IsNestEggName(string objectName)
	{
		return string.Equals(NormalizePrefabName(objectName), "NestEgg", StringComparison.OrdinalIgnoreCase);
	}

	private static string NormalizePrefabName(string objectName)
	{
		if (string.IsNullOrEmpty(objectName))
		{
			return string.Empty;
		}
		string text = objectName.Trim();
		while (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase))
		{
			text = text.Substring(0, text.Length - "(Clone)".Length);
			text = text.Trim();
		}
		return text;
	}

	private static string GetCharacterName(Character character)
	{
		if ((Object)(object)character == (Object)null)
		{
			return "Unknown";
		}
		if ((Object)(object)((MonoBehaviourPun)character).photonView != (Object)null && ((MonoBehaviourPun)character).photonView.Owner != null && !string.IsNullOrEmpty(((MonoBehaviourPun)character).photonView.Owner.NickName))
		{
			return ((MonoBehaviourPun)character).photonView.Owner.NickName;
		}
		return ((Object)((Component)character).gameObject).name;
	}
}
internal static class Magma
{
	internal const string DeveloperName = "Sapphire009";

	private const float ProtectionBypassDuration = 1.25f;

	private static Character activeLavaCharacter;

	private static float protectionBypassUntil;

	internal static void RegisterOriginalLavaHit(Character character)
	{
		if (!((Object)(object)character == (Object)null) && character.IsLocal && !((Object)(object)character.data == (Object)null) && !character.data.dead)
		{
			activeLavaCharacter = character;
			protectionBypassUntil = Time.time + 1.25f;
		}
	}

	internal static bool ShouldBypassStaminaFull(Character character)
	{
		if ((Object)(object)character == (Object)null || (Object)(object)activeLavaCharacter == (Object)null || (Object)(object)character != (Object)(object)activeLavaCharacter)
		{
			return false;
		}
		if (!character.IsLocal || (Object)(object)character.data == (Object)null || character.data.dead)
		{
			ClearActiveLavaCharacter();
			return false;
		}
		if (Time.time > protectionBypassUntil)
		{
			ClearActiveLavaCharacter();
			return false;
		}
		return true;
	}

	private static void ClearActiveLavaCharacter()
	{
		activeLavaCharacter = null;
		protectionBypassUntil = 0f;
	}
}
[HarmonyPatch(typeof(Lava), "HitPlayer", new Type[] { typeof(Character) })]
internal static class MagmaLavaHitPlayerPatch
{
	[HarmonyPrefix]
	[HarmonyPriority(800)]
	private static void Prefix(Character __0)
	{
		Magma.RegisterOriginalLavaHit(__0);
	}
}
[HarmonyPatch(typeof(StaminaFull), "CanApplyProtection", new Type[] { typeof(Character) })]
internal static class MagmaStaminaFullProtectionPatch
{
	[HarmonyPostfix]
	private static void Postfix(Character __0, ref bool __result)
	{
		if (__result && Magma.ShouldBypassStaminaFull(__0))
		{
			__result = false;
		}
	}
}
[HarmonyPatch(typeof(Breakable), "OnCollisionEnter")]
public static class NoBody
{
	private const string TargetPrefabName = "NestEgg";

	[HarmonyPrefix]
	private static bool Prefix(Breakable __instance, Collision collision)
	{
		if ((Object)(object)__instance == (Object)null || collision == null)
		{
			return true;
		}
		Item component = ((Component)__instance).GetComponent<Item>();
		if ((Object)(object)component == (Object)null || !IsNestEgg(((Object)((Component)component).gameObject).name))
		{
			return true;
		}
		Collider collider = collision.collider;
		if ((Object)(object)collider == (Object)null)
		{
			return true;
		}
		Bodypart componentInParent = ((Component)collider).GetComponentInParent<Bodypart>();
		if ((Object)(object)componentInParent != (Object)null)
		{
			return false;
		}
		return true;
	}

	private static bool IsNestEgg(string objectName)
	{
		if (string.IsNullOrWhiteSpace(objectName))
		{
			return false;
		}
		string text = objectName.Trim();
		while (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase))
		{
			text = text.Substring(0, text.Length - "(Clone)".Length).Trim();
		}
		return string.Equals(text, "NestEgg", StringComparison.OrdinalIgnoreCase);
	}
}
public static class NoEat
{
	private sealed class PendingNestEggBreak
	{
		public Vector3 BreakPosition;

		public float ExpireTime;

		public readonly HashSet<ushort> ItemIDs = new HashSet<ushort>();

		public readonly HashSet<string> ObjectNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		public readonly HashSet<string> ItemNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
	}

	[HarmonyPatch(typeof(Breakable), "Break")]
	private static class BreakableBreakPatch
	{
		[HarmonyPrefix]
		private unsafe static void Prefix(Breakable __instance)
		{
			//IL_0029: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			if (IsNestEggBreakable(__instance, out var eggItem))
			{
				RemoveExpiredBreakRecords();
				PendingNestEggBreak pendingNestEggBreak = new PendingNestEggBreak();
				pendingNestEggBreak.BreakPosition = ((Component)eggItem).transform.position;
				pendingNestEggBreak.ExpireTime = Time.time + 4f;
				RegisterSpawnList(__instance.instantiateOnBreak, pendingNestEggBreak);
				RegisterSpawnList(__instance.alternateInstantiateOnBreak, pendingNestEggBreak);
				RegisterSpawnList(__instance.instantiateNonItemOnBreak, pendingNestEggBreak);
				if (pendingNestEggBreak.ItemIDs.Count == 0 && pendingNestEggBreak.ObjectNames.Count == 0 && pendingNestEggBreak.ItemNames.Count == 0)
				{
					Logger.LogWarning((object)"[NoEat] NestEgg break detected, but no spawned Item prefab was found.");
					return;
				}
				PendingBreaks.Add(pendingNestEggBreak);
				ManualLogSource logger = Logger;
				string[] obj = new string[6] { "[NoEat] NestEgg break registered. | Position=", null, null, null, null, null };
				Vector3 breakPosition = pendingNestEggBreak.BreakPosition;
				obj[1] = ((object)(*(Vector3*)(&breakPosition))/*cast due to .constrained prefix*/).ToString();
				obj[2] = " | SpawnItemIDs=";
				obj[3] = pendingNestEggBreak.ItemIDs.Count.ToString();
				obj[4] = " | SpawnNames=";
				obj[5] = pendingNestEggBreak.ObjectNames.Count.ToString();
				logger.LogInfo((object)string.Concat(obj));
			}
		}
	}

	[HarmonyPatch(typeof(Item), "Awake")]
	private static class ItemAwakePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Item __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				if (IsNestEgg(__instance))
				{
					EnsureTimedDespawn(__instance, "NestEgg");
				}
				TryMarkSpawnedItem(__instance);
			}
		}
	}

	[HarmonyPatch(typeof(Item), "StartUsePrimary")]
	private static class StartUsePrimaryPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Item __instance)
		{
			if (!IsBlockedItem(__instance))
			{
				return true;
			}
			LogBlocked(__instance, "StartUsePrimary");
			return false;
		}
	}

	[HarmonyPatch(typeof(Item), "ContinueUsePrimary")]
	private static class ContinueUsePrimaryPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Item __instance)
		{
			return !IsBlockedItem(__instance);
		}
	}

	[HarmonyPatch(typeof(Item), "StartUseSecondary")]
	private static class StartUseSecondaryPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Item __instance)
		{
			if (!IsBlockedItem(__instance))
			{
				return true;
			}
			LogBlocked(__instance, "StartUseSecondary");
			return false;
		}
	}

	[HarmonyPatch(typeof(Item), "ContinueUseSecondary")]
	private static class ContinueUseSecondaryPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Item __instance)
		{
			return !IsBlockedItem(__instance);
		}
	}

	[HarmonyPatch(typeof(Item), "FinishCastSecondary")]
	private static class FinishCastSecondaryPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Item __instance)
		{
			if (!IsBlockedItem(__instance))
			{
				return true;
			}
			LogBlocked(__instance, "FinishCastSecondary");
			return false;
		}
	}

	[HarmonyPatch(typeof(Item), "ConsumeDelayed")]
	private static class ConsumeDelayedPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Item __instance, ref IEnumerator __result)
		{
			if (!IsBlockedItem(__instance))
			{
				return true;
			}
			LogBlocked(__instance, "ConsumeDelayed");
			__result = EmptyRoutine();
			return false;
		}
	}

	private const string LogPrefix = "[NoEat] ";

	private const string TargetPrefabName = "NestEgg";

	private const float PendingLifetime = 4f;

	private const float SpawnDetectionRadius = 6f;

	public const float GroundDespawnLifetime = 30f;

	private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.NoEat");

	private static readonly List<PendingNestEggBreak> PendingBreaks = new List<PendingNestEggBreak>();

	private static bool IsNestEggBreakable(Breakable breakable, out Item eggItem)
	{
		eggItem = null;
		if ((Object)(object)breakable == (Object)null)
		{
			return false;
		}
		eggItem = FindItem(((Component)breakable).gameObject);
		if ((Object)(object)eggItem == (Object)null)
		{
			return false;
		}
		return IsNestEgg(eggItem);
	}

	private static bool IsNestEgg(Item item)
	{
		if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).gameObject == (Object)null)
		{
			return false;
		}
		string a = NormalizeObjectName(((Object)((Component)item).gameObject).name);
		return string.Equals(a, "NestEgg", StringComparison.OrdinalIgnoreCase);
	}

	private static Item FindItem(GameObject sourceObject)
	{
		if ((Object)(object)sourceObject == (Object)null)
		{
			return null;
		}
		Item component = sourceObject.GetComponent<Item>();
		if ((Object)(object)component != (Object)null)
		{
			return component;
		}
		component = sourceObject.GetComponentInParent<Item>();
		if ((Object)(object)component != (Object)null)
		{
			return component;
		}
		return sourceObject.GetComponentInChildren<Item>(true);
	}

	private static void RegisterSpawnList(List<GameObject> spawnList, PendingNestEggBreak pendingBreak)
	{
		if (spawnList == null || pendingBreak == null)
		{
			return;
		}
		for (int i = 0; i < spawnList.Count; i++)
		{
			GameObject val = spawnList[i];
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Item val2 = FindItem(val);
			if (!((Object)(object)val2 == (Object)null))
			{
				pendingBreak.ItemIDs.Add(val2.itemID);
				AddObjectName(pendingBreak, ((Object)val).name);
				AddObjectName(pendingBreak, ((Object)((Component)val2).gameObject).name);
				if (val2.UIData != null)
				{
					AddItemName(pendingBreak, val2.UIData.itemName);
				}
			}
		}
	}

	private static void AddObjectName(PendingNestEggBreak pendingBreak, string objectName)
	{
		string text = NormalizeObjectName(objectName);
		if (!string.IsNullOrEmpty(text))
		{
			pendingBreak.ObjectNames.Add(text);
		}
	}

	private static void AddItemName(PendingNestEggBreak pendingBreak, string itemName)
	{
		if (!string.IsNullOrWhiteSpace(itemName))
		{
			pendingBreak.ItemNames.Add(itemName.Trim());
		}
	}

	private static bool MatchesPendingBreak(Item item, PendingNestEggBreak pendingBreak)
	{
		//IL_0023: 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)
		if ((Object)(object)item == (Object)null || pendingBreak == null)
		{
			return false;
		}
		float num = Vector3.Distance(((Component)item).transform.position, pendingBreak.BreakPosition);
		if (num > 6f)
		{
			return false;
		}
		if (pendingBreak.ItemIDs.Contains(item.itemID))
		{
			return true;
		}
		string item2 = NormalizeObjectName(((Object)((Component)item).gameObject).name);
		if (pendingBreak.ObjectNames.Contains(item2))
		{
			return true;
		}
		if (item.UIData != null && !string.IsNullOrWhiteSpace(item.UIData.itemName) && pendingBreak.ItemNames.Contains(item.UIData.itemName.Trim()))
		{
			return true;
		}
		return false;
	}

	private static void EnsureTimedDespawn(Item item, string sourceName)
	{
		if (!((Object)(object)item == (Object)null) && !((Object)(object)((Component)item).gameObject == (Object)null))
		{
			WatchEggTimedDespawn watchEggTimedDespawn = ((Component)item).GetComponent<WatchEggTimedDespawn>();
			if ((Object)(object)watchEggTimedDespawn == (Object)null)
			{
				watchEggTimedDespawn = ((Component)item).gameObject.AddComponent<WatchEggTimedDespawn>();
			}
			watchEggTimedDespawn.Configure(sourceName);
		}
	}

	private static void TryMarkSpawnedItem(Item item)
	{
		//IL_00e7: 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)
		if ((Object)(object)item == (Object)null)
		{
			return;
		}
		RemoveExpiredBreakRecords();
		if (PendingBreaks.Count == 0)
		{
			return;
		}
		if ((Object)(object)((Component)item).GetComponent<NoEatMarker>() != (Object)null)
		{
			EnsureTimedDespawn(item, "NestEgg break product");
			return;
		}
		for (int num = PendingBreaks.Count - 1; num >= 0; num--)
		{
			PendingNestEggBreak pendingBreak = PendingBreaks[num];
			if (MatchesPendingBreak(item, pendingBreak))
			{
				((Component)item).gameObject.AddComponent<NoEatMarker>();
				EnsureTimedDespawn(item, "NestEgg break product");
				Logger.LogInfo((object)("[NoEat] NestEgg spawned item marked as non-edible. | Object=" + ((Object)((Component)item).gameObject).name + " | ItemID=" + item.itemID + " | Position=" + ((object)((Component)item).transform.position/*cast due to .constrained prefix*/).ToString() + " | GroundDespawnSeconds=" + 30f));
				break;
			}
		}
	}

	private static bool IsBlockedItem(Item item)
	{
		if ((Object)(object)item == (Object)null)
		{
			return false;
		}
		return (Object)(object)((Component)item).GetComponent<NoEatMarker>() != (Object)null;
	}

	private static void RemoveExpiredBreakRecords()
	{
		float time = Time.time;
		for (int num = PendingBreaks.Count - 1; num >= 0; num--)
		{
			if (!(PendingBreaks[num].ExpireTime > time))
			{
				PendingBreaks.RemoveAt(num);
			}
		}
	}

	private static string NormalizeObjectName(string objectName)
	{
		if (string.IsNullOrWhiteSpace(objectName))
		{
			return string.Empty;
		}
		string text = objectName.Trim();
		while (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase))
		{
			text = text.Substring(0, text.Length - "(Clone)".Length);
			text = text.Trim();
		}
		return text;
	}

	private static void LogBlocked(Item item, string actionName)
	{
		string text = (((Object)(object)item != (Object)null) ? ((Object)((Component)item).gameObject).name : "null");
		Logger.LogWarning((object)("[NoEat] Consumption blocked. | Action=" + actionName + " | Object=" + text));
	}

	private static IEnumerator EmptyRoutine()
	{
		yield break;
	}
}
[DisallowMultipleComponent]
public sealed class NoEatMarker : MonoBehaviour
{
}
[DisallowMultipleComponent]
public sealed class WatchEggTimedDespawn : MonoBehaviour
{
	private const string LogPrefix = "[TimedDespawn] ";

	private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.TimedDespawn");

	private Item item;

	private float accumulatedGroundTime;

	private bool lifetimeExpired;

	private bool destroyIssued;

	private string sourceName = "Unknown";

	public float AccumulatedGroundTime => accumulatedGroundTime;

	public float RemainingGroundTime => Mathf.Max(0f, 30f - accumulatedGroundTime);

	private void Awake()
	{
		item = ((Component)this).GetComponent<Item>();
		if ((Object)(object)item == (Object)null)
		{
			((Behaviour)this).enabled = false;
		}
	}

	public void Configure(string configuredSourceName)
	{
		if (!string.IsNullOrWhiteSpace(configuredSourceName))
		{
			sourceName = configuredSourceName;
		}
	}

	private void Update()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Invalid comparison between Unknown and I4
		if (destroyIssued || (Object)(object)item == (Object)null || (int)item.itemState > 0)
		{
			return;
		}
		if (!lifetimeExpired)
		{
			accumulatedGroundTime += Time.deltaTime;
			if (accumulatedGroundTime < 30f)
			{
				return;
			}
			lifetimeExpired = true;
		}
		TryDestroyExpiredObject();
	}

	private void TryDestroyExpiredObject()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Invalid comparison between Unknown and I4
		if (!destroyIssued && !((Object)(object)item == (Object)null) && (int)item.itemState <= 0)
		{
			PhotonView photonView = ((MonoBehaviourPun)item).photonView;
			if (!PhotonNetwork.InRoom || (Object)(object)photonView == (Object)null || photonView.ViewID <= 0)
			{
				destroyIssued = true;
				Logger.LogInfo((object)("[TimedDespawn] Destroying expired local object. | Object=" + ((Object)((Component)this).gameObject).name + " | Source=" + sourceName + " | GroundSeconds=" + accumulatedGroundTime));
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			else if (photonView.IsMine || photonView.AmController)
			{
				destroyIssued = true;
				Logger.LogWarning((object)("[TimedDespawn] Destroying expired network object. | Object=" + ((Object)((Component)this).gameObject).name + " | Source=" + sourceName + " | ViewID=" + photonView.ViewID + " | GroundSeconds=" + accumulatedGroundTime));
				PhotonNetwork.Destroy(((Component)this).gameObject);
			}
		}
	}
}
public static class NoInventory
{
	[HarmonyPatch(typeof(CharacterItems), "EquipSlot")]
	private static class EquipSlotPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static bool Prefix(CharacterItems __instance, Optionable<byte> slotID)
		{
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			if (!IsLocalCharacterItems(__instance))
			{
				return true;
			}
			if (slotID.IsNone || __instance.currentSelectedSlot.IsNone)
			{
				return true;
			}
			int instanceID = ((Object)__instance).GetInstanceID();
			if (ForcedDropInProgress.Contains(instanceID))
			{
				return true;
			}
			byte value = __instance.currentSelectedSlot.Value;
			byte value2 = slotID.Value;
			if (value == value2)
			{
				return true;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.player == (Object)null || (Object)(object)localCharacter.data == (Object)null)
			{
				return true;
			}
			ItemSlot itemSlot = localCharacter.player.GetItemSlot(value);
			Item currentItem = localCharacter.data.currentItem;
			bool flag = IsNestEgg(currentItem);
			bool flag2 = IsNestEggSlot(itemSlot);
			if (!flag && !flag2)
			{
				return true;
			}
			if (!flag)
			{
				DropStoredEggSlot(__instance, value, "Slot switch found stored NestEgg");
				return true;
			}
			BeginHeldEggDrop(__instance, value, slotID, "Selected another inventory slot");
			return false;
		}
	}

	[HarmonyPatch(typeof(Backpack), "Stash")]
	private static class GroundBackpackStashPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static bool Prefix(Character interactor, byte backpackSlotID)
		{
			return !TryBlockBackpackStash(interactor, "Ground backpack stash blocked | BackpackSlot=" + backpackSlotID);
		}
	}

	[HarmonyPatch(typeof(CharacterBackpackHandler), "StashInBackpack")]
	private static class EquippedBackpackStashPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static bool Prefix(Character interactor, byte backpackSlotID)
		{
			return !TryBlockBackpackStash(interactor, "Equipped backpack stash blocked | BackpackSlot=" + backpackSlotID);
		}
	}

	[HarmonyPatch(typeof(BackpackData), "AddItem")]
	private static class BackpackDataAddItemPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static bool Prefix(Item prefab, ItemInstanceData data, byte backpackSlotID)
		{
			if (!IsNestEgg(prefab))
			{
				return true;
			}
			LogWarning("Blocked NestEgg from BackpackData.AddItem | BackpackSlot=" + backpackSlotID);
			return false;
		}
	}

	[HarmonyPatch(typeof(Player), "SyncInventoryRPC")]
	private static class SyncInventoryPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Player __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)Player.localPlayer != (Object)(object)__instance))
			{
				Character character = __instance.character;
				if (!((Object)(object)character == (Object)null) && character.refs != null && !((Object)(object)character.refs.items == (Object)null))
				{
					ScheduleInventoryValidation(character.refs.items, "Inventory sync received");
				}
			}
		}
	}

	[HarmonyPatch(typeof(CharacterItems), "OnPickupAccepted")]
	private static class PickupAcceptedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterItems __instance)
		{
			if (IsLocalCharacterItems(__instance))
			{
				ScheduleInventoryValidation(__instance, "Pickup accepted");
			}
		}
	}

	private const string TargetPrefabName = "NestEgg";

	private const string LogPrefix = "[NoInventory] ";

	private const float InventoryValidationDelay = 0.85f;

	private const float HeldDestroyWaitTimeout = 2f;

	private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.NoInventory");

	private static readonly HashSet<int> ForcedDropInProgress = new HashSet<int>();

	private static readonly HashSet<int> ValidationScheduled = new HashSet<int>();

	private static bool TryBlockBackpackStash(Character interactor, string reason)
	{
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)interactor == (Object)null || !interactor.IsLocal || (Object)(object)interactor != (Object)(object)Character.localCharacter || interactor.refs == null || (Object)(object)interactor.refs.items == (Object)null || (Object)(object)interactor.player == (Object)null || (Object)(object)interactor.data == (Object)null)
		{
			return false;
		}
		CharacterItems items = interactor.refs.items;
		if (items.currentSelectedSlot.IsNone)
		{
			return false;
		}
		byte value = items.currentSelectedSlot.Value;
		ItemSlot itemSlot = interactor.player.GetItemSlot(value);
		bool flag = IsNestEgg(interactor.data.currentItem);
		bool flag2 = IsNestEggSlot(itemSlot);
		if (!flag && !flag2)
		{
			return false;
		}
		if (flag)
		{
			BeginHeldEggDrop(items, value, Optionable<byte>.None, reason);
		}
		else
		{
			DropStoredEggSlot(items, value, reason);
		}
		return true;
	}

	private unsafe static void BeginHeldEggDrop(CharacterItems items, byte slotId, Optionable<byte> nextSlot, string reason)
	{
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: 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)
		if (!IsLocalCharacterItems(items))
		{
			return;
		}
		int instanceID = ((Object)items).GetInstanceID();
		if (!ForcedDropInProgress.Add(instanceID))
		{
			return;
		}
		Character localCharacter = Character.localCharacter;
		if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || (Object)(object)localCharacter.player == (Object)null)
		{
			ForcedDropInProgress.Remove(instanceID);
			return;
		}
		ItemSlot itemSlot = localCharacter.player.GetItemSlot(slotId);
		if (!IsNestEggSlot(itemSlot))
		{
			ForcedDropInProgress.Remove(instanceID);
			return;
		}
		PhotonView component = ((Component)items).GetComponent<PhotonView>();
		if ((Object)(object)component == (Object)null || (PhotonNetwork.InRoom && !component.IsMine))
		{
			LogError("Cannot force-drop NestEgg because local CharacterItems PhotonView is invalid. | Slot=" + slotId);
			ForcedDropInProgress.Remove(instanceID);
			return;
		}
		Vector3 dropPosition = GetDropPosition(localCharacter);
		string[] obj = new string[8]
		{
			"FORCE DROP HELD NEST EGG | Reason=",
			reason,
			" | Slot=",
			slotId.ToString(),
			" | NextSlot=",
			FormatSlot(nextSlot),
			" | Position=",
			null
		};
		Vector3 val = dropPosition;
		obj[7] = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString();
		LogWarning(string.Concat(obj));
		component.RPC("DropItemFromSlotRPC", (RpcTarget)5, new object[2] { slotId, dropPosition });
		component.RPC("DestroyHeldItemRpc", (RpcTarget)5, Array.Empty<object>());
		((MonoBehaviour)items).StartCoroutine(FinishHeldDropRoutine(items, nextSlot, instanceID));
	}

	private static IEnumerator FinishHeldDropRoutine(CharacterItems items, Optionable<byte> nextSlot, int instanceId)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		float timeoutAt = Time.realtimeSinceStartup + 2f;
		while ((Object)(object)items != (Object)null && (Object)(object)Character.localCharacter != (Object)null && (Object)(object)Character.localCharacter.data != (Object)null && (Object)(object)Character.localCharacter.data.currentItem != (Object)null && Time.realtimeSinceStartup < timeoutAt)
		{
			yield return null;
		}
		if ((Object)(object)items != (Object)null && IsLocalCharacterItems(items))
		{
			items.EquipSlot(nextSlot);
		}
		ForcedDropInProgress.Remove(instanceId);
	}

	private unsafe static void DropStoredEggSlot(CharacterItems items, byte slotId, string reason)
	{
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		if (!IsLocalCharacterItems(items))
		{
			return;
		}
		Character localCharacter = Character.localCharacter;
		if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.player == (Object)null)
		{
			return;
		}
		ItemSlot itemSlot = localCharacter.player.GetItemSlot(slotId);
		if (IsNestEggSlot(itemSlot))
		{
			PhotonView component = ((Component)items).GetComponent<PhotonView>();
			if (!((Object)(object)component == (Object)null) && (!PhotonNetwork.InRoom || component.IsMine))
			{
				Vector3 dropPosition = GetDropPosition(localCharacter);
				string[] obj = new string[6]
				{
					"DROP STORED NEST EGG | Reason=",
					reason,
					" | Slot=",
					slotId.ToString(),
					" | Position=",
					null
				};
				Vector3 val = dropPosition;
				obj[5] = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString();
				LogWarning(string.Concat(obj));
				component.RPC("DropItemFromSlotRPC", (RpcTarget)5, new object[2] { slotId, dropPosition });
			}
		}
	}

	private static void ScheduleInventoryValidation(CharacterItems items, string reason)
	{
		if (IsLocalCharacterItems(items))
		{
			int instanceID = ((Object)items).GetInstanceID();
			if (ValidationScheduled.Add(instanceID))
			{
				((MonoBehaviour)items).StartCoroutine(ValidateInventoryDelayed(items, reason, instanceID));
			}
		}
	}

	private static IEnumerator ValidateInventoryDelayed(CharacterItems items, string reason, int instanceId)
	{
		yield return (object)new WaitForSeconds(0.85f);
		if ((Object)(object)items != (Object)null && IsLocalCharacterItems(items) && !ForcedDropInProgress.Contains(instanceId))
		{
			ValidateInventoryNow(items, reason);
		}
		ValidationScheduled.Remove(instanceId);
	}

	private static void ValidateInventoryNow(CharacterItems items, string reason)
	{
		Character localCharacter = Character.localCharacter;
		if (!((Object)(object)localCharacter == (Object)null) && !((Object)(object)localCharacter.player == (Object)null) && !((Object)(object)localCharacter.data == (Object)null))
		{
			ValidateSlot(items, localCharacter, 0, reason);
			ValidateSlot(items, localCharacter, 1, reason);
			ValidateSlot(items, localCharacter, 2, reason);
			ValidateSlot(items, localCharacter, 250, reason);
		}
	}

	private static void ValidateSlot(CharacterItems items, Character character, byte slotId, string reason)
	{
		ItemSlot itemSlot = character.player.GetItemSlot(slotId);
		if (IsNestEggSlot(itemSlot) && (!items.currentSelectedSlot.IsSome || items.currentSelectedSlot.Value != slotId || !IsNestEgg(character.data.currentItem)))
		{
			DropStoredEggSlot(items, slotId, reason + " | Invalid inventory storage detected");
		}
	}

	private static bool IsLocalCharacterItems(CharacterItems items)
	{
		if ((Object)(object)items == (Object)null)
		{
			return false;
		}
		Character localCharacter = Character.localCharacter;
		return (Object)(object)localCharacter != (Object)null && localCharacter.refs != null && (Object)(object)localCharacter.refs.items == (Object)(object)items && localCharacter.IsLocal;
	}

	private static bool IsNestEggSlot(ItemSlot slot)
	{
		if (slot == null || slot.IsEmpty())
		{
			return false;
		}
		if (IsNestEgg(slot.prefab))
		{
			return true;
		}
		return IsNestEggName(slot.GetPrefabName());
	}

	private static bool IsNestEgg(Item item)
	{
		if ((Object)(object)item == (Object)null)
		{
			return false;
		}
		return IsNestEggName(((Object)((Component)item).gameObject).name);
	}

	private static bool IsNestEggName(string objectName)
	{
		return string.Equals(NormalizePrefabName(objectName), "NestEgg", StringComparison.OrdinalIgnoreCase);
	}

	private static string NormalizePrefabName(string objectName)
	{
		if (string.IsNullOrEmpty(objectName))
		{
			return string.Empty;
		}
		string text = objectName.Trim();
		while (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase))
		{
			text = text.Substring(0, text.Length - "(Clone)".Length).Trim();
		}
		return text;
	}

	private static Vector3 GetDropPosition(Character character)
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//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_00a0: 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)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: 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)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)character != (Object)null && (Object)(object)character.data != (Object)null && (Object)(object)character.data.currentItem != (Object)null)
		{
			return ((Component)character.data.currentItem).transform.position + Vector3.down * 0.2f;
		}
		if ((Object)(object)character != (Object)null)
		{
			return character.Center + ((Component)character).transform.forward * 0.35f + Vector3.up * 0.15f;
		}
		return Vector3.zero;
	}

	private static string FormatSlot(Optionable<byte> slot)
	{
		return slot.IsSome ? slot.Value.ToString() : "None";
	}

	private static void LogWarning(string message)
	{
		Logger.LogWarning((object)("[NoInventory] " + message));
	}

	private static void LogError(string message)
	{
		Logger.LogError((object)("[NoInventory] " + message));
	}
}
[HarmonyPatch(typeof(CharacterSpawner), "Update")]
public static class RandomStartEgg
{
	public const string DeveloperName = "Sapphire009";

	public const string TargetPrefabName = "NestEgg";

	private const float RequiredStableTime = 1.5f;

	private const float EquipRetryInterval = 2f;

	private const string LogPrefix = "[RandomStartEgg] ";

	private const string RoomPropertyGrantedKey = "Sapphire009.WatchEgg.StartEggGranted";

	private const string RoomPropertyActorKey = "Sapphire009.WatchEgg.StartEggActor";

	private const string RoomPropertySlotKey = "Sapphire009.WatchEgg.StartEggSlot";

	private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.RandomStartEgg");

	private static int currentSceneHandle = int.MinValue;

	private static bool routineStarted;

	private static bool eggGranted;

	private static bool airportPropertyReset;

	private static bool localEquipRoutineStarted;

	private static bool localEquipCompleted;

	private static int lastLoggedReadyCount = -1;

	[HarmonyPrepare]
	private static bool Prepare()
	{
		Logger.LogInfo((object)"[RandomStartEgg] PATCH READY: CharacterSpawner.Update");
		return true;
	}

	[HarmonyPostfix]
	private static void Postfix(CharacterSpawner __instance)
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Invalid comparison between Unknown and I4
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		ResetStateWhenSceneChanged();
		if ((Object)(object)__instance == (Object)null || !PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null)
		{
			return;
		}
		if (!GameHandler.IsOnIsland)
		{
			ResetRoomPropertiesInAirport();
		}
		else if ((int)MapHandler.CurrentSegmentNumber <= 0)
		{
			TryStartLocalEquipRoutine(__instance);
			if (IsEggAlreadyGrantedInRoom())
			{
				eggGranted = true;
			}
			else if (PhotonNetwork.IsMasterClient && !eggGranted && !routineStarted)
			{
				routineStarted = true;
				Scene activeScene = SceneManager.GetActiveScene();
				int handle = ((Scene)(ref activeScene)).handle;
				((MonoBehaviour)__instance).StartCoroutine(WaitForAllPlayersAndGrantEgg(handle));
			}
		}
	}

	private static IEnumerator WaitForAllPlayersAndGrantEgg(int startedSceneHandle)
	{
		float stableTime = 0f;
		int stablePlayerCount = -1;
		Logger.LogInfo((object)"[RandomStartEgg] Waiting for all connected players to finish spawning.");
		while (true)
		{
			if (!CanContinueWaiting(startedSceneHandle))
			{
				routineStarted = false;
				yield break;
			}
			if (IsEggAlreadyGrantedInRoom())
			{
				eggGranted = true;
				routineStarted = false;
				yield break;
			}
			if (!TryGetAllSpawnedCharacters(out var _, out var roomPlayerCount))
			{
				stableTime = 0f;
				stablePlayerCount = -1;
				yield return null;
			}
			else if (roomPlayerCount != stablePlayerCount)
			{
				stablePlayerCount = roomPlayerCount;
				stableTime = 0f;
				if (lastLoggedReadyCount != roomPlayerCount)
				{
					lastLoggedReadyCount = roomPlayerCount;
					Logger.LogInfo((object)("[RandomStartEgg] All current player characters are ready. | PlayerCount=" + roomPlayerCount));
				}
				yield return null;
			}
			else
			{
				stableTime += Time.unscaledDeltaTime;
				if (!(stableTime < 1.5f))
				{
					break;
				}
				yield return null;
			}
		}
		if (!TryGetAllSpawnedCharacters(out var finalCharacters, out var finalPlayerCount))
		{
			routineStarted = false;
			yield break;
		}
		if (finalCharacters.Count == 0)
		{
			Logger.LogError((object)"[RandomStartEgg] Egg grant failed: no spawned character was found.");
			routineStarted = false;
			yield break;
		}
		if (!TryGetNestEggPrefab(out var nestEggPrefab))
		{
			Logger.LogError((object)"[RandomStartEgg] Egg grant failed: NestEgg was not found in ItemDatabase.");
			routineStarted = false;
			yield break;
		}
		List<Character> eligibleCharacters = new List<Character>();
		for (int i = 0; i < finalCharacters.Count; i++)
		{
			Character character = finalCharacters[i];
			if (!((Object)(object)character == (Object)null) && !((Object)(object)character.player == (Object)null) && character.refs != null && !((Object)(object)character.refs.items == (Object)null))
			{
				if (!character.player.HasEmptySlot(nestEggPrefab.itemID))
				{
					Logger.LogWarning((object)("[RandomStartEgg] Player excluded because inventory is full. | Player=" + GetCharacterName(character)));
				}
				else
				{
					eligibleCharacters.Add(character);
				}
			}
		}
		if (eligibleCharacters.Count == 0)
		{
			Logger.LogError((object)"[RandomStartEgg] Egg grant failed: all player inventories are full.");
			routineStarted = false;
			yield break;
		}
		int randomIndex = Random.Range(0, eligibleCharacters.Count);
		Character selectedCharacter = eligibleCharacters[randomIndex];
		int actorNumber = GetActorNumber(selectedCharacter);
		if (actorNumber < 0)
		{
			Logger.LogError((object)"[RandomStartEgg] Egg grant failed: selected player ActorNumber was invalid.");
			routineStarted = false;
			yield break;
		}
		ItemSlot addedSlot = default(ItemSlot);
		if (!selectedCharacter.player.AddItem(nestEggPrefab.itemID, (ItemInstanceData)null, ref addedSlot) || addedSlot == null)
		{
			Logger.LogError((object)("[RandomStartEgg] NestEgg could not be added to " + GetCharacterName(selectedCharacter) + "'s item slot."));
			routineStarted = false;
			yield break;
		}
		SetRoomEggAssignment(granted: true, actorNumber, addedSlot.itemSlotID);
		eggGranted = true;
		routineStarted = false;
		Logger.LogWarning((object)("[RandomStartEgg] NestEgg assigned to one random player. The selected player will hold it immediately. | SelectedPlayer=" + GetCharacterName(selectedCharacter) + " | ActorNumber=" + actorNumber + " | ConnectedPlayers=" + finalPlayerCount + " | SlotID=" + addedSlot.itemSlotID + " | ItemID=" + nestEggPrefab.itemID));
	}

	private static void TryStartLocalEquipRoutine(CharacterSpawner characterSpawner)
	{
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)characterSpawner == (Object)null) && !localEquipCompleted && !localEquipRoutineStarted && PhotonNetwork.LocalPlayer != null && TryGetRoomEggAssignment(out var actorNumber, out var slotID) && PhotonNetwork.LocalPlayer.ActorNumber == actorNumber)
		{
			localEquipRoutineStarted = true;
			Scene activeScene = SceneManager.GetActiveScene();
			int handle = ((Scene)(ref activeScene)).handle;
			((MonoBehaviour)characterSpawner).StartCoroutine(WaitForLocalEggAndEquip(handle, actorNumber, slotID));
		}
	}

	private static IEnumerator WaitForLocalEggAndEquip(int startedSceneHandle, int targetActorNumber, byte targetSlotID)
	{
		float nextEquipRequestTime = 0f;
		Logger.LogInfo((object)("[RandomStartEgg] This client was selected to receive the NestEgg. Waiting for slot synchronization. | ActorNumber=" + targetActorNumber + " | SlotID=" + targetSlotID));
		Character selectedCharacter = default(Character);
		while (CanContinueLocalEquipWaiting(startedSceneHandle))
		{
			if (!TryGetRoomEggAssignment(out var currentTargetActor, out var currentTargetSlot))
			{
				localEquipRoutineStarted = false;
				yield break;
			}
			if (currentTargetActor != targetActorNumber || currentTargetSlot != targetSlotID)
			{
				localEquipRoutineStarted = false;
				yield break;
			}
			if (!PlayerHandler.TryGetCharacter(targetActorNumber, ref selectedCharacter))
			{
				yield return null;
				continue;
			}
			if ((Object)(object)selectedCharacter == (Object)null || !selectedCharacter.IsLocal || (Object)(object)selectedCharacter.data == (Object)null || (Object)(object)selectedCharacter.player == (Object)null || selectedCharacter.refs == null || (Object)(object)selectedCharacter.refs.items == (Object)null)
			{
				yield return null;
				continue;
			}
			ItemSlot eggSlot = selectedCharacter.player.GetItemSlot(targetSlotID);
			if (eggSlot == null || eggSlot.IsEmpty() || (Object)(object)eggSlot.prefab == (Object)null || !IsNestEggName(((Object)((Component)eggSlot.prefab).gameObject).name))
			{
				yield return null;
				continue;
			}
			if (IsNestEggHeldByCharacter(selectedCharacter, targetSlotID))
			{
				localEquipCompleted = true;
				localEquipRoutineStarted = false;
				Logger.LogWarning((object)("[RandomStartEgg] NestEgg is now held by the selected player. | Player=" + GetCharacterName(selectedCharacter) + " | ActorNumber=" + targetActorNumber + " | SlotID=" + targetSlotID));
				yield break;
			}
			if (Time.unscaledTime >= nextEquipRequestTime)
			{
				nextEquipRequestTime = Time.unscaledTime + 2f;
				selectedCharacter.refs.items.EquipSlot(Optionable<byte>.Some(targetSlotID));
				Logger.LogInfo((object)("[RandomStartEgg] Immediate hand equip requested. | Player=" + GetCharacterName(selectedCharacter) + " | ActorNumber=" + targetActorNumber + " | SlotID=" + targetSlotID));
			}
			yield return null;
			selectedCharacter = null;
		}
		localEquipRoutineStarted = false;
	}

	private static bool IsNestEggHeldByCharacter(Character character, byte slotID)
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Invalid comparison between Unknown and I4
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null || character.refs == null || (Object)(object)character.refs.items == (Object)null)
		{
			return false;
		}
		Item currentItem = character.data.currentItem;
		if ((Object)(object)currentItem == (Object)null || (int)currentItem.itemState != 1 || !IsNestEggName(((Object)((Component)currentItem).gameObject).name))
		{
			return false;
		}
		Optionable<byte> currentSelectedSlot = character.refs.items.currentSelectedSlot;
		if (!currentSelectedSlot.IsSome)
		{
			return false;
		}
		return currentSelectedSlot.Value == slotID;
	}

	private static bool CanContinueLocalEquipWaiting(int startedSceneHandle)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to