Decompiled source of WatchEgg v1.0.4
WatchEgg.dll
Decompiled 2 months 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.1")] public sealed class StaminaFull : BaseUnityPlugin { [HarmonyPatch(typeof(CharacterAfflictions), "AddStatus", new Type[] { typeof(STATUSTYPE), typeof(float), typeof(bool), typeof(bool), typeof(bool) })] private static class CharacterAfflictionsAddStatusPatch { [HarmonyPrefix] private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE __0, float __1, bool __2, bool __3, bool __4, ref bool __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (__1 <= 0f || !CanApplyProtection(__instance)) { return true; } __result = false; LogBlockedStatus(__0, __1, "AddStatus"); return false; } } [HarmonyPatch(typeof(CharacterAfflictions), "AdjustStatus", new Type[] { typeof(STATUSTYPE), typeof(float), typeof(bool) })] private static class CharacterAfflictionsAdjustStatusPatch { [HarmonyPrefix] private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE __0, float __1, bool __2) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (__1 <= 0f || !CanApplyProtection(__instance)) { return true; } LogBlockedStatus(__0, __1, "AdjustStatus"); return false; } } [HarmonyPatch(typeof(CharacterAfflictions), "SetStatus", new Type[] { typeof(STATUSTYPE), typeof(float), typeof(bool) })] private static class CharacterAfflictionsSetStatusPatch { [HarmonyPrefix] private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE __0, float __1, bool __2) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!CanApplyProtection(__instance)) { return true; } float currentStatus = __instance.GetCurrentStatus(__0); if (__1 <= currentStatus) { return true; } LogBlockedStatus(__0, __1 - currentStatus, "SetStatus"); return false; } } [HarmonyPatch(typeof(CharacterAfflictions), "AddAffliction", new Type[] { typeof(Affliction), typeof(bool) })] private static class CharacterAfflictionsAddAfflictionPatch { [HarmonyPrefix] private static bool Prefix(CharacterAfflictions __instance, Affliction __0, bool __1) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) if (!CanApplyProtection(__instance)) { return true; } if (blockedAfflictionLogCount < 50) { blockedAfflictionLogCount++; string text = ((__0 != null) ? ((object)__0).GetType().Name : "null"); ManualLogSource modLogger = ModLogger; if (modLogger != null) { string[] obj = new string[7] { "[StaminaFull] Affliction blocked ", $"({blockedAfflictionLogCount}/", $"{50}). ", "Affliction=", text, ", Scene=", null }; Scene activeScene = SceneManager.GetActiveScene(); obj[6] = ((Scene)(ref activeScene)).name; modLogger.LogInfo((object)string.Concat(obj)); } } return false; } } [HarmonyPatch(typeof(CharacterAfflictions), "AddThorn", new Type[] { typeof(Vector3) })] private static class CharacterAfflictionsAddThornPositionPatch { [HarmonyPrefix] private static bool Prefix(CharacterAfflictions __instance, Vector3 __0) { if (!CanApplyProtection(__instance)) { return true; } LogBlockedThorn(); return false; } } [HarmonyPatch(typeof(CharacterAfflictions), "AddThorn", new Type[] { typeof(ushort) })] private static class CharacterAfflictionsAddThornIndexPatch { [HarmonyPrefix] private static bool Prefix(CharacterAfflictions __instance, ushort __0) { if (!CanApplyProtection(__instance)) { return true; } LogBlockedThorn(); return false; } } [HarmonyPatch(typeof(CharacterAfflictions), "RPC_EnableThorn", new Type[] { typeof(int) })] private static class CharacterAfflictionsEnableThornPatch { [HarmonyPrefix] private static bool Prefix(CharacterAfflictions __instance, int __0) { if (!CanApplyProtection(__instance)) { return true; } LogBlockedThorn(); return false; } } [HarmonyPatch(typeof(Character), "FixedUpdate")] private static class CharacterFixedUpdatePatch { [HarmonyPostfix] private static void Postfix(Character __instance) { if (CanApplyProtection(__instance)) { ClearAllNegativeStates(__instance); } } } public const string PluginGUID = "Sapphire009.StaminaFull"; public const string PluginName = "StaminaFull"; public const string PluginVersion = "1.0.1"; private const string BuildMarker = "StatusProtection-NormalStamina-R3"; private const int MaximumLogCount = 50; internal static ManualLogSource ModLogger; private static int blockedStatusLogCount; private static int blockedAfflictionLogCount; private static int blockedThornLogCount; private Harmony harmony; private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown ModLogger = ((BaseUnityPlugin)this).Logger; harmony = new Harmony("Sapphire009.StaminaFull"); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"StaminaFull 1.0.1 loaded. Build: StatusProtection-NormalStamina-R3. Complete status protection is enabled outside Airport. Original stamina consumption remains enabled."); } private void OnDestroy() { blockedStatusLogCount = 0; blockedAfflictionLogCount = 0; blockedThornLogCount = 0; if (harmony != null) { harmony.UnpatchSelf(); harmony = null; } ModLogger = null; } internal static bool IsAirportScene() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; if (string.IsNullOrEmpty(name)) { return false; } return name.IndexOf("Airport", StringComparison.OrdinalIgnoreCase) >= 0; } internal static bool CanApplyProtection(Character character) { if ((Object)(object)character == (Object)null || !character.IsLocal || (Object)(object)character.data == (Object)null || character.refs == null || (Object)(object)character.refs.afflictions == (Object)null) { return false; } if (IsAirportScene()) { return false; } return true; } internal static bool CanApplyProtection(CharacterAfflictions afflictions) { if ((Object)(object)afflictions == (Object)null) { return false; } return CanApplyProtection(afflictions.character); } internal static void ClearAllNegativeStates(Character character) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (!CanApplyProtection(character)) { return; } CharacterAfflictions afflictions = character.refs.afflictions; bool flag = false; int numStatusTypes = CharacterAfflictions.NumStatusTypes; for (int i = 0; i < numStatusTypes; i++) { STATUSTYPE val = (STATUSTYPE)i; if (!(afflictions.GetCurrentStatus(val) <= 0f)) { afflictions.SetStatus(val, 0f, false); flag = true; } } if (afflictions.isWebbed) { afflictions.SetStatus((STATUSTYPE)11, 0f, false); afflictions.isWebbed = false; flag = true; } if (flag) { afflictions.PushStatuses((Player)null); } if (afflictions.afflictionList != null && afflictions.afflictionList.Count > 0) { afflictions.ClearAllAfflictions(); } if (afflictions.physicalThorns == null) { return; } for (int num = afflictions.physicalThorns.Count - 1; num >= 0; num--) { ThornOnMe val2 = afflictions.physicalThorns[num]; if (!((Object)(object)val2 == (Object)null) && val2.stuckIn) { afflictions.RemoveThorn(val2); } } } private static void LogBlockedStatus(STATUSTYPE statusType, float amount, string source) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if (blockedStatusLogCount < 50) { blockedStatusLogCount++; ManualLogSource modLogger = ModLogger; if (modLogger != null) { string[] obj = new string[9] { "[StaminaFull] Status blocked ", $"({blockedStatusLogCount}/", $"{50}). ", $"Status={statusType}, ", $"Amount={amount:0.0000}, ", "Source=", source, ", Scene=", null }; Scene activeScene = SceneManager.GetActiveScene(); obj[8] = ((Scene)(ref activeScene)).name; modLogger.LogInfo((object)string.Concat(obj)); } } } private static void LogBlockedThorn() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (blockedThornLogCount < 50) { blockedThornLogCount++; ManualLogSource modLogger = ModLogger; if (modLogger != null) { string[] obj = new string[5] { "[StaminaFull] Thorn blocked ", $"({blockedThornLogCount}/", $"{50}). ", "Scene=", null }; Scene activeScene = SceneManager.GetActiveScene(); obj[4] = ((Scene)(ref activeScene)).name; modLogger.LogInfo((object)string.Concat(obj)); } } } } namespace Sapphire009.WatchEgg; [HarmonyPatch(typeof(CharacterItems), "EquipSlot")] public static class AutoDrop { [HarmonyPatch(typeof(CharacterItems), "DropItemRpc")] private static class DropItemRpcPatch { [HarmonyPrefix] private unsafe static void Prefix(CharacterItems __instance, float throwCharge, byte slotID, Vector3 spawnPos) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = Character.localCharacter; string text = "null"; bool flag = false; if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null && (Object)(object)localCharacter.data.currentItem != (Object)null) { Item currentItem = localCharacter.data.currentItem; text = ((Object)((Component)currentItem).gameObject).name; flag = IsNestEggName(text); } string[] obj = new string[10] { "DropItemRpc CALLED | SlotID=", slotID.ToString(), " | ThrowCharge=", throwCharge.ToString(), " | SpawnPosition=", null, null, null, null, null }; Vector3 val = spawnPos; obj[5] = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString(); obj[6] = " | CurrentItem="; obj[7] = text; obj[8] = " | IsNestEgg="; obj[9] = flag.ToString(); LogWarning(string.Concat(obj)); } } public const string DeveloperName = "Sapphire009"; public const string TargetPrefabName = "NestEgg"; private const string LogPrefix = "[AutoDrop] "; private static ManualLogSource logger; public static void SetLogger(ManualLogSource pluginLogger) { logger = pluginLogger; LogInfo("AutoDrop initialized. Target prefab: NestEgg"); } [HarmonyPrepare] private static bool Prepare() { LogInfo("PATCH READY: CharacterItems.EquipSlot"); return true; } [HarmonyPrefix] private static void Prefix(CharacterItems __instance, Optionable<byte> slotID) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) LogInfo("EquipSlot PREFIX entered. | RequestedSlot=" + FormatSlot(slotID)); if ((Object)(object)__instance == (Object)null) { LogError("CharacterItems instance is null."); return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { LogWarning("Character.localCharacter is null."); return; } if (localCharacter.refs == null || (Object)(object)localCharacter.refs.items == (Object)null) { LogWarning("Local CharacterItems reference is null."); return; } if ((Object)(object)localCharacter.refs.items != (Object)(object)__instance) { LogInfo("Non-local CharacterItems ignored."); return; } if ((Object)(object)localCharacter.data == (Object)null) { LogWarning("Character.data is null."); return; } if ((Object)(object)localCharacter.player == (Object)null) { LogWarning("Character.player is null."); return; } if (slotID.IsNone) { LogInfo("Requested slot is None. Ignored."); return; } if (__instance.currentSelectedSlot.IsNone) { LogWarning("CurrentSelectedSlot is None."); return; } byte value = __instance.currentSelectedSlot.Value; byte value2 = slotID.Value; if (value == value2) { LogInfo("Same slot selected. Ignored. | Slot=" + value); return; } Item currentItem = localCharacter.data.currentItem; if ((Object)(object)currentItem == (Object)null) { LogWarning("Current held Item is null."); return; } ItemSlot itemSlot = localCharacter.player.GetItemSlot(value); if (itemSlot == null) { LogError("Current ItemSlot is null. | SlotID=" + value); return; } string text = NormalizePrefabName(((Object)((Component)currentItem).gameObject).name); string text2 = (itemSlot.IsEmpty() ? string.Empty : NormalizePrefabName(itemSlot.GetPrefabName())); string text3 = ((currentItem.UIData != null) ? currentItem.UIData.itemName : "UIData null"); bool flag = IsNestEggName(text); bool flag2 = IsNestEggName(text2); LogInfo("Detection result | CurrentSlot=" + value + " | RequestedSlot=" + value2 + " | HeldObject=" + text + " | SlotPrefab=" + text2 + " | UIItemName=" + text3 + " | HeldIsNestEgg=" + flag + " | SlotIsNestEgg=" + flag2); if (!flag && !flag2) { LogInfo("Current item is not NestEgg."); return; } if (currentItem.UIData == null) { LogError("NestEgg detected, but currentItem.UIData is null."); return; } bool canPocket = currentItem.UIData.canPocket; bool canDrop = currentItem.UIData.canDrop; currentItem.UIData.canPocket = false; currentItem.UIData.canDrop = true; Item prefab = itemSlot.prefab; if ((Object)(object)prefab != (Object)null && prefab.UIData != null) { prefab.UIData.canPocket = false; prefab.UIData.canDrop = true; } LogWarning("NEST EGG CONFIRMED. Auto-drop setting applied. | canPocket: " + canPocket + " -> " + currentItem.UIData.canPocket + " | canDrop: " + canDrop + " -> " + currentItem.UIData.canDrop); } [HarmonyPostfix] private static void Postfix(CharacterItems __instance, Optionable<byte> slotID) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = Character.localCharacter; string text = "null"; if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null && (Object)(object)localCharacter.data.currentItem != (Object)null) { text = ((Object)((Component)localCharacter.data.currentItem).gameObject).name; } LogInfo("EquipSlot POSTFIX | RequestedSlot=" + FormatSlot(slotID) + " | CurrentItemAfter=" + text); } private static bool IsNestEggName(string objectName) { return string.Equals(NormalizePrefabName(objectName), "NestEgg", StringComparison.OrdinalIgnoreCase); } private static string NormalizePrefabName(string objectName) { if (string.IsNullOrEmpty(objectName)) { return string.Empty; } string text = objectName.Trim(); while (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - "(Clone)".Length).Trim(); } return text; } private static string FormatSlot(Optionable<byte> slotID) { if (slotID.IsSome) { return slotID.Value.ToString(); } return "None"; } private static void LogInfo(string message) { if (logger != null) { logger.LogInfo((object)("[AutoDrop] " + message)); } } private static void LogWarning(string message) { if (logger != null) { logger.LogWarning((object)("[AutoDrop] " + message)); } } private static void LogError(string message) { if (logger != null) { logger.LogError((object)("[AutoDrop] " + message)); } } } [DisallowMultipleComponent] public sealed class BrighteningEgg : MonoBehaviour { [HarmonyPatch(typeof(Item), "Awake")] private static class ItemAwakePatch { [HarmonyPostfix] private static void Postfix(Item __instance) { if (IsNestEgg(__instance) && !((Object)(object)((Component)__instance).GetComponent<BrighteningEgg>() != (Object)null)) { ((Component)__instance).gameObject.AddComponent<BrighteningEgg>(); } } } public const string DeveloperName = "Sapphire009"; public const string TargetPrefabName = "NestEgg"; private const string LogPrefix = "[BrighteningEgg] "; private const float MaximumMarkerSize = 34f; private const float MinimumMarkerSize = 23f; private const float NearDistance = 4f; private const float FarDistance = 120f; private const float ScreenEdgeMargin = 40f; private const float BottomScreenMargin = 72f; private const float LabelWidth = 100f; private const float LabelHeight = 30f; private const float LabelSpacing = 3f; private const float BaseLightIntensity = 2.3f; private const float LightPulseAmount = 0.55f; private const float LightPulseSpeed = 2.2f; private const float LightRange = 4.5f; private const float CameraSearchInterval = 1f; private static readonly Color MarkerColor = new Color(1f, 0.72f, 0.08f, 1f); private static readonly Color MarkerCenterColor = new Color(1f, 0.95f, 0.45f, 1f); private static readonly Color LabelColor = new Color(1f, 0.86f, 0.2f, 1f); private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.BrighteningEgg"); private static Texture2D circleTexture; private Item item; private GameObject lightObject; private Light eggLight; private Camera cachedCamera; private float nextCameraSearchTime; private GUIStyle labelStyle; private GUIStyle labelShadowStyle; private int cachedFontSize = -1; private void Awake() { item = ((Component)this).GetComponent<Item>(); if (!IsNestEgg(item)) { ((Behaviour)this).enabled = false; return; } CreateCircleTexture(); CreateEggLight(); Logger.LogInfo((object)("[BrighteningEgg] Always-visible marker attached. | Object=" + ((Object)((Component)item).gameObject).name)); } private void Update() { if (!((Object)(object)item == (Object)null)) { UpdateEggLight(); } } private void OnGUI() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) if (!((Behaviour)this).enabled || (Object)(object)item == (Object)null || !((Component)this).gameObject.activeInHierarchy || IsHeldByLocalPlayer()) { return; } Camera viewCamera = GetViewCamera(); if (!((Object)(object)viewCamera == (Object)null)) { Vector3 val = CalculateWorldMarkerPosition(); Vector3 val2 = viewCamera.WorldToScreenPoint(val); if (!(val2.z <= 0f)) { float x = val2.x; float num = (float)Screen.height - val2.y; x = Mathf.Clamp(x, 40f, (float)Screen.width - 40f); num = Mathf.Clamp(num, 40f, (float)Screen.height - 72f); float num2 = Vector3.Distance(((Component)viewCamera).transform.position, val); float num3 = Mathf.InverseLerp(4f, 120f, num2); float markerSize = Mathf.Lerp(34f, 23f, num3); DrawMarker(x, num, markerSize); DrawEggLabel(x, num, markerSize); } } } private static void DrawMarker(float centerX, float centerY, float markerSize) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)circleTexture == (Object)null)) { Color color = GUI.color; float num = markerSize + 7f; Rect val = default(Rect); ((Rect)(ref val))..ctor(centerX - num * 0.5f, centerY - num * 0.5f, num, num); GUI.color = new Color(0f, 0f, 0f, 0.88f); GUI.DrawTexture(val, (Texture)(object)circleTexture, (ScaleMode)0, true); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(centerX - markerSize * 0.5f, centerY - markerSize * 0.5f, markerSize, markerSize); GUI.color = MarkerColor; GUI.DrawTexture(val2, (Texture)(object)circleTexture, (ScaleMode)0, true); float num2 = markerSize * 0.35f; Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(centerX - num2 * 0.5f, centerY - num2 * 0.5f, num2, num2); GUI.color = MarkerCenterColor; GUI.DrawTexture(val3, (Texture)(object)circleTexture, (ScaleMode)0, true); GUI.color = color; } } private void DrawEggLabel(float centerX, float centerY, float markerSize) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) int fontSize = Mathf.RoundToInt(Mathf.Clamp(markerSize * 0.68f, 16f, 23f)); PrepareLabelStyles(fontSize); float num = centerX - 50f; float num2 = centerY + markerSize * 0.5f + 3f; Rect val = default(Rect); ((Rect)(ref val))..ctor(num, num2, 100f, 30f); DrawLabelShadow(val, -2f, 0f); DrawLabelShadow(val, 2f, 0f); DrawLabelShadow(val, 0f, -2f); DrawLabelShadow(val, 0f, 2f); GUI.Label(val, "Egg", labelStyle); } private void DrawLabelShadow(Rect originalRect, float offsetX, float offsetY) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref originalRect)).x + offsetX, ((Rect)(ref originalRect)).y + offsetY, ((Rect)(ref originalRect)).width, ((Rect)(ref originalRect)).height); GUI.Label(val, "Egg", labelShadowStyle); } private void PrepareLabelStyles(int fontSize) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) if (labelStyle == null || labelShadowStyle == null || cachedFontSize != fontSize) { cachedFontSize = fontSize; labelStyle = new GUIStyle(GUI.skin.label); labelStyle.alignment = (TextAnchor)1; labelStyle.fontSize = fontSize; labelStyle.fontStyle = (FontStyle)1; labelStyle.wordWrap = false; labelStyle.clipping = (TextClipping)0; labelStyle.normal.textColor = LabelColor; labelShadowStyle = new GUIStyle(labelStyle); labelShadowStyle.normal.textColor = new Color(0f, 0f, 0f, 1f); } } private Camera GetViewCamera() { if ((Object)(object)cachedCamera != (Object)null && ((Behaviour)cachedCamera).isActiveAndEnabled) { return cachedCamera; } if (Time.unscaledTime < nextCameraSearchTime) { return null; } nextCameraSearchTime = Time.unscaledTime + 1f; Camera main = Camera.main; if ((Object)(object)main != (Object)null && ((Behaviour)main).isActiveAndEnabled) { cachedCamera = main; return cachedCamera; } Camera[] allCameras = Camera.allCameras; foreach (Camera val in allCameras) { if (!((Object)(object)val == (Object)null) && ((Behaviour)val).isActiveAndEnabled) { cachedCamera = val; return cachedCamera; } } return null; } private Vector3 CalculateWorldMarkerPosition() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true); bool flag = false; Bounds val = default(Bounds); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || !val2.enabled) { continue; } Bounds bounds = val2.bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (!(((Vector3)(ref size)).sqrMagnitude <= 0.0001f)) { if (!flag) { val = bounds; flag = true; } else { ((Bounds)(ref val)).Encapsulate(bounds); } } } if (!flag) { return ((Component)this).transform.position + Vector3.up * 0.65f; } float num = Mathf.Clamp(((Bounds)(ref val)).extents.y * 0.35f, 0.12f, 0.45f); return new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).max.y + num, ((Bounds)(ref val)).center.z); } private void CreateEggLight() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) lightObject = new GameObject("WatchEgg_NestEgg_AlwaysLight"); lightObject.transform.SetParent(((Component)this).transform, false); lightObject.transform.localPosition = CalculateLightLocalPosition(); lightObject.transform.localRotation = Quaternion.identity; eggLight = lightObject.AddComponent<Light>(); eggLight.type = (LightType)2; eggLight.color = MarkerColor; eggLight.intensity = 2.3f; eggLight.range = 4.5f; eggLight.shadows = (LightShadows)0; eggLight.renderMode = (LightRenderMode)0; eggLight.bounceIntensity = 0f; } private void UpdateEggLight() { if (!((Object)(object)eggLight == (Object)null) && !((Object)(object)lightObject == (Object)null)) { if (!lightObject.activeSelf) { lightObject.SetActive(true); } float num = (Mathf.Sin(Time.unscaledTime * 2.2f) + 1f) * 0.5f; eggLight.intensity = 2.3f + num * 0.55f; } } private Vector3 CalculateLightLocalPosition() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { return Vector3.zero; } bool flag = false; Bounds val = default(Bounds); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || !val2.enabled) { continue; } Bounds bounds = val2.bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (!(((Vector3)(ref size)).sqrMagnitude <= 0.0001f)) { if (!flag) { val = bounds; flag = true; } else { ((Bounds)(ref val)).Encapsulate(bounds); } } } if (!flag) { return Vector3.zero; } return ((Component)this).transform.InverseTransformPoint(((Bounds)(ref val)).center); } private bool IsHeldByLocalPlayer() { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null) { return false; } return localCharacter.IsLocal && (Object)(object)localCharacter.data.currentItem == (Object)(object)item; } private static void CreateCircleTexture() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)circleTexture != (Object)null) { return; } circleTexture = new Texture2D(64, 64, (TextureFormat)4, false); ((Object)circleTexture).name = "WatchEgg_AlwaysVisibleCircle"; ((Texture)circleTexture).wrapMode = (TextureWrapMode)1; ((Texture)circleTexture).filterMode = (FilterMode)1; ((Object)circleTexture).hideFlags = (HideFlags)61; Color[] array = (Color[])(object)new Color[4096]; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(31.5f, 31.5f); float num = 30.08f; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { float num2 = Vector2.Distance(new Vector2((float)j, (float)i), val); float num3 = Mathf.Clamp01((num - num2) * 0.8f); array[i * 64 + j] = new Color(1f, 1f, 1f, num3); } } circleTexture.SetPixels(array); circleTexture.Apply(false, true); } private void OnDestroy() { if ((Object)(object)lightObject != (Object)null) { Object.Destroy((Object)(object)lightObject); lightObject = null; } eggLight = null; cachedCamera = null; } public static bool IsNestEgg(Item targetItem) { if ((Object)(object)targetItem == (Object)null) { return false; } return IsNestEggName(((Object)((Component)targetItem).gameObject).name); } public static bool IsNestEggName(string objectName) { return string.Equals(NormalizePrefabName(objectName), "NestEgg", StringComparison.OrdinalIgnoreCase); } private static string NormalizePrefabName(string objectName) { if (string.IsNullOrEmpty(objectName)) { return string.Empty; } string text = objectName.Trim(); while (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - "(Clone)".Length).Trim(); } return text; } } [DisallowMultipleComponent] public sealed class CountUI : MonoBehaviour { [HarmonyPatch(typeof(CharacterSpawner), "Update")] private static class CharacterSpawnerUpdatePatch { [HarmonyPostfix] private static void Postfix() { EnsureCountUIExists(); } } public const string DeveloperName = "Sapphire009"; private const string LogPrefix = "[CountUI] "; private const float ReferenceScreenHeight = 1080f; private const float ReferenceWidth = 360f; private const float ReferenceHeight = 48f; private const float ReferenceBottomMargin = 115f; private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.CountUI"); private static CountUI instance; private GUIStyle textStyle; private GUIStyle shadowStyle; private int cachedFontSize = -1; private void Awake() { if ((Object)(object)instance != (Object)null && (Object)(object)instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); Logger.LogInfo((object)"[CountUI] Broken egg counter UI created."); } private void OnDestroy() { if ((Object)(object)instance == (Object)(object)this) { instance = null; } } private void OnGUI() { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) if (ShouldDisplay()) { PrepareStyles(); float num = Mathf.Clamp((float)Screen.height / 1080f, 0.75f, 1.5f); float num2 = 360f * num; float num3 = 48f * num; float num4 = ((float)Screen.width - num2) * 0.5f; float num5 = (float)Screen.height - 115f * num - num3; Rect val = default(Rect); ((Rect)(ref val))..ctor(num4, num5, num2, num3); string text = "BROKEN EGGS : " + EggCheckpoint.BrokenEggCount; Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 2f * num, ((Rect)(ref val)).y + 2f * num, ((Rect)(ref val)).width, ((Rect)(ref val)).height); GUI.Label(val2, text, shadowStyle); GUI.Label(val, text, textStyle); } } private static bool ShouldDisplay() { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || !localCharacter.IsLocal) { return false; } if (!EggCheckpoint.HasCheckpoint && EggCheckpoint.BrokenEggCount <= 0) { return false; } return true; } private void PrepareStyles() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.RoundToInt(Mathf.Clamp((float)Screen.height / 1080f * 26f, 19f, 34f)); if (textStyle == null || shadowStyle == null || cachedFontSize != num) { cachedFontSize = num; textStyle = new GUIStyle(GUI.skin.label); textStyle.alignment = (TextAnchor)4; textStyle.fontSize = num; textStyle.fontStyle = (FontStyle)1; textStyle.normal.textColor = Color.white; textStyle.wordWrap = false; textStyle.clipping = (TextClipping)0; shadowStyle = new GUIStyle(textStyle); shadowStyle.normal.textColor = new Color(0f, 0f, 0f, 0.9f); } } private static void EnsureCountUIExists() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)instance != (Object)null)) { GameObject val = new GameObject("WatchEgg_BrokenEgg_CountUI"); val.AddComponent<CountUI>(); } } } [DisallowMultipleComponent] public sealed class EggCheckpoint : MonoBehaviour { [HarmonyPatch(typeof(Item), "Awake")] private static class ItemAwakePatch { [HarmonyPostfix] private static void Postfix(Item __instance) { if (IsNestEgg(__instance) && !((Object)(object)((Component)__instance).GetComponent<EggCheckpoint>() != (Object)null)) { ((Component)__instance).gameObject.AddComponent<EggCheckpoint>(); } } } [HarmonyPatch(typeof(Breakable), "Break")] private static class BreakableBreakPatch { [HarmonyPrefix] private static void Prefix(Breakable __instance) { if ((Object)(object)__instance == (Object)null) { return; } Item val = ((Component)__instance).GetComponent<Item>(); if ((Object)(object)val == (Object)null) { val = ((Component)__instance).GetComponentInParent<Item>(); } if ((Object)(object)val == (Object)null) { val = ((Component)__instance).GetComponentInChildren<Item>(true); } if (IsNestEgg(val)) { int item = ((!((Object)(object)((MonoBehaviourPun)val).photonView != (Object)null) || ((MonoBehaviourPun)val).photonView.ViewID <= 0) ? ((Object)((Component)val).gameObject).GetInstanceID() : ((MonoBehaviourPun)val).photonView.ViewID); if (!CountedBrokenViewIds.Contains(item)) { CountedBrokenViewIds.Add(item); BrokenEggCount++; Logger.LogWarning((object)("[EggCheckpoint] NestEgg broken. | BrokenCount=" + BrokenEggCount + " | EggID=" + item)); } } } } public const string DeveloperName = "Sapphire009"; public const string TargetPrefabName = "NestEgg"; public const float TargetCheckpointDistance = 50f; private const float TargetCheckpointDistanceSquared = 2500f; private const float MinimumGroundNormalY = 0.55f; private const float GroundCastStartHeight = 2.5f; private const float GroundCastDistance = 6f; private const float InitialGroundCastDistance = 12f; private const float GroundCastRadius = 0.18f; private const float GroundSurfacePadding = 0.015f; private const float MaximumEggGroundDistanceFromHolder = 1.6f; private const string LogPrefix = "[EggCheckpoint] "; private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.EggCheckpoint"); private static readonly HashSet<int> CountedBrokenViewIds = new HashSet<int>(); private static int activeSceneHandle = int.MinValue; private Item item; private Quaternion eggRestRotation; private float pivotToEggBottom = 0.2f; public static bool HasCheckpoint { get; private set; } public static Vector3 CheckpointPosition { get; private set; } public static Quaternion CheckpointRotation { get; private set; } public static int CheckpointNumber { get; private set; } public static int BrokenEggCount { get; private set; } public static float DistanceFromLastCheckpoint { get; private set; } private void Awake() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) ResetStaticDataWhenSceneChanged(); item = ((Component)this).GetComponent<Item>(); if (!IsNestEgg(item)) { ((Behaviour)this).enabled = false; return; } eggRestRotation = ((Component)this).transform.rotation; CacheEggBottomOffset(); CacheInitialCheckpoint(); Logger.LogInfo((object)("[EggCheckpoint] Attached to " + ((Object)((Component)item).gameObject).name + " | Radius=" + 50f + " | DistanceMode=EggToCheckpoint3DSphere | MustBeHeld=True")); } private void Update() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Invalid comparison between Unknown and I4 //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) ResetStaticDataWhenSceneChanged(); if ((Object)(object)item == (Object)null) { return; } if (!HasCheckpoint) { CacheInitialCheckpoint(); if (!HasCheckpoint) { DistanceFromLastCheckpoint = 0f; return; } } Vector3 val = ((Component)this).transform.position - CheckpointPosition; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; DistanceFromLastCheckpoint = Mathf.Sqrt(sqrMagnitude); if (sqrMagnitude < 2500f || (int)item.itemState != 1 || (Object)(object)item.holderCharacter == (Object)null) { return; } Character holderCharacter = item.holderCharacter; if (IsHolderOnSafeGround(holderCharacter) && TryGetSafeHeldEggPosition(holderCharacter, out var result)) { Vector3 val2 = result - CheckpointPosition; if (!(((Vector3)(ref val2)).sqrMagnitude < 2500f)) { SaveCheckpoint(result); } } } private bool TryGetSafeHeldEggPosition(Character holder, out Vector3 result) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) result = Vector3.zero; if (!IsHolderOnSafeGround(holder)) { return false; } if (TryCastGroundBelowHeldEgg(holder, out var groundHit)) { result = ((RaycastHit)(ref groundHit)).point + Vector3.up * (pivotToEggBottom + 0.015f); return true; } if (!TryCastGroundAtHolder(holder, out groundHit)) { return false; } result = ((RaycastHit)(ref groundHit)).point + Vector3.up * (pivotToEggBottom + 0.015f); return true; } private static bool IsHolderOnSafeGround(Character holder) { if ((Object)(object)holder == (Object)null || (Object)(object)holder.data == (Object)null) { return false; } if (!holder.data.isGrounded) { return false; } if (holder.data.isClimbing || holder.data.isRopeClimbing || holder.data.isVineClimbing) { return false; } if (holder.data.dead || holder.data.fullyPassedOut) { return false; } if (holder.data.groundNormal.y < 0.55f) { return false; } return true; } private bool TryCastGroundBelowHeldEgg(Character holder, out RaycastHit groundHit) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) groundHit = default(RaycastHit); if ((Object)(object)holder == (Object)null || (Object)(object)holder.data == (Object)null) { return false; } Vector3 groundPos = holder.data.groundPos; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(((Component)this).transform.position.x, groundPos.y + 2.5f, ((Component)this).transform.position.z); if (!Physics.SphereCast(val, 0.18f, Vector3.down, ref groundHit, 6f, LayerMask.op_Implicit(HelperFunctions.GetMask((LayerType)1)), (QueryTriggerInteraction)1)) { return false; } if (((RaycastHit)(ref groundHit)).normal.y < 0.55f) { return false; } Vector3 val2 = ((RaycastHit)(ref groundHit)).point - groundPos; val2.y = 0f; return ((Vector3)(ref val2)).sqrMagnitude <= 2.5600002f; } private static bool TryCastGroundAtHolder(Character holder, out RaycastHit groundHit) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) groundHit = default(RaycastHit); if ((Object)(object)holder == (Object)null || (Object)(object)holder.data == (Object)null) { return false; } Vector3 val = holder.data.groundPos + Vector3.up * 2.5f; if (!Physics.SphereCast(val, 0.18f, Vector3.down, ref groundHit, 6f, LayerMask.op_Implicit(HelperFunctions.GetMask((LayerType)1)), (QueryTriggerInteraction)1)) { return false; } return ((RaycastHit)(ref groundHit)).normal.y >= 0.55f; } private bool TryGetGroundPositionBelowEgg(float castDistance, out Vector3 result) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) result = Vector3.zero; Vector3 val = ((Component)this).transform.position + Vector3.up * 2.5f; RaycastHit val2 = default(RaycastHit); if (!Physics.SphereCast(val, 0.18f, Vector3.down, ref val2, castDistance, LayerMask.op_Implicit(HelperFunctions.GetMask((LayerType)1)), (QueryTriggerInteraction)1)) { return false; } if (((RaycastHit)(ref val2)).normal.y < 0.55f) { return false; } result = ((RaycastHit)(ref val2)).point + Vector3.up * (pivotToEggBottom + 0.015f); return true; } private unsafe void SaveCheckpoint(Vector3 newCheckpointPosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) Vector3 checkpointPosition = CheckpointPosition; float num = Vector3.Distance(checkpointPosition, newCheckpointPosition); CheckpointPosition = newCheckpointPosition; CheckpointRotation = eggRestRotation; HasCheckpoint = true; CheckpointNumber++; DistanceFromLastCheckpoint = 0f; ManualLogSource logger = Logger; string[] obj = new string[10] { "[EggCheckpoint] New held-egg checkpoint saved. | Number=", CheckpointNumber.ToString(), " | Distance=", num.ToString(), " | PreviousPosition=", null, null, null, null, null }; Vector3 val = checkpointPosition; obj[5] = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString(); obj[6] = " | NewPosition="; obj[7] = ((object)CheckpointPosition/*cast due to .constrained prefix*/).ToString(); obj[8] = " | Holder="; obj[9] = GetCharacterName(((Object)(object)item != (Object)null) ? item.holderCharacter : null); logger.LogWarning((object)string.Concat(obj)); } private void CacheInitialCheckpoint() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 if (!HasCheckpoint && (TryGetGroundPositionBelowEgg(12f, out var result) || ((Object)(object)item != (Object)null && (int)item.itemState == 1 && (Object)(object)item.holderCharacter != (Object)null && TryGetSafeHeldEggPosition(item.holderCharacter, out result)))) { CheckpointPosition = result; CheckpointRotation = eggRestRotation; HasCheckpoint = true; CheckpointNumber = 1; DistanceFromLastCheckpoint = 0f; Logger.LogWarning((object)("[EggCheckpoint] Initial checkpoint cached. | Position=" + ((object)CheckpointPosition/*cast due to .constrained prefix*/).ToString())); } } private void CacheEggBottomOffset() { //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true); float num = float.PositiveInfinity; bool flag = false; Vector3 size; foreach (Collider val in componentsInChildren) { if ((Object)(object)val == (Object)null || !val.enabled || val.isTrigger) { continue; } Bounds bounds = val.bounds; size = ((Bounds)(ref bounds)).size; if (!(((Vector3)(ref size)).sqrMagnitude <= 0.0001f)) { if (((Bounds)(ref bounds)).min.y < num) { num = ((Bounds)(ref bounds)).min.y; } flag = true; } } if (!flag) { Renderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren2) { if ((Object)(object)val2 == (Object)null) { continue; } Bounds bounds2 = val2.bounds; size = ((Bounds)(ref bounds2)).size; if (!(((Vector3)(ref size)).sqrMagnitude <= 0.0001f)) { if (((Bounds)(ref bounds2)).min.y < num) { num = ((Bounds)(ref bounds2)).min.y; } flag = true; } } } if (!flag) { pivotToEggBottom = 0.2f; return; } float num2 = ((Component)this).transform.position.y - num; if (num2 <= 0.01f || num2 >= 3f) { pivotToEggBottom = 0.2f; } else { pivotToEggBottom = num2; } } public static bool TryGetCheckpoint(out Vector3 position, out Quaternion rotation) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) position = CheckpointPosition; rotation = CheckpointRotation; return HasCheckpoint; } public static void ResetCheckpoint() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) HasCheckpoint = false; CheckpointPosition = Vector3.zero; CheckpointRotation = Quaternion.identity; CheckpointNumber = 0; BrokenEggCount = 0; DistanceFromLastCheckpoint = 0f; CountedBrokenViewIds.Clear(); } private static void ResetStaticDataWhenSceneChanged() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); if (activeSceneHandle != ((Scene)(ref activeScene)).handle) { activeSceneHandle = ((Scene)(ref activeScene)).handle; ResetCheckpoint(); Logger.LogInfo((object)("[EggCheckpoint] Scene changed. Checkpoint data reset. | Scene=" + ((Scene)(ref activeScene)).name)); } } public static bool IsNestEgg(Item targetItem) { if ((Object)(object)targetItem == (Object)null) { return false; } return IsNestEggName(((Object)((Component)targetItem).gameObject).name); } public static bool IsNestEggName(string objectName) { return string.Equals(NormalizePrefabName(objectName), "NestEgg", StringComparison.OrdinalIgnoreCase); } private static string NormalizePrefabName(string objectName) { if (string.IsNullOrEmpty(objectName)) { return string.Empty; } string text = objectName.Trim(); while (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - "(Clone)".Length); text = text.Trim(); } return text; } private static string GetCharacterName(Character character) { if ((Object)(object)character == (Object)null) { return "Unknown"; } if ((Object)(object)((MonoBehaviourPun)character).photonView != (Object)null && ((MonoBehaviourPun)character).photonView.Owner != null && !string.IsNullOrEmpty(((MonoBehaviourPun)character).photonView.Owner.NickName)) { return ((MonoBehaviourPun)character).photonView.Owner.NickName; } return ((Object)((Component)character).gameObject).name; } } internal static class Magma { internal const string DeveloperName = "Sapphire009"; private const float ProtectionBypassDuration = 1.25f; private static Character activeLavaCharacter; private static float protectionBypassUntil; internal static void RegisterOriginalLavaHit(Character character) { if (!((Object)(object)character == (Object)null) && character.IsLocal && !((Object)(object)character.data == (Object)null) && !character.data.dead) { activeLavaCharacter = character; protectionBypassUntil = Time.time + 1.25f; } } internal static bool ShouldBypassStaminaFull(Character character) { if ((Object)(object)character == (Object)null || (Object)(object)activeLavaCharacter == (Object)null || (Object)(object)character != (Object)(object)activeLavaCharacter) { return false; } if (!character.IsLocal || (Object)(object)character.data == (Object)null || character.data.dead) { ClearActiveLavaCharacter(); return false; } if (Time.time > protectionBypassUntil) { ClearActiveLavaCharacter(); return false; } return true; } private static void ClearActiveLavaCharacter() { activeLavaCharacter = null; protectionBypassUntil = 0f; } } [HarmonyPatch(typeof(Lava), "HitPlayer", new Type[] { typeof(Character) })] internal static class MagmaLavaHitPlayerPatch { [HarmonyPrefix] [HarmonyPriority(800)] private static void Prefix(Character __0) { Magma.RegisterOriginalLavaHit(__0); } } [HarmonyPatch(typeof(StaminaFull), "CanApplyProtection", new Type[] { typeof(Character) })] internal static class MagmaStaminaFullProtectionPatch { [HarmonyPostfix] private static void Postfix(Character __0, ref bool __result) { if (__result && Magma.ShouldBypassStaminaFull(__0)) { __result = false; } } } [HarmonyPatch(typeof(Breakable), "OnCollisionEnter")] public static class NoBody { private const string TargetPrefabName = "NestEgg"; [HarmonyPrefix] private static bool Prefix(Breakable __instance, Collision collision) { if ((Object)(object)__instance == (Object)null || collision == null) { return true; } Item component = ((Component)__instance).GetComponent<Item>(); if ((Object)(object)component == (Object)null || !IsNestEgg(((Object)((Component)component).gameObject).name)) { return true; } Collider collider = collision.collider; if ((Object)(object)collider == (Object)null) { return true; } Bodypart componentInParent = ((Component)collider).GetComponentInParent<Bodypart>(); if ((Object)(object)componentInParent != (Object)null) { return false; } return true; } private static bool IsNestEgg(string objectName) { if (string.IsNullOrWhiteSpace(objectName)) { return false; } string text = objectName.Trim(); while (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - "(Clone)".Length).Trim(); } return string.Equals(text, "NestEgg", StringComparison.OrdinalIgnoreCase); } } public static class NoEat { private sealed class PendingNestEggBreak { public Vector3 BreakPosition; public float ExpireTime; public readonly HashSet<ushort> ItemIDs = new HashSet<ushort>(); public readonly HashSet<string> ObjectNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase); public readonly HashSet<string> ItemNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase); } [HarmonyPatch(typeof(Breakable), "Break")] private static class BreakableBreakPatch { [HarmonyPrefix] private unsafe static void Prefix(Breakable __instance) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if (IsNestEggBreakable(__instance, out var eggItem)) { RemoveExpiredBreakRecords(); PendingNestEggBreak pendingNestEggBreak = new PendingNestEggBreak(); pendingNestEggBreak.BreakPosition = ((Component)eggItem).transform.position; pendingNestEggBreak.ExpireTime = Time.time + 4f; RegisterSpawnList(__instance.instantiateOnBreak, pendingNestEggBreak); RegisterSpawnList(__instance.alternateInstantiateOnBreak, pendingNestEggBreak); RegisterSpawnList(__instance.instantiateNonItemOnBreak, pendingNestEggBreak); if (pendingNestEggBreak.ItemIDs.Count == 0 && pendingNestEggBreak.ObjectNames.Count == 0 && pendingNestEggBreak.ItemNames.Count == 0) { Logger.LogWarning((object)"[NoEat] NestEgg break detected, but no spawned Item prefab was found."); return; } PendingBreaks.Add(pendingNestEggBreak); ManualLogSource logger = Logger; string[] obj = new string[6] { "[NoEat] NestEgg break registered. | Position=", null, null, null, null, null }; Vector3 breakPosition = pendingNestEggBreak.BreakPosition; obj[1] = ((object)(*(Vector3*)(&breakPosition))/*cast due to .constrained prefix*/).ToString(); obj[2] = " | SpawnItemIDs="; obj[3] = pendingNestEggBreak.ItemIDs.Count.ToString(); obj[4] = " | SpawnNames="; obj[5] = pendingNestEggBreak.ObjectNames.Count.ToString(); logger.LogInfo((object)string.Concat(obj)); } } } [HarmonyPatch(typeof(Item), "Awake")] private static class ItemAwakePatch { [HarmonyPostfix] private static void Postfix(Item __instance) { if (!((Object)(object)__instance == (Object)null)) { if (IsNestEgg(__instance)) { EnsureTimedDespawn(__instance, "NestEgg"); } TryMarkSpawnedItem(__instance); } } } [HarmonyPatch(typeof(Item), "StartUsePrimary")] private static class StartUsePrimaryPatch { [HarmonyPrefix] private static bool Prefix(Item __instance) { if (!IsBlockedItem(__instance)) { return true; } LogBlocked(__instance, "StartUsePrimary"); return false; } } [HarmonyPatch(typeof(Item), "ContinueUsePrimary")] private static class ContinueUsePrimaryPatch { [HarmonyPrefix] private static bool Prefix(Item __instance) { return !IsBlockedItem(__instance); } } [HarmonyPatch(typeof(Item), "StartUseSecondary")] private static class StartUseSecondaryPatch { [HarmonyPrefix] private static bool Prefix(Item __instance) { if (!IsBlockedItem(__instance)) { return true; } LogBlocked(__instance, "StartUseSecondary"); return false; } } [HarmonyPatch(typeof(Item), "ContinueUseSecondary")] private static class ContinueUseSecondaryPatch { [HarmonyPrefix] private static bool Prefix(Item __instance) { return !IsBlockedItem(__instance); } } [HarmonyPatch(typeof(Item), "FinishCastSecondary")] private static class FinishCastSecondaryPatch { [HarmonyPrefix] private static bool Prefix(Item __instance) { if (!IsBlockedItem(__instance)) { return true; } LogBlocked(__instance, "FinishCastSecondary"); return false; } } [HarmonyPatch(typeof(Item), "ConsumeDelayed")] private static class ConsumeDelayedPatch { [HarmonyPrefix] private static bool Prefix(Item __instance, ref IEnumerator __result) { if (!IsBlockedItem(__instance)) { return true; } LogBlocked(__instance, "ConsumeDelayed"); __result = EmptyRoutine(); return false; } } private const string LogPrefix = "[NoEat] "; private const string TargetPrefabName = "NestEgg"; private const float PendingLifetime = 4f; private const float SpawnDetectionRadius = 6f; public const float GroundDespawnLifetime = 30f; private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.NoEat"); private static readonly List<PendingNestEggBreak> PendingBreaks = new List<PendingNestEggBreak>(); private static bool IsNestEggBreakable(Breakable breakable, out Item eggItem) { eggItem = null; if ((Object)(object)breakable == (Object)null) { return false; } eggItem = FindItem(((Component)breakable).gameObject); if ((Object)(object)eggItem == (Object)null) { return false; } return IsNestEgg(eggItem); } private static bool IsNestEgg(Item item) { if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).gameObject == (Object)null) { return false; } string a = NormalizeObjectName(((Object)((Component)item).gameObject).name); return string.Equals(a, "NestEgg", StringComparison.OrdinalIgnoreCase); } private static Item FindItem(GameObject sourceObject) { if ((Object)(object)sourceObject == (Object)null) { return null; } Item component = sourceObject.GetComponent<Item>(); if ((Object)(object)component != (Object)null) { return component; } component = sourceObject.GetComponentInParent<Item>(); if ((Object)(object)component != (Object)null) { return component; } return sourceObject.GetComponentInChildren<Item>(true); } private static void RegisterSpawnList(List<GameObject> spawnList, PendingNestEggBreak pendingBreak) { if (spawnList == null || pendingBreak == null) { return; } for (int i = 0; i < spawnList.Count; i++) { GameObject val = spawnList[i]; if ((Object)(object)val == (Object)null) { continue; } Item val2 = FindItem(val); if (!((Object)(object)val2 == (Object)null)) { pendingBreak.ItemIDs.Add(val2.itemID); AddObjectName(pendingBreak, ((Object)val).name); AddObjectName(pendingBreak, ((Object)((Component)val2).gameObject).name); if (val2.UIData != null) { AddItemName(pendingBreak, val2.UIData.itemName); } } } } private static void AddObjectName(PendingNestEggBreak pendingBreak, string objectName) { string text = NormalizeObjectName(objectName); if (!string.IsNullOrEmpty(text)) { pendingBreak.ObjectNames.Add(text); } } private static void AddItemName(PendingNestEggBreak pendingBreak, string itemName) { if (!string.IsNullOrWhiteSpace(itemName)) { pendingBreak.ItemNames.Add(itemName.Trim()); } } private static bool MatchesPendingBreak(Item item, PendingNestEggBreak pendingBreak) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null || pendingBreak == null) { return false; } float num = Vector3.Distance(((Component)item).transform.position, pendingBreak.BreakPosition); if (num > 6f) { return false; } if (pendingBreak.ItemIDs.Contains(item.itemID)) { return true; } string item2 = NormalizeObjectName(((Object)((Component)item).gameObject).name); if (pendingBreak.ObjectNames.Contains(item2)) { return true; } if (item.UIData != null && !string.IsNullOrWhiteSpace(item.UIData.itemName) && pendingBreak.ItemNames.Contains(item.UIData.itemName.Trim())) { return true; } return false; } private static void EnsureTimedDespawn(Item item, string sourceName) { if (!((Object)(object)item == (Object)null) && !((Object)(object)((Component)item).gameObject == (Object)null)) { WatchEggTimedDespawn watchEggTimedDespawn = ((Component)item).GetComponent<WatchEggTimedDespawn>(); if ((Object)(object)watchEggTimedDespawn == (Object)null) { watchEggTimedDespawn = ((Component)item).gameObject.AddComponent<WatchEggTimedDespawn>(); } watchEggTimedDespawn.Configure(sourceName); } } private static void TryMarkSpawnedItem(Item item) { //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null) { return; } RemoveExpiredBreakRecords(); if (PendingBreaks.Count == 0) { return; } if ((Object)(object)((Component)item).GetComponent<NoEatMarker>() != (Object)null) { EnsureTimedDespawn(item, "NestEgg break product"); return; } for (int num = PendingBreaks.Count - 1; num >= 0; num--) { PendingNestEggBreak pendingBreak = PendingBreaks[num]; if (MatchesPendingBreak(item, pendingBreak)) { ((Component)item).gameObject.AddComponent<NoEatMarker>(); EnsureTimedDespawn(item, "NestEgg break product"); Logger.LogInfo((object)("[NoEat] NestEgg spawned item marked as non-edible. | Object=" + ((Object)((Component)item).gameObject).name + " | ItemID=" + item.itemID + " | Position=" + ((object)((Component)item).transform.position/*cast due to .constrained prefix*/).ToString() + " | GroundDespawnSeconds=" + 30f)); break; } } } private static bool IsBlockedItem(Item item) { if ((Object)(object)item == (Object)null) { return false; } return (Object)(object)((Component)item).GetComponent<NoEatMarker>() != (Object)null; } private static void RemoveExpiredBreakRecords() { float time = Time.time; for (int num = PendingBreaks.Count - 1; num >= 0; num--) { if (!(PendingBreaks[num].ExpireTime > time)) { PendingBreaks.RemoveAt(num); } } } private static string NormalizeObjectName(string objectName) { if (string.IsNullOrWhiteSpace(objectName)) { return string.Empty; } string text = objectName.Trim(); while (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - "(Clone)".Length); text = text.Trim(); } return text; } private static void LogBlocked(Item item, string actionName) { string text = (((Object)(object)item != (Object)null) ? ((Object)((Component)item).gameObject).name : "null"); Logger.LogWarning((object)("[NoEat] Consumption blocked. | Action=" + actionName + " | Object=" + text)); } private static IEnumerator EmptyRoutine() { yield break; } } [DisallowMultipleComponent] public sealed class NoEatMarker : MonoBehaviour { } [DisallowMultipleComponent] public sealed class WatchEggTimedDespawn : MonoBehaviour { private const string LogPrefix = "[TimedDespawn] "; private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.TimedDespawn"); private Item item; private float accumulatedGroundTime; private bool lifetimeExpired; private bool destroyIssued; private string sourceName = "Unknown"; public float AccumulatedGroundTime => accumulatedGroundTime; public float RemainingGroundTime => Mathf.Max(0f, 30f - accumulatedGroundTime); private void Awake() { item = ((Component)this).GetComponent<Item>(); if ((Object)(object)item == (Object)null) { ((Behaviour)this).enabled = false; } } public void Configure(string configuredSourceName) { if (!string.IsNullOrWhiteSpace(configuredSourceName)) { sourceName = configuredSourceName; } } private void Update() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 if (destroyIssued || (Object)(object)item == (Object)null || (int)item.itemState > 0) { return; } if (!lifetimeExpired) { accumulatedGroundTime += Time.deltaTime; if (accumulatedGroundTime < 30f) { return; } lifetimeExpired = true; } TryDestroyExpiredObject(); } private void TryDestroyExpiredObject() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 if (!destroyIssued && !((Object)(object)item == (Object)null) && (int)item.itemState <= 0) { PhotonView photonView = ((MonoBehaviourPun)item).photonView; if (!PhotonNetwork.InRoom || (Object)(object)photonView == (Object)null || photonView.ViewID <= 0) { destroyIssued = true; Logger.LogInfo((object)("[TimedDespawn] Destroying expired local object. | Object=" + ((Object)((Component)this).gameObject).name + " | Source=" + sourceName + " | GroundSeconds=" + accumulatedGroundTime)); Object.Destroy((Object)(object)((Component)this).gameObject); } else if (photonView.IsMine || photonView.AmController) { destroyIssued = true; Logger.LogWarning((object)("[TimedDespawn] Destroying expired network object. | Object=" + ((Object)((Component)this).gameObject).name + " | Source=" + sourceName + " | ViewID=" + photonView.ViewID + " | GroundSeconds=" + accumulatedGroundTime)); PhotonNetwork.Destroy(((Component)this).gameObject); } } } } public static class NoInventory { [HarmonyPatch(typeof(CharacterItems), "EquipSlot")] private static class EquipSlotPatch { [HarmonyPrefix] [HarmonyPriority(800)] private static bool Prefix(CharacterItems __instance, Optionable<byte> slotID) { //IL_0124: Unknown result type (might be due to invalid IL or missing references) if (!IsLocalCharacterItems(__instance)) { return true; } if (slotID.IsNone || __instance.currentSelectedSlot.IsNone) { return true; } int instanceID = ((Object)__instance).GetInstanceID(); if (ForcedDropInProgress.Contains(instanceID)) { return true; } byte value = __instance.currentSelectedSlot.Value; byte value2 = slotID.Value; if (value == value2) { return true; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.player == (Object)null || (Object)(object)localCharacter.data == (Object)null) { return true; } ItemSlot itemSlot = localCharacter.player.GetItemSlot(value); Item currentItem = localCharacter.data.currentItem; bool flag = IsNestEgg(currentItem); bool flag2 = IsNestEggSlot(itemSlot); if (!flag && !flag2) { return true; } if (!flag) { DropStoredEggSlot(__instance, value, "Slot switch found stored NestEgg"); return true; } BeginHeldEggDrop(__instance, value, slotID, "Selected another inventory slot"); return false; } } [HarmonyPatch(typeof(Backpack), "Stash")] private static class GroundBackpackStashPatch { [HarmonyPrefix] [HarmonyPriority(800)] private static bool Prefix(Character interactor, byte backpackSlotID) { return !TryBlockBackpackStash(interactor, "Ground backpack stash blocked | BackpackSlot=" + backpackSlotID); } } [HarmonyPatch(typeof(CharacterBackpackHandler), "StashInBackpack")] private static class EquippedBackpackStashPatch { [HarmonyPrefix] [HarmonyPriority(800)] private static bool Prefix(Character interactor, byte backpackSlotID) { return !TryBlockBackpackStash(interactor, "Equipped backpack stash blocked | BackpackSlot=" + backpackSlotID); } } [HarmonyPatch(typeof(BackpackData), "AddItem")] private static class BackpackDataAddItemPatch { [HarmonyPrefix] [HarmonyPriority(800)] private static bool Prefix(Item prefab, ItemInstanceData data, byte backpackSlotID) { if (!IsNestEgg(prefab)) { return true; } LogWarning("Blocked NestEgg from BackpackData.AddItem | BackpackSlot=" + backpackSlotID); return false; } } [HarmonyPatch(typeof(Player), "SyncInventoryRPC")] private static class SyncInventoryPatch { [HarmonyPostfix] private static void Postfix(Player __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)Player.localPlayer != (Object)(object)__instance)) { Character character = __instance.character; if (!((Object)(object)character == (Object)null) && character.refs != null && !((Object)(object)character.refs.items == (Object)null)) { ScheduleInventoryValidation(character.refs.items, "Inventory sync received"); } } } } [HarmonyPatch(typeof(CharacterItems), "OnPickupAccepted")] private static class PickupAcceptedPatch { [HarmonyPostfix] private static void Postfix(CharacterItems __instance) { if (IsLocalCharacterItems(__instance)) { ScheduleInventoryValidation(__instance, "Pickup accepted"); } } } private const string TargetPrefabName = "NestEgg"; private const string LogPrefix = "[NoInventory] "; private const float InventoryValidationDelay = 0.85f; private const float HeldDestroyWaitTimeout = 2f; private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.NoInventory"); private static readonly HashSet<int> ForcedDropInProgress = new HashSet<int>(); private static readonly HashSet<int> ValidationScheduled = new HashSet<int>(); private static bool TryBlockBackpackStash(Character interactor, string reason) { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)interactor == (Object)null || !interactor.IsLocal || (Object)(object)interactor != (Object)(object)Character.localCharacter || interactor.refs == null || (Object)(object)interactor.refs.items == (Object)null || (Object)(object)interactor.player == (Object)null || (Object)(object)interactor.data == (Object)null) { return false; } CharacterItems items = interactor.refs.items; if (items.currentSelectedSlot.IsNone) { return false; } byte value = items.currentSelectedSlot.Value; ItemSlot itemSlot = interactor.player.GetItemSlot(value); bool flag = IsNestEgg(interactor.data.currentItem); bool flag2 = IsNestEggSlot(itemSlot); if (!flag && !flag2) { return false; } if (flag) { BeginHeldEggDrop(items, value, Optionable<byte>.None, reason); } else { DropStoredEggSlot(items, value, reason); } return true; } private unsafe static void BeginHeldEggDrop(CharacterItems items, byte slotId, Optionable<byte> nextSlot, string reason) { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) if (!IsLocalCharacterItems(items)) { return; } int instanceID = ((Object)items).GetInstanceID(); if (!ForcedDropInProgress.Add(instanceID)) { return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || (Object)(object)localCharacter.player == (Object)null) { ForcedDropInProgress.Remove(instanceID); return; } ItemSlot itemSlot = localCharacter.player.GetItemSlot(slotId); if (!IsNestEggSlot(itemSlot)) { ForcedDropInProgress.Remove(instanceID); return; } PhotonView component = ((Component)items).GetComponent<PhotonView>(); if ((Object)(object)component == (Object)null || (PhotonNetwork.InRoom && !component.IsMine)) { LogError("Cannot force-drop NestEgg because local CharacterItems PhotonView is invalid. | Slot=" + slotId); ForcedDropInProgress.Remove(instanceID); return; } Vector3 dropPosition = GetDropPosition(localCharacter); string[] obj = new string[8] { "FORCE DROP HELD NEST EGG | Reason=", reason, " | Slot=", slotId.ToString(), " | NextSlot=", FormatSlot(nextSlot), " | Position=", null }; Vector3 val = dropPosition; obj[7] = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString(); LogWarning(string.Concat(obj)); component.RPC("DropItemFromSlotRPC", (RpcTarget)5, new object[2] { slotId, dropPosition }); component.RPC("DestroyHeldItemRpc", (RpcTarget)5, Array.Empty<object>()); ((MonoBehaviour)items).StartCoroutine(FinishHeldDropRoutine(items, nextSlot, instanceID)); } private static IEnumerator FinishHeldDropRoutine(CharacterItems items, Optionable<byte> nextSlot, int instanceId) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) float timeoutAt = Time.realtimeSinceStartup + 2f; while ((Object)(object)items != (Object)null && (Object)(object)Character.localCharacter != (Object)null && (Object)(object)Character.localCharacter.data != (Object)null && (Object)(object)Character.localCharacter.data.currentItem != (Object)null && Time.realtimeSinceStartup < timeoutAt) { yield return null; } if ((Object)(object)items != (Object)null && IsLocalCharacterItems(items)) { items.EquipSlot(nextSlot); } ForcedDropInProgress.Remove(instanceId); } private unsafe static void DropStoredEggSlot(CharacterItems items, byte slotId, string reason) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) if (!IsLocalCharacterItems(items)) { return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.player == (Object)null) { return; } ItemSlot itemSlot = localCharacter.player.GetItemSlot(slotId); if (IsNestEggSlot(itemSlot)) { PhotonView component = ((Component)items).GetComponent<PhotonView>(); if (!((Object)(object)component == (Object)null) && (!PhotonNetwork.InRoom || component.IsMine)) { Vector3 dropPosition = GetDropPosition(localCharacter); string[] obj = new string[6] { "DROP STORED NEST EGG | Reason=", reason, " | Slot=", slotId.ToString(), " | Position=", null }; Vector3 val = dropPosition; obj[5] = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString(); LogWarning(string.Concat(obj)); component.RPC("DropItemFromSlotRPC", (RpcTarget)5, new object[2] { slotId, dropPosition }); } } } private static void ScheduleInventoryValidation(CharacterItems items, string reason) { if (IsLocalCharacterItems(items)) { int instanceID = ((Object)items).GetInstanceID(); if (ValidationScheduled.Add(instanceID)) { ((MonoBehaviour)items).StartCoroutine(ValidateInventoryDelayed(items, reason, instanceID)); } } } private static IEnumerator ValidateInventoryDelayed(CharacterItems items, string reason, int instanceId) { yield return (object)new WaitForSeconds(0.85f); if ((Object)(object)items != (Object)null && IsLocalCharacterItems(items) && !ForcedDropInProgress.Contains(instanceId)) { ValidateInventoryNow(items, reason); } ValidationScheduled.Remove(instanceId); } private static void ValidateInventoryNow(CharacterItems items, string reason) { Character localCharacter = Character.localCharacter; if (!((Object)(object)localCharacter == (Object)null) && !((Object)(object)localCharacter.player == (Object)null) && !((Object)(object)localCharacter.data == (Object)null)) { ValidateSlot(items, localCharacter, 0, reason); ValidateSlot(items, localCharacter, 1, reason); ValidateSlot(items, localCharacter, 2, reason); ValidateSlot(items, localCharacter, 250, reason); } } private static void ValidateSlot(CharacterItems items, Character character, byte slotId, string reason) { ItemSlot itemSlot = character.player.GetItemSlot(slotId); if (IsNestEggSlot(itemSlot) && (!items.currentSelectedSlot.IsSome || items.currentSelectedSlot.Value != slotId || !IsNestEgg(character.data.currentItem))) { DropStoredEggSlot(items, slotId, reason + " | Invalid inventory storage detected"); } } private static bool IsLocalCharacterItems(CharacterItems items) { if ((Object)(object)items == (Object)null) { return false; } Character localCharacter = Character.localCharacter; return (Object)(object)localCharacter != (Object)null && localCharacter.refs != null && (Object)(object)localCharacter.refs.items == (Object)(object)items && localCharacter.IsLocal; } private static bool IsNestEggSlot(ItemSlot slot) { if (slot == null || slot.IsEmpty()) { return false; } if (IsNestEgg(slot.prefab)) { return true; } return IsNestEggName(slot.GetPrefabName()); } private static bool IsNestEgg(Item item) { if ((Object)(object)item == (Object)null) { return false; } return IsNestEggName(((Object)((Component)item).gameObject).name); } private static bool IsNestEggName(string objectName) { return string.Equals(NormalizePrefabName(objectName), "NestEgg", StringComparison.OrdinalIgnoreCase); } private static string NormalizePrefabName(string objectName) { if (string.IsNullOrEmpty(objectName)) { return string.Empty; } string text = objectName.Trim(); while (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - "(Clone)".Length).Trim(); } return text; } private static Vector3 GetDropPosition(Character character) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character != (Object)null && (Object)(object)character.data != (Object)null && (Object)(object)character.data.currentItem != (Object)null) { return ((Component)character.data.currentItem).transform.position + Vector3.down * 0.2f; } if ((Object)(object)character != (Object)null) { return character.Center + ((Component)character).transform.forward * 0.35f + Vector3.up * 0.15f; } return Vector3.zero; } private static string FormatSlot(Optionable<byte> slot) { return slot.IsSome ? slot.Value.ToString() : "None"; } private static void LogWarning(string message) { Logger.LogWarning((object)("[NoInventory] " + message)); } private static void LogError(string message) { Logger.LogError((object)("[NoInventory] " + message)); } } [HarmonyPatch(typeof(CharacterSpawner), "Update")] public static class RandomStartEgg { public const string DeveloperName = "Sapphire009"; public const string TargetPrefabName = "NestEgg"; private const float RequiredStableTime = 1.5f; private const float EquipRetryInterval = 2f; private const string LogPrefix = "[RandomStartEgg] "; private const string RoomPropertyGrantedKey = "Sapphire009.WatchEgg.StartEggGranted"; private const string RoomPropertyActorKey = "Sapphire009.WatchEgg.StartEggActor"; private const string RoomPropertySlotKey = "Sapphire009.WatchEgg.StartEggSlot"; private static readonly ManualLogSource Logger = Logger.CreateLogSource("WatchEgg.RandomStartEgg"); private static int currentSceneHandle = int.MinValue; private static bool routineStarted; private static bool eggGranted; private static bool airportPropertyReset; private static bool localEquipRoutineStarted; private static bool localEquipCompleted; private static int lastLoggedReadyCount = -1; [HarmonyPrepare] private static bool Prepare() { Logger.LogInfo((object)"[RandomStartEgg] PATCH READY: CharacterSpawner.Update"); return true; } [HarmonyPostfix] private static void Postfix(CharacterSpawner __instance) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Invalid comparison between Unknown and I4 //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) ResetStateWhenSceneChanged(); if ((Object)(object)__instance == (Object)null || !PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return; } if (!GameHandler.IsOnIsland) { ResetRoomPropertiesInAirport(); } else if ((int)MapHandler.CurrentSegmentNumber <= 0) { TryStartLocalEquipRoutine(__instance); if (IsEggAlreadyGrantedInRoom()) { eggGranted = true; } else if (PhotonNetwork.IsMasterClient && !eggGranted && !routineStarted) { routineStarted = true; Scene activeScene = SceneManager.GetActiveScene(); int handle = ((Scene)(ref activeScene)).handle; ((MonoBehaviour)__instance).StartCoroutine(WaitForAllPlayersAndGrantEgg(handle)); } } } private static IEnumerator WaitForAllPlayersAndGrantEgg(int startedSceneHandle) { float stableTime = 0f; int stablePlayerCount = -1; Logger.LogInfo((object)"[RandomStartEgg] Waiting for all connected players to finish spawning."); while (true) { if (!CanContinueWaiting(startedSceneHandle)) { routineStarted = false; yield break; } if (IsEggAlreadyGrantedInRoom()) { eggGranted = true; routineStarted = false; yield break; } if (!TryGetAllSpawnedCharacters(out var _, out var roomPlayerCount)) { stableTime = 0f; stablePlayerCount = -1; yield return null; } else if (roomPlayerCount != stablePlayerCount) { stablePlayerCount = roomPlayerCount; stableTime = 0f; if (lastLoggedReadyCount != roomPlayerCount) { lastLoggedReadyCount = roomPlayerCount; Logger.LogInfo((object)("[RandomStartEgg] All current player characters are ready. | PlayerCount=" + roomPlayerCount)); } yield return null; } else { stableTime += Time.unscaledDeltaTime; if (!(stableTime < 1.5f)) { break; } yield return null; } } if (!TryGetAllSpawnedCharacters(out var finalCharacters, out var finalPlayerCount)) { routineStarted = false; yield break; } if (finalCharacters.Count == 0) { Logger.LogError((object)"[RandomStartEgg] Egg grant failed: no spawned character was found."); routineStarted = false; yield break; } if (!TryGetNestEggPrefab(out var nestEggPrefab)) { Logger.LogError((object)"[RandomStartEgg] Egg grant failed: NestEgg was not found in ItemDatabase."); routineStarted = false; yield break; } List<Character> eligibleCharacters = new List<Character>(); for (int i = 0; i < finalCharacters.Count; i++) { Character character = finalCharacters[i]; if (!((Object)(object)character == (Object)null) && !((Object)(object)character.player == (Object)null) && character.refs != null && !((Object)(object)character.refs.items == (Object)null)) { if (!character.player.HasEmptySlot(nestEggPrefab.itemID)) { Logger.LogWarning((object)("[RandomStartEgg] Player excluded because inventory is full. | Player=" + GetCharacterName(character))); } else { eligibleCharacters.Add(character); } } } if (eligibleCharacters.Count == 0) { Logger.LogError((object)"[RandomStartEgg] Egg grant failed: all player inventories are full."); routineStarted = false; yield break; } int randomIndex = Random.Range(0, eligibleCharacters.Count); Character selectedCharacter = eligibleCharacters[randomIndex]; int actorNumber = GetActorNumber(selectedCharacter); if (actorNumber < 0) { Logger.LogError((object)"[RandomStartEgg] Egg grant failed: selected player ActorNumber was invalid."); routineStarted = false; yield break; } ItemSlot addedSlot = default(ItemSlot); if (!selectedCharacter.player.AddItem(nestEggPrefab.itemID, (ItemInstanceData)null, ref addedSlot) || addedSlot == null) { Logger.LogError((object)("[RandomStartEgg] NestEgg could not be added to " + GetCharacterName(selectedCharacter) + "'s item slot.")); routineStarted = false; yield break; } SetRoomEggAssignment(granted: true, actorNumber, addedSlot.itemSlotID); eggGranted = true; routineStarted = false; Logger.LogWarning((object)("[RandomStartEgg] NestEgg assigned to one random player. The selected player will hold it immediately. | SelectedPlayer=" + GetCharacterName(selectedCharacter) + " | ActorNumber=" + actorNumber + " | ConnectedPlayers=" + finalPlayerCount + " | SlotID=" + addedSlot.itemSlotID + " | ItemID=" + nestEggPrefab.itemID)); } private static void TryStartLocalEquipRoutine(CharacterSpawner characterSpawner) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)characterSpawner == (Object)null) && !localEquipCompleted && !localEquipRoutineStarted && PhotonNetwork.LocalPlayer != null && TryGetRoomEggAssignment(out var actorNumber, out var slotID) && PhotonNetwork.LocalPlayer.ActorNumber == actorNumber) { localEquipRoutineStarted = true; Scene activeScene = SceneManager.GetActiveScene(); int handle = ((Scene)(ref activeScene)).handle; ((MonoBehaviour)characterSpawner).StartCoroutine(WaitForLocalEggAndEquip(handle, actorNumber, slotID)); } } private static IEnumerator WaitForLocalEggAndEquip(int startedSceneHandle, int targetActorNumber, byte targetSlotID) { float nextEquipRequestTime = 0f; Logger.LogInfo((object)("[RandomStartEgg] This client was selected to receive the NestEgg. Waiting for slot synchronization. | ActorNumber=" + targetActorNumber + " | SlotID=" + targetSlotID)); Character selectedCharacter = default(Character); while (CanContinueLocalEquipWaiting(startedSceneHandle)) { if (!TryGetRoomEggAssignment(out var currentTargetActor, out var currentTargetSlot)) { localEquipRoutineStarted = false; yield break; } if (currentTargetActor != targetActorNumber || currentTargetSlot != targetSlotID) { localEquipRoutineStarted = false; yield break; } if (!PlayerHandler.TryGetCharacter(targetActorNumber, ref selectedCharacter)) { yield return null; continue; } if ((Object)(object)selectedCharacter == (Object)null || !selectedCharacter.IsLocal || (Object)(object)selectedCharacter.data == (Object)null || (Object)(object)selectedCharacter.player == (Object)null || selectedCharacter.refs == null || (Object)(object)selectedCharacter.refs.items == (Object)null) { yield return null; continue; } ItemSlot eggSlot = selectedCharacter.player.GetItemSlot(targetSlotID); if (eggSlot == null || eggSlot.IsEmpty() || (Object)(object)eggSlot.prefab == (Object)null || !IsNestEggName(((Object)((Component)eggSlot.prefab).gameObject).name)) { yield return null; continue; } if (IsNestEggHeldByCharacter(selectedCharacter, targetSlotID)) { localEquipCompleted = true; localEquipRoutineStarted = false; Logger.LogWarning((object)("[RandomStartEgg] NestEgg is now held by the selected player. | Player=" + GetCharacterName(selectedCharacter) + " | ActorNumber=" + targetActorNumber + " | SlotID=" + targetSlotID)); yield break; } if (Time.unscaledTime >= nextEquipRequestTime) { nextEquipRequestTime = Time.unscaledTime + 2f; selectedCharacter.refs.items.EquipSlot(Optionable<byte>.Some(targetSlotID)); Logger.LogInfo((object)("[RandomStartEgg] Immediate hand equip requested. | Player=" + GetCharacterName(selectedCharacter) + " | ActorNumber=" + targetActorNumber + " | SlotID=" + targetSlotID)); } yield return null; selectedCharacter = null; } localEquipRoutineStarted = false; } private static bool IsNestEggHeldByCharacter(Character character, byte slotID) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Invalid comparison between Unknown and I4 //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null || character.refs == null || (Object)(object)character.refs.items == (Object)null) { return false; } Item currentItem = character.data.currentItem; if ((Object)(object)currentItem == (Object)null || (int)currentItem.itemState != 1 || !IsNestEggName(((Object)((Component)currentItem).gameObject).name)) { return false; } Optionable<byte> currentSelectedSlot = character.refs.items.currentSelectedSlot; if (!currentSelectedSlot.IsSome) { return false; } return currentSelectedSlot.Value == slotID; } private static bool CanContinueLocalEquipWaiting(int startedSceneHandle) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to