Decompiled source of WatchEgg v1.0.2
plugins/WatchEgg.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
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.0")] public sealed class StaminaFull : BaseUnityPlugin { [HarmonyPatch(typeof(Character), "UseStamina", new Type[] { typeof(float), typeof(bool) })] private static class CharacterUseStaminaPatch { [HarmonyPrefix] private static bool Prefix(Character __instance, float __0, bool __1, ref bool __result) { if (__0 <= 0f) { return true; } if (!CanApplyProtection(__instance)) { return true; } FillAndPreserveStamina(__instance); __instance.data.sinceUseStamina = 0f; __result = true; return false; } } [HarmonyPatch(typeof(Character), "AddStamina", new Type[] { typeof(float) })] private static class CharacterAddStaminaPatch { [HarmonyPrefix] private static bool Prefix(Character __instance, float __0) { if (__0 >= 0f) { return true; } return !CanApplyProtection(__instance); } } [HarmonyPatch(typeof(Character), "SetExtraStamina", new Type[] { typeof(float) })] private static class CharacterSetExtraStaminaPatch { [HarmonyPrefix] private static bool Prefix(Character __instance, float __0) { if (!CanApplyProtection(__instance)) { return true; } if (__0 >= __instance.data.extraStamina) { return true; } return false; } } [HarmonyPatch(typeof(Character), "AddExtraStamina", new Type[] { typeof(float) })] private static class CharacterAddExtraStaminaPatch { [HarmonyPrefix] private static bool Prefix(Character __instance, float __0) { if (__0 >= 0f) { return true; } return !CanApplyProtection(__instance); } } [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)) { if ((Object)(object)__instance != (Object)null) { PreservedExtraStamina.Remove(((Object)__instance).GetInstanceID()); } } else { ClearAllNegativeStates(__instance); FillAndPreserveStamina(__instance); } } } public const string PluginGUID = "Sapphire009.StaminaFull"; public const string PluginName = "StaminaFull"; public const string PluginVersion = "1.0.0"; private const string BuildMarker = "InfiniteStamina-AllStatusBlock-R2"; private const int MaximumLogCount = 50; internal static ManualLogSource ModLogger; private static readonly Dictionary<int, float> PreservedExtraStamina = new Dictionary<int, float>(); 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.0 loaded. Build: InfiniteStamina-AllStatusBlock-R2. Infinite stamina and complete status protection are enabled outside Airport."); } private void OnDestroy() { PreservedExtraStamina.Clear(); 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 FillAndPreserveStamina(Character character) { if (!CanApplyProtection(character)) { if ((Object)(object)character != (Object)null) { PreservedExtraStamina.Remove(((Object)character).GetInstanceID()); } return; } float maxStamina = character.GetMaxStamina(); maxStamina = Mathf.Max(maxStamina, 1f); bool flag = false; if (Mathf.Abs(character.data.currentStamina - maxStamina) > 0.0001f) { character.data.currentStamina = maxStamina; flag = true; } int instanceID = ((Object)character).GetInstanceID(); if (!PreservedExtraStamina.TryGetValue(instanceID, out var value)) { value = character.data.extraStamina; PreservedExtraStamina.Add(instanceID, value); } else if (character.data.extraStamina > value) { value = character.data.extraStamina; PreservedExtraStamina[instanceID] = value; } else if (character.data.extraStamina < value) { character.data.extraStamina = value; flag = true; } if (flag && (Object)(object)GUIManager.instance != (Object)null && (Object)(object)GUIManager.instance.bar != (Object)null) { GUIManager.instance.bar.ChangeBar(); } } 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_0064: 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_009e: 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[8] { "[StaminaFull] Status blocked ", $"({blockedStatusLogCount}/{50}). ", $"Status={statusType}, ", $"Amount={amount:0.0000}, ", "Source=", source, ", Scene=", null }; Scene activeScene = SceneManager.GetActiveScene(); obj[7] = ((Scene)(ref activeScene)).name; modLogger.LogInfo((object)string.Concat(obj)); } } } private static void LogBlockedThorn() { //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) if (blockedThornLogCount < 50) { blockedThornLogCount++; ManualLogSource modLogger = ModLogger; if (modLogger != null) { string text = $"({blockedThornLogCount}/{50}). "; Scene activeScene = SceneManager.GetActiveScene(); modLogger.LogInfo((object)("[StaminaFull] Thorn blocked " + text + "Scene=" + ((Scene)(ref activeScene)).name)); } } } } 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 : ((Object)((Component)val).gameObject).GetInstanceID()); if (!CountedBrokenViewIds.Contains(item)) { CountedBrokenViewIds.Add(item); BrokenEggCount++; Logger.LogWarning((object)("[EggCheckpoint] NestEgg broken. | BrokenCount=" + BrokenEggCount + " | ViewID=" + item)); } } } } public const string DeveloperName = "Sapphire009"; public const string TargetPrefabName = "NestEgg"; public const float TargetCheckpointDistance = 25f; public const float DistanceTolerance = 2f; public const float MinimumCheckpointDistance = 23f; public const float MaximumCheckpointDistance = 27f; private const float MaximumAcceptedFrameTravelDistance = 3f; private const float RequiredStableTime = 0.55f; private const float MaximumStableGroundSpeed = 0.45f; private const float MinimumGroundNormalY = 0.55f; private const float GroundCastStartHeight = 2.5f; private const float GroundCastDistance = 5f; private const float InitialGroundCastDistance = 12f; private const float GroundCastRadius = 0.18f; private const float GroundSurfacePadding = 0.015f; private const float MaximumEggGroundDistanceFromPlayer = 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; private Vector3 previousTrackedPosition; private bool hasPreviousTrackedPosition; private bool waitingForStableCheckpoint; private bool wasHeldByLocalPlayer; private Vector3 previousGroundPosition; private bool hasPreviousGroundPosition; private float stableGroundTimer; 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 + " | BottomOffset=" + pivotToEggBottom + " | DistanceMode=Accumulated3D")); } private void Update() { ResetStaticDataWhenSceneChanged(); if ((Object)(object)item == (Object)null) { return; } if (!IsHeldByLocalPlayer(out var localCharacter)) { HandleNotHeld(); return; } HandleHeld(localCharacter); UpdateAccumulatedTravelDistance(localCharacter); bool flag = UpdateStableGroundState(localCharacter); if (!HasCheckpoint) { DistanceFromLastCheckpoint = 0f; if (flag) { SaveCheckpoint(localCharacter, initialCheckpoint: true); } return; } if (DistanceFromLastCheckpoint >= 23f) { waitingForStableCheckpoint = true; } if (waitingForStableCheckpoint && flag) { SaveCheckpoint(localCharacter, initialCheckpoint: false); } } private bool IsHeldByLocalPlayer(out Character localCharacter) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Invalid comparison between Unknown and I4 localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || !localCharacter.IsLocal || (Object)(object)item == (Object)null) { return false; } return (Object)(object)localCharacter.data.currentItem == (Object)(object)item && (int)item.itemState == 1; } private void HandleHeld(Character localCharacter) { //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) if (!wasHeldByLocalPlayer) { wasHeldByLocalPlayer = true; stableGroundTimer = 0f; hasPreviousGroundPosition = false; hasPreviousTrackedPosition = false; if ((Object)(object)localCharacter != (Object)null) { previousTrackedPosition = ((Component)localCharacter).transform.position; hasPreviousTrackedPosition = true; } Logger.LogInfo((object)("[EggCheckpoint] NestEgg tracking started. | AccumulatedDistance=" + DistanceFromLastCheckpoint)); } } private void HandleNotHeld() { if (wasHeldByLocalPlayer) { wasHeldByLocalPlayer = false; stableGroundTimer = 0f; hasPreviousGroundPosition = false; hasPreviousTrackedPosition = false; Logger.LogInfo((object)("[EggCheckpoint] NestEgg tracking paused. | AccumulatedDistance=" + DistanceFromLastCheckpoint)); } } private void UpdateAccumulatedTravelDistance(Character localCharacter) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)localCharacter == (Object)null) { hasPreviousTrackedPosition = false; return; } Vector3 position = ((Component)localCharacter).transform.position; if (!hasPreviousTrackedPosition) { previousTrackedPosition = position; hasPreviousTrackedPosition = true; return; } float num = Vector3.Distance(previousTrackedPosition, position); previousTrackedPosition = position; if (!float.IsNaN(num) && !float.IsInfinity(num)) { if (num > 3f) { Logger.LogWarning((object)("[EggCheckpoint] Large position jump ignored. | FrameDistance=" + num)); } else { DistanceFromLastCheckpoint += num; } } } private bool UpdateStableGroundState(Character character) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0110: 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_00d3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null) { ResetStableGroundState(); return false; } if (!character.data.isGrounded || character.data.isClimbing || character.data.isRopeClimbing || character.data.isVineClimbing || character.data.dead || character.data.fullyPassedOut || !(character.data.groundNormal.y >= 0.55f)) { ResetStableGroundState(); return false; } Vector3 groundPos = character.data.groundPos; if (!hasPreviousGroundPosition) { previousGroundPosition = groundPos; hasPreviousGroundPosition = true; stableGroundTimer = 0f; return false; } float num = Mathf.Max(Time.deltaTime, 0.0001f); float num2 = Vector3.Distance(previousGroundPosition, groundPos) / num; previousGroundPosition = groundPos; if (num2 <= 0.45f) { stableGroundTimer += Time.deltaTime; } else { stableGroundTimer = 0f; } return stableGroundTimer >= 0.55f; } private void ResetStableGroundState() { stableGroundTimer = 0f; hasPreviousGroundPosition = false; } private void SaveCheckpoint(Character localCharacter, bool initialCheckpoint) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) if (!TryGetGroundAttachedEggPosition(localCharacter, out var result)) { Logger.LogWarning((object)"[EggCheckpoint] Checkpoint save delayed: safe ground was not found."); return; } float distanceFromLastCheckpoint = DistanceFromLastCheckpoint; CheckpointPosition = result; CheckpointRotation = eggRestRotation; HasCheckpoint = true; CheckpointNumber++; DistanceFromLastCheckpoint = 0f; waitingForStableCheckpoint = false; stableGroundTimer = 0f; hasPreviousGroundPosition = false; if ((Object)(object)localCharacter != (Object)null) { previousTrackedPosition = ((Component)localCharacter).transform.position; hasPreviousTrackedPosition = true; } else { hasPreviousTrackedPosition = false; } Logger.LogWarning((object)("[EggCheckpoint] " + (initialCheckpoint ? "Initial checkpoint saved." : "Travel checkpoint saved.") + " | Number=" + CheckpointNumber + " | TravelDistance=" + distanceFromLastCheckpoint + " | Position=" + ((object)CheckpointPosition/*cast due to .constrained prefix*/).ToString())); } private bool TryGetGroundAttachedEggPosition(Character localCharacter, 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_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_0054: 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_005e: 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_0086: 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_009c: 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) result = Vector3.zero; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null) { return false; } if (TryCastGroundBelowEgg(localCharacter, out var groundHit)) { result = ((RaycastHit)(ref groundHit)).point + Vector3.up * (pivotToEggBottom + 0.015f); return true; } if (!TryCastGroundAtPlayer(localCharacter, out groundHit)) { return false; } result = ((RaycastHit)(ref groundHit)).point + Vector3.up * (pivotToEggBottom + 0.015f); return true; } private bool TryCastGroundBelowEgg(Character localCharacter, out RaycastHit groundHit) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_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_0094: 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) Vector3 groundPos = localCharacter.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, 5f, 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)).magnitude <= 1.6f; } private bool TryCastGroundAtPlayer(Character localCharacter, out RaycastHit groundHit) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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) Vector3 val = localCharacter.data.groundPos + Vector3.up * 2.5f; if (!Physics.SphereCast(val, 0.18f, Vector3.down, ref groundHit, 5f, LayerMask.op_Implicit(HelperFunctions.GetMask((LayerType)1)), (QueryTriggerInteraction)1)) { return false; } return ((RaycastHit)(ref groundHit)).normal.y >= 0.55f; } private void CacheInitialCheckpoint() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if (!HasCheckpoint) { Vector3 val = ((Component)this).transform.position + Vector3.up * 2.5f; RaycastHit val2 = default(RaycastHit); if (Physics.SphereCast(val, 0.18f, Vector3.down, ref val2, 12f, LayerMask.op_Implicit(HelperFunctions.GetMask((LayerType)1)), (QueryTriggerInteraction)1) && !(((RaycastHit)(ref val2)).normal.y < 0.55f)) { CheckpointPosition = ((RaycastHit)(ref val2)).point + Vector3.up * (pivotToEggBottom + 0.015f); CheckpointRotation = eggRestRotation; HasCheckpoint = true; CheckpointNumber = 1; DistanceFromLastCheckpoint = 0f; waitingForStableCheckpoint = false; Logger.LogWarning((object)("[EggCheckpoint] Initial spawn 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(); int handle = ((Scene)(ref activeScene)).handle; if (activeSceneHandle != handle) { activeSceneHandle = handle; ResetCheckpoint(); Logger.LogInfo((object)"[EggCheckpoint] Scene changed. Checkpoint data reset."); } } 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; } } [HarmonyPatch(typeof(Breakable), "OnCollisionEnter")] public static class NoBody { public const string DeveloperName = "Sapphire009"; public const string TargetPrefabName = "NestEgg"; private const string LogPrefix = "[NoBody] "; private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.NoBody"); [HarmonyPrepare] private static bool Prepare() { Logger.LogInfo((object)"[NoBody] PATCH READY: Breakable.OnCollisionEnter"); return true; } [HarmonyPrefix] private static bool Prefix(Breakable __instance, Collision collision) { //IL_007a: 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) if ((Object)(object)__instance == (Object)null || collision == null) { return true; } Item item = FindItem(((Component)__instance).gameObject); if (!IsNestEgg(item)) { return true; } if (!TryGetCollidedCharacter(collision, out var character)) { return true; } ManualLogSource logger = Logger; string[] obj = new string[6] { "[NoBody] NestEgg body collision ignored. | Player=", GetCharacterName(character), " | RelativeVelocity=", null, null, null }; Vector3 relativeVelocity = collision.relativeVelocity; obj[3] = ((Vector3)(ref relativeVelocity)).magnitude.ToString(); obj[4] = " | Collider="; obj[5] = GetColliderName(collision); logger.LogInfo((object)string.Concat(obj)); return false; } private static bool TryGetCollidedCharacter(Collision collision, out Character character) { character = null; if (collision == null) { return false; } if ((Object)(object)collision.collider != (Object)null) { character = ((Component)collision.collider).GetComponentInParent<Character>(); if ((Object)(object)character != (Object)null) { return true; } } if ((Object)(object)collision.rigidbody != (Object)null) { character = ((Component)collision.rigidbody).GetComponentInParent<Character>(); if ((Object)(object)character != (Object)null) { return true; } } if ((Object)(object)collision.transform != (Object)null) { character = ((Component)collision.transform).GetComponentInParent<Character>(); if ((Object)(object)character != (Object)null) { return true; } } return false; } 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 bool IsNestEgg(Item item) { if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).gameObject == (Object)null) { return false; } return string.Equals(NormalizePrefabName(((Object)((Component)item).gameObject).name), "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 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; } private static string GetColliderName(Collision collision) { if (collision == null || (Object)(object)collision.collider == (Object)null || (Object)(object)((Component)collision.collider).gameObject == (Object)null) { return "Unknown"; } return ((Object)((Component)collision.collider).gameObject).name; } } 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 { private sealed class PendingSlotBreak { public byte SlotId; public float StartedAt; public float NextEquipAttemptAt; public float HeldDetectedAt = -1f; } [HarmonyPatch(typeof(CharacterItems), "EquipSlot", new Type[] { typeof(Optionable<byte>) })] private static class CharacterItemsEquipSlotPatch { [HarmonyPrefix] private static bool Prefix(CharacterItems __instance, Optionable<byte> __0) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00a9: Unknown result type (might be due to invalid IL or missing references) Character val = ResolveCharacter(__instance); if (!IsValidLocalCharacter(val)) { return true; } Item currentItem = val.data.currentItem; if (!IsNestEgg(currentItem) || (int)currentItem.itemState != 1) { return true; } if (__0.IsSome && __instance.currentSelectedSlot.IsSome && __0.Value == __instance.currentSelectedSlot.Value) { return true; } int instanceID = ((Object)val).GetInstanceID(); PendingSlotBreaks.Remove(instanceID); Optionable<byte> backingSlot = FindHeldEggBackingSlot(__instance, val); BreakHeldEgg(__instance, backingSlot, __0, "EggLeftPlayerHand"); return false; } } [HarmonyPatch(typeof(CharacterItems), "Update")] private static class CharacterItemsUpdatePatch { [HarmonyPostfix] private static void Postfix(CharacterItems __instance) { Character character = ResolveCharacter(__instance); if (IsValidLocalCharacter(character)) { ScanWorldBackpackedEggs(); if (!ProcessPendingSlotBreak(__instance, character) && TryFindIllegalEggSlot(__instance, character, out var illegalSlotId)) { StartPendingSlotBreak(__instance, character, illegalSlotId); } } } } [HarmonyPatch(typeof(Item), "PutInBackpackRPC", new Type[] { typeof(byte), typeof(BackpackReference) })] private static class ItemPutInBackpackRpcPatch { [HarmonyPostfix] private static void Postfix(Item __instance, byte __0, BackpackReference __1) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (IsNestEgg(__instance)) { BreakBackpackedEgg(__instance, __1, "PutInBackpackRPC"); } } } private const string LogPrefix = "[NoInventory] "; private const string TargetPrefabName = "NestEgg"; private const float HeldAttachSafetyDelay = 0.06f; private const float NormalEquipGraceSeconds = 0.75f; private const float PendingBreakTimeoutSeconds = 3f; private const float EquipRetryIntervalSeconds = 0.2f; private const float BackpackScanIntervalSeconds = 0.1f; private const int MaximumLogCount = 100; private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.NoInventory"); private static readonly Dictionary<int, PendingSlotBreak> PendingSlotBreaks = new Dictionary<int, PendingSlotBreak>(); private static readonly HashSet<int> BreakingEggInstanceIds = new HashSet<int>(); private static float nextBackpackScanAt; private static int inventoryBreakLogCount; private static int backpackBreakLogCount; private static int rejectedBreakLogCount; private static bool IsNestEgg(Item item) { if ((Object)(object)item == (Object)null) { return false; } string a = NormalizeObjectName(((Object)((Component)item).gameObject).name); return string.Equals(a, "NestEgg", StringComparison.OrdinalIgnoreCase); } private static bool SlotContainsNestEgg(ItemSlot slot) { return slot != null && !slot.IsEmpty() && IsNestEgg(slot.prefab); } private static string NormalizeObjectName(string objectName) { if (string.IsNullOrWhiteSpace(objectName)) { return string.Empty; } string text = objectName.Trim(); if (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - "(Clone)".Length); text = text.Trim(); } return text; } private static Character ResolveCharacter(CharacterItems items) { if ((Object)(object)items == (Object)null) { return null; } Character val = ((Component)items).GetComponent<Character>(); if ((Object)(object)val == (Object)null) { val = ((Component)items).GetComponentInParent<Character>(); } return val; } private static bool IsValidLocalCharacter(Character character) { return (Object)(object)character != (Object)null && character.IsLocal && (Object)(object)character.data != (Object)null && (Object)(object)character.player != (Object)null; } private static bool IsEggLegallyHeldFromSlot(CharacterItems items, Character character, byte slotId) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 if ((Object)(object)items == (Object)null || (Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null) { return false; } if (!items.currentSelectedSlot.IsSome || items.currentSelectedSlot.Value != slotId) { return false; } Item currentItem = character.data.currentItem; return IsNestEgg(currentItem) && (int)currentItem.itemState == 1; } private static bool IsRecentNormalEquip(CharacterItems items, byte slotId) { if ((Object)(object)items == (Object)null || !items.lastSelectedSlot.IsSome || items.lastSelectedSlot.Value != slotId) { return false; } return Time.time - items.lastEquippedSlotTime < 0.75f; } private static Optionable<byte> FindHeldEggBackingSlot(CharacterItems items, Character character) { //IL_0027: 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_00f0: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)items == (Object)null || (Object)(object)character == (Object)null || (Object)(object)character.player == (Object)null) { return Optionable<byte>.None; } if (items.currentSelectedSlot.IsSome) { byte value = items.currentSelectedSlot.Value; ItemSlot itemSlot = character.player.GetItemSlot(value); if (SlotContainsNestEgg(itemSlot)) { return Optionable<byte>.Some(value); } } ItemSlot[] itemSlots = character.player.itemSlots; if (itemSlots != null) { for (byte b = 0; b < itemSlots.Length; b++) { if (SlotContainsNestEgg(itemSlots[b])) { return Optionable<byte>.Some(b); } } } if (SlotContainsNestEgg(character.player.tempFullSlot)) { return Optionable<byte>.Some((byte)250); } return Optionable<byte>.None; } private static bool TryFindIllegalEggSlot(CharacterItems items, Character character, out byte illegalSlotId) { illegalSlotId = 0; if ((Object)(object)items == (Object)null || (Object)(object)character == (Object)null || (Object)(object)character.player == (Object)null) { return false; } ItemSlot[] itemSlots = character.player.itemSlots; if (itemSlots != null) { for (byte b = 0; b < itemSlots.Length; b++) { ItemSlot slot = itemSlots[b]; if (SlotContainsNestEgg(slot) && !IsEggLegallyHeldFromSlot(items, character, b) && !IsRecentNormalEquip(items, b)) { illegalSlotId = b; return true; } } } if (SlotContainsNestEgg(character.player.tempFullSlot) && !IsEggLegallyHeldFromSlot(items, character, 250) && !IsRecentNormalEquip(items, 250)) { illegalSlotId = 250; return true; } return false; } private static bool CanBreakLocally(Item egg) { if ((Object)(object)egg == (Object)null) { return false; } if (!PhotonNetwork.InRoom || (Object)(object)((MonoBehaviourPun)egg).photonView == (Object)null) { return true; } return ((MonoBehaviourPun)egg).photonView.IsMine; } private static void PrepareEggForForcedBreak(Item egg, Vector3 dropPosition) { //IL_0026: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_00e6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)egg == (Object)null) { return; } ((Component)egg).transform.SetParent((Transform)null, true); ((Component)egg).transform.position = dropPosition; egg.itemState = (ItemState)0; egg.holderCharacter = null; egg.backpackSlotTransform = null; egg.backpackReference = Optionable<(byte, BackpackReference)>.None; if ((Object)(object)egg.rig != (Object)null) { egg.rig.position = dropPosition; egg.rig.useGravity = true; egg.rig.isKinematic = false; egg.rig.interpolation = (RigidbodyInterpolation)1; egg.rig.collisionDetectionMode = (CollisionDetectionMode)2; egg.rig.excludeLayers = LayerMask.op_Implicit(0); egg.rig.linearVelocity = Vector3.down * 1.5f; egg.rig.angularVelocity = new Vector3(1.5f, 0.75f, -1f); } Collider[] array = egg.colliders; if (array == null || array.Length == 0) { array = ((Component)egg).GetComponentsInChildren<Collider>(true); } foreach (Collider val in array) { if (!((Object)(object)val == (Object)null)) { val.enabled = true; val.isTrigger = false; } } Renderer[] componentsInChildren = ((Component)egg).GetComponentsInChildren<Renderer>(true); for (int j = 0; j < componentsInChildren.Length; j++) { if ((Object)(object)componentsInChildren[j] != (Object)null) { componentsInChildren[j].enabled = true; } } } private unsafe static bool ForceBreakEgg(Item egg, Vector3 dropPosition, string reason) { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) if (!IsNestEgg(egg)) { return false; } int instanceID = ((Object)egg).GetInstanceID(); if (!BreakingEggInstanceIds.Add(instanceID)) { return false; } if (!CanBreakLocally(egg)) { BreakingEggInstanceIds.Remove(instanceID); LogRejected(egg, reason, "Local client does not own the egg PhotonView."); return false; } BreakableEgg val = ((Component)egg).GetComponent<BreakableEgg>(); if ((Object)(object)val == (Object)null) { val = ((Component)egg).GetComponentInChildren<BreakableEgg>(true); } if ((Object)(object)val == (Object)null) { BreakingEggInstanceIds.Remove(instanceID); LogRejected(egg, reason, "BreakableEgg component was not found."); return false; } try { PrepareEggForForcedBreak(egg, dropPosition); ((Breakable)val).spawnsItemsKinematic = false; ((Breakable)val).ragdollCharacterOnBreak = false; ((Breakable)val).Break((Collision)null); ManualLogSource logger = Logger; string[] obj = new string[6] { "[NoInventory] NestEgg was forcibly broken. Reason=", reason, " | Position=", null, null, null }; Vector3 val2 = dropPosition; obj[3] = ((object)(*(Vector3*)(&val2))/*cast due to .constrained prefix*/).ToString(); obj[4] = " | ViewID="; obj[5] = (((Object)(object)((MonoBehaviourPun)egg).photonView != (Object)null) ? ((MonoBehaviourPun)egg).photonView.ViewID.ToString() : "None"); logger.LogWarning((object)string.Concat(obj)); return true; } catch (Exception ex) { BreakingEggInstanceIds.Remove(instanceID); Logger.LogError((object)("[NoInventory] Failed to forcibly break NestEgg. Reason=" + reason + " | Exception=" + ex)); return false; } } private static Vector3 GetHandDropPosition(Character character, Item egg) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_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_0096: 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) //IL_006f: 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_00a3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null) { return ((Object)(object)egg != (Object)null) ? ((Component)egg).transform.position : Vector3.zero; } Vector3 val = ((Component)character).transform.forward; if ((Object)(object)character.data != (Object)null && ((Vector3)(ref character.data.lookDirection)).sqrMagnitude > 0.001f) { val = ((Vector3)(ref character.data.lookDirection)).normalized; } return character.Center + val * 0.3f + Vector3.down * 0.15f; } private static Vector3 GetBackpackDropPosition(Item egg, BackpackReference backpackReference) { //IL_0001: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_0054: 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_005e: 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_00ba: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)backpackReference.view != (Object)null) { Character component = ((Component)backpackReference.view).GetComponent<Character>(); if ((Object)(object)component != (Object)null) { return component.Center + ((Component)component).transform.forward * 0.25f + Vector3.down * 0.1f; } return ((Component)backpackReference.view).transform.position + Vector3.up * 0.25f; } return ((Object)(object)egg != (Object)null) ? (((Component)egg).transform.position + Vector3.down * 0.1f) : Vector3.zero; } private static void BreakHeldEgg(CharacterItems items, Optionable<byte> backingSlot, Optionable<byte> slotToEquipAfterBreak, string reason) { //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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)items == (Object)null) { return; } Character val = ResolveCharacter(items); if (!IsValidLocalCharacter(val)) { return; } Item currentItem = val.data.currentItem; if (!IsNestEgg(currentItem)) { return; } if (backingSlot.IsNone) { backingSlot = FindHeldEggBackingSlot(items, val); } if (backingSlot.IsSome) { ItemSlot itemSlot = val.player.GetItemSlot(backingSlot.Value); if (SlotContainsNestEgg(itemSlot)) { val.player.EmptySlot(backingSlot); } } Vector3 handDropPosition = GetHandDropPosition(val, currentItem); items.UnAttachEquippedItem(); if (ForceBreakEgg(currentItem, handDropPosition, reason) && inventoryBreakLogCount < 100) { inventoryBreakLogCount++; Logger.LogInfo((object)("[NoInventory] Inventory egg violation handled. Count=" + inventoryBreakLogCount + "/" + 100 + " | Reason=" + reason + " | BackingSlot=" + (backingSlot.IsSome ? backingSlot.Value.ToString() : "None"))); } ((MonoBehaviour)items).StartCoroutine(ContinueEquipAfterBreak(items, slotToEquipAfterBreak)); } private static IEnumerator ContinueEquipAfterBreak(CharacterItems items, Optionable<byte> requestedSlot) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result