Decompiled source of Njord v1.1.0

Njord/plugins/Njord.dll

Decompiled 6 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Njord.Core;
using Njord.HUD;
using Njord.Patches;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 Njord
{
	public static class NjordBoatController
	{
		public static string GetShipPrefabName(object ship)
		{
			Component val = (Component)((ship is Component) ? ship : null);
			if (val == null)
			{
				return "Unknown";
			}
			return ((Object)val.gameObject).name.Replace("(Clone)", "").Trim();
		}

		public static float GetBaseline(NjordSailState state, string shipName)
		{
			NjordRuntimeConfig runtimeConfig = NjordSync.RuntimeConfig;
			if (runtimeConfig == null)
			{
				return 0f;
			}
			return state switch
			{
				NjordSailState.Forward => runtimeConfig.BaseForwardForce, 
				NjordSailState.Half => runtimeConfig.BaseForwardForce, 
				NjordSailState.Full => runtimeConfig.BaseForwardForce, 
				_ => 0f, 
			};
		}

		public static float ApplyAcceleration(float baseline, float dt)
		{
			NjordRuntimeConfig runtimeConfig = NjordSync.RuntimeConfig;
			if (runtimeConfig == null)
			{
				return 0f;
			}
			float num = baseline * runtimeConfig.AccelerationMultiplier;
			if (float.IsNaN(num) || float.IsInfinity(num))
			{
				return 0f;
			}
			return num;
		}

		public static float GetSailMult(NjordSailState state)
		{
			NjordRuntimeConfig runtimeConfig = NjordSync.RuntimeConfig;
			if (runtimeConfig == null)
			{
				return 1f;
			}
			return state switch
			{
				NjordSailState.Forward => runtimeConfig.SailForwardForce, 
				NjordSailState.Half => runtimeConfig.HalfSailForce, 
				NjordSailState.Full => runtimeConfig.FullSailForce, 
				_ => 1f, 
			};
		}

		public static float GetReverseForce(float dt)
		{
			NjordRuntimeConfig runtimeConfig = NjordSync.RuntimeConfig;
			if (runtimeConfig == null)
			{
				return 0f;
			}
			float num = runtimeConfig.BaseReverseForce * runtimeConfig.ReverseKick;
			if (float.IsNaN(num) || float.IsInfinity(num))
			{
				return 0f;
			}
			return num;
		}
	}
	public static class Njord_ShipControlTracker
	{
		public const float READY_DELAY = 0.35f;

		private static Dictionary<ZDOID, long> _controlMap;

		private static float _lastLookupLogTime = -10f;

		private const float LOOKUP_LOG_INTERVAL = 2f;

		public static long CurrentController { get; private set; } = 0L;


		public static bool ShouldShowHud { get; private set; } = false;


		public static float ReadyTimer { get; private set; } = 0f;


		public static bool SteeringGateReady { get; private set; } = false;


		private static Dictionary<ZDOID, long> ControlMap
		{
			get
			{
				if (_controlMap == null)
				{
					_controlMap = new Dictionary<ZDOID, long>();
				}
				return _controlMap;
			}
		}

		public static long GetControllerForShip(object shipObj)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			if (shipObj == null)
			{
				return 0L;
			}
			Ship val = (Ship)((shipObj is Ship) ? shipObj : null);
			if (val == null)
			{
				return 0L;
			}
			ZNetView component = ((Component)val).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return 0L;
			}
			ZDO zDO = component.GetZDO();
			if (zDO == null)
			{
				return 0L;
			}
			ZDOID uid = zDO.m_uid;
			if (ControlMap.TryGetValue(uid, out var value))
			{
				if (NjordConfig.Debug_Enable.Value && Time.time - _lastLookupLogTime >= 2f)
				{
					NjordDebug.Debug($"[Tracker] Lookup: {((Object)val).name} ({uid}) → controller={value}");
					_lastLookupLogTime = Time.time;
				}
				return value;
			}
			if (NjordConfig.Debug_Enable.Value && Time.time - _lastLookupLogTime >= 2f)
			{
				NjordDebug.Debug($"[Tracker] Lookup: {((Object)val).name} ({uid}) → no entry");
				_lastLookupLogTime = Time.time;
			}
			return 0L;
		}

		private static bool LocalPlayerHasControl()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return false;
			}
			long playerID = Player.m_localPlayer.GetPlayerID();
			if (playerID == 0L)
			{
				return false;
			}
			foreach (KeyValuePair<ZDOID, long> item in ControlMap)
			{
				if (item.Value == playerID)
				{
					if (NjordConfig.Debug_Enable.Value)
					{
						NjordDebug.Debug($"[Tracker] LocalPlayerHasControl → TRUE (ship {item.Key})");
					}
					return true;
				}
			}
			if (NjordConfig.Debug_Enable.Value)
			{
				NjordDebug.Debug("[Tracker] LocalPlayerHasControl → FALSE");
			}
			return false;
		}

		private static void RecalculateHudState()
		{
			bool flag = (Object)(object)Player.m_localPlayer != (Object)null;
			bool flag2 = LocalPlayerHasControl();
			bool value = Plugin.HudEnabledByUser.Value;
			bool flag3 = flag && flag2 && value;
			if (ShouldShowHud != flag3 && NjordConfig.Debug_Enable.Value)
			{
				NjordDebug.Debug($"[Tracker] HUD state changed → {flag3}  (hasPlayer={flag}, hasControl={flag2}, hudEnabled={value})");
			}
			ShouldShowHud = flag3;
		}

		public static void SetControl(Ship ship, long playerID)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ship == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)ship).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return;
			}
			ZDO zDO = component.GetZDO();
			if (zDO != null)
			{
				ZDOID uid = zDO.m_uid;
				ControlMap[uid] = playerID;
				CurrentController = playerID;
				Njord_Telemetry.ClearErrors();
				if (NjordConfig.Debug_Enable.Value)
				{
					NjordDebug.Debug($"[Tracker] SetControl: ship={((Object)ship).name} ({uid}) → player={playerID}");
				}
				RecalculateHudState();
			}
		}

		public static void ClearControl(Ship ship)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ship == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)ship).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return;
			}
			ZDO zDO = component.GetZDO();
			if (zDO == null)
			{
				return;
			}
			ZDOID uid = zDO.m_uid;
			ControlMap.Remove(uid);
			Player localPlayer = Player.m_localPlayer;
			long num = ((localPlayer != null) ? localPlayer.GetPlayerID() : 0);
			if (num == CurrentController)
			{
				if (NjordConfig.Debug_Enable.Value)
				{
					NjordDebug.Debug($"[Tracker] ClearControl: local player lost control of {((Object)ship).name} ({uid})");
				}
				CurrentController = 0L;
			}
			else if (NjordConfig.Debug_Enable.Value)
			{
				NjordDebug.Debug($"[Tracker] ClearControl: removed entry for {((Object)ship).name} ({uid}), local player unaffected");
			}
			RecalculateHudState();
		}

		public static void UpdateController(long controller, float dt)
		{
			if (NjordConfig.Debug_Enable.Value && Time.time - _lastLookupLogTime >= 2f)
			{
				NjordDebug.Debug($"[AuthoritySync] UpdateController: controller={controller}, dt={dt:F4}");
			}
			CurrentController = controller;
			if (controller != 0L)
			{
				ReadyTimer += dt;
				if (ReadyTimer >= 0.35f)
				{
					SteeringGateReady = true;
				}
			}
			else
			{
				ReadyTimer = 0f;
				SteeringGateReady = false;
			}
			RecalculateHudState();
		}
	}
	public static class NjordDebug
	{
		private static bool _startupPrinted;

		private static bool IsEnabled()
		{
			try
			{
				return NjordConfig.Debug_Enable != null && NjordConfig.Debug_Enable.Value;
			}
			catch
			{
				return false;
			}
		}

		public static void Startup()
		{
			if (!_startupPrinted)
			{
				_startupPrinted = true;
				if (Plugin.Log != null)
				{
					Plugin.Log.LogInfo((object)"⚓ [Njord] The longship wakes. The sea remembers your hand.");
				}
			}
		}

		public static void Info(string msg)
		{
			if (IsEnabled())
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)("[Njord] " + msg));
				}
			}
		}

		public static void Debug(string msg)
		{
			if (IsEnabled())
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogDebug((object)("[Njord] " + msg));
				}
			}
		}

		public static void Warn(string msg)
		{
			if (IsEnabled())
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Njord] " + msg));
				}
			}
		}

		public static void Log(string msg)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)("[Njord] " + msg));
			}
		}

		public static void Error(string msg)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogError((object)("[Njord] " + msg));
			}
		}
	}
	[BepInPlugin("wubarrk.njord", "Njord", "1.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass13_0
		{
			public Action<string[]> action;

			public ConsoleEvent <>9__0;

			internal void <WaitAndRegister>b__0(ConsoleEventArgs args)
			{
				action(args.Args);
			}
		}

		[CompilerGenerated]
		private sealed class <WaitAndRegister>d__13 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Action<string[]> action;

			public string name;

			private <>c__DisplayClass13_0 <>8__1;

			private float <timeout>5__2;

			private float <start>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WaitAndRegister>d__13(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>8__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00db: Expected O, but got Unknown
				//IL_00e0: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>8__1 = new <>c__DisplayClass13_0();
					<>8__1.action = action;
					<timeout>5__2 = 10f;
					<start>5__3 = Time.time;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (Time.time - <start>5__3 < <timeout>5__2)
				{
					Type typeFromHandle = typeof(Terminal);
					FieldInfo field = typeFromHandle.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					object obj = null;
					if (field != null)
					{
						obj = field.GetValue(null);
					}
					else
					{
						PropertyInfo property = typeFromHandle.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
						if (property != null)
						{
							obj = property.GetValue(null);
						}
					}
					if (obj != null)
					{
						try
						{
							string text = name;
							ConsoleEvent obj2 = <>8__1.<>9__0;
							if (obj2 == null)
							{
								<>c__DisplayClass13_0 <>c__DisplayClass13_ = <>8__1;
								ConsoleEvent val = delegate(ConsoleEventArgs args)
								{
									<>8__1.action(args.Args);
								};
								ConsoleEvent val2 = val;
								<>c__DisplayClass13_.<>9__0 = val;
								obj2 = val2;
							}
							new ConsoleCommand(text, "", obj2, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
							Log.LogInfo((object)("Registered console command '" + name + "' after Terminal became available."));
						}
						catch (Exception ex)
						{
							Log.LogWarning((object)("Failed to register console command '" + name + "' after wait: " + ex.Message));
						}
						return false;
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				Log.LogWarning((object)("Timed out waiting for Terminal to register console command '" + name + "'."));
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		internal static Plugin Instance;

		internal static Harmony Harmony;

		internal static ManualLogSource Log;

		public static ConfigEntry<float> HudPositionX;

		public static ConfigEntry<float> HudPositionY;

		public static ConfigEntry<bool> HudEnabledByUser;

		private bool _hudCreated;

		private void Awake()
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			NjordDebug.Startup();
			Log.LogInfo((object)"The sea stirs. The runes awaken.");
			NjordConfig.Bind(((BaseUnityPlugin)this).Config);
			HudPositionX = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "HudPositionX", 40f, "Njord HUD X position.");
			HudPositionY = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "HudPositionY", 200f, "Njord HUD Y position.");
			HudEnabledByUser = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "HudEnabled", true, "If false, Njord HUD is hidden (F7 toggles).");
			NjordSync.Initialize();
			Harmony = new Harmony("wubarrk.njord");
			NjordPatchCaller.ApplyPatches();
			NjordHudManager.Initialize();
			RegisterConsoleCommands();
			Log.LogInfo((object)"Njord console commands registered (including njord.dumpvfx).");
			try
			{
				Version version = Assembly.GetExecutingAssembly().GetName().Version;
				Log.LogInfo((object)$"Njord DLL version: {version}");
			}
			catch
			{
			}
			Log.LogInfo((object)"Njord, god of the sea, obeys your command.");
		}

		private void Update()
		{
			if (!_hudCreated && (Object)(object)ZNet.instance != (Object)null)
			{
				_hudCreated = true;
				NjordHudManager.CreateHud();
			}
			if (Input.GetKeyDown((KeyCode)289))
			{
				if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
				{
					NjordSync.ServerReloadAndBroadcast();
					NjordDebug.Info("Njord config reloaded (server) and broadcast to all clients.");
					MessageHud instance = MessageHud.instance;
					if (instance != null)
					{
						instance.ShowMessage((MessageType)1, "Njord config reloaded (server)", 0, (Sprite)null, false);
					}
				}
				else
				{
					NjordSync.Client_RequestConfigUpdate();
					NjordDebug.Info("Njord config update request sent to server.");
					MessageHud instance2 = MessageHud.instance;
					if (instance2 != null)
					{
						instance2.ShowMessage((MessageType)1, "Njord config update request sent", 0, (Sprite)null, false);
					}
				}
			}
			if (Input.GetKeyDown((KeyCode)288))
			{
				HudEnabledByUser.Value = !HudEnabledByUser.Value;
			}
		}

		private void OnGUI()
		{
			NjordHudManager.OnGUI();
		}

		private void RegisterConsoleCommands()
		{
			ConsoleCommand("njord.reload", delegate
			{
				if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
				{
					Log.LogWarning((object)"njord.reload can only be run on the server.");
				}
				else
				{
					NjordSync.ServerReloadAndBroadcast();
					Log.LogInfo((object)"Njord config reloaded from disk and broadcast to all clients.");
				}
			});
			ConsoleCommand("njord.push", delegate
			{
				if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
				{
					Log.LogWarning((object)"njord.push can only be run on the server.");
				}
				else
				{
					typeof(NjordSync).GetMethod("ServerReloadAndBroadcast", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null);
					Log.LogInfo((object)"Njord runtime config pushed to all clients.");
				}
			});
			ConsoleCommand("njord.dumpvfx", delegate
			{
				try
				{
					NjordRuneSpriteTrail.DumpEmitters();
					try
					{
						NjordRunePiggyback.DumpEmitters();
					}
					catch
					{
					}
					Log.LogInfo((object)"Njord: dumped VFX emitter state to Njord debug log.");
					try
					{
						MessageHud instance = MessageHud.instance;
						if (instance != null)
						{
							instance.ShowMessage((MessageType)1, "Njord: VFX dump written to log.", 0, (Sprite)null, false);
						}
					}
					catch
					{
					}
				}
				catch (Exception ex3)
				{
					Log.LogWarning((object)("njord.dumpvfx failed: " + ex3.Message));
				}
			});
			ConsoleCommand("njord.vfx.orientation", delegate(string[] args)
			{
				try
				{
					if (args.Length < 1)
					{
						Log.LogInfo((object)"Usage: njord.vfx.orientation <flat|flatinv|upright|camera>");
					}
					else
					{
						string text = args[0].ToLowerInvariant();
						switch (text)
						{
						case "flat":
							NjordRunePiggyback_SetOrientation("Flat");
							break;
						case "flatinv":
							NjordRunePiggyback_SetOrientation("FlatInverted");
							break;
						case "upright":
							NjordRunePiggyback_SetOrientation("Upright");
							break;
						case "camera":
							NjordRunePiggyback_SetOrientation("CameraFacing");
							break;
						default:
							Log.LogInfo((object)"Unknown orientation. Valid: flat, flatinv, upright, camera");
							return;
						}
						Log.LogInfo((object)("Njord: set VFX spawn orientation -> " + text));
					}
				}
				catch (Exception ex2)
				{
					Log.LogWarning((object)("njord.vfx.orientation failed: " + ex2.Message));
				}
			});
			ConsoleCommand("njord.testtrail", delegate
			{
				//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_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//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_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: 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_0099: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					Player localPlayer = Player.m_localPlayer;
					if ((Object)(object)localPlayer == (Object)null)
					{
						Log.LogWarning((object)"njord.testtrail: no local player");
					}
					else
					{
						Transform transform = ((Component)localPlayer).transform;
						NjordRuntimeConfig njordRuntimeConfig = NjordSync.RuntimeConfig ?? NjordRuntimeConfig.FromConfig();
						Color vFX_Color = njordRuntimeConfig.VFX_Color;
						float num = 0.6f;
						Vector3 val = transform.position - transform.forward * 1f + Vector3.up * 0.5f;
						for (int i = 0; i < 8; i++)
						{
							Vector3 pos = val - transform.forward * ((float)i * num);
							NjordRunePiggyback.SpawnAtWorldPosition(pos, vFX_Color);
						}
						Log.LogInfo((object)"njord.testtrail: spawned test trail behind player");
					}
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("njord.testtrail failed: " + ex.Message));
				}
			});
			Log.LogInfo((object)"Registered console command 'njord.dumpvfx'.");
		}

		public static void NjordRunePiggyback_SetOrientation(string name)
		{
			try
			{
				Type typeFromHandle = typeof(NjordRunePiggyback);
				Type nestedType = typeFromHandle.GetNestedType("OrientationMode", BindingFlags.Public | BindingFlags.NonPublic);
				if (!(nestedType == null))
				{
					object value = Enum.Parse(nestedType, name);
					FieldInfo field = typeFromHandle.GetField("_spawnOrientation", BindingFlags.Static | BindingFlags.NonPublic);
					if (field != null)
					{
						field.SetValue(null, value);
					}
				}
			}
			catch
			{
			}
		}

		private void ConsoleCommand(string name, Action<string[]> action)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				new ConsoleCommand(name, "", (ConsoleEvent)delegate(ConsoleEventArgs args)
				{
					action(args.Args);
				}, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				Log.LogInfo((object)("Registered console command '" + name + "' (immediate)."));
				return;
			}
			catch (Exception ex)
			{
				Log.LogInfo((object)("Immediate registration of console command '" + name + "' failed, will wait for Terminal: " + ex.Message));
			}
			Type typeFromHandle = typeof(Terminal);
			object obj = null;
			FieldInfo field = typeFromHandle.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				obj = field.GetValue(null);
			}
			else
			{
				PropertyInfo property = typeFromHandle.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null)
				{
					obj = property.GetValue(null);
				}
			}
			if (obj != null)
			{
				try
				{
					new ConsoleCommand(name, "", (ConsoleEvent)delegate(ConsoleEventArgs args)
					{
						action(args.Args);
					}, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
					Log.LogInfo((object)("Registered console command '" + name + "' after Terminal detected via reflection."));
					return;
				}
				catch (Exception ex2)
				{
					Log.LogWarning((object)("Failed to register console command '" + name + "' after reflection detect: " + ex2.Message));
					return;
				}
			}
			((MonoBehaviour)this).StartCoroutine(WaitAndRegister(name, action));
		}

		[IteratorStateMachine(typeof(<WaitAndRegister>d__13))]
		private IEnumerator WaitAndRegister(string name, Action<string[]> action)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitAndRegister>d__13(0)
			{
				name = name,
				action = action
			};
		}
	}
	public static class NjordRunePiggyback
	{
		public enum OrientationMode
		{
			Flat,
			FlatInverted,
			Upright,
			CameraFacing
		}

		private class Emitter : MonoBehaviour
		{
			private Transform _stern;

			private Color _color = Color.white;

			private float _spacing = 0.6f;

			private Vector3 _lastSpawnPos = Vector3.zero;

			private Action<GameObject> _returnToPool;

			private Sprite _sprite;

			private Texture2D _tex;

			private bool _active = true;

			private ParticleSystem _wakePS;

			private Particle[] _buffer = (Particle[])(object)new Particle[512];

			private float _wakeInterval = 0.1f;

			private float _lastWake;

			private float _lastSternTime;

			private Vector3 _lastSternPos = Vector3.zero;

			private float _minSpeed = 0.5f;

			private float _lastLogTime = -10f;

			public void Initialize(Transform stern, Color color, float rateMultiplier, Action<GameObject> returnToPool, Sprite sprite, Texture2D tex)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_00be: 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_00d2: 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)
				_stern = stern;
				_color = color;
				_returnToPool = returnToPool;
				_sprite = sprite;
				_tex = tex;
				_spacing = 0.6f;
				_wakeInterval = 0.1f;
				_minSpeed = 0.5f;
				try
				{
					if (NjordConfig.Debug_Enable != null && NjordConfig.Debug_Enable.Value)
					{
						_minSpeed = Mathf.Min(_minSpeed, 0.1f);
					}
				}
				catch
				{
				}
				_lastSpawnPos = (((Object)(object)_stern != (Object)null) ? (_stern.TransformPoint(new Vector3(0f, -0.25f, -1f)) - Vector3.one * 1000f) : Vector3.zero);
				_lastSternPos = (((Object)(object)_stern != (Object)null) ? _stern.position : Vector3.zero);
				_lastSternTime = Time.time;
				_active = true;
				try
				{
					ParticleSystem[] componentsInChildren = ((Component)_stern).GetComponentsInChildren<ParticleSystem>(true);
					ParticleSystem val = null;
					ParticleSystem[] array = componentsInChildren;
					foreach (ParticleSystem val2 in array)
					{
						if (!((Object)(object)val2 == (Object)null))
						{
							string text = ((Object)((Component)val2).gameObject).name.ToLowerInvariant();
							if (text.Contains("wake") || text.Contains("trail") || text.Contains("speed") || text.Contains("mask"))
							{
								val = val2;
								break;
							}
						}
					}
					if ((Object)(object)val == (Object)null && componentsInChildren.Length != 0)
					{
						val = componentsInChildren[0];
					}
					_wakePS = val;
					if (IsDebugEnabled())
					{
						try
						{
							Plugin.Log.LogInfo((object)("[VFX-Piggyback] Emitter init: wakePS=" + (((Object)(object)_wakePS != (Object)null) ? ((Object)((Component)_wakePS).gameObject).name : "(none)")));
						}
						catch
						{
						}
					}
					if (!((Object)(object)_wakePS == (Object)null))
					{
						return;
					}
					_active = false;
					if (IsDebugEnabled())
					{
						try
						{
							Plugin.Log.LogInfo((object)"[VFX-Piggyback] No wake PS found; emitter disabled (sprite trail used instead)");
							return;
						}
						catch
						{
							return;
						}
					}
				}
				catch
				{
				}
			}

			public void UpdateParams(Transform stern, Color color, float rateMultiplier)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				_stern = stern ?? _stern;
				_color = color;
				_spacing = 0.6f;
			}

			public void SetActive(bool v)
			{
				_active = v;
			}

			private void Update()
			{
				//IL_0315: Unknown result type (might be due to invalid IL or missing references)
				//IL_0318: Unknown result type (might be due to invalid IL or missing references)
				//IL_031d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0322: 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_032c: 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_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_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_024d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0250: Unknown result type (might be due to invalid IL or missing references)
				//IL_0255: Unknown result type (might be due to invalid IL or missing references)
				//IL_025a: Unknown result type (might be due to invalid IL or missing references)
				//IL_025c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0264: Unknown result type (might be due to invalid IL or missing references)
				//IL_0205: Unknown result type (might be due to invalid IL or missing references)
				//IL_0207: Unknown result type (might be due to invalid IL or missing references)
				//IL_0211: 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_021d: Unknown result type (might be due to invalid IL or missing references)
				//IL_021f: Unknown result type (might be due to invalid IL or missing references)
				//IL_01be: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c3: 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_01ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0129: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0133: Unknown result type (might be due to invalid IL or missing references)
				//IL_0238: 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_0282: Unknown result type (might be due to invalid IL or missing references)
				//IL_028d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0292: Unknown result type (might be due to invalid IL or missing references)
				//IL_0297: Unknown result type (might be due to invalid IL or missing references)
				//IL_029d: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a6: 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_02bc: Unknown result type (might be due to invalid IL or missing references)
				if (!_active || (Object)(object)_stern == (Object)null)
				{
					return;
				}
				NjordRuntimeConfig njordRuntimeConfig = NjordSync.RuntimeConfig ?? NjordRuntimeConfig.FromConfig();
				float time = Time.time;
				float num = Mathf.Max(1E-06f, time - _lastSternTime);
				float num2 = Vector3.Distance(_stern.position, _lastSternPos) / num;
				_lastSternPos = _stern.position;
				_lastSternTime = time;
				if ((Object)(object)_wakePS != (Object)null)
				{
					if (Time.time - _lastWake < _wakeInterval)
					{
						return;
					}
					_lastWake = Time.time;
					int particles = _wakePS.GetParticles(_buffer);
					if (IsDebugEnabled())
					{
						try
						{
							Plugin.Log.LogDebug((object)$"[VFX-Piggyback] Wake sample: count={particles} speed={num2} minSpeed={_minSpeed}");
						}
						catch
						{
						}
					}
					if (particles <= 0)
					{
						return;
					}
					int num3 = Mathf.Min(4, particles);
					int num4 = Mathf.Max(1, particles / num3);
					for (int i = 0; i < particles; i += num4)
					{
						Vector3 worldPos = ((Component)_wakePS).transform.TransformPoint(((Particle)(ref _buffer[i])).position);
						if (num2 < _minSpeed)
						{
							if (!(Time.time - _lastLogTime > 1f))
							{
								continue;
							}
							if (IsDebugEnabled())
							{
								try
								{
									Plugin.Log.LogInfo((object)$"[VFX-Piggyback] Skipping wake spawn: speed {num2} < min {_minSpeed}");
								}
								catch
								{
								}
							}
							_lastLogTime = Time.time;
						}
						else
						{
							TrySpawnAt(worldPos);
						}
					}
					return;
				}
				Vector3 val = _stern.TransformPoint(new Vector3(0f, -0.25f, -1f));
				Vector3 val2 = val;
				int num5 = 0;
				try
				{
					num5 = ((LayerMask.NameToLayer("Water") >= 0) ? (1 << LayerMask.NameToLayer("Water")) : 0);
				}
				catch
				{
					num5 = 0;
				}
				if (num5 == 0)
				{
					num5 = -1;
				}
				if (num5 != 0)
				{
					Vector3 val3 = val + Vector3.up * 2f;
					RaycastHit val4 = default(RaycastHit);
					if (Physics.Raycast(val3, Vector3.down, ref val4, 10f, num5))
					{
						val2.y = ((RaycastHit)(ref val4)).point.y + 0.02f;
					}
				}
				Vector3 val5 = val2 - _lastSpawnPos;
				for (float num6 = Vector3.Dot(val5, _stern.forward); num6 >= _spacing; num6 = Vector3.Dot(val5, _stern.forward))
				{
					_lastSpawnPos += _stern.forward * _spacing;
					Vector3 lastSpawnPos = _lastSpawnPos;
					lastSpawnPos.y = val2.y;
					if (num2 >= _minSpeed)
					{
						TrySpawnAt(lastSpawnPos);
					}
					else if (Time.time - _lastLogTime > 1f)
					{
						if (IsDebugEnabled())
						{
							try
							{
								Plugin.Log.LogInfo((object)$"[VFX-Piggyback] Skipping trail spawn: speed {num2} < min {_minSpeed}");
							}
							catch
							{
							}
						}
						_lastLogTime = Time.time;
					}
					val5 = val2 - _lastSpawnPos;
				}
			}

			public bool TrySpawnAt(Vector3 worldPos)
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				if (!_active || (Object)(object)_stern == (Object)null)
				{
					return false;
				}
				float num = Vector3.Distance(worldPos, _lastSpawnPos);
				if (num < _spacing)
				{
					if (Time.time - _lastLogTime > 1f)
					{
						if (IsDebugEnabled())
						{
							try
							{
								Plugin.Log.LogInfo((object)$"[VFX-Piggyback] TrySpawnAt rejected: dist {num} < spacing {_spacing}");
							}
							catch
							{
							}
						}
						_lastLogTime = Time.time;
					}
					return false;
				}
				_lastSpawnPos = worldPos;
				SpawnVisual(worldPos, _color, _sprite, _tex, null, _stern);
				return true;
			}

			private void DoSpawn(Vector3 pos)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				SpawnVisual(pos, _color, _sprite, _tex, null, _stern);
			}
		}

		private class RuneFader : MonoBehaviour
		{
			private SpriteRenderer _sr;

			private Vector3 _vel;

			private float _life;

			private float _age;

			private float _startScale;

			private Color _startColor;

			private Action<GameObject> _onFinish;

			public void Init(Action<GameObject> onFinish)
			{
				_sr = ((Component)this).GetComponent<SpriteRenderer>();
				_onFinish = onFinish;
			}

			public void Play(Vector3 velocity, float life, float startScale, Color color)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: 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_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				_vel = velocity;
				_life = Mathf.Max(0.01f, life);
				_age = 0f;
				_startScale = Mathf.Max(0.01f, startScale);
				_startColor = color;
				if ((Object)(object)_sr != (Object)null)
				{
					_sr.color = color;
					((Component)_sr).transform.localScale = Vector3.one * _startScale;
				}
			}

			private void Update()
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: 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_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				float deltaTime = Time.deltaTime;
				_age += deltaTime;
				Transform transform = ((Component)this).transform;
				transform.position += _vel * deltaTime;
				float num = Mathf.Clamp01(_age / _life);
				if ((Object)(object)_sr != (Object)null)
				{
					Color startColor = _startColor;
					startColor.a = Mathf.Lerp(_startColor.a, 0f, num);
					_sr.color = startColor;
					float num2 = Mathf.Lerp(_startScale, _startScale * 0.4f, num);
					((Component)_sr).transform.localScale = Vector3.one * num2;
				}
				if (_age >= _life)
				{
					_onFinish?.Invoke(((Component)this).gameObject);
				}
			}
		}

		private const int POOL_INITIAL = 64;

		private const int POOL_MAX = 1024;

		private static Queue<GameObject> _pool = new Queue<GameObject>();

		private static GameObject _poolRoot;

		private static Texture2D _runeTex;

		private static Sprite _runeSprite;

		private static Mesh _debugQuadMesh;

		private static bool _inited = false;

		private static OrientationMode _spawnOrientation = OrientationMode.Flat;

		private static readonly Dictionary<object, Emitter> _emitters = new Dictionary<object, Emitter>();

		private static bool IsDebugEnabled()
		{
			try
			{
				NjordRuntimeConfig njordRuntimeConfig = NjordSync.RuntimeConfig ?? NjordRuntimeConfig.FromConfig();
				if (njordRuntimeConfig != null && njordRuntimeConfig.Debug_Enable)
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				if (NjordConfig.Debug_Enable != null && NjordConfig.Debug_Enable.Value)
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static void EnsureInit()
		{
			//IL_0032: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			if (_inited)
			{
				return;
			}
			_inited = true;
			_runeTex = NjordRuneTextureGenerator.GenerateRune((Color)(((??)NjordConfig.VFX_Color?.Value) ?? new Color(0.3f, 0.6f, 1f, 1f)));
			if ((Object)(object)_runeTex != (Object)null)
			{
				_runeSprite = Sprite.Create(_runeTex, new Rect(0f, 0f, (float)((Texture)_runeTex).width, (float)((Texture)_runeTex).height), new Vector2(0.5f, 0.5f), 100f);
			}
			else
			{
				Texture2D val = new Texture2D(16, 16, (TextureFormat)4, false);
				Color[] array = (Color[])(object)new Color[256];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = Color.white;
				}
				val.SetPixels(array);
				val.Apply(false);
				_runeTex = val;
				_runeSprite = Sprite.Create(_runeTex, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
			}
			_poolRoot = new GameObject("NjordRunePiggybackPool");
			Object.DontDestroyOnLoad((Object)(object)_poolRoot);
			for (int j = 0; j < 64; j++)
			{
				_pool.Enqueue(CreatePooledGO());
			}
		}

		private static Mesh GetOrCreateDebugQuadMesh()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_debugQuadMesh != (Object)null)
			{
				return _debugQuadMesh;
			}
			Mesh val = new Mesh();
			((Object)val).name = "Njord_DebugQuadMesh";
			Vector3[] vertices = (Vector3[])(object)new Vector3[4]
			{
				new Vector3(-0.5f, 0f, -0.5f),
				new Vector3(0.5f, 0f, -0.5f),
				new Vector3(0.5f, 0f, 0.5f),
				new Vector3(-0.5f, 0f, 0.5f)
			};
			int[] triangles = new int[6] { 0, 1, 2, 0, 2, 3 };
			Vector2[] uv = (Vector2[])(object)new Vector2[4]
			{
				new Vector2(0f, 0f),
				new Vector2(1f, 0f),
				new Vector2(1f, 1f),
				new Vector2(0f, 1f)
			};
			val.vertices = vertices;
			val.triangles = triangles;
			val.uv = uv;
			val.RecalculateNormals();
			val.RecalculateBounds();
			_debugQuadMesh = val;
			return _debugQuadMesh;
		}

		private static GameObject CreatePooledGO()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_00f3: 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)
			GameObject val = new GameObject("NjordRune");
			val.transform.SetParent(_poolRoot.transform, false);
			SpriteRenderer val2 = val.AddComponent<SpriteRenderer>();
			val2.sprite = _runeSprite;
			((Renderer)val2).sortingLayerName = "Default";
			((Renderer)val2).sortingOrder = 5000;
			((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
			try
			{
				Shader val3 = Shader.Find("Sprites/Default");
				if ((Object)(object)val3 != (Object)null)
				{
					Material val4 = new Material(val3);
					if (val4.HasProperty("_MainTex") && (Object)(object)_runeTex != (Object)null)
					{
						val4.SetTexture("_MainTex", (Texture)(object)_runeTex);
					}
					((Renderer)val2).material = val4;
				}
			}
			catch
			{
			}
			RuneFader runeFader = val.AddComponent<RuneFader>();
			runeFader.Init(ReturnToPool);
			try
			{
				GameObject val5 = new GameObject("Njord_DebugQuad");
				val5.transform.SetParent(val.transform, false);
				val5.transform.localPosition = Vector3.zero;
				val5.transform.localRotation = Quaternion.identity;
				MeshFilter val6 = val5.AddComponent<MeshFilter>();
				val6.mesh = GetOrCreateDebugQuadMesh();
				MeshRenderer val7 = val5.AddComponent<MeshRenderer>();
				((Renderer)val7).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val7).receiveShadows = false;
				((Renderer)val7).enabled = false;
			}
			catch
			{
			}
			val.SetActive(false);
			return val;
		}

		private static GameObject GetFromPool()
		{
			if (!_inited)
			{
				EnsureInit();
			}
			if (_pool.Count > 0)
			{
				return _pool.Dequeue();
			}
			if (_pool.Count + 1 <= 1024)
			{
				return CreatePooledGO();
			}
			return null;
		}

		private static void ReturnToPool(GameObject go)
		{
			if (!((Object)(object)go == (Object)null))
			{
				go.SetActive(false);
				go.transform.SetParent(_poolRoot.transform, false);
				if (_pool.Count < 1024)
				{
					_pool.Enqueue(go);
				}
				else
				{
					Object.Destroy((Object)(object)go);
				}
			}
		}

		public static void SpawnBurst(Vector3 pos, Color color, int count)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			if (!NjordConfig.VFX_Enable.Value)
			{
				return;
			}
			EnsureInit();
			float life = 2.5f;
			float startScale = 1.125f;
			for (int i = 0; i < Mathf.Max(1, count); i++)
			{
				GameObject fromPool = GetFromPool();
				if (!((Object)(object)fromPool == (Object)null))
				{
					SpriteRenderer component = fromPool.GetComponent<SpriteRenderer>();
					if ((Object)(object)component != (Object)null)
					{
						component.sprite = _runeSprite;
						component.color = color;
					}
					fromPool.transform.position = pos + Random.insideUnitSphere * 0.35f;
					fromPool.transform.rotation = Quaternion.Euler(90f, Random.Range(0f, 360f), 0f);
					fromPool.SetActive(true);
					RuneFader component2 = fromPool.GetComponent<RuneFader>();
					if ((Object)(object)component2 != (Object)null)
					{
						Vector3 velocity = (Random.onUnitSphere + Vector3.back * 1.5f) * 0.4f;
						component2.Play(velocity, life, startScale, color);
					}
				}
			}
		}

		public static void StartTrailForShip(object ship, Transform stern, Color color, float rateMultiplier = 1f)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (ship == null || (Object)(object)stern == (Object)null || !NjordConfig.VFX_Enable.Value)
			{
				return;
			}
			EnsureInit();
			if (_emitters.TryGetValue(ship, out var value) && (Object)(object)value != (Object)null)
			{
				value.SetActive(v: true);
				value.UpdateParams(stern, color, rateMultiplier);
				return;
			}
			GameObject val = new GameObject($"NjordRuneEmitter_{ship.GetHashCode()}");
			val.transform.SetParent(stern, true);
			val.transform.position = stern.TransformPoint(new Vector3(0f, -0.25f, -1f));
			Emitter emitter = val.AddComponent<Emitter>();
			try
			{
				emitter.Initialize(stern, color, rateMultiplier, ReturnToPool, _runeSprite, _runeTex);
				_emitters[ship] = emitter;
				if (IsDebugEnabled())
				{
					try
					{
						NjordDebug.Info($"[VFX-Piggyback] Created emitter for ship {ship} (stern={((stern != null) ? ((Object)stern).name : null)})");
					}
					catch
					{
					}
				}
				if (IsDebugEnabled())
				{
					try
					{
						Plugin.Log.LogInfo((object)$"[VFX-Piggyback] Created emitter for ship {ship} (stern={((stern != null) ? ((Object)stern).name : null)})");
						return;
					}
					catch
					{
						return;
					}
				}
			}
			catch (Exception ex)
			{
				if (IsDebugEnabled())
				{
					try
					{
						Plugin.Log.LogWarning((object)$"[VFX-Piggyback] Failed to initialize emitter for ship {ship}: {ex.Message}");
					}
					catch
					{
					}
				}
				if (IsDebugEnabled())
				{
					try
					{
						NjordDebug.Warn($"[VFX-Piggyback] Failed to initialize emitter for ship {ship}: {ex.Message}");
					}
					catch
					{
					}
				}
				try
				{
					if ((Object)(object)emitter != (Object)null && (Object)(object)((Component)emitter).gameObject != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)emitter).gameObject);
					}
				}
				catch
				{
				}
			}
		}

		public static void StopTrailForShip(object ship)
		{
			if (ship != null && _emitters.TryGetValue(ship, out var value) && (Object)(object)value != (Object)null)
			{
				value.SetActive(v: false);
			}
		}

		public static void RemoveEmitterForShip(object ship)
		{
			if (ship == null)
			{
				return;
			}
			if (_emitters.TryGetValue(ship, out var value) && (Object)(object)value != (Object)null)
			{
				try
				{
					if ((Object)(object)((Component)value).gameObject != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)value).gameObject);
					}
				}
				catch
				{
				}
			}
			_emitters.Remove(ship);
		}

		public static void DumpEmitters()
		{
			try
			{
				if (IsDebugEnabled())
				{
					try
					{
						Plugin.Log.LogInfo((object)$"[VFX-Piggyback] Emitters: count={_emitters.Count} pool={_pool.Count}");
					}
					catch
					{
					}
				}
				foreach (KeyValuePair<object, Emitter> emitter in _emitters)
				{
					object key = emitter.Key;
					Emitter value = emitter.Value;
					if ((Object)(object)value == (Object)null)
					{
						if (IsDebugEnabled())
						{
							try
							{
								Plugin.Log.LogInfo((object)$"[VFX-Piggyback] Emitter for {key}: null");
							}
							catch
							{
							}
						}
					}
					else if (IsDebugEnabled())
					{
						try
						{
							ManualLogSource log = Plugin.Log;
							object arg = ((Behaviour)value).isActiveAndEnabled;
							GameObject gameObject = ((Component)value).gameObject;
							log.LogInfo((object)$"[VFX-Piggyback] Emitter for {key}: active={arg} go={((gameObject != null) ? ((Object)gameObject).name : null)}");
						}
						catch
						{
						}
					}
				}
			}
			catch
			{
			}
		}

		public static void SpawnAtWorldPosition(Vector3 pos, Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			SpawnVisual(pos, color, _runeSprite, _runeTex, null, null);
		}

		private static void SpawnVisual(Vector3 pos, Color color, Sprite sprite, Texture2D tex, Vector3? velocityOverride, Transform stern)
		{
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_042e: 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_0260: 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_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			//IL_047c: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ee: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0503: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: 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_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Expected O, but got Unknown
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			if (!NjordConfig.VFX_Enable.Value)
			{
				return;
			}
			EnsureInit();
			GameObject fromPool = GetFromPool();
			if ((Object)(object)fromPool == (Object)null)
			{
				return;
			}
			SpriteRenderer component = fromPool.GetComponent<SpriteRenderer>();
			if ((Object)(object)component != (Object)null)
			{
				component.sprite = sprite ?? _runeSprite;
				component.color = color;
				((Renderer)component).sortingLayerName = "Default";
				((Renderer)component).sortingOrder = 32767;
			}
			fromPool.transform.position = pos;
			try
			{
				switch (_spawnOrientation)
				{
				case OrientationMode.Flat:
					fromPool.transform.rotation = Quaternion.Euler(90f, Random.Range(0f, 360f), 0f);
					break;
				case OrientationMode.FlatInverted:
					fromPool.transform.rotation = Quaternion.Euler(-90f, Random.Range(0f, 360f), 0f);
					break;
				case OrientationMode.Upright:
					fromPool.transform.rotation = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f);
					break;
				case OrientationMode.CameraFacing:
					if ((Object)(object)Camera.main != (Object)null)
					{
						fromPool.transform.rotation = Quaternion.LookRotation(((Component)Camera.main).transform.forward);
					}
					else
					{
						fromPool.transform.rotation = Quaternion.Euler(90f, Random.Range(0f, 360f), 0f);
					}
					break;
				default:
					fromPool.transform.rotation = Quaternion.Euler(90f, Random.Range(0f, 360f), 0f);
					break;
				}
			}
			catch
			{
				fromPool.transform.rotation = Quaternion.Euler(90f, Random.Range(0f, 360f), 0f);
			}
			fromPool.SetActive(true);
			float life = 2.5f;
			float startScale = 0.75f;
			Vector3 velocity = (velocityOverride.HasValue ? velocityOverride.Value : ((!((Object)(object)stern != (Object)null)) ? (Vector3.back * 0.6f + Random.insideUnitSphere * 0.2f) : (-stern.forward * Random.Range(0.6f, 1.2f) + stern.right * Random.Range(-0.25f, 0.25f) + stern.up * Random.Range(-0.05f, 0.05f))));
			RuneFader component2 = fromPool.GetComponent<RuneFader>();
			if ((Object)(object)component2 != (Object)null)
			{
				try
				{
					component2.Play(velocity, life, startScale, color);
				}
				catch
				{
					try
					{
						component2.Play(velocity, life, startScale, color);
					}
					catch
					{
					}
				}
			}
			try
			{
				fromPool.layer = 0;
				SpriteRenderer component3 = fromPool.GetComponent<SpriteRenderer>();
				if ((Object)(object)component3 != (Object)null)
				{
					((Renderer)component3).sortingOrder = 32767;
				}
			}
			catch
			{
			}
			try
			{
				if (IsDebugEnabled())
				{
					Transform val = fromPool.transform.Find("Njord_DebugQuad");
					if ((Object)(object)val != (Object)null)
					{
						MeshRenderer component4 = ((Component)val).GetComponent<MeshRenderer>();
						if ((Object)(object)component4 != (Object)null)
						{
							if ((Object)(object)((Renderer)component4).sharedMaterial == (Object)null)
							{
								Shader val2 = Shader.Find("Unlit/Texture") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Sprites/Default");
								if ((Object)(object)val2 != (Object)null)
								{
									try
									{
										Material val3 = new Material(val2);
										if (val3.HasProperty("_MainTex") && (Object)(object)tex != (Object)null)
										{
											val3.SetTexture("_MainTex", (Texture)(object)tex);
										}
										if (val3.HasProperty("_Color"))
										{
											val3.SetColor("_Color", color);
										}
										((Renderer)component4).material = val3;
									}
									catch
									{
									}
								}
							}
							val.localScale = Vector3.one * 0.3f;
							((Renderer)component4).enabled = true;
							try
							{
								((Renderer)component4).material.renderQueue = 5000;
							}
							catch
							{
							}
							if (IsDebugEnabled())
							{
								try
								{
									Plugin.Log.LogInfo((object)$"[VFX-Piggyback] Spawned debug quad at {pos}");
								}
								catch
								{
								}
							}
						}
					}
				}
			}
			catch
			{
			}
			if (IsDebugEnabled())
			{
				try
				{
					Plugin.Log.LogInfo((object)$"[VFX-Piggyback] DoSpawn at {pos}");
				}
				catch
				{
				}
			}
			try
			{
				if (NjordConfig.Debug_Enable == null || !NjordConfig.Debug_Enable.Value)
				{
					return;
				}
				GameObject val4 = GameObject.CreatePrimitive((PrimitiveType)0);
				val4.transform.position = pos + Vector3.up * 0.15f;
				val4.transform.localScale = Vector3.one * 0.125f;
				try
				{
					Collider component5 = val4.GetComponent<Collider>();
					if ((Object)(object)component5 != (Object)null)
					{
						Object.Destroy((Object)(object)component5);
					}
				}
				catch
				{
				}
				try
				{
					Shader val5 = Shader.Find("Unlit/Color") ?? Shader.Find("Unlit/Texture");
					if ((Object)(object)val5 != (Object)null)
					{
						Material val6 = new Material(val5);
						if (val6.HasProperty("_Color"))
						{
							val6.SetColor("_Color", Color.magenta);
						}
						MeshRenderer component6 = val4.GetComponent<MeshRenderer>();
						if ((Object)(object)component6 != (Object)null)
						{
							((Renderer)component6).material = val6;
						}
					}
				}
				catch
				{
				}
				Object.Destroy((Object)(object)val4, 6f);
			}
			catch
			{
			}
		}
	}
	public static class NjordRuneSpriteTrail
	{
		private class Emitter : MonoBehaviour
		{
			private Transform _stern;

			private Color _color = Color.white;

			private float _life = 1.2f;

			private float _scale = 0.7f;

			private float _spacing = 0.6f;

			private Vector3 _lastSpawnPos;

			private Action<GameObject> _returnToPool;

			private Sprite _sprite;

			private bool _active = true;

			private bool _useTelemetry;

			private float _cachedWaterY = float.MinValue;

			private float _lastWaterSampleTime = -10f;

			private const float WATER_SAMPLE_INTERVAL = 0.1f;

			private const float WATER_SURFACE_OFFSET = 0.02f;

			private int _waterMask;

			private bool _usedAllLayersFallback;

			private bool _loggedLayerResolution;

			private float _lastSpawnDebugLog = -10f;

			private const float SPAWN_DEBUG_LOG_INTERVAL = 1f;

			private bool _debugNotified;

			public void Initialize(Transform stern, Color color, float rateMultiplier, Action<GameObject> returnToPool, Sprite sprite, bool useTelemetry)
			{
				//IL_0010: 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)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0240: 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_027d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0260: Unknown result type (might be due to invalid IL or missing references)
				//IL_0265: Unknown result type (might be due to invalid IL or missing references)
				_stern = stern;
				_useTelemetry = useTelemetry;
				_color = color;
				_sprite = sprite;
				_returnToPool = returnToPool;
				_active = true;
				NjordRuntimeConfig njordRuntimeConfig = NjordSync.RuntimeConfig ?? NjordRuntimeConfig.FromConfig();
				_life = 2.5f;
				_scale = 0.41343752f;
				_spacing = 0.49980003f;
				_lastSpawnPos = (((Object)(object)_stern != (Object)null) ? _stern.position : Vector3.zero);
				if (_useTelemetry && (Object)(object)_stern != (Object)null)
				{
					try
					{
						NjordDebug.Debug($"[VFX-Sprite] Telemetry emitter seeded cachedY={_cachedWaterY = GetRealisticTelemetryWaterY():F2}");
					}
					catch
					{
					}
				}
				string text = null;
				string text2 = null;
				List<string> list = new List<string>();
				if (!string.IsNullOrEmpty(text))
				{
					list.Add(text);
				}
				list.AddRange(new string[7] { "Water", "water", "WaterSurface", "Ocean", "Sea", "SeaWater", "WaterPlane" });
				foreach (string item in list)
				{
					if (!string.IsNullOrEmpty(item))
					{
						int num = LayerMask.NameToLayer(item);
						if (num >= 0)
						{
							_waterMask = 1 << num;
							text2 = item;
							_usedAllLayersFallback = false;
							break;
						}
					}
				}
				if (text2 == null)
				{
					ConfigEntry<bool> debug_Enable = NjordConfig.Debug_Enable;
					if (debug_Enable != null && debug_Enable.Value)
					{
						_waterMask = -1;
						_usedAllLayersFallback = true;
					}
					else
					{
						_waterMask = 0;
						_usedAllLayersFallback = false;
					}
				}
				if (!_loggedLayerResolution)
				{
					string arg = text2 ?? (_usedAllLayersFallback ? "(AllLayers)" : "(none)");
					NjordDebug.Debug($"[VFX-Sprite] Resolved water layer -> '{arg}' mask={_waterMask}");
					_loggedLayerResolution = true;
				}
				if (_useTelemetry || !((Object)(object)_stern != (Object)null))
				{
					return;
				}
				try
				{
					int num2 = _waterMask;
					if (num2 == 0)
					{
						ConfigEntry<bool> debug_Enable2 = NjordConfig.Debug_Enable;
						if (debug_Enable2 != null && debug_Enable2.Value)
						{
							num2 = -1;
						}
					}
					RaycastHit val = default(RaycastHit);
					if (num2 != 0 && (Physics.Raycast(_stern.position, Vector3.down, ref val, 10f, num2) || Physics.Raycast(_stern.position, Vector3.up, ref val, 10f, num2)))
					{
						_cachedWaterY = ((RaycastHit)(ref val)).point.y;
						NjordDebug.Debug($"[VFX-Sprite] Immediate water sample cachedY={_cachedWaterY:F2}");
					}
				}
				catch
				{
				}
			}

			public void UpdateParams(Transform stern, Color color, float rateMultiplier)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				_stern = stern ?? _stern;
				_color = color;
				_spacing = 0.6f;
			}

			public void SetActive(bool v)
			{
				_active = v;
			}

			private float GetRealisticTelemetryWaterY()
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				float num = (((Object)(object)_stern != (Object)null) ? _stern.position.y : 0f);
				float waterLevel = Njord_Telemetry.WaterLevel;
				float boatY = Njord_Telemetry.BoatY;
				if (float.IsNaN(waterLevel) || float.IsInfinity(waterLevel))
				{
					return num;
				}
				float num2 = waterLevel;
				if ((Object)(object)_stern != (Object)null && !float.IsNaN(boatY) && !float.IsInfinity(boatY) && Mathf.Abs(boatY) > 0.0001f)
				{
					num2 = waterLevel + (num - boatY);
				}
				return Mathf.Clamp(num2, num - 3f, num + 3f);
			}

			private void Update()
			{
				//IL_0192: Unknown result type (might be due to invalid IL or missing references)
				//IL_01af: 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_01e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0201: 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_022b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0235: Unknown result type (might be due to invalid IL or missing references)
				//IL_023a: Unknown result type (might be due to invalid IL or missing references)
				//IL_023e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0243: 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_0246: Unknown result type (might be due to invalid IL or missing references)
				//IL_0256: Unknown result type (might be due to invalid IL or missing references)
				//IL_025b: Unknown result type (might be due to invalid IL or missing references)
				//IL_026b: Unknown result type (might be due to invalid IL or missing references)
				//IL_026c: 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_0277: Unknown result type (might be due to invalid IL or missing references)
				//IL_027c: Unknown result type (might be due to invalid IL or missing references)
				//IL_028c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0291: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c7: 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_02d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02de: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_030d: Unknown result type (might be due to invalid IL or missing references)
				//IL_030e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0314: Unknown result type (might be due to invalid IL or missing references)
				//IL_0319: Unknown result type (might be due to invalid IL or missing references)
				//IL_031e: Unknown result type (might be due to invalid IL or missing references)
				//IL_032e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0333: Unknown result type (might be due to invalid IL or missing references)
				//IL_0349: Unknown result type (might be due to invalid IL or missing references)
				//IL_034e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0118: Unknown result type (might be due to invalid IL or missing references)
				//IL_011d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0155: Unknown result type (might be due to invalid IL or missing references)
				//IL_0138: 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_0077: Unknown result type (might be due to invalid IL or missing references)
				if (!_active)
				{
					return;
				}
				if ((Object)(object)_stern == (Object)null)
				{
					_active = false;
					NjordDebug.Warn("[VFX-Sprite] Emitter stern destroyed; deactivating.");
					return;
				}
				if (_useTelemetry)
				{
					try
					{
						float waterLevel = Njord_Telemetry.WaterLevel;
						float boatY = Njord_Telemetry.BoatY;
						if (!float.IsNaN(waterLevel) && !float.IsInfinity(waterLevel))
						{
							float num = waterLevel;
							if (!float.IsNaN(boatY) && Mathf.Abs(boatY) > 0.0001f)
							{
								num = waterLevel + (_stern.position.y - boatY);
							}
							_cachedWaterY = Mathf.Clamp(num, _stern.position.y - 3f, _stern.position.y + 3f);
						}
					}
					catch
					{
					}
				}
				else if (Time.time - _lastWaterSampleTime > 0.1f)
				{
					_lastWaterSampleTime = Time.time;
					int num2 = _waterMask;
					if (num2 == 0)
					{
						ConfigEntry<bool> debug_Enable = NjordConfig.Debug_Enable;
						if (debug_Enable != null && debug_Enable.Value)
						{
							num2 = -1;
						}
					}
					if (num2 != 0)
					{
						try
						{
							RaycastHit val = default(RaycastHit);
							if (Physics.Raycast(_stern.position, Vector3.down, ref val, 10f, num2) || Physics.Raycast(_stern.position, Vector3.up, ref val, 10f, num2))
							{
								_cachedWaterY = ((RaycastHit)(ref val)).point.y;
							}
						}
						catch
						{
						}
					}
				}
				if (_cachedWaterY == float.MinValue)
				{
					_cachedWaterY = _stern.position.y;
				}
				float num3 = _stern.position.x - _lastSpawnPos.x;
				float num4 = _stern.position.z - _lastSpawnPos.z;
				if (!(num3 * num3 + num4 * num4 < _spacing * _spacing))
				{
					Vector3 val2 = default(Vector3);
					((Vector3)(ref val2))..ctor(_stern.position.x, _cachedWaterY + 0.02f, _stern.position.z);
					Vector3 val3 = new Vector3(_stern.right.x, 0f, _stern.right.z);
					Vector3 normalized = ((Vector3)(ref val3)).normalized;
					SpawnOneAt(val2 + normalized * Random.Range(-0.15f, 0.15f), 1.1475f);
					SpawnOneAt(val2 - normalized * 0.9f + normalized * Random.Range(-0.15f, 0.15f), 0.837f);
					SpawnOneAt(val2 + normalized * 0.9f + normalized * Random.Range(-0.15f, 0.15f), 0.837f);
					SpawnOneAt(val2 - normalized * 1.8f + normalized * Random.Range(-0.15f, 0.15f), 1.1475f);
					SpawnOneAt(val2 + normalized * 1.8f + normalized * Random.Range(-0.15f, 0.15f), 1.1475f);
					_lastSpawnPos = _stern.position;
				}
			}

			public bool TrySpawnAt(Vector3 worldPos)
			{
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: 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)
				if (!_active || (Object)(object)_stern == (Object)null)
				{
					return false;
				}
				float num = worldPos.x - _lastSpawnPos.x;
				float num2 = worldPos.z - _lastSpawnPos.z;
				if (num * num + num2 * num2 < _spacing * _spacing)
				{
					return false;
				}
				if (_useTelemetry)
				{
					try
					{
						worldPos.y = GetRealisticTelemetryWaterY() + 0.02f;
					}
					catch
					{
					}
				}
				_lastSpawnPos = worldPos;
				SpawnOneAt(worldPos);
				return true;
			}

			private void SpawnOneAt(Vector3 spawnPos, float scaleMultiplier = 1f)
			{
				//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0129: Unknown result type (might be due to invalid IL or missing references)
				//IL_040b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0418: Unknown result type (might be due to invalid IL or missing references)
				//IL_0422: Unknown result type (might be due to invalid IL or missing references)
				//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0501: Unknown result type (might be due to invalid IL or missing references)
				//IL_0504: Unknown result type (might be due to invalid IL or missing references)
				//IL_0515: Unknown result type (might be due to invalid IL or missing references)
				//IL_0446: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_025a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0264: Expected O, but got Unknown
				//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b4: 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_01a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_030c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0313: Expected O, but got Unknown
				//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e0: Expected O, but got Unknown
				//IL_0355: Unknown result type (might be due to invalid IL or missing references)
				if (_useTelemetry)
				{
					try
					{
						spawnPos.y = GetRealisticTelemetryWaterY() + 0.02f;
					}
					catch
					{
					}
				}
				GameObject fromPool = GetFromPool();
				if ((Object)(object)fromPool == (Object)null)
				{
					return;
				}
				SpriteRenderer component = fromPool.GetComponent<SpriteRenderer>();
				if ((Object)(object)component != (Object)null)
				{
					component.sprite = ((_runeSprites != null && _runeSprites.Length != 0) ? _runeSprites[Random.Range(0, _runeSprites.Length)] : _sprite);
					component.color = _color;
					if ((Object)(object)component.sprite == (Object)null)
					{
						NjordDebug.Warn($"[VFX-Sprite] SpawnOneAt: sprite is null for spawned GO at {spawnPos}");
					}
					try
					{
						NjordRuntimeConfig njordRuntimeConfig = NjordSync.RuntimeConfig ?? NjordRuntimeConfig.FromConfig();
						if (njordRuntimeConfig != null && njordRuntimeConfig.Debug_Enable)
						{
							Shader val = Shader.Find("Sprites/Default");
							if ((Object)(object)val != (Object)null)
							{
								try
								{
									((Renderer)component).material = new Material(val);
								}
								catch
								{
								}
							}
						}
					}
					catch
					{
					}
				}
				fromPool.transform.position = spawnPos;
				fromPool.transform.rotation = Quaternion.Euler(Random.Range(0f, 360f), Random.Range(0f, 360f), Random.Range(0f, 360f));
				fromPool.SetActive(true);
				try
				{
					NjordRuntimeConfig njordRuntimeConfig2 = NjordSync.RuntimeConfig ?? NjordRuntimeConfig.FromConfig();
					if (njordRuntimeConfig2 != null && njordRuntimeConfig2.Debug_Enable)
					{
						if (Time.time - _lastSpawnDebugLog > 1f)
						{
							string text = (((Object)(object)component == (Object)null || (Object)(object)component.sprite == (Object)null) ? "(sprite-null)" : "(sprite-ok)");
							NjordDebug.Info($"[VFX-Sprite] SpawnOneAt: pos={spawnPos} cachedY={_cachedWaterY} {text} goLayer={fromPool.layer} sortingOrder={(((Object)(object)component != (Object)null) ? ((Renderer)component).sortingOrder : (-1))} active={fromPool.activeSelf}");
							_lastSpawnDebugLog = Time.time;
						}
						if (!_debugNotified)
						{
							try
							{
								MessageHud instance = MessageHud.instance;
								if (instance != null)
								{
									instance.ShowMessage((MessageType)1, "Njord VFX debug spawns active", 0, (Sprite)null, false);
								}
							}
							catch
							{
							}
							_debugNotified = true;
						}
						try
						{
							if ((Object)(object)component != (Object)null)
							{
								Shader val2 = Shader.Find("Sprites/Default");
								if ((Object)(object)val2 != (Object)null)
								{
									try
									{
										((Renderer)component).material = new Material(val2);
									}
									catch
									{
									}
								}
								((Renderer)component).sortingOrder = 32767;
							}
							fromPool.layer = 0;
							try
							{
								Transform val3 = fromPool.transform.Find("Njord_DebugQuad");
								if ((Object)(object)val3 != (Object)null)
								{
									MeshRenderer component2 = ((Component)val3).GetComponent<MeshRenderer>();
									MeshFilter component3 = ((Component)val3).GetComponent<MeshFilter>();
									if ((Object)(object)component2 != (Object)null && (Object)(object)component3 != (Object)null)
									{
										if ((Object)(object)((Renderer)component2).sharedMaterial == (Object)null)
										{
											Shader val4 = Shader.Find("Unlit/Texture") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Sprites/Default");
											if ((Object)(object)val4 != (Object)null)
											{
												try
												{
													Material val5 = new Material(val4);
													if (val5.HasProperty("_MainTex") && (Object)(object)_runeTex != (Object)null)
													{
														val5.SetTexture("_MainTex", (Texture)(object)_runeTex);
													}
													if (val5.HasProperty("_Color"))
													{
														val5.SetColor("_Color", _color);
													}
													val5.renderQueue = 5000;
													((Renderer)component2).material = val5;
												}
												catch
												{
												}
											}
										}
										try
										{
											NjordRuntimeConfig njordRuntimeConfig3 = NjordSync.RuntimeConfig ?? NjordRuntimeConfig.FromConfig();
											float num = Mathf.Max(0.25f, njordRuntimeConfig3.Debug_Enable ? 1.5f : 0.6f);
											val3.localScale = Vector3.one * num;
										}
										catch
										{
											val3.localScale = Vector3.one * 0.6f;
										}
										((Renderer)component2).enabled = true;
										try
										{
											((Renderer)component2).material.renderQueue = 5000;
										}
										catch
										{
										}
									}
								}
							}
							catch
							{
							}
							GameObject val6 = GameObject.CreatePrimitive((PrimitiveType)0);
							try
							{
								val6.transform.position = spawnPos;
								val6.transform.localScale = Vector3.one * 0.25f;
								Renderer component4 = val6.GetComponent<Renderer>();
								if ((Object)(object)component4 != (Object)null)
								{
									try
									{
										component4.material.color = Color.magenta;
									}
									catch
									{
									}
								}
								Object.Destroy((Object)(object)val6, 3f);
							}
							catch
							{
								try
								{
									Object.Destroy((Object)(object)val6);
								}
								catch
								{
								}
							}
						}
						catch
						{
						}
					}
				}
				catch
				{
				}
				RuneSprite_Fader component5 = fromPool.GetComponent<RuneSprite_Fader>();
				if ((Object)(object)component5 != (Object)null)
				{
					float num2 = Random.Range(1.5f, 3.5f);
					float num3 = Random.Range(0.2f, 0.7f);
					float num4 = Random.Range(-0.4f, 0.4f);
					Vector3 velocity = Vector3.up * num2 + -_stern.forward * num3 + _stern.right * num4;
					component5.Play(velocity, _life, _scale * scaleMultiplier, _color);
				}
			}
		}

		private class RuneSprite_Fader : MonoBehaviour
		{
			private SpriteRenderer _sr;

			private Vector3 _vel;

			private Vector3 _angularVelocity;

			private float _life;

			private float _age;

			private float _startScale;

			private Color _startColor;

			private Action<GameObject> _onFinish;

			private const float GRAVITY = -0.35f;

			private const float DRAG = 2.8f;

			public void Init(Action<GameObject> onFinish)
			{
				_sr = ((Component)this).GetComponent<SpriteRenderer>();
				_onFinish = onFinish;
			}

			public void Play(Vector3 velocity, float life, float startScale, Color color)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: 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_006a: 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_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: 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)
				_vel = velocity;
				_life = Mathf.Max(0.01f, life);
				_age = 0f;
				_startScale = Mathf.Max(0.01f, startScale);
				_startColor = color;
				_angularVelocity = new Vector3(Random.Range(-240f, 240f), Random.Range(-240f, 240f), Random.Range(-240f, 240f));
				if ((Object)(object)_sr != (Object)null)
				{
					_sr.color = color;
					((Component)_sr).transform.localScale = Vector3.one * _startScale;
				}
			}

			private void Update()
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: 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_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0101: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				//IL_015c: Unknown result type (might be due to invalid IL or missing references)
				//IL_016d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0182: Unknown result type (might be due to invalid IL or missing references)
				//IL_0189: Unknown result type (might be due to invalid IL or missing references)
				float deltaTime = Time.deltaTime;
				_age += deltaTime;
				_vel *= Mathf.Exp(-2.8f * deltaTime);
				_vel.y += -0.35f * deltaTime;
				Transform transform = ((Component)this).transform;
				transform.position += _vel * deltaTime;
				((Component)this).transform.Rotate(_angularVelocity * deltaTime, (Space)0);
				float num = Mathf.Clamp01(_age / _life);
				if ((Object)(object)_sr != (Object)null)
				{
					float num2;
					if (num < 0.3f)
					{
						num2 = 1f;
					}
					else
					{
						float num3 = (num - 0.3f) / 0.7f;
						num3 *= num3;
						num2 = 1f - num3;
						num2 *= 1f + 0.28f * Mathf.Sin(_age * 18f);
						num2 = Mathf.Clamp01(num2);
					}
					Color startColor = _startColor;
					startColor.a = _startColor.a * num2;
					_sr.color = startColor;
					float num4 = ((num < 0.3f) ? _startScale : Mathf.Lerp(_startScale, 0f, (num - 0.3f) / 0.7f));
					((Component)_sr).transform.localScale = Vector3.one * Mathf.Max(0f, num4);
					((Component)_sr).transform.localScale = Vector3.one * num4;
				}
				if (_age >= _life)
				{
					_onFinish?.Invoke(((Component)this).gameObject);
				}
			}
		}

		private class WakeSampler : MonoBehaviour
		{
			private ParticleSystem _ps;

			private Particle[] _buffer = (Particle[])(object)new Particle[512];

			private float _interval = 0.1f;

			private float _last;

			private Color _color = Color.white;

			private Emitter _emitterRef;

			public void Init(ParticleSystem ps, Color color, float rate, Emitter emitterRef)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				_ps = ps;
				_color = color;
				_interval = Mathf.Max(0.05f, 1f / Mathf.Max(1f, rate));
				_last = Time.time - _interval;
				_emitterRef = emitterRef;
			}

			private void Update()
			{
				//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ad: 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)
				try
				{
					NjordRuntimeConfig njordRuntimeConfig = NjordSync.RuntimeConfig ?? NjordRuntimeConfig.FromConfig();
					if (!njordRuntimeConfig.VFX_Enable || (Object)(object)_ps == (Object)null || (Object)(object)_emitterRef == (Object)null || Time.time - _last < _interval)
					{
						return;
					}
					_last = Time.time;
					int particles = _ps.GetParticles(_buffer);
					if (particles <= 0)
					{
						return;
					}
					int num = Mathf.Min(4, particles);
					int num2 = Mathf.Max(1, particles / num);
					for (int i = 0; i < particles; i += num2)
					{
						Vector3 worldPos = ((Component)_ps).transform.TransformPoint(((Particle)(ref _buffer[i])).position);
						try
						{
							_emitterRef.TrySpawnAt(worldPos);
						}
						catch
						{
						}
					}
				}
				catch
				{
				}
			}
		}

		private const int POOL_INITIAL = 64;

		private const int POOL_MAX = 1024;

		private const float VISIBILITY_MULT = 5f;

		private static Queue<GameObject> _pool = new Queue<GameObject>();

		private static GameObject _poolRoot;

		private static Sprite[] _runeSprites;

		private static Sprite _runeSprite;

		private static Texture2D _runeTex;

		private static Mesh _debugQuadMesh;

		private static readonly Dictionary<object, Emitter> _emitters = new Dictionary<object, Emitter>();

		private static readonly Dictionary<object, WakeSampler> _wakeSamplers = new Dictionary<object, WakeSampler>();

		private static bool _inited = false;

		private static void EnsureInit(Color color)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_0094: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//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)
			if (_inited)
			{
				return;
			}
			_inited = true;
			_runeSprites = (Sprite[])(object)new Sprite[16];
			for (int i = 0; i < 16; i++)
			{
				Texture2D val = NjordRuneTextureGenerator.GenerateRune(Color.white, i);
				if ((Object)(object)val == (Object)null)
				{
					val = new Texture2D(16, 16, (TextureFormat)4, false);
					Color[] array = (Color[])(object)new Color[256];
					for (int j = 0; j < array.Length; j++)
					{
						array[j] = Color.white;
					}
					val.SetPixels(array);
					val.Apply(false);
				}
				_runeSprites[i] = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
			}
			_runeTex = NjordRuneTextureGenerator.GenerateRune(Color.white, 0);
			_runeSprite = _runeSprites[0];
			NjordDebug.Debug($"[VFX-Sprite] Generated {16} rune sprites.");
			_poolRoot = new GameObject("NjordRuneSpritePool");
			Object.DontDestroyOnLoad((Object)(object)_poolRoot);
			for (int k = 0; k < 64; k++)
			{
				_pool.Enqueue(CreatePooledGO());
			}
			NjordDebug.Log("[VFX-Sprite] Initialized rune sprite trail pool.");
		}

		private static GameObject CreatePooledGO()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("NjordRuneSprite");
			val.transform.SetParent(_poolRoot.transform, false);
			SpriteRenderer val2 = val.AddComponent<SpriteRenderer>();
			val2.sprite = _runeSprite;
			((Renderer)val2).sortingLayerName = "Default";
			((Renderer)val2).sortingOrder = 5000;
			((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
			RuneSprite_Fader runeSprite_Fader = val.AddComponent<RuneSprite_Fader>();
			runeSprite_Fader.Init(ReturnToPool);
			try
			{
				GameObject val3 = new GameObject("Njord_DebugQuad");
				val3.transform.SetParent(val.transform, false);
				val3.transform.localPosition = Vector3.zero;
				val3.transform.localRotation = Quaternion.identity;
				MeshFilter val4 = val3.AddComponent<MeshFilter>();
				val4.mesh = GetOrCreateDebugQuadMesh();
				MeshRenderer val5 = val3.AddComponent<MeshRenderer>();
				((Renderer)val5).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val5).receiveShadows = false;
				((Renderer)val5).enabled = false;
				val3.SetActive(true);
			}
			catch
			{
			}
			val.SetActive(false);
			return val;
		}

		private static GameObject GetFromPool()
		{
			if (_pool.Count > 0)
			{
				return _pool.Dequeue();
			}
			if (_pool.Count + 1 <= 1024)
			{
				return CreatePooledGO();
			}
			return null;
		}

		private static void ReturnToPool(GameObject go)
		{
			if (!((Object)(object)go == (Object)null))
			{
				go.SetActive(false);
				go.transform.SetParent(_poolRoot.transform, false);
				if (_pool.Count < 1024)
				{
					_pool.Enqueue(go);
				}
				else
				{
					Object.Destroy((Object)(object)go);
				}
			}
		}

		private static Mesh GetOrCreateDebugQuadMesh()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_debugQuadMesh != (Object)null)
			{
				return _debugQuadMesh;
			}
			Mesh val = new Mesh();
			((Object)val).name = "Njord_DebugQuadMesh";
			Vector3[] vertices = (Vector3[])(object)new Vector3[4]
			{
				new Vector3(-0.5f, 0f, -0.5f),
				new Vector3(0.5f, 0f, -0.5f),
				new Vector3(0.5f, 0f, 0.5f),
				new Vector3(-0.5f, 0f, 0.5f)
			};
			int[] triangles = new int[6] { 0, 1, 2, 0, 2, 3 };
			Vector2[] uv = (Vector2[])(object)new Vector2[4]
			{
				new Vector2(0f, 0f),
				new Vector2(1f, 0f),
				new Vector2(1f, 1f),
				new Vector2(0f, 1f)
			};
			val.vertices = vertices;
			val.triangles = triangles;
			val.uv = uv;
			val.RecalculateNormals();
			val.RecalculateBounds();
			_debugQuadMesh = val;
			return _debugQuadMesh;
		}

		public static void SpawnBurst(Vector3 pos, Color color, int count)
		{
			//IL_0018: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: 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)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			NjordRuntimeConfig njordRuntimeConfig = NjordSync.RuntimeConfig ?? NjordRuntimeConfig.FromConfig();
			if (!njordRuntimeConfig.VFX_Enable)
			{
				return;
			}
			EnsureInit(color);
			float life = 12.5f;
			float startScale = 1.125f;
			for (int i = 0; i < Mathf.Max(1, count); i++)
			{
				GameObject fromPool = GetFromPool();
				if (!((Object)(object)fromPool == (Object)null))
				{
					SpriteRenderer component = fromPool.GetComponent<SpriteRenderer>();
					if ((Object)(object)component != (Object)null)
					{
						component.sprite = ((_runeSprites != null) ? _runeSprites[Random.Range(0, _runeSprites.Length)] : _runeSprite);
						component.color = color;
					}
					fromPool.transform.position = pos + Random.insideUnitSphere * 0.35f;
					fromPool.transform.rotation = Quaternion.Euler(90f, Random.Range(0f, 360f), 0f);
					fromPool.SetActive(true);
					RuneSprite_Fader component2 = fromPool.GetComponent<RuneSprite_Fader>();
					if ((Object)(object)component2 != (Object)null)
					{
						Vector3 velocity = (Random.onUnitSphere + Vector3.back * 1.5f) * 0.4f;
						component2.Play(ve