Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of GladiatorArenaCompat v1.0.1
BepInEx/plugins/GladiatorArenaCompat/ArenaLoaderCompat.dll
Decompiled 4 hours 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.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; using UnityEngine.AI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace ArenaLoaderCompat; [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("chatgpt.repo.arenaloadercompat", "Arena Loader Compatibility", "0.3.2")] public sealed class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static Plugin Instance; internal static ConfigEntry<float> FeralMusicVolume; internal static ConfigEntry<float> FeralPreparationDelaySeconds; private Harmony _harmony; private void Awake() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Instance = this; FeralMusicVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Feral Arena", "MusicVolume", 0.05f, "Volume de la musique Gladiator/Feral Arena. 0 = muet, 1 = volume original."); FeralPreparationDelaySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Feral Arena", "PreparationDelaySeconds", 12f, "Temps de preparation apres le debut du round avant que les ennemis puissent detecter les joueurs. 0 = desactive."); if (Mathf.Approximately(FeralMusicVolume.Value, 0.25f)) { FeralMusicVolume.Value = 0.05f; ((BaseUnityPlugin)this).Config.Save(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[ArenaCompat] Migrated Feral music volume from 0.25 to 0.05."); } _harmony = new Harmony("chatgpt.repo.arenaloadercompat.v032"); DisableLegacyArenaLoaderPostfix(); MethodInfo methodInfo = AccessTools.Method(typeof(LevelGenerator), "Start", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(LevelGeneratorStartPatch), "Postfix", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"[ArenaCompat] LevelGenerator.Start patch could not be installed."); return; } HarmonyMethod val = new HarmonyMethod(methodInfo2); val.priority = 0; _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); InstallStalePlayerDeathHeadGuard(); InstallCustomArenaStaleScriptGuards(); InstallFeralPreparationSafetyGuard(); InstallFeralCrownGrabHooks(); InstallFeralCrownLifetimeGuard(); ((MonoBehaviour)this).StartCoroutine(InstallFeralRuntimeCompatibility()); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Arena Loader Compatibility 0.3.2 FINAL loaded. 50/50 vanilla/Gladiator rotation active. Feral music volume=" + Mathf.Clamp01(FeralMusicVolume.Value).ToString("0.00") + ", preparation delay=" + Mathf.Max(0f, FeralPreparationDelaySeconds.Value).ToString("0.0") + "s.")); } private void InstallStalePlayerDeathHeadGuard() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown Type type = AccessTools.TypeByName("PlayerDeathHead"); if (type == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"[ArenaCompat] PlayerDeathHead type not found; stale prefab guard not installed."); return; } MethodInfo methodInfo = AccessTools.Method(typeof(StaleArenaComponentGuard), "PlayerDeathHeadPrefix", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(type, "Start", (Type[])null, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(type, "Update", (Type[])null, (Type[])null); if (!(methodInfo == null)) { HarmonyMethod val = new HarmonyMethod(methodInfo); val.priority = 800; if (methodInfo2 != null) { _harmony.Patch((MethodBase)methodInfo2, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodInfo3 != null) { _harmony.Patch((MethodBase)methodInfo3, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"[ArenaCompat] Custom-arena PlayerDeathHead stale-component guard active."); } } private void InstallCustomArenaStaleScriptGuards() { MethodInfo methodInfo = AccessTools.Method(typeof(CustomArenaStaleScriptGuard), "ComponentPrefix", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(CustomArenaStaleScriptGuard), "ArenaVisualPrefix", (Type[])null, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(typeof(CustomArenaStaleScriptGuard), "ArenaFinalizer", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null || methodInfo3 == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"[ArenaCompat] Feral stale-script guard methods were not found."); return; } int num = 0; num += PatchPrefixByName("ArenaPlatform", "Start", methodInfo); MethodInfo methodInfo4 = AccessTools.Method(typeof(CustomArenaStaleScriptGuard), "ArenaPlatformPulsateLightsPrefix", (Type[])null, (Type[])null); if (methodInfo4 != null) { num += PatchPrefixByName("ArenaPlatform", "PulsateLights", methodInfo4); } num += PatchPrefixByName("ArenaLight", "Start", methodInfo); num += PatchPrefixByName("ArenaLight", "Update", methodInfo); num += PatchPrefixByName("ArenaLight", "PulsateLight", methodInfo); num += PatchPrefixByName("ArenaPedistalScreen", "Update", methodInfo); int num2 = 0; MethodInfo methodInfo5 = AccessTools.Method(typeof(CustomArenaStaleScriptGuard), "ItemBatteryLookAtPrefix", (Type[])null, (Type[])null); if (methodInfo5 != null) { num2 += PatchPrefixByName("ItemBattery", "BatteryLookAt", methodInfo5); } int num3 = 0; num3 += PatchPrefixByName("Arena", "MainLightAnimation", methodInfo2); num3 += PatchFinalizerByName("Arena", "AllPlayersKilled", methodInfo3); num3 += PatchFinalizerByName("Arena", "PlayerKilledRPC", methodInfo3); num3 += PatchFinalizerByName("Arena", "DestroyCrownCageRPC", methodInfo3); num3 += PatchFinalizerByName("Arena", "CrownGrabRPC", methodInfo3); ((BaseUnityPlugin)this).Logger.LogInfo((object)("[ArenaCompat] Feral stale-script guards active | componentMethods=" + num + " | batteryMethods=" + num2 + " | arenaMethods=" + num3 + ".")); } private int PatchPrefixByName(string typeName, string methodName, MethodInfo prefix) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown Type type = AccessTools.TypeByName(typeName); if (type == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[ArenaCompat] Type not found for stale guard: " + typeName + ".")); return 0; } MethodInfo methodInfo = AccessTools.Method(type, methodName, (Type[])null, (Type[])null); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[ArenaCompat] Method not found for stale guard: " + typeName + "." + methodName + ".")); return 0; } HarmonyMethod val = new HarmonyMethod(prefix); val.priority = 800; _harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); return 1; } private int PatchFinalizerByName(string typeName, string methodName, MethodInfo finalizer) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown Type type = AccessTools.TypeByName(typeName); if (type == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[ArenaCompat] Type not found for finalizer: " + typeName + ".")); return 0; } MethodInfo methodInfo = AccessTools.Method(type, methodName, (Type[])null, (Type[])null); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[ArenaCompat] Method not found for finalizer: " + typeName + "." + methodName + ".")); return 0; } HarmonyMethod val = new HarmonyMethod(finalizer); val.priority = 0; _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, val, (HarmonyMethod)null); return 1; } private void InstallFeralPreparationSafetyGuard() { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown Type type = AccessTools.TypeByName("EnemyOnScreen"); MethodInfo methodInfo = ((type != null) ? AccessTools.Method(type, "GetOnScreen", new Type[1] { typeof(PlayerAvatar) }, (Type[])null) : null); MethodInfo methodInfo2 = AccessTools.Method(typeof(FeralPreparationOnScreenGuard), "Prefix", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"[ArenaCompat] FERAL preparation EnemyOnScreen guard could not be installed."); return; } HarmonyMethod val = new HarmonyMethod(methodInfo2); val.priority = 800; _harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[ArenaCompat] FERAL preparation EnemyOnScreen guard active."); } private void InstallFeralCrownGrabHooks() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown Type type = AccessTools.TypeByName("StaticGrabObject"); MethodInfo methodInfo = AccessTools.Method(typeof(FeralCrownGrabHook), "Postfix", (Type[])null, (Type[])null); if (type == null || methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"[ArenaCompat] FERAL true crown grab hooks could not be installed."); return; } int num = 0; MethodInfo methodInfo2 = AccessTools.Method(type, "GrabStarted", (Type[])null, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(type, "GrabStartedRPC", (Type[])null, (Type[])null); HarmonyMethod val = new HarmonyMethod(methodInfo); val.priority = 0; if (methodInfo2 != null) { _harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); num++; } if (methodInfo3 != null) { _harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); num++; } ((BaseUnityPlugin)this).Logger.LogInfo((object)("[ArenaCompat] FERAL true crown grab hook active | methods=" + num + ".")); } private void InstallFeralCrownLifetimeGuard() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown Type type = AccessTools.TypeByName("StaticGrabObject"); MethodInfo methodInfo = ((type != null) ? AccessTools.Method(type, "Update", (Type[])null, (Type[])null) : null); MethodInfo methodInfo2 = AccessTools.Method(typeof(FeralCrownLifetimeGuard), "Prefix", (Type[])null, (Type[])null); if (type == null || methodInfo == null || methodInfo2 == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"[ArenaCompat] FERAL crown lifetime guard could not be installed."); return; } HarmonyMethod val = new HarmonyMethod(methodInfo2); val.priority = 800; _harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[ArenaCompat] FERAL crown lifetime guard active."); } private IEnumerator InstallFeralRuntimeCompatibility() { for (int attempt = 0; attempt < 40; attempt++) { Type feralType = AccessTools.TypeByName("CustomArenaMod.CustomArenaMod"); if (feralType != null) { MethodInfo methodInfo = AccessTools.Method(feralType, "OnSceneLoaded", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(FeralSceneLoadedPatch), "Prefix", (Type[])null, (Type[])null); if (methodInfo != null && methodInfo2 != null) { HarmonyMethod val = new HarmonyMethod(methodInfo2); val.priority = 800; _harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo3 = AccessTools.Method(feralType, "Update", (Type[])null, (Type[])null); MethodInfo methodInfo4 = AccessTools.Method(typeof(FeralUpdateScopePatch), "Prefix", (Type[])null, (Type[])null); if (methodInfo3 != null && methodInfo4 != null) { HarmonyMethod val2 = new HarmonyMethod(methodInfo4); val2.priority = 800; _harmony.Patch((MethodBase)methodInfo3, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo5 = AccessTools.Method(feralType, "PlayArenaMusic", (Type[])null, (Type[])null); MethodInfo methodInfo6 = AccessTools.Method(typeof(FeralMusicPatch), "Postfix", (Type[])null, (Type[])null); if (methodInfo5 != null && methodInfo6 != null) { HarmonyMethod val3 = new HarmonyMethod(methodInfo6); val3.priority = 0; _harmony.Patch((MethodBase)methodInfo5, (HarmonyMethod)null, val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"[ArenaCompat] Feral runtime scoped to Disposal Arena; Racing Arena protected."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[ArenaCompat] Feral music volume patch active."); yield break; } } yield return (object)new WaitForSeconds(0.25f); } ((BaseUnityPlugin)this).Logger.LogWarning((object)"[ArenaCompat] Feral Arena runtime was not found; Feral-specific compatibility not installed."); } private void DisableLegacyArenaLoaderPostfix() { MethodInfo methodInfo = AccessTools.Method(typeof(LevelGenerator), "Start", (Type[])null, (Type[])null); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"[ArenaCompat] LevelGenerator.Start not found while removing legacy Arena Loader patch."); return; } Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo); if (patchInfo == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"[ArenaCompat] LevelGenerator.Start has no Harmony patch info yet."); return; } List<MethodInfo> list = new List<MethodInfo>(); foreach (Patch postfix in patchInfo.Postfixes) { MethodInfo patchMethod = postfix.PatchMethod; Type type = ((patchMethod != null) ? patchMethod.DeclaringType : null); string text = ((type != null) ? type.FullName : ""); if (string.Equals(text, "Empress_ArenaLoaderAPI.LevelGeneratorPatch", StringComparison.Ordinal) || text.IndexOf("Empress_ArenaLoaderAPI", StringComparison.OrdinalIgnoreCase) >= 0) { if (patchMethod != null) { list.Add(patchMethod); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("[ArenaCompat] Found legacy Arena Loader postfix on LevelGenerator.Start | owner='" + postfix.owner + "' | method='" + ((patchMethod != null) ? patchMethod.Name : "<null>") + "'.")); } } if (list.Count == 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"[ArenaCompat] No legacy Arena Loader postfix found on LevelGenerator.Start."); return; } int num = 0; for (int i = 0; i < list.Count; i++) { try { _harmony.Unpatch((MethodBase)methodInfo, list[i]); num++; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("[ArenaCompat] Failed to remove legacy postfix '" + list[i].Name + "': " + ex)); } } ((BaseUnityPlugin)this).Logger.LogInfo((object)("[ArenaCompat] Legacy ArenaLoaderAPI LevelGenerator.Start postfix removed safely: " + num + "/" + list.Count + ".")); } } internal static class FeralSceneLoadedPatch { internal static bool Prefix(object __instance) { FeralRuntimeCompatibility.ResetFeralSceneState(__instance); FeralRuntimeCompatibility.QueueSceneCheck(__instance); return false; } } internal static class FeralUpdateScopePatch { internal static bool Prefix() { return FeralRuntimeCompatibility.IsDisposalArenaLevel(); } } internal static class FeralMusicPatch { internal static void Postfix(object __instance) { if (__instance == null) { return; } FeralRuntimeCompatibility.NotifyFeralRoundStarted(); if (Plugin.FeralMusicVolume != null) { AudioSource feralMusicSource = FeralRuntimeCompatibility.GetFeralMusicSource(__instance); if (!((Object)(object)feralMusicSource == (Object)null)) { feralMusicSource.volume = Mathf.Clamp01(Plugin.FeralMusicVolume.Value); Plugin.Log.LogInfo((object)("[ArenaCompat] FERAL music volume applied: " + feralMusicSource.volume.ToString("0.00") + ".")); } } } } internal static class FeralPreparationOnScreenGuard { private static bool _logged; private static bool _missingKeyLogged; internal static bool Prefix(object __instance, PlayerAvatar __0, ref bool __result) { if (!FeralRuntimeCompatibility.IsCustomArenaActive()) { return true; } if (FeralRuntimeCompatibility.IsPreparationPhaseActive()) { __result = false; if (!_logged) { _logged = true; Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL preparation phase is suppressing EnemyOnScreen detection until release."); } return false; } if (!HasPlayerEntry(__instance, __0)) { __result = false; if (!_missingKeyLogged) { _missingKeyLogged = true; Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL EnemyOnScreen missing-key race suppressed until PlayerAdded catches up."); } return false; } return true; } private static bool HasPlayerEntry(object onScreen, PlayerAvatar player) { if (onScreen == null || (Object)(object)player == (Object)null) { return false; } try { object member = GetMember(player, "photonView"); if (!(((member != null) ? GetMember(member, "ViewID") : null) is int num)) { return false; } return GetMember(onScreen, "OnScreenPlayer") is IDictionary dictionary && dictionary.Contains(num); } catch { return false; } } private static object GetMember(object instance, string name) { if (instance == null) { return null; } Type type = instance.GetType(); BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; while (type != null) { FieldInfo field = type.GetField(name, bindingAttr); if (field != null) { return field.GetValue(instance); } PropertyInfo property = type.GetProperty(name, bindingAttr); if (property != null && property.CanRead) { return property.GetValue(instance, null); } type = type.BaseType; } return null; } internal static void ResetLogState() { _logged = false; _missingKeyLogged = false; } } internal static class StaleArenaComponentGuard { private static bool _logged; internal static bool PlayerDeathHeadPrefix(object __instance) { Component val = (Component)((__instance is Component) ? __instance : null); if ((Object)(object)val == (Object)null) { return true; } if (!FeralRuntimeCompatibility.IsInsideCustomArena(val.transform)) { return true; } Behaviour val2 = (Behaviour)((__instance is Behaviour) ? __instance : null); if ((Object)(object)val2 != (Object)null) { val2.enabled = false; } if (!_logged) { _logged = true; Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL stale PlayerDeathHead components suppressed inside custom arena."); } return false; } } internal static class CustomArenaStaleScriptGuard { private static bool _componentLogged; private static bool _arenaPlatformPulsateLogged; private static bool _arenaVisualLogged; private static bool _arenaExceptionLogged; private static bool _postArenaCleanupLogged; private static readonly HashSet<int> _feralRuntimeInstanceIds = new HashSet<int>(); private static bool TrackOrWasFeralRuntimeInstance(object instance, bool broadWhileActive) { Component val = (Component)((instance is Component) ? instance : null); if ((Object)(object)val == (Object)null) { return false; } int instanceID = ((Object)val).GetInstanceID(); bool flag = FeralRuntimeCompatibility.IsCustomArenaActive(); if (flag && (broadWhileActive || FeralRuntimeCompatibility.IsInsideCustomArena(val.transform))) { _feralRuntimeInstanceIds.Add(instanceID); return true; } if (_feralRuntimeInstanceIds.Contains(instanceID)) { if (!flag && !_postArenaCleanupLogged) { _postArenaCleanupLogged = true; Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL post-arena stale runtime callbacks suppressed after level transition."); } return true; } return false; } internal static bool ComponentPrefix(object __instance) { if (!TrackOrWasFeralRuntimeInstance(__instance, broadWhileActive: false)) { return true; } if (!_componentLogged) { _componentLogged = true; Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL stale ArenaPlatform/ArenaLight/ArenaPedistalScreen runtime scripts suppressed."); } return false; } internal static bool ArenaPlatformPulsateLightsPrefix(object __instance) { if (!TrackOrWasFeralRuntimeInstance(__instance, broadWhileActive: true)) { return true; } if (!_arenaPlatformPulsateLogged) { _arenaPlatformPulsateLogged = true; Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL obsolete ArenaPlatform.PulsateLights suppressed during platform warning."); } return false; } internal static bool ItemBatteryLookAtPrefix(object __instance) { return !TrackOrWasFeralRuntimeInstance(__instance, broadWhileActive: true); } internal static bool ArenaVisualPrefix(object __instance) { if (!TrackOrWasFeralRuntimeInstance(__instance, broadWhileActive: true)) { return true; } if (!_arenaVisualLogged) { _arenaVisualLogged = true; Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL obsolete Arena.MainLightAnimation suppressed."); } return false; } internal static Exception ArenaFinalizer(object __instance, Exception __exception) { if (__exception == null) { return null; } if (!TrackOrWasFeralRuntimeInstance(__instance, broadWhileActive: true)) { return __exception; } if (!_arenaExceptionLogged) { _arenaExceptionLogged = true; Plugin.Log.LogWarning((object)"[ArenaCompat] FERAL contained an obsolete vanilla Arena death/crown exception. Remaining compatible logic continues."); } return null; } } internal static class FeralCrownLifetimeGuard { internal static bool Prefix(object __instance) { FeralRuntimeCompatibility.ProtectTrueCrownLifetime(__instance); return true; } } internal static class FeralCrownGrabHook { internal static void Postfix(object __instance) { FeralRuntimeCompatibility.OnTrueCrownGrabStarted(__instance); } } internal static class FeralRuntimeCompatibility { private static object _currentFeralArena; private static object _currentTrueCrown; private static bool _crownInteractionReady; private static bool _crownInteractionPrepared; private static bool _crownGrabForwardInProgress; private static bool _crownGameOverRequested; private static GameObject _crownVisibilityMarker; private static GameObject _crownReadableVisual; private static GameObject _crownGrabProxy; private static GameObject _crownSafeRoot; private static bool _crownHierarchyDetachedLogged; private static bool _sceneCheckRunning; private static NavMeshDataInstance _feralNavMeshInstance; private static bool _feralNavMeshAdded; private static Bounds _feralPlayableBounds; private static bool _feralPlayableBoundsValid; private static Bounds _feralArenaGroundBounds; private static bool _feralArenaGroundBoundsValid; private static bool _crownLifetimeGuardLogged; private static bool _preparationArmed; private static bool _preparationWaitingForRoundStart; private static bool _preparationReleased = true; private static bool _preparationReleaseLogged; private static float _preparationReleaseAt = -1f; internal static void QueueSceneCheck(object feralPlugin) { if (!_sceneCheckRunning && !((Object)(object)Plugin.Instance == (Object)null)) { _sceneCheckRunning = true; ((MonoBehaviour)Plugin.Instance).StartCoroutine(SingleSceneCheck(feralPlugin)); } } private static IEnumerator SingleSceneCheck(object feralPlugin) { IEnumerator routine = HandleScene(feralPlugin); while (routine != null) { bool more; try { more = routine.MoveNext(); } catch (Exception ex) { Plugin.Log.LogError((object)("[ArenaCompat] FERAL scene-check failed: " + ex)); break; } if (!more) { break; } yield return routine.Current; } _sceneCheckRunning = false; } internal static IEnumerator HandleScene(object feralPlugin) { int step = 0; while (step < 120 && (!((Object)(object)RunManager.instance != (Object)null) || !((Object)(object)LevelGenerator.Instance != (Object)null) || !LevelGenerator.Instance.Generated)) { step++; yield return (object)new WaitForSeconds(0.25f); } if ((Object)(object)RunManager.instance == (Object)null || (Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated || !IsDisposalArenaLevel()) { yield break; } Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL arena detected without obsolete Level.ResourcePath lookup."); GameObject arenaRoot = null; for (int i = 0; i < 24; i++) { if (!((Object)(object)arenaRoot == (Object)null)) { break; } arenaRoot = GameObject.Find("Start Room - Arena(Clone)") ?? GameObject.Find("Start Room - Arena"); if ((Object)(object)arenaRoot == (Object)null) { yield return (object)new WaitForSeconds(0.25f); } } if ((Object)(object)arenaRoot == (Object)null) { Plugin.Log.LogWarning((object)"[ArenaCompat] FERAL custom arena root was not found after generation."); yield break; } if (TryBuildFeralNavMesh(arenaRoot)) { SnapArenaLevelPointsToNavMesh(arenaRoot); if ((Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(RepairFeralAgentsDelayed()); } } int deathHeads = RemoveStalePlayerDeathHeads(arenaRoot); Plugin.Log.LogInfo((object)("[ArenaCompat] FERAL immediate sanitizer removed " + deathHeads + " stale PlayerDeathHead component(s).")); IEnumerator originalSanitizer = InvokeCoroutine(feralPlugin, "SilentSanitize", arenaRoot); if (originalSanitizer != null && (Object)(object)Plugin.Instance != (Object)null) { yield return ((MonoBehaviour)Plugin.Instance).StartCoroutine(originalSanitizer); } EnsureArenaEnemyTrigger(arenaRoot); ArmFeralPreparationPhase(); if (SemiFunc.IsMasterClientOrSingleplayer()) { IEnumerator enumerator = InvokeCoroutine(feralPlugin, "RoundStartRunnerSpawn", 4); if (enumerator != null && (Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(enumerator); } } Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL post-load setup completed."); if ((Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(FeralLateSpawnPlayerRegistration()); ((MonoBehaviour)Plugin.Instance).StartCoroutine(FeralCrownCompatibility()); } } private static void ArmFeralPreparationPhase() { float num = ((Plugin.FeralPreparationDelaySeconds != null) ? Mathf.Max(0f, Plugin.FeralPreparationDelaySeconds.Value) : 0f); _preparationArmed = num > 0f; _preparationWaitingForRoundStart = num > 0f; _preparationReleased = num <= 0f; _preparationReleaseLogged = false; _preparationReleaseAt = -1f; FeralPreparationOnScreenGuard.ResetLogState(); if (num <= 0f) { Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL preparation phase disabled (PreparationDelaySeconds=0)."); } else { Plugin.Log.LogInfo((object)("[ArenaCompat] FERAL preparation phase armed | delay=" + num.ToString("0.0") + "s | trigger=PlayArenaMusic/door movement.")); } } internal static void NotifyFeralRoundStarted() { if (_preparationArmed && !_preparationReleased && _preparationWaitingForRoundStart) { float num = ((Plugin.FeralPreparationDelaySeconds != null) ? Mathf.Max(0f, Plugin.FeralPreparationDelaySeconds.Value) : 0f); _preparationWaitingForRoundStart = false; _preparationReleaseAt = Time.unscaledTime + num; Plugin.Log.LogInfo((object)("[ArenaCompat] FERAL preparation phase started | delay=" + num.ToString("0.0") + "s | enemies remain blind until release.")); } } internal static bool IsPreparationPhaseActive() { if (!IsCustomArenaActive()) { return false; } if (!_preparationArmed || _preparationReleased) { return false; } return true; } private static bool IsFeralPlayerRegistrationReleased() { if (!_preparationArmed || _preparationReleased) { return true; } if (_preparationWaitingForRoundStart) { return false; } if (_preparationReleaseAt >= 0f && Time.unscaledTime >= _preparationReleaseAt) { _preparationReleased = true; if (!_preparationReleaseLogged) { _preparationReleaseLogged = true; Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL preparation phase complete | enabling vanilla Enemy.PlayerAdded registration now."); } return true; } return false; } private static IEnumerator FeralLateSpawnPlayerRegistration() { yield return (object)new WaitForSeconds(0.25f); HashSet<string> handledPairs = new HashSet<string>(); int registrations = 0; bool startupLogged = false; while (IsCustomArenaActive()) { if (!IsFeralPlayerRegistrationReleased()) { yield return (object)new WaitForSeconds(0.1f); continue; } int passRegistrations = 0; try { Type type = AccessTools.TypeByName("EnemyDirector"); object obj = ((type != null) ? GetStaticMember(type, "instance") : null); IEnumerable enumerable = ((obj != null) ? (GetMember(obj, "enemiesSpawned") as IEnumerable) : null); object obj2 = null; Type type2 = AccessTools.TypeByName("GameDirector"); if (type2 != null) { obj2 = GetStaticMember(type2, "instance"); } IList list = ((obj2 != null) ? (GetMember(obj2, "PlayerList") as IList) : null); if (!startupLogged && (Object)(object)LevelGenerator.Instance != (Object)null) { startupLogged = true; object member = GetMember(LevelGenerator.Instance, "EnemiesSpawned"); object member2 = GetMember(LevelGenerator.Instance, "EnemiesSpawnTarget"); Plugin.Log.LogInfo((object)string.Concat("[ArenaCompat] FERAL late-spawn player registration active | Generated=", LevelGenerator.Instance.Generated, " | EnemiesSpawned=", member ?? "?", " | EnemiesSpawnTarget=", member2 ?? "?", ".")); } if (enumerable != null && list != null && list.Count > 0) { foreach (object item2 in enumerable) { if (item2 == null) { continue; } object member3 = GetMember(item2, "Spawned"); if (member3 is bool && !(bool)member3) { continue; } object member4 = GetMember(item2, "Enemy"); if (member4 == null) { continue; } MethodInfo methodInfo = AccessTools.Method(member4.GetType(), "PlayerAdded", new Type[1] { typeof(int) }, (Type[])null); if (methodInfo == null) { continue; } int runtimeObjectId = GetRuntimeObjectId(member4); for (int i = 0; i < list.Count; i++) { object? obj3 = list[i]; PlayerAvatar val = (PlayerAvatar)((obj3 is PlayerAvatar) ? obj3 : null); if ((Object)(object)val == (Object)null) { continue; } int playerViewId = GetPlayerViewId(val); if (playerViewId <= 0) { continue; } string item = runtimeObjectId + ":" + playerViewId; if (!handledPairs.Contains(item)) { bool flag = IsEnemyVisionPlayerRegistered(member4, playerViewId); bool flag2 = IsEnemyOnScreenPlayerRegistered(member4, playerViewId); try { methodInfo.Invoke(member4, new object[1] { playerViewId }); handledPairs.Add(item); registrations++; passRegistrations++; bool flag3 = IsEnemyVisionPlayerRegistered(member4, playerViewId); bool flag4 = IsEnemyOnScreenPlayerRegistered(member4, playerViewId); Plugin.Log.LogInfo((object)("[ArenaCompat] FERAL late-spawn PlayerAdded restored | enemyId=" + runtimeObjectId + " | playerViewID=" + playerViewId + " | vision=" + flag + "->" + flag3 + " | onScreen=" + flag2 + "->" + flag4 + ".")); } catch (Exception ex) { Exception ex2 = ((ex is TargetInvocationException && ex.InnerException != null) ? ex.InnerException : ex); Plugin.Log.LogWarning((object)("[ArenaCompat] FERAL late-spawn PlayerAdded failed | enemyId=" + runtimeObjectId + " | playerViewID=" + playerViewId + " | " + ex2.GetType().Name + ": " + ex2.Message)); } } } } } } catch (Exception ex3) { Plugin.Log.LogWarning((object)("[ArenaCompat] FERAL late-spawn registration pass failed: " + ex3.Message)); } if (passRegistrations > 0) { Plugin.Log.LogInfo((object)("[ArenaCompat] FERAL late-spawn registration pass | addedPairs=" + passRegistrations + " | totalPairs=" + registrations + ".")); } yield return (object)new WaitForSeconds(0.25f); } Plugin.Log.LogInfo((object)("[ArenaCompat] FERAL late-spawn player registration stopped | totalPairs=" + registrations + ".")); } private static IEnumerator FeralCrownCompatibility() { object arena = null; object crownGrab = null; bool startupLogged = false; bool releaseRequested = false; float releaseRequestedAt = -1f; bool localReleaseLogged = false; bool grabRequested = false; float grabRequestedAt = -1f; bool winnerLogged = false; bool crownPlacedForWinner = false; int lastAlivePlayers = -999; int lastTotalPlayers = -999; while (IsDisposalArenaLevel()) { try { if (arena == null || IsUnityObjectDestroyed(arena)) { arena = FindFeralArenaComponent(); crownGrab = ((arena != null) ? GetMember(arena, "crownGrab") : null); if (crownGrab != null) { ProtectTrueCrownLifetime(crownGrab); DetachTrueCrownFromFragileHierarchy(crownGrab, arena); } _currentFeralArena = arena; _currentTrueCrown = crownGrab; _crownInteractionReady = false; _crownInteractionPrepared = false; _crownGrabForwardInProgress = false; _crownGameOverRequested = false; startupLogged = false; releaseRequested = false; releaseRequestedAt = -1f; localReleaseLogged = false; grabRequested = false; grabRequestedAt = -1f; winnerLogged = false; crownPlacedForWinner = false; lastAlivePlayers = -999; lastTotalPlayers = -999; } else if (crownGrab == null || IsUnityObjectDestroyed(crownGrab)) { crownGrab = GetMember(arena, "crownGrab"); if (crownGrab != null) { ProtectTrueCrownLifetime(crownGrab); DetachTrueCrownFromFragileHierarchy(crownGrab, arena); } _currentTrueCrown = crownGrab; } if (arena != null && crownGrab != null) { if (!startupLogged) { startupLogged = true; Component val = (Component)((crownGrab is Component) ? crownGrab : null); string text = (((Object)(object)val != (Object)null) ? ((Object)val.gameObject).name : crownGrab.GetType().Name); object obj; if (!((Object)(object)val != (Object)null)) { obj = "?"; } else { Vector3 position = val.transform.position; obj = ((Vector3)(ref position)).ToString("F2"); } string text2 = (string)obj; object member = GetMember(crownGrab, "colliderTransform"); Component val2 = (Component)((member is Component) ? member : null); string text3 = (((Object)(object)val2 != (Object)null) ? ((Object)val2.gameObject).name : "null"); Plugin.Log.LogInfo((object)("[ArenaCompat] FERAL crown compatibility active | trueCrown='" + text + "' | position=" + text2 + " | cageDestroyed=" + IsCrownCageDestroyed(arena) + " | dead=" + Convert.ToString(GetMember(crownGrab, "dead")) + " | grabActive=" + ((Object)(object)val != (Object)null && val.gameObject.activeInHierarchy) + " | colliderTransform='" + text3 + "'.")); } if (!IsFeralPlayerRegistrationReleased()) { SetTrueCrownGrabEnabled(crownGrab, enabled: false); HideLegacyCrownRenderers(crownGrab, arena); HideCrownVisibilityMarker(); _crownInteractionReady = false; } if (IsFeralPlayerRegistrationReleased()) { CountArenaPlayersVanillaSemantic(out var total, out var alive); bool flag = alive == 1; bool flag2 = IsCrownCageDestroyed(arena); if (alive != lastAlivePlayers || total != lastTotalPlayers) { lastAlivePlayers = alive; lastTotalPlayers = total; Plugin.Log.LogInfo((object)("[ArenaCompat] FERAL crown eligibility | totalPlayers=" + total + " | alivePlayers=" + alive + " | eligible=" + flag + " | source=SemiFunc.PlayerGetAll().")); } if (!flag) { SetTrueCrownGrabEnabled(crownGrab, enabled: false); HideLegacyCrownRenderers(crownGrab, arena); HideCrownVisibilityMarker(); _crownInteractionReady = false; } if (flag && !flag2) { if (SemiFunc.IsMasterClientOrSingleplayer() && !releaseRequested) { releaseRequested = true; releaseRequestedAt = Time.unscaledTime; TryInvokeArenaMethod(arena, "DestroyCrownCage"); Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL crown cage release requested through vanilla Arena.DestroyCrownCage() | alivePlayers=1."); } if ((!releaseRequested || (releaseRequestedAt >= 0f && Time.unscaledTime - releaseRequestedAt >= 0.75f)) && !IsCrownCageDestroyed(arena)) { SafeReleaseCrownLocally(arena, crownGrab); if (!localReleaseLogged) { localReleaseLogged = true; Plugin.Log.LogWarning((object)"[ArenaCompat] FERAL crown cage stale-prefab fallback applied locally."); } } } flag2 = IsCrownCageDestroyed(arena); if (flag && flag2) { if (!crownPlacedForWinner) { crownPlacedForWinner = true; _crownInteractionPrepared = false; Component val3 = (Component)((crownGrab is Component) ? crownGrab : null); ManualLogSource log = Plugin.Log; object obj2; if (!((Object)(object)val3 != (Object)null)) { obj2 = "?"; } else { Vector3 position2 = val3.transform.position; obj2 = ((Vector3)(ref position2)).ToString("F2"); } log.LogInfo((object)("[ArenaCompat] FERAL final crown unlocked at original tower position | position=" + (string?)obj2 + " | alivePlayers=1.")); } EnsureTrueCrownActive(crownGrab, arena); SetTrueCrownGrabEnabled(crownGrab, enabled: true); int num = HideLegacyCrownRenderers(crownGrab, arena); EnsureReadableCrownVisual(crownGrab); EnsureCrownVisibilityMarker(crownGrab, arena); if (!_crownInteractionPrepared) { Component val4 = (Component)((crownGrab is Component) ? crownGrab : null); ManualLogSource log2 = Plugin.Log; object[] array = new object[9] { "[ArenaCompat] FERAL tower crown READY | position=", null, null, null, null, null, null, null, null }; object obj3; if (!((Object)(object)val4 != (Object)null)) { obj3 = "?"; } else { Vector3 position3 = val4.transform.position; obj3 = ((Vector3)(ref position3)).ToString("F2"); } array[1] = obj3; array[2] = " | legacyRenderersHidden="; array[3] = num; array[4] = " | totalPlayers="; array[5] = total; array[6] = " | alivePlayers="; array[7] = alive; array[8] = "."; log2.LogInfo((object)string.Concat(array)); } if (!_crownInteractionPrepared) { PrepareTrueCrownInteraction(crownGrab, arena); _crownInteractionPrepared = true; } _crownInteractionReady = true; object member2 = GetMember(arena, "winnerPlayer"); if (member2 != null && !IsUnityObjectDestroyed(member2)) { TryForceArenaGameOver(arena); if (!winnerLogged) { winnerLogged = true; HideCrownVisibilityMarker(); Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL crown winner registered by vanilla Arena logic."); } } else if (SemiFunc.IsMasterClientOrSingleplayer() && IsCrownCurrentlyGrabbed(crownGrab)) { if (!grabRequested) { grabRequested = true; grabRequestedAt = Time.unscaledTime; Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL true crown grab detected | forwarding to vanilla Arena.CrownGrab()."); TryInvokeArenaMethod(arena, "CrownGrab"); } else if (grabRequestedAt >= 0f && Time.unscaledTime - grabRequestedAt >= 1f && GetMember(arena, "winnerPlayer") == null && TryRestoreCrownWinnerFromActualGrabber(arena, crownGrab)) { winnerLogged = true; Plugin.Log.LogWarning((object)"[ArenaCompat] FERAL crown winner fallback restored from the actual crown grabber."); } } else if (!IsCrownCurrentlyGrabbed(crownGrab)) { grabRequested = false; grabRequestedAt = -1f; } } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ArenaCompat] FERAL crown compatibility pass failed: " + ex.Message)); } yield return (object)new WaitForSeconds(0.2f); } DestroyCrownVisibilityMarker(); DestroyCrownSafeRoot(); _currentFeralArena = null; _currentTrueCrown = null; _crownInteractionReady = false; _crownInteractionPrepared = false; _crownGrabForwardInProgress = false; _crownGameOverRequested = false; } private static object FindFeralArenaComponent() { Type type = AccessTools.TypeByName("Arena"); if (type == null) { return null; } Object[] array = Object.FindObjectsOfType(type); if (array == null || array.Length == 0) { return null; } object obj = null; foreach (Object obj2 in array) { Component val = (Component)(object)((obj2 is Component) ? obj2 : null); if (!((Object)(object)val == (Object)null)) { if (obj == null && GetMember(val, "crownGrab") != null) { obj = val; } if (IsInsideCustomArena(val.transform) && GetMember(val, "crownGrab") != null) { return val; } } } return obj; } private static void CountArenaPlayersVanillaSemantic(out int total, out int alive) { total = 0; alive = 0; try { IList list = null; MethodInfo methodInfo = AccessTools.Method(typeof(SemiFunc), "PlayerGetAll", (Type[])null, (Type[])null); if (methodInfo != null) { list = methodInfo.Invoke(null, null) as IList; } if (list == null) { Type type = AccessTools.TypeByName("GameDirector"); object obj = ((type != null) ? GetStaticMember(type, "instance") : null); list = ((obj != null) ? (GetMember(obj, "PlayerList") as IList) : null); } if (list == null) { return; } total = list.Count; for (int i = 0; i < list.Count; i++) { object obj2 = list[i]; if (obj2 != null && !IsUnityObjectDestroyed(obj2)) { object member = GetMember(obj2, "isDisabled"); if (!(member is bool) || !(bool)member) { alive++; } } } } catch { total = 0; alive = 0; } } internal static void ProtectTrueCrownLifetime(object instance) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) try { if (instance == null || !IsDisposalArenaLevel()) { return; } Component val = (Component)((instance is Component) ? instance : null); if (!((Object)(object)val == (Object)null) && string.Equals(((Object)val.gameObject).name, "Crown Grab", StringComparison.OrdinalIgnoreCase) && IsInsideCustomArena(val.transform)) { object member = GetMember(instance, "dead"); bool flag = member is bool && (bool)member; if (flag) { SetMember(instance, "dead", false); } if (!_crownLifetimeGuardLogged) { _crownLifetimeGuardLogged = true; ManualLogSource log = Plugin.Log; object[] array = new object[5] { "[ArenaCompat] FERAL true crown lifetime protected | dead=", flag, "->False | position=", null, null }; Vector3 position = val.transform.position; array[3] = ((Vector3)(ref position)).ToString("F2"); array[4] = "."; log.LogInfo((object)string.Concat(array)); } } } catch (Exception ex) { if (!_crownLifetimeGuardLogged) { _crownLifetimeGuardLogged = true; Plugin.Log.LogWarning((object)("[ArenaCompat] FERAL crown lifetime guard failed: " + ex.Message)); } } } internal static void OnTrueCrownGrabStarted(object instance) { if (!_crownInteractionReady || _crownGrabForwardInProgress || !IsCustomArenaActive() || instance == null || _currentTrueCrown == null || !object.ReferenceEquals(instance, _currentTrueCrown) || !SemiFunc.IsMasterClientOrSingleplayer() || !(GetMember(instance, "playerGrabbing") is IList { Count: not 0 })) { return; } object member = GetMember(_currentFeralArena, "winnerPlayer"); if (member == null || IsUnityObjectDestroyed(member)) { _crownGrabForwardInProgress = true; Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL true crown GrabStarted detected | forwarding to vanilla Arena.CrownGrab()."); TryInvokeArenaMethod(_currentFeralArena, "CrownGrab"); object member2 = GetMember(_currentFeralArena, "winnerPlayer"); if (member2 != null && !IsUnityObjectDestroyed(member2)) { TryForceArenaGameOver(_currentFeralArena); } if ((Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(CrownGrabForwardFallback()); } } } private static IEnumerator CrownGrabForwardFallback() { yield return (object)new WaitForSeconds(1f); try { if (!IsCustomArenaActive() || _currentFeralArena == null || _currentTrueCrown == null) { _crownGrabForwardInProgress = false; yield break; } object member = GetMember(_currentFeralArena, "winnerPlayer"); if (member != null && !IsUnityObjectDestroyed(member)) { TryForceArenaGameOver(_currentFeralArena); Plugin.Log.LogInfo((object)"[ArenaCompat] FERAL crown winner confirmed after GrabStarted hook."); _crownGrabForwardInProgress = false; } else if (IsCrownCurrentlyGrabbed(_currentTrueCrown) && TryRestoreCrownWinnerFromActualGrabber(_currentFeralArena, _currentTrueCrown)) { Plugin.Log.LogWarning((object)"[ArenaCompat] FERAL crown winner fallback restored after GrabStarted hook."); TryForceArenaGameOver(_currentFeralArena); } } finally { _crownGrabForwardInProgress = false; } } private static void DetachTrueCrownFromFragileHierarchy(object crownGrab, object arena) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0037: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) Component val = (Component)((crownGrab is Component) ? crownGrab : null); if (!((Object)(object)val == (Object)null)) { if ((Object)(object)_crownSafeRoot == (Object)null) { _crownSafeRoot = new GameObject("ArenaCompat Crown Safe Root"); _crownSafeRoot.transform.position = Vector3.zero; _crownSafeRoot.transform.rotation = Quaternion.identity; _crownSafeRoot.transform.localScale = Vector3.one; } Transform transform = val.transform; object member = GetMember(arena, "crownTransform"); Transform val2 = (Transform)((member is Transform) ? member : null); string text = (((Object)(object)transform.parent != (Object)null) ? ((Object)((Component)transform.parent).gameObject).name : "<root>"); string text2 = (((Object)(object)val2 != (Object)null && (Object)(object)val2.parent != (Object)null) ? ((Object)((Component)val2.parent).gameObject).name : "<root>"); if ((Object)(object)transform.parent != (Object)(object)_crownSafeRoot.transform) { transform.SetParent(_crownSafeRoot.transform, true); } if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)transform && !val2.IsChildOf(transform) && (Object)(object)val2.parent != (Object)(object)_crownSafeRoot.transform) { val2.SetParent(_crownSafeRoot.transform, true); } if (!_crownHierarchyDetachedLogged) { _crownHierarchyDetachedLogged = true; ManualLogSource log = Plugin.Log; string[] array = new string[7] { "[ArenaCompat] FERAL true crown detached from fragile prefab hierarchy | grabParent='", text, "' | visualParent='", text2, "' | position=", null, null }; Vector3 position = transform.position; array[5] = ((Vector3)(ref position)).ToString("F2"); array[6] = "."; log.LogInfo((object)string.Concat(array)); } } } private static void SetTrueCrownGrabEnabled(object crownGrab, bool enabled) { Component val = (Component)((crownGrab is Component) ? crownGrab : null); Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null); if ((Object)(object)val2 != (Object)null) { val2.enabled = enabled; } } private static bool TryMoveTrueCrownToArenaGround(object crownGrab, object arena, out Vector3 placedPosition) { //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_0035: 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_00be: 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_00dc: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) placedPosition = Vector3.zero; Component val = (Component)((crownGrab is Component) ? crownGrab : null); if ((Object)(object)val == (Object)null) { return false; } bool flag = false; Bounds val2; if (_feralArenaGroundBoundsValid) { val2 = _feralArenaGroundBounds; flag = true; } else { val2 = default(Bounds); GameObject[] array = Object.FindObjectsOfType<GameObject>(); foreach (GameObject val3 in array) { if (!((Object)(object)val3 == (Object)null) && string.Equals(((Object)val3).name, "Arena_Ground", StringComparison.OrdinalIgnoreCase)) { Renderer component = val3.GetComponent<Renderer>(); Collider component2 = val3.GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { val2 = component.bounds; flag = true; break; } if ((Object)(object)component2 != (Object)null) { val2 = component2.bounds; flag = true; break; } } } } if (!flag) { return false; } Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(((Bounds)(ref val2)).center.x, ((Bounds)(ref val2)).max.y + 0.75f, ((Bounds)(ref val2)).center.z); Transform val5 = (((Object)(object)_crownSafeRoot != (Object)null) ? _crownSafeRoot.transform : null); if ((Object)(object)val5 != (Object)null) { val.transform.SetParent(val5, true); } else { val.transform.SetParent((Transform)null, true); } val.transform.position = val4; val.transform.rotation = Quaternion.identity; val.gameObject.SetActive(true); object member = GetMember(arena, "crownTransform"); Transform val6 = (Transform)((member is Transform) ? member : null); if ((Object)(object)val6 != (Object)null && (Object)(object)val6 != (Object)(object)val.transform) { if ((Object)(object)val5 != (Object)null) { val6.SetParent(val5, true); } else { val6.SetParent((Transform)null, true); } val6.position = val4; val6.rotation = Quaternion.identity; ((Component)val6).gameObject.SetActive(true); } placedPosition = val4; return true; } private static int HideLegacyCrownRenderers(object crownGrab, object arena) { Component val = (Component)((crownGrab is Component) ? crownGrab : null); if ((Object)(object)val == (Object)null) { return 0; } int num = 0; HashSet<int> hashSet = new HashSet<int>(); object member = GetMember(arena, "crownTransform"); Transform val2 = (Transform)((member is Transform) ? member : null); if ((Object)(object)val2 != (Object)null) { Renderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Renderer>(true); foreach (Renderer val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)null)) { int instanceID = ((Object)val3).GetInstanceID(); if (!hashSet.Contains(instanceID)) { hashSet.Add(instanceID); val3.enabled = false; num++; } } } } return num; } private static int ForceTrueCrownRenderersVisible(object crownGrab, object arena) { Component val = (Component)((crownGrab is Component) ? crownGrab : null); if ((Object)(object)val == (Object)null) { return 0; } int num = 0; HashSet<int> hashSet = new HashSet<int>(); object member = GetMember(arena, "crownTransform"); Transform val2 = (Transform)((member is Transform) ? member : null); Transform[] array = (Transform[])(object)(((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)val.transform) ? new Transform[2] { val2, val.transform } : new Transform[1] { val.transform }); foreach (Transform val3 in array) { if ((Object)(object)val3 == (Object)null) { continue; } Transform val4 = val3; while ((Object)(object)val4 != (Object)null) { if (!((Component)val4).gameObject.activeSelf) { ((Component)val4).gameObject.SetActive(true); } val4 = val4.parent; } Renderer[] componentsInChildren = ((Component)val3).GetComponentsInChildren<Renderer>(true); foreach (Renderer val5 in componentsInChildren) { if ((Object)(object)val5 == (Object)null) { continue; } int instanceID = ((Object)val5).GetInstanceID(); if (!hashSet.Contains(instanceID)) { hashSet.Add(instanceID); if (!((Component)val5).gameObject.activeSelf) { ((Component)val5).gameObject.SetActive(true); } val5.enabled = true; num++; } } } return num; } private static void EnsureReadableCrownVisual(object crownGrab) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //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_0030: 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_0085: Expected O, but got Unknown //IL_008b: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) Component val = (Component)((crownGrab is Component) ? crownGrab : null); if ((Object)(object)val == (Object)null) { return; } Vector3 position = val.transform.position + Vector3.up * 0.85f; if ((Object)(object)_crownReadableVisual != (Object)null) { if (!_crownReadableVisual.activeSelf) { _crownReadableVisual.SetActive(true); } _crownReadableVisual.transform.position = position; _crownReadableVisual.transform.rotation = Quaternion.identity; return; } GameObject val2 = new GameObject("ArenaCompat Readable Crown Visual"); val2.transform.position = position; val2.transform.rotation = Quaternion.identity; val2.transform.localScale = Vector3.one; int layer = (val2.layer = val.gameObject.layer); CreateCrownVisualPrimitive((PrimitiveType)2, "ArenaCompat Crown Band", val2.transform, new Vector3(0f, -0.18f, 0f), Quaternion.identity, new Vector3(0.72f, 0.12f, 0.72f), layer); Vector3 localPosition = default(Vector3); for (int i = 0; i < 6; i++) { float num = 60f * (float)i; float num2 = num * ((float)Math.PI / 180f); ((Vector3)(ref localPosition))..ctor(Mathf.Sin(num2) * 0.48f, 0.22f, Mathf.Cos(num2) * 0.48f); Quaternion localRotation = Quaternion.Euler(0f, num, 0f); CreateCrownVisualPrimitive((PrimitiveType)3, "ArenaCompat Crown Point " + i, val2.transform, localPosition, localRotation, new Vector3(0.16f, 0.62f, 0.16f), layer); CreateCrownVisualPrimitive((PrimitiveType)0, "ArenaCompat Crown Jewel " + i, val2.transform, new Vector3(Mathf.Sin(num2) * 0.48f, 0.57f, Mathf.Cos(num2) * 0.48f), Quaternion.identity, new Vector3(0.2f, 0.2f, 0.2f), layer); } CreateCrownVisualPrimitive((PrimitiveType)0, "ArenaCompat Crown Center Jewel", val2.transform, new Vector3(0f, 0.52f, 0f), Quaternion.identity, new Vector3(0.32f, 0.32f, 0.32f), layer); Light val3 = val2.AddComponent<Light>(); val3.type = (LightType)2; val3.color = new Color(1f, 0.72f, 0.08f, 1f); val3.range = 7f; val3.intensity = 2.5f; _crownReadableVisual = val2; Plugin.Log.LogInfo((object)("[ArenaCompat] FERAL readable crown visual active | position=" + ((Vector3)(ref position)).ToString("F2") + " | parts=14 | grabProxyAligned=True.")); } private static GameObject CreateCrownVisualPrimitive(PrimitiveType primitiveType, string name, Transform parent, Vector3 localPosition, Quaternion localRotation, Vector3 localScale, int layer) { //IL_0000: 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) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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) GameObject val = GameObject.CreatePrimitive(primitiveType); ((Object)val).name = name; val.layer = layer; val.transform.SetParent(parent, false); val.transform.localPosition = localPosition; val.transform.localRotation = localRotation; val.transform.localScale = localScale; Collider component = val.GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } Renderer component2 = val.GetComponent<Renderer>(); if ((Object)(object)component2 != (Object)null) { try { component2.material.color = new Color(1f, 0.72f, 0.08f, 1f); } catch { } } return val; } private static void EnsureCrownVisibilityMarker(object crownGrab, object arena) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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_008a: 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) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) Component val = (Component)((crownGrab is Component) ? crownGrab : null); if ((Object)(object)val == (Object)null) { return; } Vector3 position = val.transform.position + Vector3.up * 3f; if ((Object)(object)_crownVisibilityMarker != (Object)null) { if (!_crownVisibilityMarker.activeSelf) { _crownVisibilityMarker.SetActive(true); } _crownVisibilityMarker.transform.position = position; return; } GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)val2).name = "ArenaCompat True Crown World Beacon"; val2.transform.position = position; val2.transform.rotation = Quaternion.identity; val2.transform.localScale = new Vector3(0.9f, 0.9f, 0.9f); Collider component = val2.GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } Renderer component2 = val2.GetComponent<Renderer>(); if ((Object)(object)component2 != (Object)null) { try { component2.material.color = new Color(1f, 0.72f, 0.08f, 1f); } catch { } } Light val3 = val2.AddComponent<Light>(); val3.type = (LightType)2; val3.color = new Color(1f, 0.72f, 0.08f, 1f); val3.range = 14f; val3.intensity = 4.5f; GameObject val4 = GameObject.CreatePrimitive((PrimitiveType)2); ((Object)val4).name = "ArenaCompat True Crown Beacon Beam"; val4.transform.SetParent(val2.transform, false); val4.transform.localPosition = new Vector3(0f, 3.5f, 0f); val4.transform.localRotation = Quaternion.identity; val4.transform.localScale = new Vector3(0.12f, 3.5f, 0.12f); Collider component3 = val4.GetComponent<Collider>(); if ((Object)(object)component3 != (Object)null) { Object.Destroy((Object)(object)component3); } Renderer component4 = val4.GetComponent<Renderer>(); if ((Object)(object)component4 != (Object)null) { try { component4.material.color = new Color(1f, 0.72f, 0.08f, 1f); } catch { } } _crownVisibilityMarker = val2; object member = GetMember(arena, "crownTransform"); Transform val5 = (Transform)((member is Transform) ? member : null); Renderer[] array = (((Object)(object)val5 != (Object)null) ? ((Component)val5).GetComponentsInChildren<Renderer>(true) : val.GetComponentsInChildren<Renderer>(true)); ManualLogSource log = Plugin.Log; object[] array2 = new object[7] { "[ArenaCompat] FERAL true crown WORLD beacon active | crownPosition=", null, null, null, null, null, null }; Vector3 position2 = val.transform.position; array2[1] = ((Vector3)(ref position2)).ToString("F2"); array2[2] = " | beaconPosition="; Vector3 position3 = val2.transform.position; array2[3] = ((Vector3)(ref position3)).ToString("F2"); array2[4] = " | crownRenderers="; array2[5] = ((array != null) ? array.Length : 0); array2[6] = "."; log.LogInfo((object)string.Concat(array2)); } private static void HideCrownVisibilityMarker() { if ((Object)(object)_crownVisibilityMarker != (Object)null) { _crownVisibilityMarker.SetActive(false); } if ((Object)(object)_crownReadableVisual != (Object)null) { _crownReadableVisual.SetActive(false); } } private static void DestroyCrownVisibilityMarker() { if ((Object)(object)_crownVisibilityMarker != (Object)null) { Object.Destroy((Object)(object)_crownVisibilityMarker); _crownVisibilityMarker = null; } if ((Object)(object)_crownReadableVisual != (Object)null) { Object.Destroy((Object)(object)_crownReadableVisual); _crownReadableVisual = null; } if ((Object)(object)_crownGrabProxy != (Object)null) { Object.Destroy((Object)(object)_crownGrabProxy); _crownGrabProxy = null; } } private static void DestroyCrownSafeRoot() { if ((Object)(object)_crownSafeRoot != (Object)null) { Object.Destroy((Object)(object)_crownSafeRoot); } _crownSafeRoot = null; _crownHierarchyDetachedLogged = false; } private static void PrepareTrueCrownInteraction(object crownGrab, object arena) { //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0157: 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_010e: Expected O, but got Unknown Component val = (Component)((crownGrab is Component) ? crownGrab : null); Component val2 = (Component)((arena is Component) ? arena : null); if ((Object)(object)val == (Object)null) { return; } Transform val3 = (((Object)(object)val2 != (Object)null) ? val2.transform : null); if (!val.gameObject.activeInHierarchy && (Object)(object)val3 != (Object)null) { val.transform.SetParent(val3, true); val.gameObject.SetActive(true); } else if (!val.gameObject.activeSelf) { val.gameObject.SetActive(true); } Behaviour val4 = (Behaviour)(object)((val is Behaviour) ? val : null); if ((Object)(object)val4 != (Object)null) { val4.enabled = true; } object member = GetMember(arena, "crownTransform"); Transform val5 = (Transform)((member is Transform) ? member : null); if ((Object)(object)val5 != (Object)null) { if (!((Component)val5).gameObject.activeInHierarchy && (Object)(object)val3 != (Object)null) { val5.SetParent(val3, true); ((Component)val5).gameObject.SetActive(true); } else if (!((Component)val5).gameObject.activeSelf) { ((Component)val5).gameObject.SetActive(true); } } if ((Object)(object)_crownGrabProxy == (Object)null) { _crownGrabProxy = new GameObject("ArenaCompat Crown World Grab Proxy"); } Transform transform = _crownGrabProxy.transform; transform.SetParent((Transform)null, true); transform.position = val.transform.position + Vector3.up * 0.85f; transform.rotation = Quaternion.identity; transform.localScale = Vector3.one; transform.SetParent(val.transform, true); int num = LayerMask.NameToLayer("StaticGrabObject"); _crownGrabProxy.layer = ((num >= 0) ? num : val.gameObject.layer); try { _crownGrabProxy.tag = "Phys Grab Object"; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ArenaCompat] FERAL crown proxy tag assignment failed: " + ex.GetType().Name + " - " + ex.Message)); } SphereCollider val6 = _crownGrabProxy.GetComponent<SphereCollider>(); if ((Object)(object)val6 == (Object)null) { val6 = _crownGrabProxy.AddComponent<SphereCollider>(); } val6.radius = 0.9f; ((Collider)val6).isTrigger = false; ((Collider)val6).enabled = true; SetMember(crownGrab, "colliderTransform", transform); SetMember(crownGrab, "hoverText", "CROWN - GRAB TO WIN"); Renderer[] array = (((Object)(object)val5 != (Object)null) ? ((Component)val5).GetComponentsInChildren<Renderer>(true) : val.GetComponentsInChildren<Renderer>(true)); ManualLogSource log = Plugin.Log; object[] array2 = new object[15] { "[ArenaCompat] FERAL true crown interaction repaired | position=", null, null, null, null, null, null, null, null, null, null, null, null, null, null }; Vector3 position = val.transform.position; array2[1] = ((Vector3)(ref position)).ToString("F2"); array2[2] = " | proxyPosition="; Vector3 position2 = transform.position; array2[3] = ((Vector3)(ref position2)).ToString("F2"); array2[4] = " | proxyParent='"; array2[5] = (((Object)(object)transform.parent != (Object)null) ? ((Object)((Component)transform.parent).gameObject).name : "<root>"); array2[6] = "' | proxyTag='"; array2[7] = _crownGrabProxy.tag; array2[8] = "' | proxyLayer="; array2[9] = _crownGrabProxy.layer; array2[10] = " | colliderRadius=0.90 | renderers="; array2[11] = ((array != null) ? array.Length : 0); array2[12] = " | active="; array2[13] = val.gameObject.activeInHierarchy; array2[14] = "."; log.LogInfo((object)string.Concat(array2)); } private static bool IsCrownCageDestroyed(object arena) { object member = GetMember(arena, "crownCageDestroyed"); if (member is bool) { return (bool)member; } return false; } private static void SafeReleaseCrownLocally(object arena, object crownGrab) { if (arena != null) { DestroyReferencedGameObject(arena, "crownSphere"); DestroyReferencedGameObject(arena, "crownMechanic"); SetMember(arena, "crownCageDestroyed", true); EnsureTrueCrownActive(crownGrab, arena); } } private static void DestroyReferencedGameObject(object owner, string memberName) { object member = GetMember(owner, memberName); Component val = (Component)((member is Component) ? member : null); GameObject val2 = (GameObject)((member is GameObject) ? member : null); if ((Object)(object)val != (Object)null) { val2 = val.gameObject; } if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } } private static void EnsureTrueCrownActive(object crownGrab, object arena) { Component val = (Component)((crownGrab is Component) ? crownGrab : null); if ((Object)(object)val != (Object)null) { if (!val.gameObject.activeSelf) { val.gameObject.SetActive(true); } Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null); if ((Object)(object)val2 != (Object)null && !val2.enabled) { val2.enabled = true; } } object member = GetMember(arena, "crownTransform"); Transform val3 = (Transform)((member is Transform) ? member : null); if ((Object)(object)val3 != (Object)null && !((Component)val3).gameObject.activeSelf) { ((Component)val3).gameObject.SetActive(true); } } private static bool IsCrownCurrentlyGrabbed(object crownGrab) { object member = GetMember(crownGrab, "grabbed"); IList list = GetMember(crownGrab, "playerGrabbing") as IList; if (!(member is bool) || !(bool)member) { if (list != null) { return list.Count > 0; } return false; } return true; } private static bool TryRestoreCrownWinnerFromActualGrabber(object arena, object crownGrab) { try { if (!(GetMember(crownGrab, "playerGrabbing") is IList { Count: not 0 } list) || list[0] == null) { return false; } object member = GetMember(list[0], "playerAvatar"); if (member == null || IsUnityObjectDestroyed(member)) { return false; } SetMember(arena, "winnerPlayer", member); object member2 = GetMember(member, "steamID"); Type type = AccessTools.TypeByName("SessionManager"); object obj = ((type != null) ? GetStaticMember(type, "instance") : null); if (obj != null && member2 != null) { SetMember(obj, "crownedPlayerSteamID", member2); } Type type2 = AccessTools.TypeByName("StatsManager"); object obj2 = ((type2 != null) ? GetStaticMember(type2, "instance") : null); if (obj2 != null && member2 != null) { MethodInfo methodInfo = AccessTools.Method(obj2.GetType(), "UpdateCrown", (Type[])null, (Type[])null); if (methodInfo != null) { try { methodInfo.Invoke(obj2, new object[1] { member2 }); } catch { } } } TryRestoreCrownWinUi(member); object member3 = GetMember(arena, "crownExplosion"); GameObject val = (GameObject)((member3 is GameObject) ? member3 : null); Component val2 = (Component)((member3 is Component) ? member3 : null); if ((Object)(object)val2 != (Object)null) { val = val2.gameObject; } if ((Object)(object)val != (Object)null) { val.SetActive(true); } return true; } catch { return false; } } private static void TryRestoreCrownWinUi(object player) { if (player == null) { return; } try { Type type = AccessTools.TypeByName("ArenaMessageWinUI"); object obj = ((type != null) ? GetStaticMember(type, "instance") : null); object obj2 = ((obj != null) ? GetMember(obj, "kingObject") : null); GameObject val = (GameObject)((obj2 is GameObject) ? obj2 : null); Component val2 = (Component)((obj2 is Component) ? obj2 : null); if ((Object)(object)val2 != (Object)null) { val = val2.gameObject; } if ((Object)(object)val == (Object)null) { return; } Type type2 = AccessTools.TypeByName("MenuPlayerListed"); if (type2 == null) { return; } Component component = val.GetComponent(type2); if (!((Object)(object)component == (Object)null)) { MethodInfo methodInfo = AccessTools.Method(((object)component).GetType(), "ForcePlayer", (Type[])null, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(component, new object[1] { player }); } } } catch { } } private static bool TryForceArenaGameOver(object arena) { if (arena == null || IsUnityObjectDestroyed(arena)) { return false; } object member = GetMember(arena, "winnerPlayer"); if (member == null || IsUnityObjectDestroyed(member)) { return false; } try { Type type = arena.GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "currentState"); if (fieldInfo == null) { return false; } Type fieldType = fieldInfo.FieldType; object value = fieldInfo.GetValue(arena); int num = ((value != null) ? Convert.ToInt32(value) : (-1)); if (num == 8) { _crownGameOverRequested = true; return true; } if (_crownGameOverRequested) { return true; } if (!fieldType.IsEnum) { Plugin.Log.LogWarning((object)"[ArenaCompat] FERAL crown victory could not resolve Arena.States enum."); return false; } MethodInfo methodInfo = AccessTools.Method(type, "StateSet", new Type[1] { fieldType }, (Type[])null); if (methodInfo == null) { Plugin.Log.LogWarning((object)"[ArenaCompat] FERAL crown victory could not find Arena.StateSet(States)."); return false; } object obj = Enum.ToObject(fieldType, 8); _crownGameOverRequested = true; methodInfo.Invoke(arena, new object[1] { obj }); Plugin.Log.LogInfo((object)("[ArenaCompat] FERAL crown victory -> vanilla Arena GameOver requested | previousState=" + num + " | targetState=8.")); return true; } catch (Exception ex) { _crownGameOverRequested = false; Exception ex2 = ((ex is TargetInvocationException && ex.InnerException != null) ? ex.InnerException : ex); Plugin.Log.LogWarning((object)("[ArenaCompat] FERAL crown victory GameOver transition failed: " + ex2.GetType().Name + ": " + ex2.Message)); return false; } } private static bool TryInvokeArenaMethod(object arena, string methodName) { if (arena == null) { return false; } try { MethodInfo methodInfo = AccessTools.Method(arena.GetType(), methodName, Type.EmptyTypes, (Type[])null); if (methodInfo == null) { return false; } methodInfo.Invoke(arena, null); return true; } catch (Exception ex) { Exception ex2 = ((ex is TargetInvocationException && ex.InnerException != null) ? ex.InnerException : ex); Plugin.Log.LogWarning((object)("[ArenaCompat] FERAL vanilla Arena." + methodName + " failed: " + ex2.GetType().Name + ": " + ex2.Message)); return false; } } private static bool IsUnityObjectDestroyed(object value) { Object val = (Object)((value is Object) ? value : null); if (object.ReferenceEquals(val, null)) { return false; } return !Object.op_Implicit(val); } private static int GetRuntimeObjectId(object value) { Object val = (Object)((value is Object) ? value : null); if (val != (Object)null) { return val.GetInstanceID(); } return value?.GetHashCode() ?? 0; } private static int GetPlayerViewId(PlayerAvatar player) { if ((Object)(object)player == (Object)null) { return 0; } object member = GetMember(player, "photonView"); if (member == null) { member = GetMember(player, "PhotonView"); } object member2 = GetMember(member, "ViewID"); if (member2 is int) { return (int)member2; } try { return (member2 != null) ? Convert.ToInt32(member2) : 0; } catch { return 0; } } private static bool IsEnemyVisionPlayerRegistered(object enemy, int viewId) { object member = GetMember(enemy, "HasVision"); if (member is bool && !(bool)member) { return true; } object member2 = GetMember(enemy, "Vision"); if (member2 == null) { return true; } if (DictionaryContainsKey(GetMember(member2, "VisionsTriggered"), viewId)) { return DictionaryContainsKey(GetMember(member2, "VisionTriggered"), viewId); } return false; } private static bool IsEnemyOnScreenPlayerRegistered(object enemy, int viewId) { object member = GetMember(enemy, "HasOnScreen"); if (member is bool && !(bool)member) { return true; } object member2 = GetMember(enemy, "OnScreen"); if (member2 == null) { return true; } if (DictionaryContainsKey(GetMember(member2, "OnScreenPlayer"), viewId)) { return DictionaryContainsKey(GetMember(member2, "CulledPlayer"), viewId); } return false; } private static bool DictionaryContainsKey(object dictionary, int key) { if (dictionary == null) { return false; } if (dictionary is IDictionary dictionary2) { return dictionary2.Contains(key); } try { MethodInfo methodInfo = AccessTools.Method(dictionary.GetType(), "ContainsKey", new Type[1] { typeof(int) }, (Type[])null); if (methodInfo != null) { object obj = methodInfo.Invoke(dictionary, new object[1] { key }); if (obj is bool) { return (bool)obj; } } } catch { } return false; } internal static bool IsCustomArenaActive() { try { if (!IsDisposalArenaLevel()) { return false; } GameObject val = GameObject.Find("Start Room - Arena(Clone)") ?? GameObject.Find("Start Room - Arena"); return (Object)(object)val != (Object)null; } catch { return false; } } internal static bool IsInsideCustomArena(Transform transform) { Transform val = transform; while ((Object)(object)val != (Object)null) { string text = ((Object)val).name ?? ""; if (text.StartsWith("Start Room - Arena", StringComparison.OrdinalIgnoreCase)) { return true; } val = val.parent; } return false; } internal static bool IsDisposalArenaLevel() { try { if ((Object)(object)RunManager.instance == (Object)null || (Object)(object)RunManager.instance.levelCurrent == (Object)null) { return false; } string a = ((Object)RunManager.instance.levelCurrent).name ?? ""; return string.Equals(a, "Level - Arena Fight", StringComparison.OrdinalIgnoreCase); } catch { return false; } } internal static AudioSource GetFeralMusicSource(object feralPlugin) { object memberValue = GetMemberValue(feralPlugin, "musicSource"); return (AudioSource)((memberValue is AudioSource) ? memberValue : null); } internal static void ResetFeralSceneState(object feralPlugin) { if (feralPlugin == null) { return; } try { RemoveFeralNavMesh(); DestroyCrownVisibilityMarker(); DestroyCrownSafeRoot(); _currentFeralArena = null; _currentTrueCrown = null; _crownInteractionReady = false; _crownInteractionPrepared = false; _crownGrabForwardInProgress = false; _crownGameOverRequested = false; _preparationArmed = false; _preparationWaitingForRoundStart = false; _preparationReleased = true; _preparationReleaseLogged = false; _preparationReleaseAt = -1f; FeralPreparationOnScreenGuard.ResetLogState(); AudioSource feralMusicSource = GetFeralMusicSource(feralPlugin); if ((Object)(object)feralMusicSource != (Object)null && feralMusicSource.isPlaying) { feralMusicSource.Stop(); } SetMember(feralPlugin, "musicTriggered", false); SetMember(feralPlugin, "floorDoor", null); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ArenaCompat] FERAL scene-state reset failed: " + ex.Message)); } } private static bool TryBuildFeralNavMesh(GameObject arenaRoot) { //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: 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) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)arenaRoot == (Object)null) { return false; } try { if (_feralNavMeshAdded && ((NavMeshDataInstance)(ref _feralNavMeshInstance)).valid) { return true; } Renderer val = null; Collider val2 = null; Renderer[] componentsInChildren = arenaRoot.GetComponentsInChildren<Renderer>(true); foreach (Renderer val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)null) && string.Equals(((Object)((Component)val3).gameObject).name, "Arena_Ground", StringComparison.OrdinalIgnoreCase)) { val = val3; break; } } Collider[] componentsInChildren2 = arenaRoot.GetComponentsInChildren<Collider>(true); foreach (Collider val4 in componentsInChildren2) { if (!((Object)(object)val4 == (Object)null) && string.Equals(((Object)((Component)val4).gameObject).name, "Arena_Ground", StringComparison.OrdinalIgnoreCase)) { val2 = val4; break; } } Bounds bounds; if ((Object)(object)val != (Object)null) { bounds = val.bounds; } else { if (!((Object)(object)val2 != (Object)null)) { Plugin.Log.LogWarning((object)"[ArenaCompat] FERAL NavMesh: Arena_Ground renderer/collider not found."); return false; } bounds = val2.bounds; } _feralArenaGroundBounds = bounds; _feralArenaGroundBoundsValid = true; float y = ((Bounds)(ref bounds)).max.y; Bounds playableBounds = bounds; foreach (Renderer val5 in componentsInChildren) { if (!((Object)(object)val5 == (Object)null)) { EncapsulatePlayableBounds(ref playableBounds, val5.bounds, bounds); } } foreach (Collider val6 in componentsInChildren2) { if (!((Object)(object)val6 == (Object)null) && !val6.isTrigger) { EncapsulatePlayableBounds(ref playableBounds, val6.bounds, bounds); } } bool flag = false; try { if ((Object)(object)PlayerController.instance != (Object)null && (Object)(object)PlayerController.instance.playerAvatarScript != (Object)null) { Vector3 position = ((Component)PlayerController.instance.playerAvatarScript).transform.position; Vector3 val7 = default(Vector3); ((Vector3)(ref val7))..ctor(position.x, ((Bounds)(ref bounds)).center.y, position.z); ((Bounds)(ref playableBounds)).Encapsulate(val7); flag = true; } } catch { } float num = Mathf.Max(8f, ((Bounds)(ref playableBounds)).size.x + 12f); float num2 = Mathf.Max(8f, ((Bounds)(ref playableBounds)).size.z + 12f); Vector3 val8 = default(Vector3); ((Vector3)(ref val8))..ctor(((Bounds)(ref playableBounds)).center.x, ((Bounds)(ref bounds)).center.y, ((Bounds)(ref playableBounds)).center.z); _feralPlayableBounds = new Bounds(new Vector3(val8.x, y + 2f, val8.z), new Vector3(num, 12f, num2)); _feralPlayableBoundsValid = true; NavMeshBuildSource item = default(NavMeshBuildSource); ((NavMeshBuildSource)(ref item)).shape = (NavMeshBuildSourceShape)2; ((NavMeshBuildSource)(ref item)).area = 0; ((NavMeshBuildSource)(ref item)).size = new Vector3(num, 0.2f, num2); ((NavMeshBuildSource)(ref item)).transform = Matrix4x4.TRS(new Vector3(val8.x, y - 0.1f, val8.z), Quaternion.identity, Vector3.one); List<NavMeshBuildSource> list = new List<NavMeshBuildSource>(); list.Add(item); int settingsCount = NavMesh.GetSettingsCount(); if (settingsCount <= 0) { Plugin.Log.LogWarning((object)"[ArenaCompat] FERAL NavMesh: no NavMesh build settings available."); return false; } NavMeshBuildSettings settingsByIndex = NavMesh.GetSettingsByIndex(0); Bounds val9 = default(Bounds); ((Bounds)(ref val9))..ctor(new Vector3(val8.x, y + 2f, val8.z), new Vector3(num + 4f, 12f, num2 + 4f)); NavMeshData val10 = NavMeshBuilder.BuildNavMeshData(settingsByIndex, list, val9, Vector3.zero, Quaternion.identity); if ((Object)(object)val10 == (Object)null) { Plugin.Log.LogWarning((object)"[ArenaCompat] FERAL NavMesh: BuildNavMeshData returned null."); return false; } _feralNavMeshInstance = NavMesh.AddNavMeshData(val10); _feralNavMeshAdded = ((NavMeshDataInstance)(ref _feralNavMeshInstance)).valid; ManualLogSource log = Plugin.Log; object[] array = new object[17] { "[ArenaCompat] FERAL expanded fallback NavMesh built | floorCenter=", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null }; Vector3 center = ((Bounds)(ref bounds)).center; array[1] = ((Vector3)(ref center)).ToString("F2"); array[2] = " | floorSize="; Vector3 size = ((Bounds)(ref bounds)).size; array[3] = ((Vector3)(ref size)).ToString("F2"); array[4] = " | navCenter="; array[5] = ((Vector3)(ref val8)).ToString("F2"); array[6] = " | navSize=("; array[7] = num.ToString("F2"); array[8] = ", "; array[9] = num2.ToString("F2"); array[10] = ") | playerIncluded="; array[11] = flag; array[12] = " | agentType="; array[13] = ((NavMeshBuildSettings)(ref settingsByIndex)).agentTypeID; array[14] = " | valid="; array[15] = _feralNavMeshAdded; array[16] = "."; log.LogInfo((object)string.Concat(array)); return _feralNavMeshAdded; } catch (Exception ex) { Plugin.Log.LogError((object)("[ArenaCompat] FERAL fallback NavMesh build failed: " + ex)); return false; } } private static void EncapsulatePlayableBounds(ref Bounds playableBounds, Bounds candidate, Bounds floorBounds) { //IL_0002: 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_0037: 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_0056: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_00da: 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) if (!(((Bounds)(ref candidate)).size.x <= 0.01f) || !(((Bounds)(ref candidate)).size.z <= 0.01f)) { Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(((Bounds)(ref floorBounds)).center.x, ((Bounds)(ref floorBounds)).center.z); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(((Bounds)(ref candidate)).center.x, ((Bounds)(ref candidate)).center.z); if (!(Vector2.Distance(val, val2) > 80f) && !(((Bounds)(ref candidate)).size.x > 120f) && !(((Bounds)(ref candidate)).size.z > 120f)) { Vector3 min = ((Bounds)(ref candidate)).min; Vector3 max = ((Bounds)(ref candidate)).max; ((Bounds)(ref playableBounds)).Encapsulate(new Vector3(min.x, ((Bounds)(ref floorBounds)).center.y, min.z)); ((Bounds)(ref playableBounds)).Encapsulate(new Vector3(max.x, ((Bounds)(ref floorBounds)).center.y, max.z)); } } } private static IEnumerator RepairFeralAgentsDelayed() { float[] waits = new float[3] { 1f, 2f, 3f }; for (int pass = 0; pass < waits.Length; pass++) { yield return (object)new WaitForSeconds(waits[pass]); if (IsCustomArenaActive()) { RepairFeralAgentsAndLog(pass + 1); continue; } break; } } private static void RepairFeralAgentsAndLog(int pass) { //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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected O, but got Unknown //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: 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_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Invalid comparison between Unknown and I4 //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; NavMeshAgent[] array = Object.FindObjectsOfType<NavMeshAgent>(); NavMeshHit val2 = default(NavMeshHit); foreach (NavMeshAgent val in array) { if ((Object)(object)val == (Object)null || !((Behaviour)val).enabled || !((Component)val).gameObject.activeInHierarchy || (_feralPlayableBoundsValid && !InsidePlayableXZ(((Component)val).transform.position, _feralPlayableBounds, 12f))) { continue; } num++; bool flag = false; try { flag = val.isOnNavMesh; } catch { } if (flag) { num2++; continue; } if (NavMesh.SamplePosition(((Component)val).transform.position, ref val2, 10f, -1)) { try { if (val.Warp(((NavMeshHit)(ref val2)).position)) { num3++; continue; } } catch { } } num4++; } bool flag2 = false; bool flag3 = false; Vector3 val3 = Vector3.zero; Vector3 val4 = Vector3.zero; try { if ((Object)(object)PlayerController.instance != (Object)null && (Object)(object)PlayerController.instance.playerAvatarScript != (Object)null) { PlayerAvatar playerAvatarScript = PlayerController.instance.playerAvatarScript; val3 = ((Component)playerAvatarScript).transform.position; NavMeshHit val5 = default(NavMeshHit); flag2 = NavMesh.SamplePosition(val3, ref val5, 6f, -1); if (flag2) { val4 = ((NavMeshHit)(ref val5)).position; } if (flag2) { foreach (NavMeshAgent val6 in array) { if ((Object)(object)val6 == (Object)null || !((Behaviour)val6).enabled) { continue; } bool flag4 = false; try { flag4 = val6.isOnNavMesh; } catch { } if (flag4) { NavMeshPath val7 = new NavMeshPath(); if (NavMesh.CalculatePath(((Component)val6).transform.position, val4, -1, val7)) { flag3 = (int)val7.status == 0; } break; } } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ArenaCompat] FERAL NavMesh player diagnostic failed: " + ex.Message)); } Plugin.Log.LogInfo((object)("[ArenaCompat] FERAL NavMesh agent pass " + pass + " | agents=" + num + " | onMesh=" + num2 + " | warped=" + num3 + " | unresolved=" + num4 + " | playerCurrent=" + ((Vector3)(ref val3)).ToString("F2") + " | currentOnNav=" + flag2 + " | sampleEnemyToPlayerPathComplete=" + flag3 + ".")); } private static bool InsidePlayableXZ(Vector3 position, Bounds bounds, float padding) { //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_000a: 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) Vector3 min = ((Bounds)(ref bounds)).min; Vector3 max = ((Bounds)(ref bounds)).max; if (position.x >= min.x - padding && position.x <= max.x + padding && position.z >= min.z - padding) { return position.z <= max.z + padding; } return false; } private static void SnapArenaLevelPointsToNavMesh(GameObject arenaRoot) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)arenaRoot == (Object)null) { return; } Type type = AccessTools.TypeByName("LevelPoint"); if (type == null || !typeof(Component).IsAssignableFrom(type)) { Plugin.Log.LogWarning((object)"[ArenaCompat] FERAL NavMesh: LevelPoint type not found; spawn-point snap skipped."); return; } Component[] componentsInChildren = arenaRoot.GetComponentsInChildren(type, true); int num = 0; int num2 = 0; int num3 = 0; NavMeshHit