Decompiled source of LaserWandMod v1.0.2

plugins\LaserWandMod\LaserWandMod.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LaserWandMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LaserWandMod")]
[assembly: AssemblyTitle("LaserWandMod")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 LaserWandMod
{
	public class Class1
	{
	}
	internal struct WandPartData
	{
		public Mesh mesh;

		public Material[] materials;

		public Vector3 relPos;

		public Quaternion relRot;

		public Vector3 worldScale;
	}
	internal static class WandAssets
	{
		[CompilerGenerated]
		private sealed class <LoadSoundsFromDisk>d__19 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string pluginDir;

			public ManualLogSource log;

			private List<AudioClip> <loaded>5__2;

			private string[] <>7__wrap2;

			private int <>7__wrap3;

			private string <name>5__5;

			private UnityWebRequest <req>5__6;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<loaded>5__2 = null;
				<>7__wrap2 = null;
				<name>5__5 = null;
				<req>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Invalid comparison between Unknown and I4
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
					{
						<>1__state = -1;
						string[] array = new string[3] { "valuable star wand sparkle01.ogg", "valuable star wand sparkle02.ogg", "valuable star wand sparkle03.ogg" };
						<loaded>5__2 = new List<AudioClip>();
						<>7__wrap2 = array;
						<>7__wrap3 = 0;
						break;
					}
					case 1:
						<>1__state = -3;
						if ((int)<req>5__6.result == 1)
						{
							AudioClip content = DownloadHandlerAudioClip.GetContent(<req>5__6);
							((Object)content).name = Path.GetFileNameWithoutExtension(<name>5__5);
							<loaded>5__2.Add(content);
						}
						else
						{
							log.LogWarning((object)("Could not load sound " + <name>5__5 + ": " + <req>5__6.error));
						}
						<>m__Finally1();
						<req>5__6 = null;
						<name>5__5 = null;
						<>7__wrap3++;
						break;
					}
					if (<>7__wrap3 < <>7__wrap2.Length)
					{
						<name>5__5 = <>7__wrap2[<>7__wrap3];
						string text = "file:///" + Path.Combine(pluginDir, <name>5__5).Replace('\\', '/');
						<req>5__6 = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)14);
						<>1__state = -3;
						<>2__current = <req>5__6.SendWebRequest();
						<>1__state = 1;
						return true;
					}
					<>7__wrap2 = null;
					if (<loaded>5__2.Count > 0)
					{
						Sounds = <loaded>5__2.ToArray();
						log.LogInfo((object)$"Loaded {<loaded>5__2.Count} sparkle sounds from disk.");
					}
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<req>5__6 != null)
				{
					((IDisposable)<req>5__6).Dispose();
				}
			}

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

		public static List<WandPartData>? Parts;

		public static AudioClip[]? Sounds;

		public static GameObject? ParticleTemplate;

		public static Vector3 ParticleTipRelPos;

		public static Quaternion ParticleTipRelRot;

		public static Vector3 ParticleTipWorldScale;

		private static readonly Vector3 DefaultTipRelPos = new Vector3(-0.003f, 0.0405f, 0.739f);

		private static readonly Quaternion DefaultTipRelRot = new Quaternion(0f, -0.92388f, 0f, 0.38268f);

		private static readonly Vector3 DefaultTipScale = new Vector3(0.75f, 0.75f, 0.75f);

		private static readonly Vector3 DefaultMeshRelPos = new Vector3(0f, 0.03975f, 0.031f);

		private static readonly Quaternion DefaultMeshRelRot = new Quaternion(0.5f, 0.5f, 0.5f, 0.5f);

		private static readonly Vector3 DefaultMeshScale = new Vector3(0.272872f, 0.272872f, 0.272872f);

		public static bool Ready { get; private set; }

		public static void LoadFromDisk(string pluginDir, ManualLogSource log)
		{
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_00f5: 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_0114: 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_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			string text = Path.Combine(pluginDir, "WandPrefab.glb");
			if (!File.Exists(text))
			{
				log.LogWarning((object)("WandPrefab.glb not found at " + text + " — will use scene fallback."));
				return;
			}
			if (!TryParseGlb(File.ReadAllBytes(text), out var mesh, out var tex, log))
			{
				log.LogError((object)"Failed to parse WandPrefab.glb.");
				return;
			}
			Material val = new Material(Shader.Find("Unlit/Texture") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Standard") ?? Shader.Find("Diffuse"))
			{
				name = "Valuable Star Wand"
			};
			val.mainTexture = (Texture)(object)tex;
			try
			{
				val.SetTexture("_BaseMap", (Texture)(object)tex);
			}
			catch
			{
			}
			try
			{
				val.SetInt("_Cull", 0);
			}
			catch
			{
			}
			List<WandPartData> list = new List<WandPartData>();
			list.Add(new WandPartData
			{
				mesh = mesh,
				materials = (Material[])(object)new Material[1] { val },
				relPos = DefaultMeshRelPos,
				relRot = DefaultMeshRelRot,
				worldScale = DefaultMeshScale
			});
			Parts = list;
			ParticleTipRelPos = DefaultTipRelPos;
			ParticleTipRelRot = DefaultTipRelRot;
			ParticleTipWorldScale = DefaultTipScale;
			Ready = true;
			log.LogInfo((object)$"Wand mesh loaded from disk: {mesh.vertexCount} verts.");
		}

		public static void RefineFromScene(Transform wandRoot, ManualLogSource log)
		{
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			List<WandPartData> list = new List<WandPartData>();
			MeshFilter[] componentsInChildren = ((Component)wandRoot).GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				if ((Object)(object)val.sharedMesh == (Object)null)
				{
					continue;
				}
				MeshRenderer component = ((Component)val).GetComponent<MeshRenderer>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				bool flag = false;
				Material[] sharedMaterials = ((Renderer)component).sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					if ((Object)(object)sharedMaterials[j] != (Object)null)
					{
						flag = true;
						break;
					}
				}
				if (flag)
				{
					list.Add(new WandPartData
					{
						mesh = val.sharedMesh,
						materials = ((Renderer)component).sharedMaterials,
						relPos = wandRoot.InverseTransformPoint(((Component)val).transform.position),
						relRot = Quaternion.Inverse(wandRoot.rotation) * ((Component)val).transform.rotation,
						worldScale = ((Component)val).transform.lossyScale
					});
				}
			}
			if (list.Count > 0)
			{
				Parts = list;
			}
			if ((Object)(object)ParticleTemplate == (Object)null)
			{
				Transform val2 = FindChildByName(wandRoot, "Star Particles");
				if ((Object)(object)val2 != (Object)null)
				{
					ParticleTipRelPos = wandRoot.InverseTransformPoint(val2.position);
					ParticleTipRelRot = Quaternion.Inverse(wandRoot.rotation) * val2.rotation;
					ParticleTipWorldScale = val2.lossyScale;
					ParticleTemplate = Object.Instantiate<GameObject>(((Component)val2).gameObject);
					Object.DontDestroyOnLoad((Object)(object)ParticleTemplate);
					ParticleTemplate.SetActive(false);
					ParticleSystem[] componentsInChildren2 = ParticleTemplate.GetComponentsInChildren<ParticleSystem>(true);
					foreach (ParticleSystem obj in componentsInChildren2)
					{
						MainModule main = obj.main;
						((MainModule)(ref main)).loop = false;
						((MainModule)(ref main)).playOnAwake = false;
						obj.Stop(true, (ParticleSystemStopBehavior)0);
					}
					log.LogInfo((object)"Particle template captured from scene.");
				}
			}
			Ready = true;
			log.LogInfo((object)$"Wand assets refined from scene: {list.Count} mesh parts.");
		}

		public static void TryCacheSounds()
		{
			if (Sounds != null && Sounds.Length != 0)
			{
				return;
			}
			List<AudioClip> list = new List<AudioClip>();
			AudioClip[] array = Resources.FindObjectsOfTypeAll<AudioClip>();
			foreach (AudioClip val in array)
			{
				string text = ((Object)val).name.ToLower();
				if (text.Contains("wand") && text.Contains("sparkle"))
				{
					list.Add(val);
				}
			}
			if (list.Count > 0)
			{
				Sounds = list.ToArray();
			}
		}

		[IteratorStateMachine(typeof(<LoadSoundsFromDisk>d__19))]
		public static IEnumerator LoadSoundsFromDisk(string pluginDir, ManualLogSource log)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadSoundsFromDisk>d__19(0)
			{
				pluginDir = pluginDir,
				log = log
			};
		}

		private static bool TryParseGlb(byte[] d, out Mesh mesh, out Texture2D tex, ManualLogSource log)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: 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_01d6: Expected O, but got Unknown
			mesh = null;
			tex = null;
			try
			{
				if (d.Length < 28 || BitConverter.ToUInt32(d, 0) != 1179937895)
				{
					log.LogError((object)"Not a valid GLB file.");
					return false;
				}
				int num = (int)BitConverter.ToUInt32(d, 12);
				int num2 = 28 + num;
				tex = new Texture2D(2, 2, (TextureFormat)4, false);
				byte[] array = new byte[38109];
				Buffer.BlockCopy(d, num2, array, 0, 38109);
				ImageConversion.LoadImage(tex, array);
				int num3 = num2 + 38112;
				Vector3[] array2 = (Vector3[])(object)new Vector3[306];
				Vector3[] array3 = (Vector3[])(object)new Vector3[306];
				Vector2[] array4 = (Vector2[])(object)new Vector2[306];
				for (int i = 0; i < 306; i++)
				{
					int num4 = num3 + i * 48;
					float num5 = BitConverter.ToSingle(d, num4);
					float num6 = BitConverter.ToSingle(d, num4 + 4);
					float num7 = BitConverter.ToSingle(d, num4 + 8);
					array2[i] = new Vector3(0f - num5, num6, num7);
					float num8 = BitConverter.ToSingle(d, num4 + 12);
					float num9 = BitConverter.ToSingle(d, num4 + 16);
					float num10 = BitConverter.ToSingle(d, num4 + 20);
					array3[i] = new Vector3(0f - num8, num9, num10);
					float num11 = BitConverter.ToSingle(d, num4 + 40);
					float num12 = BitConverter.ToSingle(d, num4 + 44);
					array4[i] = new Vector2(num11, 1f - num12);
				}
				int num13 = num2 + 52800;
				int[] array5 = new int[528];
				for (int j = 0; j < 528; j += 3)
				{
					array5[j] = BitConverter.ToUInt16(d, num13 + j * 2);
					array5[j + 1] = BitConverter.ToUInt16(d, num13 + (j + 2) * 2);
					array5[j + 2] = BitConverter.ToUInt16(d, num13 + (j + 1) * 2);
				}
				mesh = new Mesh
				{
					name = "Wand Mesh"
				};
				mesh.vertices = array2;
				mesh.uv = array4;
				mesh.triangles = array5;
				mesh.RecalculateNormals();
				mesh.RecalculateBounds();
				return true;
			}
			catch (Exception ex)
			{
				log.LogError((object)("GLB parse error: " + ex.Message));
				return false;
			}
		}

		private static Transform? FindChildByName(Transform root, string name)
		{
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (((Object)val).name == name)
				{
					return val;
				}
			}
			return null;
		}
	}
	[BepInPlugin("com.merzl.laserwandmod", "LaserWandMod", "1.0.2")]
	public class Plugin : BaseUnityPlugin
	{
		private static GameObject? _updaterGO;

		private void Awake()
		{
			SceneManager.sceneLoaded += OnSceneLoaded;
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			WandAssets.LoadFromDisk(directoryName, ((BaseUnityPlugin)this).Logger);
			((MonoBehaviour)this).StartCoroutine(WandAssets.LoadSoundsFromDisk(directoryName, ((BaseUnityPlugin)this).Logger));
			((BaseUnityPlugin)this).Logger.LogInfo((object)("LaserWandMod ready. Disk assets: " + (WandAssets.Ready ? "loaded" : "missing — using scene fallback")));
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)_updaterGO != (Object)null))
			{
				_updaterGO = new GameObject("LaserWandUpdater");
				Object.DontDestroyOnLoad((Object)(object)_updaterGO);
				_updaterGO.AddComponent<MeshReplacer>().Init(((BaseUnityPlugin)this).Logger);
			}
		}
	}
	public class MeshReplacer : MonoBehaviour
	{
		private ManualLogSource? _log;

		private float _pollTimer;

		private readonly HashSet<int> _replaced = new HashSet<int>();

		private AudioSource? _audioSource;

		private ParticleSystem[] _particles = Array.Empty<ParticleSystem>();

		private Transform? _gunRoot;

		private Vector3 _lastGunPos;

		private float _soundCooldown;

		private const float MOVE_THRESHOLD = 0.005f;

		private const float SOUND_INTERVAL_MIN = 0.25f;

		private const float SOUND_INTERVAL_RAND = 0.3f;

		public void Init(ManualLogSource log)
		{
			_log = log;
		}

		private void Update()
		{
			_pollTimer += Time.deltaTime;
			float num = ((WandAssets.Ready && (Object)(object)_gunRoot != (Object)null) ? 10f : 1f);
			if (_pollTimer >= num)
			{
				_pollTimer = 0f;
				TryReplace();
			}
			UpdateEffects();
		}

		private void UpdateEffects()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_gunRoot == (Object)null || (Object)(object)_audioSource == (Object)null)
			{
				return;
			}
			_soundCooldown -= Time.deltaTime;
			float num = Vector3.Distance(_gunRoot.position, _lastGunPos);
			_lastGunPos = _gunRoot.position;
			if (!(num > 0.005f))
			{
				return;
			}
			ParticleSystem[] particles = _particles;
			foreach (ParticleSystem val in particles)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.Emit(1);
				}
			}
			if (!(_soundCooldown <= 0f))
			{
				return;
			}
			WandAssets.TryCacheSounds();
			AudioClip[] sounds = WandAssets.Sounds;
			if (sounds != null && sounds.Length != 0)
			{
				AudioClip val2 = sounds[Random.Range(0, sounds.Length)];
				if ((Object)(object)val2 != (Object)null)
				{
					_audioSource.PlayOneShot(val2, 0.15f);
					_soundCooldown = 0.25f + Random.Range(0f, 0.3f);
				}
			}
		}

		private void TryReplace()
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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_0112: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)WandAssets.ParticleTemplate == (Object)null)
			{
				Transform val = FindItemRoot("wand");
				if ((Object)(object)val != (Object)null)
				{
					WandAssets.RefineFromScene(val, _log);
				}
			}
			if (WandAssets.Parts == null || !WandAssets.Ready || (Object)(object)_gunRoot != (Object)null)
			{
				return;
			}
			Transform val2 = FindGunRoot();
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)val2).GetInstanceID();
			if (_replaced.Contains(instanceID))
			{
				return;
			}
			MeshRenderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<MeshRenderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Renderer)componentsInChildren[i]).enabled = false;
			}
			foreach (WandPartData part in WandAssets.Parts)
			{
				GameObject val3 = new GameObject("WandPart_" + ((Object)part.mesh).name);
				val3.transform.SetParent(val2, false);
				val3.transform.localPosition = part.relPos;
				val3.transform.localRotation = part.relRot;
				Vector3 lossyScale = val2.lossyScale;
				Vector3 worldScale = part.worldScale;
				val3.transform.localScale = new Vector3((lossyScale.x != 0f) ? (worldScale.x / lossyScale.x) : worldScale.x, (lossyScale.y != 0f) ? (worldScale.y / lossyScale.y) : worldScale.y, (lossyScale.z != 0f) ? (worldScale.z / lossyScale.z) : worldScale.z);
				val3.AddComponent<MeshFilter>().sharedMesh = part.mesh;
				((Renderer)val3.AddComponent<MeshRenderer>()).sharedMaterials = part.materials;
			}
			AttachEffects(val2);
			_replaced.Add(instanceID);
			ManualLogSource? log = _log;
			if (log != null)
			{
				log.LogInfo((object)$"Gun replaced with wand ({WandAssets.Parts.Count} parts).");
			}
		}

		private void AttachEffects(Transform gunRoot)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			_audioSource = ((Component)gunRoot).GetComponent<AudioSource>() ?? ((Component)gunRoot).gameObject.AddComponent<AudioSource>();
			_audioSource.spatialBlend = 1f;
			_audioSource.rolloffMode = (AudioRolloffMode)1;
			_audioSource.maxDistance = 10f;
			WandAssets.TryCacheSounds();
			_particles = SpawnParticles(gunRoot);
			_gunRoot = gunRoot;
			_lastGunPos = gunRoot.position;
			ManualLogSource? log = _log;
			if (log != null)
			{
				AudioClip[]? sounds = WandAssets.Sounds;
				log.LogInfo((object)$"Effects attached. Sounds: {((sounds != null) ? sounds.Length : 0)}, Particles: {_particles.Length}");
			}
		}

		private ParticleSystem[] SpawnParticles(Transform gunRoot)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val;
			if ((Object)(object)WandAssets.ParticleTemplate != (Object)null)
			{
				val = Object.Instantiate<GameObject>(WandAssets.ParticleTemplate, gunRoot);
				val.transform.localPosition = WandAssets.ParticleTipRelPos;
				val.transform.localRotation = WandAssets.ParticleTipRelRot;
				Vector3 lossyScale = gunRoot.lossyScale;
				Vector3 particleTipWorldScale = WandAssets.ParticleTipWorldScale;
				val.transform.localScale = new Vector3((lossyScale.x != 0f) ? (particleTipWorldScale.x / lossyScale.x) : particleTipWorldScale.x, (lossyScale.y != 0f) ? (particleTipWorldScale.y / lossyScale.y) : particleTipWorldScale.y, (lossyScale.z != 0f) ? (particleTipWorldScale.z / lossyScale.z) : particleTipWorldScale.z);
				val.SetActive(true);
			}
			else
			{
				val = BuildProceduralSparkles(gunRoot);
			}
			ParticleSystem[] componentsInChildren = val.GetComponentsInChildren<ParticleSystem>(true);
			ParticleSystem[] array = componentsInChildren;
			foreach (ParticleSystem obj in array)
			{
				MainModule main = obj.main;
				((MainModule)(ref main)).loop = false;
				((MainModule)(ref main)).playOnAwake = false;
				obj.Stop(true, (ParticleSystemStopBehavior)0);
			}
			return componentsInChildren;
		}

		private GameObject BuildProceduralSparkles(Transform parent)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			GameObject val = new GameObject("WandSparkles");
			val.transform.SetParent(parent, false);
			val.transform.localPosition = WandAssets.ParticleTipRelPos;
			val.transform.localRotation = WandAssets.ParticleTipRelRot;
			ParticleSystem obj = val.AddComponent<ParticleSystem>();
			MainModule main = obj.main;
			((MainModule)(ref main)).loop = false;
			((MainModule)(ref main)).playOnAwake = false;
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
			((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.5f, 1.5f);
			((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.2f, 0.6f);
			((MainModule)(ref main)).startSize = new MinMaxCurve(0.03f, 0.08f);
			((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(1f, 0.95f, 0.3f), new Color(1f, 0.55f, 0.05f));
			((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.05f);
			EmissionModule emission = obj.emission;
			((EmissionModule)(ref emission)).enabled = false;
			ShapeModule shape = obj.shape;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
			((ShapeModule)(ref shape)).radius = 0.015f;
			ParticleSystemRenderer component = val.GetComponent<ParticleSystemRenderer>();
			component.renderMode = (ParticleSystemRenderMode)0;
			((Renderer)component).material = BuildSparkMaterial();
			return val;
		}

		private Material BuildSparkMaterial()
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00c0: Expected O, but got Unknown
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: 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_02ee: Expected O, but got Unknown
			//IL_02ef: Expected O, but got Unknown
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Expected O, but got Unknown
			//IL_015b: Expected O, but got Unknown
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			Texture2D tex = BuildSparkTexture();
			Color color = default(Color);
			((Color)(ref color))..ctor(1f, 0.85f, 0.2f, 1f);
			ParticleSystemRenderer[] array = Resources.FindObjectsOfTypeAll<ParticleSystemRenderer>();
			foreach (ParticleSystemRenderer val in array)
			{
				if ((Object)(object)((Renderer)val).sharedMaterial == (Object)null)
				{
					continue;
				}
				string text = ((Object)((Component)val).gameObject).name.ToLower();
				if (text.Contains("sparkle") || text.Contains("star") || text.Contains("wand"))
				{
					ManualLogSource? log = _log;
					if (log != null)
					{
						log.LogInfo((object)("SparkMat: wand particle shader = " + ((Object)((Renderer)val).sharedMaterial.shader).name));
					}
					Material val2 = new Material(((Renderer)val).sharedMaterial);
					ApplySparkAppearance(val2, tex, color);
					return val2;
				}
			}
			array = Object.FindObjectsOfType<ParticleSystemRenderer>();
			foreach (ParticleSystemRenderer val3 in array)
			{
				Material sharedMaterial = ((Renderer)val3).sharedMaterial;
				if ((Object)(object)((sharedMaterial != null) ? sharedMaterial.shader : null) == (Object)null)
				{
					continue;
				}
				string name = ((Object)((Renderer)val3).sharedMaterial.shader).name;
				if (!name.Contains("Standard") || name.Contains("Particle"))
				{
					ManualLogSource? log2 = _log;
					if (log2 != null)
					{
						log2.LogInfo((object)("SparkMat: scene particle shader = " + name));
					}
					Material val4 = new Material(((Renderer)val3).sharedMaterial);
					ApplySparkAppearance(val4, tex, color);
					return val4;
				}
			}
			string[] array2 = new string[5] { "Universal Render Pipeline/Particles/Unlit", "Universal Render Pipeline/Particles/Lit", "Particles/Additive", "Particles/Alpha Blended Premultiply", "Legacy Shaders/Particles/Additive" };
			foreach (string text2 in array2)
			{
				Shader val5 = Shader.Find(text2);
				if (!((Object)(object)val5 == (Object)null))
				{
					ManualLogSource? log3 = _log;
					if (log3 != null)
					{
						log3.LogInfo((object)("SparkMat: named shader = " + text2));
					}
					Material val6 = new Material(val5);
					if (text2.Contains("Universal"))
					{
						val6.SetFloat("_Surface", 1f);
						val6.SetFloat("_Blend", 3f);
						val6.SetInt("_SrcBlend", 1);
						val6.SetInt("_DstBlend", 1);
						val6.SetInt("_ZWrite", 0);
						val6.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
						val6.EnableKeyword("_BLENDMODE_ADDITIVE");
						val6.renderQueue = 3000;
					}
					ApplySparkAppearance(val6, tex, color);
					return val6;
				}
			}
			ManualLogSource? log4 = _log;
			if (log4 != null)
			{
				log4.LogWarning((object)"SparkMat: falling back to Standard transparent.");
			}
			Material val7 = new Material(Shader.Find("Standard"));
			val7.SetFloat("_Mode", 3f);
			val7.SetInt("_SrcBlend", 5);
			val7.SetInt("_DstBlend", 10);
			val7.SetInt("_ZWrite", 0);
			val7.EnableKeyword("_ALPHABLEND_ON");
			val7.renderQueue = 3000;
			ApplySparkAppearance(val7, tex, color);
			return val7;
		}

		private static void ApplySparkAppearance(Material m, Texture2D tex, Color color)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			m.mainTexture = (Texture)(object)tex;
			m.color = color;
			try
			{
				m.SetTexture("_BaseMap", (Texture)(object)tex);
			}
			catch
			{
			}
			try
			{
				m.SetColor("_BaseColor", color);
			}
			catch
			{
			}
			try
			{
				m.SetColor("_EmissionColor", color * 0.5f);
			}
			catch
			{
			}
		}

		private static Texture2D BuildSparkTexture()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0075: 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)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			float num = 31.5f;
			float num2 = 31.5f;
			float num3 = 28.16f;
			float num4 = num3 * 0.4f;
			Vector2[] array = (Vector2[])(object)new Vector2[10];
			for (int i = 0; i < 10; i++)
			{
				float num5 = MathF.PI * (float)i / 5f - MathF.PI / 2f;
				float num6 = ((i % 2 == 0) ? num3 : num4);
				array[i] = new Vector2(num + num6 * Mathf.Cos(num5), num2 + num6 * Mathf.Sin(num5));
			}
			float num7 = num3 * 0.3f;
			Color[] array2 = (Color[])(object)new Color[4096];
			for (int j = 0; j < 64; j++)
			{
				for (int k = 0; k < 64; k++)
				{
					float num9;
					if (IsInsidePolygon(k, j, array))
					{
						float num8 = Mathf.Sqrt(((float)k - num) * ((float)k - num) + ((float)j - num2) * ((float)j - num2));
						num9 = Mathf.Lerp(1f, 0.8f, Mathf.Clamp01(num8 / num3));
					}
					else
					{
						float num10 = (float)k - num;
						float num11 = (float)j - num2;
						float num12 = Mathf.Sqrt(num10 * num10 + num11 * num11);
						float num13 = Mathf.Max(0f, num12 - num3) / num7;
						num9 = Mathf.Clamp01(1f - num13) * 0.45f;
						num9 *= num9;
					}
					array2[j * 64 + k] = new Color(1f, 1f, 1f, num9);
				}
			}
			val.SetPixels(array2);
			val.Apply();
			return val;
		}

		private static bool IsInsidePolygon(float px, float py, Vector2[] poly)
		{
			bool flag = false;
			int num = poly.Length;
			int num2 = 0;
			int num3 = num - 1;
			while (num2 < num)
			{
				float x = poly[num2].x;
				float y = poly[num2].y;
				float x2 = poly[num3].x;
				float y2 = poly[num3].y;
				if (y > py != y2 > py && px < (x2 - x) * (py - y) / (y2 - y) + x)
				{
					flag = !flag;
				}
				num3 = num2++;
			}
			return flag;
		}

		private static Transform? FindItemRoot(string keyword)
		{
			MeshFilter[] array = Object.FindObjectsOfType<MeshFilter>();
			foreach (MeshFilter val in array)
			{
				if ((Object)(object)val.sharedMesh == (Object)null)
				{
					continue;
				}
				Transform val2 = ((Component)val).transform;
				Transform val3 = null;
				while ((Object)(object)val2 != (Object)null)
				{
					if (((Object)val2).name.ToLower().Contains(keyword))
					{
						val3 = val2;
					}
					val2 = val2.parent;
				}
				if ((Object)(object)val3 != (Object)null)
				{
					return val3;
				}
			}
			return null;
		}

		private static Transform? FindGunRoot()
		{
			MeshFilter[] array = Object.FindObjectsOfType<MeshFilter>();
			foreach (MeshFilter val in array)
			{
				if (((Object)((Component)val).gameObject).name != "Laser gun")
				{
					continue;
				}
				Transform val2 = ((Component)val).transform;
				while ((Object)(object)val2 != (Object)null)
				{
					string text = ((Object)val2).name.ToLower();
					if (text.Contains("laser") || text.Contains("photon"))
					{
						return ((Component)val).transform.parent ?? ((Component)val).transform;
					}
					val2 = val2.parent;
				}
				return ((Component)val).transform.parent ?? ((Component)val).transform;
			}
			return null;
		}
	}
}