Decompiled source of WildEvents v1.0.0

plugins\WildEvents\WildEvents.dll

Decompiled 9 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("WildEvents")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("WildEvents")]
[assembly: AssemblyTitle("WildEvents")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace WildEvents
{
	[BepInPlugin("com.howtofish.wildevents", "Wild Events", "1.0.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "com.howtofish.wildevents";

		public const string Name = "Wild Events";

		public const string Version = "1.0.0";

		private static ManualLogSource Log;

		private ConfigEntry<bool> _enabled;

		private ConfigEntry<float> _minInterval;

		private ConfigEntry<float> _maxInterval;

		private ConfigEntry<string> _excludedScenes;

		private ConfigEntry<bool> _seahorseEnabled;

		private ConfigEntry<int> _seahorseMin;

		private ConfigEntry<int> _seahorseMax;

		private ConfigEntry<bool> _piranhaEnabled;

		private ConfigEntry<int> _piranhaMin;

		private ConfigEntry<int> _piranhaMax;

		private ConfigEntry<float> _piranhaHeight;

		private ConfigEntry<bool> _piranhaBossUi;

		private ConfigEntry<bool> _piranhaBossMusic;

		private ConfigEntry<bool> _urchinEnabled;

		private ConfigEntry<int> _urchinMin;

		private ConfigEntry<int> _urchinMax;

		private ConfigEntry<bool> _urchinBossUi;

		private ConfigEntry<bool> _urchinBossMusic;

		private ConfigEntry<bool> _debugHotkeys;

		private ConfigEntry<KeyCode> _seahorseDebugKey;

		private ConfigEntry<KeyCode> _piranhaDebugKey;

		private ConfigEntry<KeyCode> _urchinDebugKey;

		private ConfigEntry<KeyCode> _dumpDebugKey;

		private float _nextEventAt;

		private bool _eventRunning;

		private string _currentEvent = "";

		private readonly List<Object> _eventEntities = new List<Object>();

		private int _eventTotal;

		private float _eventStartedAt;

		private Component _bossUi;

		private bool _ownsBossUi;

		private bool _bossUiWasShown;

		private bool _eventUsesBossPresentation;

		private bool _eventBossMusicStarted;

		private string _eventMusicClip = "";

		private string _eventMusicIntro = "";

		private string _eventMusicOutro = "";

		private Object _seahorsePrefab;

		private Object _piranhaPrefab;

		private Object _urchinPrefab;

		private void Awake()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Expected O, but got Unknown
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Expected O, but got Unknown
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Expected O, but got Unknown
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Expected O, but got Unknown
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable or disable Wild Events.");
			_minInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Events", "MinInterval", 120f, new ConfigDescription("Minimum seconds between random events. Default: 2 minutes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 600f), Array.Empty<object>()));
			_maxInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Events", "MaxInterval", 240f, new ConfigDescription("Maximum seconds between random events. Default: 4 minutes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 600f), Array.Empty<object>()));
			_excludedScenes = ((BaseUnityPlugin)this).Config.Bind<string>("Events", "ExcludedScenes", "Island1", "Comma-separated island names where events are disabled. Example: Island1,Island7");
			_seahorseEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Seahorse Stampede", "Enabled", true, "Enable Seahorse Stampede.");
			_seahorseMin = ((BaseUnityPlugin)this).Config.Bind<int>("Seahorse Stampede", "MinCount", 10, new ConfigDescription("Minimum Seahorses spawned.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
			_seahorseMax = ((BaseUnityPlugin)this).Config.Bind<int>("Seahorse Stampede", "MaxCount", 20, new ConfigDescription("Maximum Seahorses spawned.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
			_piranhaEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Piranha Rain", "Enabled", true, "Enable Piranha Rain.");
			_piranhaMin = ((BaseUnityPlugin)this).Config.Bind<int>("Piranha Rain", "MinCount", 25, new ConfigDescription("Minimum Piranhas spawned.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
			_piranhaMax = ((BaseUnityPlugin)this).Config.Bind<int>("Piranha Rain", "MaxCount", 40, new ConfigDescription("Maximum Piranhas spawned.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
			_piranhaHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Piranha Rain", "SpawnHeight", 15.77867f, new ConfigDescription("Height above the player where Piranhas spawn.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 60f), Array.Empty<object>()));
			_piranhaBossUi = ((BaseUnityPlugin)this).Config.Bind<bool>("Piranha Rain", "UseBossUI", true, "Use the native Boss UI as event progress when no real boss is active.");
			_piranhaBossMusic = ((BaseUnityPlugin)this).Config.Bind<bool>("Piranha Rain", "UseBossMusic", true, "Play the game's boss music while Piranha Rain is active.");
			_urchinEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Urchin Invasion", "Enabled", true, "Enable Urchin Invasion.");
			_urchinMin = ((BaseUnityPlugin)this).Config.Bind<int>("Urchin Invasion", "MinCount", 18, new ConfigDescription("Minimum Sea Urchins spawned.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>()));
			_urchinMax = ((BaseUnityPlugin)this).Config.Bind<int>("Urchin Invasion", "MaxCount", 25, new ConfigDescription("Maximum Sea Urchins spawned.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>()));
			_urchinBossUi = ((BaseUnityPlugin)this).Config.Bind<bool>("Urchin Invasion", "UseBossUI", true, "Use the native Boss UI as event progress when no real boss is active.");
			_urchinBossMusic = ((BaseUnityPlugin)this).Config.Bind<bool>("Urchin Invasion", "UseBossMusic", true, "Play the game's boss music while Urchin Invasion is active.");
			_debugHotkeys = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebugHotkeys", false, "Enable development event/dump hotkeys.");
			_seahorseDebugKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Debug", "SeahorseEventKey", (KeyCode)257, "Force Seahorse Stampede.");
			_piranhaDebugKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Debug", "PiranhaEventKey", (KeyCode)258, "Force Piranha Rain.");
			_urchinDebugKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Debug", "UrchinEventKey", (KeyCode)259, "Force Urchin Invasion.");
			_dumpDebugKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Debug", "DumpKey", (KeyCode)256, "Dump Wild Events creature/prefab/Boss UI/announcement UI information.");
			ScheduleNextEvent();
			Log.LogInfo((object)"Wild Events 1.0.0 loaded (BepInEx 5).");
			Log.LogInfo((object)"Debug: Numpad1=Seahorse, Numpad2=Piranha, Numpad3=Urchin, Numpad0=Dump. Island detection uses loaded scenes (same as Wild Albatross).");
			CachePrefabs();
		}

		private void OnDestroy()
		{
			if (_ownsBossUi && !HasRealBoss())
			{
				SetBossUiVisible(visible: false);
			}
		}

		private void Update()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if (!_enabled.Value)
			{
				return;
			}
			if (_debugHotkeys.Value)
			{
				if (Input.GetKeyDown(_dumpDebugKey.Value))
				{
					DumpWildEvents();
					return;
				}
				if (!_eventRunning && Input.GetKeyDown(_seahorseDebugKey.Value))
				{
					((MonoBehaviour)this).StartCoroutine(StartSeahorseStampede());
					return;
				}
				if (!_eventRunning && Input.GetKeyDown(_piranhaDebugKey.Value))
				{
					((MonoBehaviour)this).StartCoroutine(StartPiranhaRain());
					return;
				}
				if (!_eventRunning && Input.GetKeyDown(_urchinDebugKey.Value))
				{
					((MonoBehaviour)this).StartCoroutine(StartUrchinInvasion());
					return;
				}
			}
			if (_eventRunning)
			{
				UpdateEventState();
			}
			else if (IsEligibleIslandLoaded() && Time.unscaledTime >= _nextEventAt)
			{
				((MonoBehaviour)this).StartCoroutine(StartRandomEvent());
			}
		}

		private IEnumerator StartRandomEvent()
		{
			if (_eventRunning)
			{
				yield break;
			}
			List<int> list = new List<int>();
			if (_seahorseEnabled.Value)
			{
				list.Add(0);
			}
			if (_piranhaEnabled.Value)
			{
				list.Add(1);
			}
			if (_urchinEnabled.Value)
			{
				list.Add(2);
			}
			if (list.Count == 0)
			{
				ScheduleNextEvent();
				yield break;
			}
			switch (list[Random.Range(0, list.Count)])
			{
			case 0:
				yield return StartSeahorseStampede();
				break;
			case 1:
				yield return StartPiranhaRain();
				break;
			default:
				yield return StartUrchinInvasion();
				break;
			}
		}

		private unsafe IEnumerator StartSeahorseStampede()
		{
			if (!CanStartEvent("SEAHORSE STAMPEDE"))
			{
				yield break;
			}
			CachePrefabs();
			if (_seahorsePrefab == (Object)null)
			{
				Log.LogWarning((object)"[SEAHORSE] Fishable prefab not found.");
				FinishEvent(completed: false);
				yield break;
			}
			int count = RandomCount(_seahorseMin.Value, _seahorseMax.Value);
			BeginEvent("SEAHORSE STAMPEDE", count);
			Vector3 player = GetPlayerPosition();
			Log.LogInfo((object)("[SEAHORSE] PlayerWorld=" + ((object)(*(Vector3*)(&player))/*cast due to .constrained prefix*/).ToString()));
			if (player == Vector3.zero)
			{
				Log.LogWarning((object)"[SEAHORSE] Player world position not found; event aborted.");
				FinishEvent(completed: false);
				yield break;
			}
			for (int i = 0; i < count; i++)
			{
				if (!TryFindGroundPoint(player, 5f, 14f, out var point))
				{
					point = player + Random.insideUnitSphere * 8f + Vector3.up * 5f;
				}
				yield return SpawnOne(_seahorsePrefab, point + Vector3.up * 1f, spawnInAir: false);
				yield return (object)new WaitForSeconds(0.08f);
			}
			Log.LogWarning((object)$"[EVENT] Seahorse Stampede spawned {_eventEntities.Count}/{count} seahorses (spawn radius ~5-14m).");
			_eventTotal = Math.Max(1, _eventEntities.Count);
			if (_eventEntities.Count == 0)
			{
				FinishEvent(completed: false);
			}
		}

		private unsafe IEnumerator StartPiranhaRain()
		{
			if (!CanStartEvent("PIRANHA RAIN"))
			{
				yield break;
			}
			if ((_piranhaBossUi.Value || _piranhaBossMusic.Value) && HasRealBoss())
			{
				Log.LogInfo((object)"[PIRANHA RAIN] Real boss active; postponing event.");
				ScheduleNextEvent(10f, 20f);
				yield break;
			}
			CachePrefabs();
			if (_piranhaPrefab == (Object)null)
			{
				Log.LogWarning((object)"[PIRANHA] Fishable prefab not found.");
				FinishEvent(completed: false);
				yield break;
			}
			int count = RandomCount(_piranhaMin.Value, _piranhaMax.Value);
			BeginEvent("PIRANHA RAIN", count);
			if (!HasRealBoss())
			{
				StartEventBossPresentation("PIRANHA RAIN", _piranhaBossUi.Value, _piranhaBossMusic.Value);
			}
			Vector3 player = GetPlayerPosition();
			Log.LogInfo((object)("[PIRANHA] PlayerWorld=" + ((object)(*(Vector3*)(&player))/*cast due to .constrained prefix*/).ToString()));
			if (player == Vector3.zero)
			{
				Log.LogWarning((object)"[PIRANHA] Player world position not found; event aborted.");
				FinishEvent(completed: false);
				yield break;
			}
			for (int i = 0; i < count; i++)
			{
				Vector2 val = Random.insideUnitCircle * 9f;
				Vector3 position = player + new Vector3(val.x, _piranhaHeight.Value + Random.Range(-2f, 4f), val.y);
				yield return SpawnOne(_piranhaPrefab, position, spawnInAir: true);
				yield return (object)new WaitForSeconds(0.06f);
			}
			_eventTotal = Math.Max(1, _eventEntities.Count);
			Log.LogWarning((object)$"[EVENT] Piranha Rain spawned {_eventEntities.Count}/{count} piranhas (horizontal radius <=9m).");
			if (_eventEntities.Count == 0)
			{
				FinishEvent(completed: false);
			}
		}

		private unsafe IEnumerator StartUrchinInvasion()
		{
			if (!CanStartEvent("URCHIN INVASION"))
			{
				yield break;
			}
			CachePrefabs();
			if (_urchinPrefab == (Object)null)
			{
				Log.LogWarning((object)"[URCHIN] Fishable prefab not found.");
				FinishEvent(completed: false);
				yield break;
			}
			int count = RandomCount(_urchinMin.Value, _urchinMax.Value);
			BeginEvent("URCHIN INVASION", count);
			if (HasRealBoss() && (_urchinBossUi.Value || _urchinBossMusic.Value))
			{
				Log.LogInfo((object)"[URCHIN INVASION] Real boss active; postponing event.");
				FinishEvent(completed: false);
				ScheduleNextEvent(10f, 20f);
				yield break;
			}
			if (!HasRealBoss())
			{
				StartEventBossPresentation("URCHIN INVASION", _urchinBossUi.Value, _urchinBossMusic.Value);
			}
			Vector3 player = GetPlayerPosition();
			Log.LogInfo((object)("[URCHIN] PlayerWorld=" + ((object)(*(Vector3*)(&player))/*cast due to .constrained prefix*/).ToString()));
			if (player == Vector3.zero)
			{
				Log.LogWarning((object)"[URCHIN] Player world position not found; event aborted.");
				FinishEvent(completed: false);
				yield break;
			}
			for (int i = 0; i < count; i++)
			{
				if (!TryFindGroundPoint(player, 6f, 16f, out var point))
				{
					point = player + Random.insideUnitSphere * 9f + Vector3.up * 4f;
				}
				yield return SpawnOne(_urchinPrefab, point + Vector3.up * 0.8f, spawnInAir: false);
				yield return (object)new WaitForSeconds(0.09f);
			}
			_eventTotal = Math.Max(1, _eventEntities.Count);
			Log.LogWarning((object)$"[EVENT] Urchin Invasion spawned {_eventEntities.Count}/{count} urchins (spawn radius ~6-16m).");
			if (_eventEntities.Count == 0)
			{
				FinishEvent(completed: false);
			}
		}

		private bool CanStartEvent(string eventName)
		{
			if (_eventRunning)
			{
				return false;
			}
			if (!IsEligibleIslandLoaded())
			{
				string text = GetCurrentIslandName() ?? "<unknown>";
				Log.LogInfo((object)("[" + eventName + "] No eligible island loaded. Detected=" + text + ", Excluded='" + _excludedScenes.Value + "'."));
				ScheduleNextEvent(10f, 20f);
				return false;
			}
			return true;
		}

		private void BeginEvent(string name, int expectedCount)
		{
			_eventRunning = true;
			_currentEvent = name;
			_eventEntities.Clear();
			_eventTotal = Math.Max(1, expectedCount);
			_eventStartedAt = Time.unscaledTime;
			_ownsBossUi = false;
			_bossUiWasShown = false;
			_eventUsesBossPresentation = false;
			_eventBossMusicStarted = false;
			_eventMusicClip = "";
			_eventMusicIntro = "";
			_eventMusicOutro = "";
			Log.LogWarning((object)("================ WILD EVENT: " + name + " ================"));
		}

		private void UpdateEventState()
		{
			if (_eventUsesBossPresentation && HasRealBoss())
			{
				Log.LogWarning((object)"[EVENT BOSS] Real boss appeared. Releasing event Boss UI/music ownership.");
				_ownsBossUi = false;
				_bossUi = null;
				_eventBossMusicStarted = false;
				_eventUsesBossPresentation = false;
			}
			int num = 0;
			for (int num2 = _eventEntities.Count - 1; num2 >= 0; num2--)
			{
				Object obj = _eventEntities[num2];
				if (IsEntityStillInEvent(obj))
				{
					num++;
				}
				else
				{
					_eventEntities.RemoveAt(num2);
				}
			}
			if (_eventUsesBossPresentation && _ownsBossUi)
			{
				float progress = ((_eventTotal <= 0) ? 0f : Mathf.Clamp01((float)num / (float)_eventTotal));
				UpdateBossUiProgress(progress);
			}
			if (num <= 0 && Time.unscaledTime - _eventStartedAt > 1.5f)
			{
				FinishEvent(completed: true);
			}
		}

		private bool IsEntityStillInEvent(Object obj)
		{
			if (obj == (Object)null)
			{
				return false;
			}
			Component val = (Component)(object)((obj is Component) ? obj : null);
			GameObject val2 = (GameObject)(object)((obj is GameObject) ? obj : null);
			if ((Object)(object)val != (Object)null)
			{
				val2 = val.gameObject;
			}
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			object fieldValue = GetFieldValue(val, "_localIsDead");
			if (fieldValue is bool && (bool)fieldValue)
			{
				return false;
			}
			object propertyOrField = GetPropertyOrField(val, "Hp", "<Hp>k__BackingField", "_localHp");
			if (propertyOrField is int && (int)propertyOrField <= 0)
			{
				return false;
			}
			if (Time.unscaledTime - _eventStartedAt > 2.5f)
			{
				object propertyOrField2 = GetPropertyOrField(val, "_isUnderwater", "_isUnderWater");
				if (propertyOrField2 is bool && (bool)propertyOrField2)
				{
					return false;
				}
			}
			return true;
		}

		private void FinishEvent(bool completed)
		{
			string currentEvent = _currentEvent;
			if (_eventUsesBossPresentation && _ownsBossUi && !HasRealBoss())
			{
				UpdateBossUiProgress(0f);
			}
			if (_eventBossMusicStarted && !HasRealBoss())
			{
				StopEventBossMusic();
			}
			if (_ownsBossUi && !HasRealBoss())
			{
				SetBossUiVisible(visible: false);
			}
			_ownsBossUi = false;
			_bossUi = null;
			_bossUiWasShown = false;
			_eventUsesBossPresentation = false;
			_eventBossMusicStarted = false;
			_eventEntities.Clear();
			_eventRunning = false;
			_currentEvent = "";
			_eventTotal = 0;
			Log.LogWarning((object)("[EVENT] " + currentEvent + " " + (completed ? "COMPLETED" : "ABORTED") + "."));
			ScheduleNextEvent();
		}

		private IEnumerator SpawnOne(Object prefab, Vector3 position, bool spawnInAir)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Type type = FindType("ItemSpawner");
			if (type == null || prefab == (Object)null)
			{
				yield break;
			}
			GameObject spawnerGo = new GameObject("WildEvents_TemporarySpawner");
			spawnerGo.transform.position = position;
			spawnerGo.SetActive(false);
			BoxCollider val = spawnerGo.AddComponent<BoxCollider>();
			((Collider)val).isTrigger = true;
			val.center = Vector3.zero;
			val.size = (spawnInAir ? new Vector3(2f, 2f, 2f) : new Vector3(2.5f, 6f, 2.5f));
			Component spawner = spawnerGo.AddComponent(type);
			SetField(spawner, "_isActive", true);
			SetField(spawner, "_itemToSpawn", prefab);
			SetField(spawner, "_spawnsDeadCreature", false);
			SetField(spawner, "_useRandomRotation", true);
			SetField(spawner, "_maxItemsSpawned", 1);
			SetField(spawner, "_spawnInstant", true);
			SetField(spawner, "_onlySpawnOnce", true);
			SetField(spawner, "_spawnInAir", spawnInAir);
			SetField(spawner, "_spawnDelay", 0f);
			SetField(spawner, "_spawnCount", 1);
			SetField(spawner, "_spawnBox", val);
			SetField(spawner, "_hasSpawned", false);
			FieldInfo listField = FindField(type, "_itemsSpawned");
			if (listField != null)
			{
				try
				{
					object value = Activator.CreateInstance(listField.FieldType);
					listField.SetValue(spawner, value);
				}
				catch
				{
				}
			}
			spawnerGo.SetActive(true);
			MethodInfo method = type.GetMethod("SpawnItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method == null)
			{
				Object.Destroy((Object)(object)spawnerGo);
				yield break;
			}
			IEnumerator enumerator = null;
			try
			{
				enumerator = method.Invoke(spawner, null) as IEnumerator;
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[SPAWN] SpawnItem invoke failed: " + ex.Message));
			}
			if (enumerator != null)
			{
				yield return ((MonoBehaviour)this).StartCoroutine(enumerator);
			}
			yield return null;
			if (listField != null)
			{
				try
				{
					if (listField.GetValue(spawner) is IEnumerable enumerable)
					{
						foreach (object item in enumerable)
						{
							Object val2 = (Object)((item is Object) ? item : null);
							if (val2 != (Object)null && !_eventEntities.Contains(val2))
							{
								_eventEntities.Add(val2);
							}
						}
					}
				}
				catch
				{
				}
			}
			Object.Destroy((Object)(object)spawnerGo);
		}

		private void DumpWildEvents()
		{
			Log.LogInfo((object)"");
			Log.LogInfo((object)"================ WILD EVENTS DUMP ================");
			Log.LogInfo((object)("CurrentIsland=" + (GetCurrentIslandName() ?? "<unknown>")));
			Log.LogInfo((object)$"RealBossActive={HasRealBoss()}");
			Log.LogInfo((object)$"EventRunning={_eventRunning}, CurrentEvent='{_currentEvent}', Tracked={_eventEntities.Count}");
			CachePrefabs();
			DumpPrefab("Seahorse", _seahorsePrefab);
			DumpPrefab("Piranha", _piranhaPrefab);
			DumpPrefab("SeaUrchin", _urchinPrefab);
			DumpTypeSummary("Fish");
			DumpTypeSummary("AttackingFish");
			DumpTypeSummary("Piranha");
			DumpTypeSummary("ItemSpawner");
			DumpTypeSummary("BossManager");
			DumpTypeSummary("BossUI");
			DumpEventAnnouncementUi();
			DumpMusicSystem();
			DumpBossLifecycleListeners("OnGlobalBossSpawn");
			DumpBossLifecycleListeners("OnGlobalBossDeath");
			DumpBossLifecycleListeners("OnGlobalBossDespawn");
			Log.LogInfo((object)"---------------- PIRANHA / SUMMON METHODS ----------------");
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				Type[] source;
				try
				{
					source = assembly.GetTypes();
				}
				catch (ReflectionTypeLoadException ex)
				{
					source = ex.Types.Where((Type t) => t != null).ToArray();
				}
				catch
				{
					continue;
				}
				foreach (Type item in source.Where((Type t) => t != null))
				{
					string text = item.FullName ?? item.Name ?? "";
					if (text.IndexOf("Piranha", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Fish", StringComparison.OrdinalIgnoreCase) < 0)
					{
						continue;
					}
					MethodInfo[] methods;
					try
					{
						methods = item.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					}
					catch
					{
						continue;
					}
					MethodInfo[] array = methods;
					foreach (MethodInfo methodInfo in array)
					{
						string text2 = methodInfo.Name ?? "";
						if (text2.IndexOf("Spawn", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("Summon", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("Water", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("Jump", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							string text3 = string.Join(", ", from p in methodInfo.GetParameters()
								select p.ParameterType.Name + " " + p.Name);
							Log.LogInfo((object)("[METHOD] " + item.FullName + "." + methodInfo.Name + "(" + text3 + ") -> " + methodInfo.ReturnType.Name));
						}
					}
				}
			}
			Log.LogInfo((object)"================ END WILD EVENTS DUMP ============");
			Log.LogInfo((object)"");
		}

		private void DumpEventAnnouncementUi()
		{
			Log.LogInfo((object)"");
			Log.LogInfo((object)"---------------- EVENT ANNOUNCEMENT UI SEARCH ----------------");
			string[] keywords = new string[15]
			{
				"announcement", "announce", "notification", "notify", "message", "toast", "banner", "warning", "quest", "objective",
				"title", "location", "area", "popup", "prompt"
			};
			Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, "Assembly-CSharp", StringComparison.OrdinalIgnoreCase));
			if (assembly != null)
			{
				Type[] source;
				try
				{
					source = assembly.GetTypes();
				}
				catch (ReflectionTypeLoadException ex)
				{
					source = ex.Types.Where((Type t) => t != null).ToArray();
				}
				catch
				{
					source = Array.Empty<Type>();
				}
				foreach (Type item in from t in source
					where t != null && keywords.Any((string k) => (t.FullName ?? t.Name ?? "").IndexOf(k, StringComparison.OrdinalIgnoreCase) >= 0)
					orderby t.FullName
					select t)
				{
					Log.LogInfo((object)("[ANNOUNCE TYPE] " + item.FullName + " : base=" + (item.BaseType?.FullName ?? "null")));
					MethodInfo[] array;
					try
					{
						array = item.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					}
					catch
					{
						array = Array.Empty<MethodInfo>();
					}
					MethodInfo[] array2 = array;
					foreach (MethodInfo methodInfo in array2)
					{
						string text = methodInfo.Name ?? "";
						if (text.IndexOf("Show", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Display", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Open", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Toggle", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Message", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Notify", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Quest", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Objective", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Title", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Text", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Fade", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							string text2 = string.Join(", ", from p in methodInfo.GetParameters()
								select p.ParameterType.Name + " " + p.Name);
							Log.LogInfo((object)("    METHOD " + methodInfo.ReturnType.Name + " " + methodInfo.Name + "(" + text2 + ")"));
						}
					}
				}
			}
			Log.LogInfo((object)"");
			Log.LogInfo((object)"---------------- LIVE ANNOUNCEMENT-LIKE OBJECTS ----------------");
			Transform[] source2 = Resources.FindObjectsOfTypeAll<Transform>();
			int num2 = 0;
			foreach (Transform item2 in from t in source2
				where (Object)(object)t != (Object)null && (Object)(object)((Component)t).gameObject != (Object)null
				orderby ((Object)t).name
				select t)
			{
				string name = ((Object)item2).name ?? "";
				string path = GetTransformPath(item2);
				if (!keywords.Any((string k) => name.IndexOf(k, StringComparison.OrdinalIgnoreCase) >= 0 || path.IndexOf(k, StringComparison.OrdinalIgnoreCase) >= 0))
				{
					continue;
				}
				Component[] components = ((Component)item2).GetComponents<Component>();
				Log.LogInfo((object)($"[ANNOUNCE GO] '{name}' activeSelf={((Component)item2).gameObject.activeSelf} " + $"activeHierarchy={((Component)item2).gameObject.activeInHierarchy} " + "path='" + path + "' components=[" + string.Join(", ", from c in components
					where (Object)(object)c != (Object)null
					select ((object)c).GetType().FullName) + "]"));
				Component[] array3 = components;
				foreach (Component val in array3)
				{
					if (!((Object)(object)val == (Object)null))
					{
						DumpAnnouncementComponentFields(val);
					}
				}
				num2++;
				if (num2 >= 80)
				{
					Log.LogWarning((object)"[ANNOUNCE UI] Result limit reached (80 objects).");
					break;
				}
			}
			Log.LogInfo((object)$"[ANNOUNCE UI] matching live objects={num2}");
		}

		private void DumpAnnouncementComponentFields(Component component)
		{
			string[] source = new string[16]
			{
				"text", "title", "message", "duration", "time", "fade", "canvas", "group", "alpha", "holder",
				"panel", "anim", "show", "active", "quest", "objective"
			};
			Type type = ((object)component).GetType();
			while (type != null && typeof(Component).IsAssignableFrom(type))
			{
				FieldInfo[] fields;
				try
				{
					fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				catch
				{
					break;
				}
				FieldInfo[] array = fields;
				foreach (FieldInfo fieldInfo in array)
				{
					string fieldName = fieldInfo.Name ?? "";
					if (source.Any((string k) => fieldName.IndexOf(k, StringComparison.OrdinalIgnoreCase) >= 0))
					{
						try
						{
							object value = fieldInfo.GetValue(component);
							Log.LogInfo((object)("    " + type.Name + "." + fieldInfo.Name + " = " + FormatDumpValue(value)));
						}
						catch
						{
						}
					}
				}
				type = type.BaseType;
			}
		}

		private static string GetTransformPath(Transform transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return "";
			}
			Stack<string> stack = new Stack<string>();
			Transform val = transform;
			while ((Object)(object)val != (Object)null)
			{
				stack.Push(((Object)val).name ?? "<unnamed>");
				val = val.parent;
			}
			return string.Join("/", stack);
		}

		private void DumpMusicSystem()
		{
			Log.LogInfo((object)"");
			Log.LogInfo((object)"---------------- MUSIC SYSTEM DUMP ----------------");
			string[] array = new string[3] { "MusicManager", "AudioManager", "AudioSequenceManager" };
			foreach (string text in array)
			{
				Type type = FindType(text);
				if (type == null)
				{
					Log.LogWarning((object)("[MUSIC TYPE] " + text + ": NOT FOUND"));
					continue;
				}
				Log.LogInfo((object)("[MUSIC TYPE] " + type.FullName + " : base=" + (type.BaseType?.FullName ?? "null")));
				FieldInfo[] array2;
				try
				{
					array2 = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				}
				catch
				{
					array2 = Array.Empty<FieldInfo>();
				}
				FieldInfo[] array3 = array2;
				foreach (FieldInfo fieldInfo in array3)
				{
					string text2 = fieldInfo.Name ?? "";
					if (text2.IndexOf("music", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("boss", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("track", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("song", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("clip", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("source", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("current", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("playing", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("fade", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						Log.LogInfo((object)("    FIELD " + (fieldInfo.IsStatic ? "static " : "") + fieldInfo.FieldType.FullName + " " + fieldInfo.Name));
					}
				}
				MethodInfo[] array4;
				try
				{
					array4 = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				}
				catch
				{
					array4 = Array.Empty<MethodInfo>();
				}
				MethodInfo[] array5 = array4;
				foreach (MethodInfo methodInfo in array5)
				{
					string text3 = methodInfo.Name ?? "";
					if (text3.IndexOf("music", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("play", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("stop", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("boss", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("track", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("song", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("fade", StringComparison.OrdinalIgnoreCase) >= 0 || text3.IndexOf("volume", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						string text4 = string.Join(", ", from p in methodInfo.GetParameters()
							select p.ParameterType.FullName + " " + p.Name);
						Log.LogInfo((object)("    METHOD " + (methodInfo.IsStatic ? "static " : "") + methodInfo.ReturnType.FullName + " " + methodInfo.Name + "(" + text4 + ")"));
					}
				}
				Object[] array6;
				try
				{
					array6 = Resources.FindObjectsOfTypeAll(type);
				}
				catch
				{
					array6 = Array.Empty<Object>();
				}
				Log.LogInfo((object)$"    LIVE INSTANCES={array6.Length}");
				Object[] array7 = array6;
				foreach (Object obj4 in array7)
				{
					Component val = (Component)(object)((obj4 is Component) ? obj4 : null);
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					Log.LogInfo((object)$"    INSTANCE GO='{((Object)val.gameObject).name}' active={val.gameObject.activeInHierarchy}");
					array3 = array2;
					foreach (FieldInfo fieldInfo2 in array3)
					{
						string text5 = fieldInfo2.Name ?? "";
						if ((text5.IndexOf("music", StringComparison.OrdinalIgnoreCase) >= 0 || text5.IndexOf("boss", StringComparison.OrdinalIgnoreCase) >= 0 || text5.IndexOf("track", StringComparison.OrdinalIgnoreCase) >= 0 || text5.IndexOf("song", StringComparison.OrdinalIgnoreCase) >= 0 || text5.IndexOf("clip", StringComparison.OrdinalIgnoreCase) >= 0 || text5.IndexOf("source", StringComparison.OrdinalIgnoreCase) >= 0 || text5.IndexOf("current", StringComparison.OrdinalIgnoreCase) >= 0 || text5.IndexOf("playing", StringComparison.OrdinalIgnoreCase) >= 0) && !fieldInfo2.IsStatic)
						{
							try
							{
								Log.LogInfo((object)("        " + fieldInfo2.Name + " = " + FormatDumpValue(fieldInfo2.GetValue(val))));
							}
							catch
							{
							}
						}
					}
				}
			}
			Log.LogInfo((object)"");
			Log.LogInfo((object)"---------------- AUDIOMANAGER SOURCES ----------------");
			Type type2 = FindType("AudioManager");
			if (type2 != null)
			{
				Object[] source;
				try
				{
					source = Resources.FindObjectsOfTypeAll(type2);
				}
				catch
				{
					source = Array.Empty<Object>();
				}
				foreach (Component item in source.OfType<Component>())
				{
					AudioSource[] components = item.GetComponents<AudioSource>();
					for (int num2 = 0; num2 < components.Length; num2++)
					{
						AudioSource val2 = components[num2];
						if (!((Object)(object)val2 == (Object)null))
						{
							string arg = (((Object)(object)val2.clip != (Object)null) ? ((Object)val2.clip).name : "<null>");
							Log.LogInfo((object)($"[AUDIO SOURCE {num2}] GO='{((Object)((Component)val2).gameObject).name}' " + $"clip='{arg}' playing={val2.isPlaying} " + $"loop={val2.loop} volume={val2.volume:0.###} time={val2.time:0.###}"));
						}
					}
				}
			}
			Log.LogInfo((object)"---------------- END MUSIC SYSTEM DUMP ------------");
		}

		private void DumpBossLifecycleListeners(string fieldName)
		{
			Type type = FindType("BossManager");
			if (type == null)
			{
				return;
			}
			FieldInfo field = type.GetField(fieldName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			Delegate obj = ((field != null) ? (field.GetValue(null) as Delegate) : null);
			if ((object)obj == null)
			{
				Log.LogInfo((object)("[BOSS LISTENERS] " + fieldName + ": none"));
				return;
			}
			Delegate[] invocationList = obj.GetInvocationList();
			foreach (Delegate obj2 in invocationList)
			{
				Log.LogInfo((object)("[BOSS LISTENERS] " + fieldName + ": " + obj2.Method?.DeclaringType?.FullName + "." + obj2.Method?.Name));
			}
		}

		private void DumpPrefab(string label, Object prefab)
		{
			if (prefab == (Object)null)
			{
				Log.LogWarning((object)("[PREFAB] " + label + ": NOT FOUND"));
				return;
			}
			GameObject val = (GameObject)(object)((prefab is GameObject) ? prefab : null);
			Component val2 = (Component)(object)((prefab is Component) ? prefab : null);
			if ((Object)(object)val2 != (Object)null)
			{
				val = val2.gameObject;
			}
			Log.LogInfo((object)"");
			Log.LogInfo((object)("[PREFAB] " + label + ": name='" + prefab.name + "', runtimeType=" + ((object)prefab).GetType().FullName));
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Component[] components = val.GetComponents<Component>();
			Log.LogInfo((object)("  Components=[" + string.Join(", ", from c in components
				where (Object)(object)c != (Object)null
				select ((object)c).GetType().FullName) + "]"));
			string[] source = new string[16]
			{
				"hp", "dead", "death", "water", "underwater", "jump", "force", "attack", "damage", "spawn",
				"summon", "boss", "speed", "worth", "drop", "time"
			};
			Component[] array = components;
			foreach (Component val3 in array)
			{
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				Type type = ((object)val3).GetType();
				while (type != null && typeof(Component).IsAssignableFrom(type))
				{
					FieldInfo[] fields;
					try
					{
						fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					}
					catch
					{
						break;
					}
					FieldInfo[] array2 = fields;
					foreach (FieldInfo fieldInfo in array2)
					{
						string fieldName = fieldInfo.Name ?? "";
						if (source.Any((string k) => fieldName.IndexOf(k, StringComparison.OrdinalIgnoreCase) >= 0))
						{
							try
							{
								Log.LogInfo((object)("  " + type.Name + "." + fieldInfo.Name + " = " + FormatDumpValue(fieldInfo.GetValue(val3))));
							}
							catch
							{
							}
						}
					}
					type = type.BaseType;
				}
			}
		}

		private void DumpTypeSummary(string typeName)
		{
			Type type = FindType(typeName);
			if (type == null)
			{
				Log.LogWarning((object)("[TYPE] " + typeName + ": NOT FOUND"));
				return;
			}
			Log.LogInfo((object)"");
			Log.LogInfo((object)("[TYPE] " + type.FullName + " : base=" + (type.BaseType?.FullName ?? "null")));
			string[] source = new string[11]
			{
				"spawn", "summon", "water", "jump", "attack", "damage", "boss", "dead", "death", "hp",
				"item"
			};
			FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo f in fields)
			{
				if (source.Any((string k) => (f.Name ?? "").IndexOf(k, StringComparison.OrdinalIgnoreCase) >= 0))
				{
					Log.LogInfo((object)("  FIELD " + f.FieldType.Name + " " + f.Name));
				}
			}
			MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo m in methods)
			{
				if (source.Any((string k) => (m.Name ?? "").IndexOf(k, StringComparison.OrdinalIgnoreCase) >= 0))
				{
					string text = string.Join(", ", from p in m.GetParameters()
						select p.ParameterType.Name + " " + p.Name);
					Log.LogInfo((object)("  METHOD " + m.ReturnType.Name + " " + m.Name + "(" + text + ")"));
				}
			}
		}

		private static string FormatDumpValue(object value)
		{
			if (value == null)
			{
				return "null";
			}
			Object val = (Object)((value is Object) ? value : null);
			if (val != (Object)null)
			{
				return ((object)val).GetType().Name + "('" + val.name + "')";
			}
			try
			{
				string text = value.ToString();
				if (text != null && text.Length > 180)
				{
					text = text.Substring(0, 180) + "...";
				}
				return text ?? "null";
			}
			catch
			{
				return "<ToString failed>";
			}
		}

		private void CachePrefabs()
		{
			if (_seahorsePrefab == (Object)null)
			{
				_seahorsePrefab = FindFishablePrefab("Seahorse");
			}
			if (_piranhaPrefab == (Object)null)
			{
				_piranhaPrefab = FindFishablePrefab("Piranha");
			}
			if (_urchinPrefab == (Object)null)
			{
				_urchinPrefab = FindFishablePrefab("SeaUrchin");
			}
		}

		private Object FindFishablePrefab(string fishableName)
		{
			Type type = FindType("Fishable");
			if (type == null)
			{
				return null;
			}
			Object[] array;
			try
			{
				array = Resources.FindObjectsOfTypeAll(type);
			}
			catch
			{
				return null;
			}
			Object[] array2 = array;
			foreach (Object val in array2)
			{
				if (val == (Object)null || !string.Equals(val.name, fishableName, StringComparison.OrdinalIgnoreCase))
				{
					continue;
				}
				FieldInfo fieldInfo = FindField(type, "_itemToSpawn");
				if (fieldInfo == null)
				{
					continue;
				}
				try
				{
					object? value = fieldInfo.GetValue(val);
					Object val2 = (Object)((value is Object) ? value : null);
					if (val2 != (Object)null)
					{
						Log.LogInfo((object)("[PREFAB] " + fishableName + " -> '" + val2.name + "' (" + ((object)val2).GetType().Name + ")"));
						return val2;
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private bool TryFindGroundPoint(Vector3 origin, float minRadius, float maxRadius, out Vector3 point)
		{
			//IL_001f: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: 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_0094: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 18; i++)
			{
				float num = Random.Range(0f, MathF.PI * 2f);
				float num2 = Random.Range(minRadius, maxRadius);
				RaycastHit[] array = Physics.RaycastAll(origin + new Vector3(Mathf.Cos(num) * num2, 45f, Mathf.Sin(num) * num2), Vector3.down, 100f);
				if (array == null || array.Length == 0)
				{
					continue;
				}
				foreach (RaycastHit item in array.OrderBy((RaycastHit h) => ((RaycastHit)(ref h)).distance))
				{
					RaycastHit current = item;
					if (!((Object)(object)((RaycastHit)(ref current)).collider == (Object)null) && !((RaycastHit)(ref current)).collider.isTrigger)
					{
						string obj = LayerMask.LayerToName(((Component)((RaycastHit)(ref current)).collider).gameObject.layer) ?? "";
						string text = ((Object)((Component)((RaycastHit)(ref current)).collider).gameObject).name ?? "";
						if (obj.IndexOf("water", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("water", StringComparison.OrdinalIgnoreCase) < 0)
						{
							point = ((RaycastHit)(ref current)).point;
							return true;
						}
					}
				}
			}
			point = origin;
			return false;
		}

		private Vector3 GetPlayerPosition()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Transform val = FindActualPlayerWorldTransform();
			if ((Object)(object)val != (Object)null)
			{
				return val.position;
			}
			return Vector3.zero;
		}

		private Transform FindActualPlayerWorldTransform()
		{
			//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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: 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_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: 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_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: 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)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			Vector3 currentGameplayReferencePosition = GetCurrentGameplayReferencePosition();
			Component val = FindLocalOwnedPlayerComponent();
			if ((Object)(object)val != (Object)null)
			{
				Transform val2 = FindBestWorldTransformInsidePlayer(val.transform, currentGameplayReferencePosition);
				if ((Object)(object)val2 != (Object)null)
				{
					Log.LogInfo((object)($"[PLAYER WORLD] IslandRef={currentGameplayReferencePosition}, " + $"Owned root={val.transform.position}, " + $"using '{((Object)val2).name}' world={val2.position}."));
					return val2;
				}
			}
			Transform val3 = null;
			float num = float.MaxValue;
			Vector2 val4 = default(Vector2);
			((Vector2)(ref val4))..ctor(currentGameplayReferencePosition.x, currentGameplayReferencePosition.z);
			string[] array = new string[4] { "PlayerMovement", "PlayerController", "PlayerCamera", "CameraController" };
			Vector2 val6;
			for (int i = 0; i < array.Length; i++)
			{
				Type type = FindType(array[i]);
				if (type == null || !typeof(Object).IsAssignableFrom(type))
				{
					continue;
				}
				Object[] array2;
				try
				{
					array2 = Resources.FindObjectsOfTypeAll(type);
				}
				catch
				{
					continue;
				}
				Object[] array3 = array2;
				foreach (Object obj2 in array3)
				{
					Component val5 = (Component)(object)((obj2 is Component) ? obj2 : null);
					if ((Object)(object)val5 == (Object)null || (Object)(object)val5.gameObject == (Object)null || !val5.gameObject.activeInHierarchy)
					{
						continue;
					}
					Transform transform = val5.transform;
					if (!IsBadPlayerWorldCandidate(transform, currentGameplayReferencePosition))
					{
						Vector3 position = transform.position;
						val6 = new Vector2(position.x, position.z) - val4;
						float num2 = ((Vector2)(ref val6)).sqrMagnitude;
						if ((Object)(object)((Component)transform).GetComponent<Camera>() != (Object)null)
						{
							num2 -= 5000f;
						}
						if ((Object)(object)((Component)transform).GetComponent<CharacterController>() != (Object)null)
						{
							num2 -= 4000f;
						}
						if ((Object)(object)((Component)transform).GetComponent<Rigidbody>() != (Object)null)
						{
							num2 -= 1500f;
						}
						if (num2 < num)
						{
							num = num2;
							val3 = transform;
						}
					}
				}
			}
			Camera[] array4 = Resources.FindObjectsOfTypeAll<Camera>();
			foreach (Camera val7 in array4)
			{
				if ((Object)(object)val7 == (Object)null || (Object)(object)((Component)val7).gameObject == (Object)null || !((Component)val7).gameObject.activeInHierarchy)
				{
					continue;
				}
				Transform transform2 = ((Component)val7).transform;
				if (!IsBadPlayerWorldCandidate(transform2, currentGameplayReferencePosition))
				{
					Vector3 position2 = transform2.position;
					val6 = new Vector2(position2.x, position2.z) - val4;
					float num3 = ((Vector2)(ref val6)).sqrMagnitude - 5000f;
					if (num3 < num)
					{
						num = num3;
						val3 = transform2;
					}
				}
			}
			if ((Object)(object)val3 != (Object)null)
			{
				Log.LogInfo((object)($"[PLAYER WORLD] Fallback IslandRef={currentGameplayReferencePosition}, " + $"transform='{((Object)val3).name}' pos={val3.position}."));
			}
			else
			{
				Log.LogWarning((object)$"[PLAYER WORLD] No valid world transform near IslandRef={currentGameplayReferencePosition}.");
			}
			return val3;
		}

		private Component FindLocalOwnedPlayerComponent()
		{
			Type type = FindType("Player");
			if (type == null)
			{
				return null;
			}
			Object[] array;
			try
			{
				array = Resources.FindObjectsOfTypeAll(type);
			}
			catch
			{
				return null;
			}
			Object[] array2 = array;
			foreach (Object obj2 in array2)
			{
				Component val = (Component)(object)((obj2 is Component) ? obj2 : null);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.gameObject == (Object)null) && val.gameObject.activeInHierarchy)
				{
					object propertyOrField = GetPropertyOrField(val, "IsOwner");
					if (propertyOrField is bool && (bool)propertyOrField)
					{
						return val;
					}
				}
			}
			return null;
		}

		private bool IsBadPlayerWorldCandidate(Transform t, Vector3 reference)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)t == (Object)null || (Object)(object)((Component)t).gameObject == (Object)null || !((Component)t).gameObject.activeInHierarchy)
			{
				return true;
			}
			string text = ((Object)t).name ?? "";
			if (text.IndexOf("HiddenQuest", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("QuestPos", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("SpawnPos", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			Vector3 position = t.position;
			if (((Vector3)(ref position)).sqrMagnitude < 0.25f && ((Vector3)(ref reference)).sqrMagnitude > 100f)
			{
				return true;
			}
			if (Mathf.Abs(position.y - reference.y) > 180f)
			{
				return true;
			}
			return false;
		}

		private Transform FindBestWorldTransformInsidePlayer(Transform playerRoot, Vector3 reference)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)playerRoot == (Object)null)
			{
				return null;
			}
			Transform[] componentsInChildren = ((Component)playerRoot).GetComponentsInChildren<Transform>(true);
			Transform result = null;
			float num = float.MaxValue;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(reference.x, reference.z);
			Transform[] array = componentsInChildren;
			foreach (Transform val2 in array)
			{
				if (!IsBadPlayerWorldCandidate(val2, reference))
				{
					Vector3 position = val2.position;
					Vector2 val3 = new Vector2(position.x, position.z) - val;
					float num2 = ((Vector2)(ref val3)).sqrMagnitude;
					if ((Object)(object)((Component)val2).GetComponent<Camera>() != (Object)null)
					{
						num2 -= 10000f;
					}
					if ((Object)(object)((Component)val2).GetComponent<CharacterController>() != (Object)null)
					{
						num2 -= 8000f;
					}
					if ((Object)(object)((Component)val2).GetComponent<Rigidbody>() != (Object)null)
					{
						num2 -= 3000f;
					}
					string obj = ((Object)val2).name ?? "";
					if (obj.IndexOf("Camera", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						num2 -= 4000f;
					}
					if (obj.IndexOf("Player", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						num2 -= 1000f;
					}
					if (num2 < num)
					{
						num = num2;
						result = val2;
					}
				}
			}
			return result;
		}

		private Vector3 GetCurrentGameplayReferencePosition()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			if (TryGetCurrentLoadedIslandPosition(out var position))
			{
				return position;
			}
			Scene gameplayIslandScene = GetGameplayIslandScene();
			if (((Scene)(ref gameplayIslandScene)).IsValid() && string.Equals(((Scene)(ref gameplayIslandScene)).name, "DevIsland", StringComparison.OrdinalIgnoreCase))
			{
				return Vector3.zero;
			}
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null && ((Component)main).gameObject.activeInHierarchy)
			{
				Vector3 position2 = ((Component)main).transform.position;
				if (((Vector3)(ref position2)).sqrMagnitude > 1f)
				{
					Vector3 position3 = ((Component)main).transform.position;
					return new Vector3(position3.x, 0f, position3.z);
				}
			}
			return Vector3.zero;
		}

		private bool TryGetCurrentLoadedIslandPosition(out Vector3 position)
		{
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			position = Vector3.zero;
			Scene gameplayIslandScene = GetGameplayIslandScene();
			if (!((Scene)(ref gameplayIslandScene)).IsValid() || !((Scene)(ref gameplayIslandScene)).isLoaded)
			{
				return false;
			}
			string text = ((Scene)(ref gameplayIslandScene)).name ?? "";
			if (!text.StartsWith("Island", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			if (!int.TryParse(text.Substring("Island".Length), out var result))
			{
				return false;
			}
			return TryGetIslandPosition(result - 1, out position);
		}

		private bool TryGetIslandPosition(int index, out Vector3 position)
		{
			//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_00d7: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			position = Vector3.zero;
			Type type = FindType("IslandManager");
			if (type == null)
			{
				return false;
			}
			Component val = null;
			try
			{
				val = Resources.FindObjectsOfTypeAll(type).OfType<Component>().FirstOrDefault((Func<Component, bool>)((Component c) => (Object)(object)c != (Object)null));
			}
			catch
			{
				return false;
			}
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			FieldInfo fieldInfo = FindField(((object)val).GetType(), "_islandInfos");
			Array array = ((fieldInfo != null) ? (fieldInfo.GetValue(val) as Array) : null);
			if (array == null || index < 0 || index >= array.Length)
			{
				return false;
			}
			object value = array.GetValue(index);
			if (value == null)
			{
				return false;
			}
			object propertyOrField = GetPropertyOrField(value, "IslandPosition");
			if (propertyOrField is Vector3)
			{
				position = (Vector3)propertyOrField;
				return true;
			}
			FieldInfo fieldInfo2 = FindField(value.GetType(), "<IslandPosition>k__BackingField");
			if (fieldInfo2 != null)
			{
				object value2 = fieldInfo2.GetValue(value);
				if (value2 is Vector3)
				{
					position = (Vector3)value2;
					return true;
				}
			}
			return false;
		}

		private bool IsEligibleIslandLoaded()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Scene gameplayIslandScene = GetGameplayIslandScene();
			if (!((Scene)(ref gameplayIslandScene)).IsValid() || !((Scene)(ref gameplayIslandScene)).isLoaded)
			{
				return false;
			}
			return !IsIslandExcluded(((Scene)(ref gameplayIslandScene)).name);
		}

		private string GetCurrentIslandName()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Scene gameplayIslandScene = GetGameplayIslandScene();
			if (!((Scene)(ref gameplayIslandScene)).IsValid() || !((Scene)(ref gameplayIslandScene)).isLoaded)
			{
				return null;
			}
			return ((Scene)(ref gameplayIslandScene)).name;
		}

		private Scene GetGameplayIslandScene()
		{
			//IL_0005: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < SceneManager.sceneCount; i++)
			{
				Scene sceneAt = SceneManager.GetSceneAt(i);
				if (((Scene)(ref sceneAt)).IsValid() && ((Scene)(ref sceneAt)).isLoaded)
				{
					string text = ((Scene)(ref sceneAt)).name ?? "";
					if (text.StartsWith("Island", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "DevIsland", StringComparison.OrdinalIgnoreCase) || text.StartsWith("HTFE_Island", StringComparison.OrdinalIgnoreCase))
					{
						return sceneAt;
					}
				}
			}
			return default(Scene);
		}

		private bool IsIslandExcluded(string islandName)
		{
			if (string.IsNullOrWhiteSpace(islandName))
			{
				return true;
			}
			return (from x in (_excludedScenes.Value ?? "").Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)
				select x.Trim()).Any((string x) => string.Equals(x, islandName, StringComparison.OrdinalIgnoreCase));
		}

		private bool HasRealBoss()
		{
			Type type = FindType("BossManager");
			if (type == null)
			{
				return false;
			}
			PropertyInfo property = type.GetProperty("Boss", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (property == null)
			{
				return false;
			}
			try
			{
				return property.GetValue(null) != null;
			}
			catch
			{
				return false;
			}
		}

		private void StartEventBossPresentation(string title, bool useUi, bool useMusic)
		{
			_eventUsesBossPresentation = useUi || useMusic;
			if (useUi)
			{
				_ownsBossUi = TryAcquireBossUi(title);
				_bossUiWasShown = _ownsBossUi;
				if (_ownsBossUi)
				{
					UpdateBossUiProgress(1f);
				}
				else
				{
					Log.LogWarning((object)("[" + title + "] Boss UI could not be acquired."));
				}
			}
			if (useMusic)
			{
				_eventBossMusicStarted = StartEventBossMusic();
				if (!_eventBossMusicStarted)
				{
					Log.LogWarning((object)("[" + title + "] Could not start native boss music."));
				}
			}
		}

		private bool StartEventBossMusic()
		{
			try
			{
				if (!TryFindNativeBossMusic(out var clip, out var intro, out var outro))
				{
					Log.LogWarning((object)"[EVENT BOSS MUSIC] Could not discover a native boss music clip.");
					return false;
				}
				Type type = FindType("MusicManager");
				if (type == null)
				{
					Log.LogWarning((object)"[EVENT BOSS MUSIC] MusicManager type not found.");
					return false;
				}
				MethodInfo method = type.GetMethod("PlayMusic", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[4]
				{
					typeof(string),
					typeof(string),
					typeof(float),
					typeof(bool)
				}, null);
				if (method == null)
				{
					Log.LogWarning((object)"[EVENT BOSS MUSIC] MusicManager.PlayMusic(string,string,float,bool) not found.");
					return false;
				}
				MethodInfo method2 = type.GetMethod("FadeOutMusic", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(bool) }, null);
				try
				{
					method2?.Invoke(null, new object[1] { false });
				}
				catch
				{
				}
				method.Invoke(null, new object[4]
				{
					clip,
					intro ?? "",
					0f,
					true
				});
				_eventMusicClip = clip ?? "";
				_eventMusicIntro = intro ?? "";
				_eventMusicOutro = outro ?? "";
				Log.LogWarning((object)("[EVENT BOSS MUSIC] PLAY native boss track: clip='" + _eventMusicClip + "', intro='" + _eventMusicIntro + "', outro='" + _eventMusicOutro + "'."));
				return true;
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[EVENT BOSS MUSIC] Play failed: " + ex.GetBaseException().Message));
				return false;
			}
		}

		private void StopEventBossMusic()
		{
			try
			{
				Type type = FindType("MusicManager");
				if (!(type == null))
				{
					MethodInfo method = type.GetMethod("StopMusic", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
					{
						typeof(string),
						typeof(string)
					}, null);
					if (method != null && !string.IsNullOrWhiteSpace(_eventMusicClip))
					{
						method.Invoke(null, new object[2]
						{
							_eventMusicClip,
							_eventMusicOutro ?? ""
						});
						Log.LogWarning((object)("[EVENT BOSS MUSIC] STOP native boss track: clip='" + _eventMusicClip + "', outro='" + _eventMusicOutro + "'."));
					}
					else
					{
						type.GetMethod("FadeOutMusic", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(bool) }, null)?.Invoke(null, new object[1] { false });
						Log.LogWarning((object)"[EVENT BOSS MUSIC] STOP via FadeOutMusic(false).");
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[EVENT BOSS MUSIC] Stop failed: " + ex.GetBaseException().Message));
			}
			finally
			{
				_eventMusicClip = "";
				_eventMusicIntro = "";
				_eventMusicOutro = "";
			}
		}

		private bool TryFindNativeBossMusic(out string clip, out string intro, out string outro)
		{
			clip = "";
			intro = "";
			outro = "";
			Type type = FindType("MusicTrigger");
			if (type != null)
			{
				Object[] source;
				try
				{
					source = Resources.FindObjectsOfTypeAll(type);
				}
				catch
				{
					source = Array.Empty<Object>();
				}
				Component val = ((IEnumerable<Component>)(from c in source.OfType<Component>()
					where (Object)(object)c != (Object)null && (Object)(object)c.gameObject != (Object)null
					select c).OrderByDescending(delegate(Component c)
				{
					string transformPath = GetTransformPath(c.transform);
					string text2 = ((Object)c.gameObject).name + " " + transformPath;
					int num = 0;
					if (text2.IndexOf("boss", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						num += 100;
					}
					if (text2.IndexOf("fight", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						num += 50;
					}
					return num;
				})).FirstOrDefault((Func<Component, bool>)((Component c) => !string.IsNullOrWhiteSpace(ReadStringMember(c, "_musicToPlay", "MusicToPlay", "_music", "Music"))));
				if ((Object)(object)val != (Object)null)
				{
					clip = ReadStringMember(val, "_musicToPlay", "MusicToPlay", "_music", "Music") ?? "";
					intro = ReadStringMember(val, "_intro", "_introMusic", "Intro", "IntroMusic") ?? "";
					outro = ReadStringMember(val, "_outro", "_outroMusic", "Outro", "OutroMusic") ?? "";
					if (!string.IsNullOrWhiteSpace(clip))
					{
						Log.LogInfo((object)("[EVENT BOSS MUSIC] MusicTrigger source: GO='" + ((Object)val.gameObject).name + "', path='" + GetTransformPath(val.transform) + "', clip='" + clip + "', intro='" + intro + "', outro='" + outro + "'."));
						return true;
					}
				}
			}
			Type type2 = FindType("AudioManager");
			if (type2 != null && type2.GetField("_realClips", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null) is IDictionary dictionary)
			{
				List<string> list = new List<string>();
				foreach (DictionaryEntry item in dictionary)
				{
					string text = item.Key as string;
					if (!string.IsNullOrWhiteSpace(text))
					{
						list.Add(text);
					}
				}
				clip = list.FirstOrDefault((string k) => k.IndexOf("boss", StringComparison.OrdinalIgnoreCase) >= 0) ?? list.FirstOrDefault((string k) => k.IndexOf("fight", StringComparison.OrdinalIgnoreCase) >= 0 || k.IndexOf("combat", StringComparison.OrdinalIgnoreCase) >= 0) ?? "";
				if (!string.IsNullOrWhiteSpace(clip))
				{
					Log.LogInfo((object)("[EVENT BOSS MUSIC] AudioManager dictionary fallback: '" + clip + "'."));
					return true;
				}
			}
			return false;
		}

		private static string ReadStringMember(object target, params string[] names)
		{
			if (target == null || names == null)
			{
				return null;
			}
			Type type = target.GetType();
			while (type != null)
			{
				foreach (string name in names)
				{
					FieldInfo field = type.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (field != null && field.FieldType == typeof(string))
					{
						try
						{
							return field.GetValue(field.IsStatic ? null : target) as string;
						}
						catch
						{
						}
					}
					PropertyInfo property = type.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (!(property != null) || !(property.PropertyType == typeof(string)))
					{
						continue;
					}
					try
					{
						MethodInfo getMethod = property.GetGetMethod(nonPublic: true);
						if (getMethod != null)
						{
							return property.GetValue(getMethod.IsStatic ? null : target, null) as string;
						}
					}
					catch
					{
					}
				}
				type = type.BaseType;
			}
			return null;
		}

		private bool TryAcquireBossUi(string title)
		{
			Type type = FindType("BossUI");
			if (type == null)
			{
				Log.LogWarning((object)"[EVENT UI] BossUI type not found.");
				return false;
			}
			Object[] source;
			try
			{
				source = Resources.FindObjectsOfTypeAll(type);
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[EVENT UI] BossUI search failed: " + ex.Message));
				return false;
			}
			Component val = source.OfType<Component>().FirstOrDefault((Func<Component, bool>)((Component c) => (Object)(object)c != (Object)null && (Object)(object)c.gameObject != (Object)null && c.gameObject.activeInHierarchy));
			if ((Object)(object)val == (Object)null)
			{
				val = source.OfType<Component>().FirstOrDefault((Func<Component, bool>)((Component c) => (Object)(object)c != (Object)null && (Object)(object)c.gameObject != (Object)null));
			}
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)"[EVENT UI] No BossUI instance found.");
				return false;
			}
			_bossUi = val;
			SetBossUiTitle(title);
			SetBossUiVisible(visible: true);
			ForceBossCanvasVisible();
			UpdateBossUiProgress(1f);
			Log.LogInfo((object)("[EVENT UI] Boss UI acquired for '" + title + "' on '" + ((Object)val.gameObject).name + "'."));
			return true;
		}

		private void SetBossUiTitle(string title)
		{
			if ((Object)(object)_bossUi == (Object)null)
			{
				return;
			}
			FieldInfo fieldInfo = FindField(((object)_bossUi).GetType(), "_bossNameText");
			if (fieldInfo == null)
			{
				Log.LogWarning((object)"[EVENT UI] _bossNameText field not found.");
				return;
			}
			try
			{
				object value = fieldInfo.GetValue(_bossUi);
				PropertyInfo propertyInfo = value?.GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (propertyInfo != null)
				{
					propertyInfo.SetValue(value, title);
					Log.LogInfo((object)("[EVENT UI] Title set to '" + title + "'."));
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[EVENT UI] Setting title failed: " + ex.Message));
			}
		}

		private void SetBossUiVisible(bool visible)
		{
			if ((Object)(object)_bossUi == (Object)null)
			{
				return;
			}
			MethodInfo methodInfo = ((object)_bossUi).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo m)
			{
				if (!string.Equals(m.Name, "ToggleBossUI", StringComparison.Ordinal))
				{
					return false;
				}
				ParameterInfo[] parameters = m.GetParameters();
				return parameters.Length == 1 && parameters[0].ParameterType == typeof(bool);
			});
			try
			{
				if (methodInfo != null)
				{
					methodInfo.Invoke(_bossUi, new object[1] { visible });
					Log.LogInfo((object)("[EVENT UI] ToggleBossUI(" + visible + ") invoked."));
				}
				else
				{
					Log.LogWarning((object)"[EVENT UI] ToggleBossUI(bool) not found.");
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[EVENT UI] ToggleBossUI failed: " + ex.GetBaseException().Message));
			}
			if (visible)
			{
				ForceBossCanvasVisible();
			}
		}

		private void ForceBossCanvasVisible()
		{
			if ((Object)(object)_bossUi == (Object)null)
			{
				return;
			}
			FieldInfo fieldInfo = FindField(((object)_bossUi).GetType(), "_bossCanvasLerped");
			if (fieldInfo != null)
			{
				try
				{
					object value = fieldInfo.GetValue(_bossUi);
					if (value != null)
					{
						PropertyInfo? property = value.GetType().GetProperty("alpha");
						PropertyInfo property2 = value.GetType().GetProperty("interactable");
						PropertyInfo property3 = value.GetType().GetProperty("blocksRaycasts");
						property?.SetValue(value, 1f);
						property2?.SetValue(value, false);
						property3?.SetValue(value, false);
					}
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("[EVENT UI] CanvasGroup force-visible failed: " + ex.Message));
				}
			}
			MethodInfo methodInfo = ((object)_bossUi).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo m)
			{
				if (m.Name != "LerpBossCanvasAlpha")
				{
					return false;
				}
				ParameterInfo[] parameters = m.GetParameters();
				return parameters.Length == 1 && parameters[0].ParameterType == typeof(float);
			});
			if (!(methodInfo != null))
			{
				return;
			}
			try
			{
				methodInfo.Invoke(_bossUi, new object[1] { 1f });
			}
			catch
			{
			}
		}

		private void UpdateBossUiProgress(float progress)
		{
			if ((Object)(object)_bossUi == (Object)null)
			{
				return;
			}
			progress = Mathf.Clamp01(progress);
			ForceBossCanvasVisible();
			int num = Mathf.RoundToInt(progress * 100f);
			MethodInfo methodInfo = ((object)_bossUi).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo m)
			{
				if (m.Name != "UpdateBossHp")
				{
					return false;
				}
				ParameterInfo[] parameters = m.GetParameters();
				return parameters.Length == 1 && parameters[0].ParameterType == typeof(int);
			});
			MethodInfo methodInfo2 = ((object)_bossUi).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo m)
			{
				if (m.Name != "UpdateBossLerpHp")
				{
					return false;
				}
				ParameterInfo[] parameters = m.GetParameters();
				return parameters.Length == 1 && parameters[0].ParameterType == typeof(float);
			});
			try
			{
				if (methodInfo != null)
				{
					methodInfo.Invoke(_bossUi, new object[1] { num });
				}
				if (methodInfo2 != null)
				{
					methodInfo2.Invoke(_bossUi, new object[1] { progress });
				}
			}
			catch (Exception ex)
			{
				Log.LogDebug((object)("[EVENT UI] Native health update failed: " + ex.GetBaseException().Message));
			}
			SetImageFill(_bossUi, "_bossHealth", progress);
			SetImageFill(_bossUi, "_bossHealthLerped", progress);
		}

		private void SetImageFill(Component ui, string fieldName, float value)
		{
			FieldInfo fieldInfo = FindField(((object)ui).GetType(), fieldName);
			if (fieldInfo == null)
			{
				return;
			}
			try
			{
				object value2 = fieldInfo.GetValue(ui);
				(value2?.GetType().GetProperty("fillAmount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))?.SetValue(value2, value);
			}
			catch
			{
			}
		}

		private void ScheduleNextEvent()
		{
			ScheduleNextEvent(_minInterval.Value, _maxInterval.Value);
		}

		private void ScheduleNextEvent(float min, float max)
		{
			float num = Mathf.Max(5f, Math.Min(min, max));
			float num2 = Mathf.Max(num, Math.Max(min, max));
			_nextEventAt = Time.unscaledTime + Random.Range(num, num2);
			Log.LogInfo((object)$"[EVENT] Next event in ~{Mathf.RoundToInt(_nextEventAt - Time.unscaledTime)}s.");
		}

		private int RandomCount(int min, int max)
		{
			int num = Math.Max(1, Math.Min(min, max));
			int num2 = Math.Max(num, Math.Max(min, max));
			return Random.Range(num, num2 + 1);
		}

		private static Type FindType(string name)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				Type type = null;
				try
				{
					type = assembly.GetType(name, throwOnError: false);
				}
				catch
				{
				}
				if (type != null)
				{
					return type;
				}
				try
				{
					type = assembly.GetTypes().FirstOrDefault((Type x) => x != null && x.Name == name);
				}
				catch (ReflectionTypeLoadException ex)
				{
					type = ex.Types.FirstOrDefault((Type x) => x != null && x.Name == name);
				}
				catch
				{
				}
				if (type != null)
				{
					return type;
				}
			}
			return null;
		}

		private static FieldInfo FindField(Type type, string name)
		{
			Type type2 = type;
			while (type2 != null)
			{
				FieldInfo field = type2.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					return field;
				}
				type2 = type2.BaseType;
			}
			return null;
		}

		private static void SetField(object obj, string name, object value)
		{
			if (obj == null)
			{
				return;
			}
			FieldInfo fieldInfo = FindField(obj.GetType(), name);
			if (fieldInfo == null)
			{
				return;
			}
			try
			{
				fieldInfo.SetValue(obj, value);
			}
			catch
			{
			}
		}

		private static object GetFieldValue(object obj, string name)
		{
			if (obj == null)
			{
				return null;
			}
			FieldInfo fieldInfo = FindField(obj.GetType(), name);
			if (fieldInfo == null)
			{
				return null;
			}
			try
			{
				return fieldInfo.GetValue(obj);
			}
			catch
			{
				return null;
			}
		}

		private static object GetPropertyOrField(object obj, params string[] names)
		{
			if (obj == null)
			{
				return null;
			}
			Type type = obj.GetType();
			foreach (string name in names)
			{
				Type type2 = type;
				while (type2 != null)
				{
					PropertyInfo property = type2.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (property != null)
					{
						try
						{
							return property.GetValue(obj);
						}
						catch
						{
						}
					}
					FieldInfo field = type2.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field != null)
					{
						try
						{
							return field.GetValue(obj);
						}
						catch
						{
						}
					}
					type2 = type2.BaseType;
				}
			}
			return null;
		}
	}
}