Decompiled source of MagicWandMod v1.0.0

plugins\MagicWandMod\MagicWandMod.dll

Decompiled 8 hours 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 HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using UnityEngine.Networking;

[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("MagicWandMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MagicWandMod")]
[assembly: AssemblyTitle("MagicWandMod")]
[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 MagicWandMod
{
	[HarmonyPatch]
	internal static class StatsManagerInitPatch
	{
		private static MethodBase? TargetMethod()
		{
			Type type = AccessTools.TypeByName("StatsManager");
			if (type == null)
			{
				return null;
			}
			string[] array = new string[5] { "Awake", "Start", "Initialize", "Init", "Setup" };
			foreach (string text in array)
			{
				MethodInfo methodInfo = AccessTools.Method(type, text, (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					return methodInfo;
				}
			}
			return null;
		}

		private static void Postfix()
		{
			if ((Object)(object)WandItemCreator.WandPrefab == (Object)null)
			{
				WandItemCreator.TryCreateAndRegister();
			}
			if (!WandItemCreator.RegisteredViaREPOLib)
			{
				InjectIntoStatsManager();
			}
		}

		private static void InjectIntoStatsManager()
		{
			if ((Object)(object)WandItemCreator.WandPrefab == (Object)null)
			{
				return;
			}
			ItemAttributes component = WandItemCreator.WandPrefab.GetComponent<ItemAttributes>();
			if ((Object)(object)component?.item == (Object)null)
			{
				return;
			}
			Type type = AccessTools.TypeByName("StatsManager");
			if (type == null)
			{
				return;
			}
			object obj = GetStaticPropOrField(type, "instance") ?? GetStaticPropOrField(type, "Instance");
			if (obj == null)
			{
				return;
			}
			string[] array = new string[6] { "itemDictionary", "items", "_items", "itemList", "allItems", "itemsMelee" };
			foreach (string text in array)
			{
				FieldInfo fieldInfo = AccessTools.Field(type, text);
				if (fieldInfo == null)
				{
					continue;
				}
				object value = fieldInfo.GetValue(obj);
				if (value == null)
				{
					continue;
				}
				MethodInfo method = value.GetType().GetMethod("Add");
				if (method == null)
				{
					continue;
				}
				try
				{
					ParameterInfo[] parameters = method.GetParameters();
					if (parameters.Length == 1)
					{
						method.Invoke(value, new object[1] { component.item });
					}
					else if (parameters.Length == 2)
					{
						method.Invoke(value, new object[2] { "Magic Wand", component.item });
					}
					Plugin.Log.LogInfo((object)("[MagicWand] Injected item into StatsManager." + text + "."));
					break;
				}
				catch
				{
				}
			}
		}

		private static object? GetStaticPropOrField(Type t, string name)
		{
			try
			{
				PropertyInfo property = t.GetProperty(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null)
				{
					return property.GetValue(null);
				}
			}
			catch
			{
			}
			try
			{
				FieldInfo field = t.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					return field.GetValue(null);
				}
			}
			catch
			{
			}
			return null;
		}
	}
	[HarmonyPatch]
	internal static class PrefabRefPatch
	{
		private static MethodBase? TargetMethod()
		{
			Type type = AccessTools.TypeByName("PrefabRef");
			if (type == null)
			{
				Plugin.Log.LogWarning((object)"[MagicWand] PrefabRef type not found — patch skipped.");
				return null;
			}
			MethodInfo methodInfo = AccessTools.PropertyGetter(type, "Prefab");
			if (methodInfo == null)
			{
				Plugin.Log.LogWarning((object)"[MagicWand] PrefabRef.get_Prefab not found.");
				return methodInfo;
			}
			Plugin.Log.LogInfo((object)"[MagicWand] PrefabRefPatch ready.");
			return methodInfo;
		}

		private static bool Prefix(object __instance, ref GameObject __result)
		{
			try
			{
				if (AccessTools.Field(__instance.GetType(), "prefabName")?.GetValue(__instance) is string text && WandItemCreator.CustomPrefabs.TryGetValue(text, out GameObject value))
				{
					Plugin.Log.LogInfo((object)("[MagicWand] PrefabRef intercepted (prefix): '" + text + "' → " + ((Object)value).name));
					__result = value;
					return false;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[MagicWand] PrefabRef prefix error: " + ex.Message));
			}
			return true;
		}

		private static void Postfix(object __instance, ref GameObject __result)
		{
			if ((Object)(object)__result != (Object)null)
			{
				return;
			}
			try
			{
				string text = AccessTools.Field(__instance.GetType(), "prefabName")?.GetValue(__instance) as string;
				if (text != null && WandItemCreator.CustomPrefabs.TryGetValue(text, out GameObject value))
				{
					Plugin.Log.LogInfo((object)("[MagicWand] PrefabRef fallback (postfix): '" + text + "' → " + ((Object)value).name));
					__result = value;
				}
				else if (text != null && text.Contains("Magic Wand"))
				{
					Plugin.Log.LogWarning((object)("[MagicWand] PrefabRef postfix: '" + text + "' not in CustomPrefabs " + $"(dict size={WandItemCreator.CustomPrefabs.Count})."));
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[MagicWand] PrefabRef postfix error: " + ex.Message));
			}
		}
	}
	[HarmonyPatch]
	internal static class MeleeAttackSparkPatch
	{
		private static MethodBase? TargetMethod()
		{
			string[] array = new string[13]
			{
				"MeleeTriggerRPC", "ActivateAttackHurtColliders", "EventMelee", "EventMeleeHit", "MeleeHitRPC", "MeleeSwingRPC", "SwingRPC", "ActivateMelee", "DoMeleeAttack", "MeleeAttack",
				"ItemMeleeRPC", "AttackRPC", "HitRPC"
			};
			foreach (string text in array)
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(ItemMelee), text, (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					Plugin.Log.LogInfo((object)("[MagicWand] MeleeAttackSparkPatch targeting: " + text));
					return methodInfo;
				}
			}
			Plugin.Log.LogWarning((object)"[MagicWand] MeleeAttackSparkPatch: no trigger method found — patch skipped.");
			return null;
		}

		private static void Postfix(ItemMelee __instance)
		{
			if ((Object)(object)((Component)__instance).GetComponent<WandHitDetector>() == (Object)null)
			{
				return;
			}
			ParticleSystem[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem obj in componentsInChildren)
			{
				if (obj != null)
				{
					obj.Emit(5);
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemMelee), "ActivateHitbox")]
	internal static class ItemMeleeActivateHitboxPatch
	{
		private static bool Prefix(ItemMelee __instance)
		{
			if (((Object)((Component)__instance).gameObject).name.StartsWith("Magic Wand"))
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal static class ItemMeleeSwingHitPatch
	{
		[CompilerGenerated]
		private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private MethodBase <>2__current;

			private int <>l__initialThreadId;

			private string[] <>7__wrap1;

			private int <>7__wrap2;

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

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

			[DebuggerHidden]
			public <TargetMethods>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

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

			private bool MoveNext()
			{
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_00dc;
				}
				<>1__state = -1;
				<>7__wrap1 = new string[10] { "SwingHit", "SwingHitRPC", "PlayerSwingHit", "EnemySwingHit", "EnemyOrPVPSwingHitRPC", "GroundHit", "MeleeBreak", "MeleeBreakRPC", "MeleeFix", "MeleeFixRPC" };
				<>7__wrap2 = 0;
				goto IL_00ea;
				IL_00dc:
				<>7__wrap2++;
				goto IL_00ea;
				IL_00ea:
				if (<>7__wrap2 < <>7__wrap1.Length)
				{
					string text = <>7__wrap1[<>7__wrap2];
					MethodInfo methodInfo = AccessTools.Method(typeof(ItemMelee), text, (Type[])null, (Type[])null);
					if (methodInfo != null)
					{
						Plugin.Log.LogInfo((object)("[MagicWand] SwingHitPatch: suppressing " + text + "."));
						<>2__current = methodInfo;
						<>1__state = 1;
						return true;
					}
					goto IL_00dc;
				}
				<>7__wrap1 = null;
				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();
			}

			[DebuggerHidden]
			IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <TargetMethods>d__0(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<MethodBase>)this).GetEnumerator();
			}
		}

		[IteratorStateMachine(typeof(<TargetMethods>d__0))]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TargetMethods>d__0(-2);
		}

		private static bool Prefix(ItemMelee __instance)
		{
			if (((Object)((Component)__instance).gameObject).name.StartsWith("Magic Wand"))
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(HurtCollider), "OnEnable")]
	internal static class HurtColliderOnEnablePatch
	{
		private static bool Prefix(HurtCollider __instance)
		{
			try
			{
				Transform val = ((Component)__instance).transform;
				while ((Object)(object)val != (Object)null && (Object)(object)val.parent != (Object)null)
				{
					val = val.parent;
				}
				if (val != null && ((Object)((Component)val).gameObject).name.StartsWith("Magic Wand"))
				{
					Collider component = ((Component)__instance).GetComponent<Collider>();
					if ((Object)(object)component != (Object)null)
					{
						component.enabled = false;
					}
					return false;
				}
			}
			catch
			{
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemMelee), "Update")]
	internal static class ItemMeleeUpdateGuard
	{
		private static Exception? Finalizer(ItemMelee __instance, Exception __exception)
		{
			if (__exception == null)
			{
				return null;
			}
			if ((Object)(object)__instance != (Object)null && ((Object)((Component)__instance).gameObject).name.StartsWith("Magic Wand"))
			{
				return null;
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(ItemMelee), "FixedUpdate")]
	internal static class ItemMeleeFixedUpdateGuard
	{
		private static Exception? Finalizer(ItemMelee __instance, Exception __exception)
		{
			if (__exception == null)
			{
				return null;
			}
			if ((Object)(object)__instance != (Object)null && ((Object)((Component)__instance).gameObject).name.StartsWith("Magic Wand"))
			{
				return null;
			}
			return __exception;
		}
	}
	public class PlayerColorEffect : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <RunEffect>d__4 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PlayerColorEffect <>4__this;

			public float duration;

			private PlayerAvatar <pa>5__2;

			private int <original>5__3;

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

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

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

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

			private bool MoveNext()
			{
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Expected O, but got Unknown
				int num = <>1__state;
				PlayerColorEffect playerColorEffect = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<pa>5__2 = ((Component)playerColorEffect).GetComponent<PlayerAvatar>();
					if ((Object)(object)<pa>5__2 == (Object)null)
					{
						return false;
					}
					<original>5__3 = GetColorIndex(<pa>5__2);
					int colorIndex = PickDifferentColorIndex(<original>5__3, 8);
					ApplyColorIndex(<pa>5__2, colorIndex);
					<>2__current = (object)new WaitForSeconds(duration);
					<>1__state = 1;
					return true;
				}
				case 1:
					<>1__state = -1;
					ApplyColorIndex(<pa>5__2, <original>5__3);
					playerColorEffect._routine = null;
					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();
			}
		}

		private Coroutine? _routine;

		private const int COLOR_PALETTE_SIZE = 8;

		public static void Apply(PlayerAvatar player, float duration)
		{
			(((Component)player).GetComponent<PlayerColorEffect>() ?? ((Component)player).gameObject.AddComponent<PlayerColorEffect>()).StartEffect(duration);
		}

		private void StartEffect(float duration)
		{
			if (_routine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_routine);
			}
			_routine = ((MonoBehaviour)this).StartCoroutine(RunEffect(duration));
		}

		[IteratorStateMachine(typeof(<RunEffect>d__4))]
		private IEnumerator RunEffect(float duration)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RunEffect>d__4(0)
			{
				<>4__this = this,
				duration = duration
			};
		}

		private static int GetColorIndex(PlayerAvatar pa)
		{
			string[] array = new string[6] { "colorIndex", "playerColorIndex", "currentColorIndex", "customColorIndex", "selectedColor", "playerColor" };
			foreach (string name in array)
			{
				FieldInfo field = GetField(typeof(PlayerAvatar), name);
				if (field == null)
				{
					continue;
				}
				try
				{
					object value = field.GetValue(pa);
					if (value is int)
					{
						return (int)value;
					}
				}
				catch
				{
				}
			}
			return 0;
		}

		private static int PickDifferentColorIndex(int current, int paletteSize)
		{
			int num = Random.Range(0, paletteSize - 1);
			if (num >= current)
			{
				num++;
			}
			return Mathf.Clamp(num, 0, paletteSize - 1);
		}

		private static void ApplyColorIndex(PlayerAvatar pa, int colorIndex)
		{
			bool flag = false;
			try
			{
				flag = PhotonNetwork.IsConnected;
			}
			catch
			{
			}
			if (flag)
			{
				try
				{
					PhotonView val = ((Component)pa).GetComponent<PhotonView>() ?? ((Component)pa).GetComponentInParent<PhotonView>();
					if ((Object)(object)val != (Object)null)
					{
						val.RPC("SetColorRPC", (RpcTarget)0, new object[1] { colorIndex });
						return;
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[MagicWand] Photon RPC failed: " + ex.Message));
				}
			}
			MethodInfo method = GetMethod(typeof(PlayerAvatar), "PlayerAvatarSetColor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method != null)
			{
				try
				{
					method.Invoke(pa, new object[1] { colorIndex });
					return;
				}
				catch (Exception ex2)
				{
					Plugin.Log.LogWarning((object)("[MagicWand] PlayerAvatarSetColor failed: " + ex2.Message));
				}
			}
			Plugin.Log.LogWarning((object)"[MagicWand] Could not apply color — no method worked.");
		}

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

		private static MethodInfo? GetMethod(Type type, string name, BindingFlags flags)
		{
			Type type2 = type;
			while (type2 != null)
			{
				MethodInfo method = type2.GetMethod(name, flags);
				if (method != null)
				{
					return method;
				}
				type2 = type2.BaseType;
			}
			return null;
		}
	}
	[BepInPlugin("com.smokebellew.magicwandmod", "MagicWandMod", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <RegistrationLoop>d__13 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private int <i>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<i>5__2++;
					break;
				}
				if (<i>5__2 < 30)
				{
					if (WandItemCreator.TryCreateAndRegister())
					{
						return false;
					}
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				}
				Log.LogWarning((object)"[MagicWand] Could not register Magic Wand after 30 attempts.");
				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();
			}
		}

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		public static string PluginDir { get; private set; }

		private void Awake()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			PluginDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			WandAssets.LoadFromDisk(PluginDir);
			((MonoBehaviour)this).StartCoroutine(WandAssets.LoadSoundsFromDisk(PluginDir));
			Harmony val = new Harmony("com.smokebellew.magicwandmod");
			Type[] types = typeof(Plugin).Assembly.GetTypes();
			foreach (Type type in types)
			{
				try
				{
					val.CreateClassProcessor(type).Patch();
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("[MagicWand] Patch skipped " + type.Name + ": " + ex.Message));
				}
			}
			((MonoBehaviour)this).StartCoroutine(RegistrationLoop());
			Log.LogInfo((object)"MagicWandMod loaded.");
		}

		[IteratorStateMachine(typeof(<RegistrationLoop>d__13))]
		private IEnumerator RegistrationLoop()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RegistrationLoop>d__13(0);
		}
	}
	internal static class WandAssets
	{
		[CompilerGenerated]
		private sealed class <LoadSoundsFromDisk>d__24 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string pluginDir;

			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__24(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
						{
							Plugin.Log.LogWarning((object)("[MagicWand] Could not load " + <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();
						Plugin.Log.LogInfo((object)$"[MagicWand] Loaded {<loaded>5__2.Count} sounds.");
					}
					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();
			}
		}

		private const int TEX_OFF = 0;

		private const int TEX_LEN = 38109;

		private const int VRT_OFF = 38112;

		private const int VRT_CNT = 306;

		private const int VRT_STRIDE = 48;

		private const int IDX_OFF = 52800;

		private const int IDX_CNT = 528;

		public static bool MeshReady { get; private set; }

		public static Mesh? WandMesh { get; private set; }

		public static Material? WandMaterial { get; private set; }

		public static AudioClip[]? Sounds { get; private set; }

		public static void LoadFromDisk(string pluginDir)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			string text = Path.Combine(pluginDir, "WandPrefab.glb");
			if (!File.Exists(text))
			{
				Plugin.Log.LogWarning((object)("[MagicWand] WandPrefab.glb not found at " + text + "."));
				return;
			}
			if (!TryParseGlb(File.ReadAllBytes(text), out Mesh mesh, out Texture2D tex))
			{
				Plugin.Log.LogError((object)"[MagicWand] Failed to parse WandPrefab.glb.");
				return;
			}
			Material val = new Material(Shader.Find("Unlit/Texture") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Standard"))
			{
				name = "Magic Wand"
			};
			val.mainTexture = (Texture)(object)tex;
			try
			{
				val.SetTexture("_BaseMap", (Texture)(object)tex);
			}
			catch
			{
			}
			try
			{
				val.SetInt("_Cull", 0);
			}
			catch
			{
			}
			WandMesh = mesh;
			WandMaterial = val;
			MeshReady = true;
			Plugin.Log.LogInfo((object)$"[MagicWand] Wand mesh loaded ({mesh.vertexCount} verts).");
		}

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

		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();
			}
		}

		private static bool TryParseGlb(byte[] d, out Mesh mesh, out Texture2D tex)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Expected O, but got Unknown
			mesh = null;
			tex = null;
			try
			{
				if (d.Length < 28 || BitConverter.ToUInt32(d, 0) != 1179937895)
				{
					Plugin.Log.LogError((object)"[MagicWand] Not a valid GLB.");
					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];
				Vector2[] array3 = (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 + 40);
					float num9 = BitConverter.ToSingle(d, num4 + 44);
					array3[i] = new Vector2(num8, 1f - num9);
				}
				int num10 = num2 + 52800;
				int[] array4 = new int[528];
				for (int j = 0; j < 528; j += 3)
				{
					array4[j] = BitConverter.ToUInt16(d, num10 + j * 2);
					array4[j + 1] = BitConverter.ToUInt16(d, num10 + (j + 2) * 2);
					array4[j + 2] = BitConverter.ToUInt16(d, num10 + (j + 1) * 2);
				}
				mesh = new Mesh
				{
					name = "Magic Wand Mesh"
				};
				mesh.vertices = array2;
				mesh.uv = array3;
				mesh.triangles = array4;
				mesh.RecalculateNormals();
				mesh.RecalculateBounds();
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[MagicWand] GLB parse error: " + ex.Message));
				return false;
			}
		}
	}
	public class WandHitDetector : MonoBehaviour
	{
		private ItemMelee? _melee;

		private AudioSource? _audio;

		private WandTipMarker? _tip;

		private ParticleSystem? _sparklePs;

		private HurtCollider[] _hurtColliders = Array.Empty<HurtCollider>();

		private Collider[] _hurtColliders_cols = Array.Empty<Collider>();

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

		private Renderer[] _foreignRenderers = Array.Empty<Renderer>();

		private SphereCollider? _hitSphere;

		private Vector3 _lastPos;

		private float _soundCooldown;

		private const float MOVE_THRESHOLD = 0.004f;

		private const float SOUND_MIN = 0.25f;

		private const float SOUND_RAND = 0.3f;

		private float _angularVelMag;

		private Rigidbody? _rb;

		private const float SWING_ANG_THRESHOLD = 2.5f;

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

		private void Start()
		{
			//IL_00a9: 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)
			_melee = ((Component)this).GetComponent<ItemMelee>();
			_audio = ((Component)this).GetComponent<AudioSource>();
			_rb = ((Component)this).GetComponent<Rigidbody>();
			_tip = ((Component)this).GetComponentInChildren<WandTipMarker>(true);
			if ((Object)(object)_tip != (Object)null)
			{
				_sparklePs = ((Component)_tip).GetComponent<ParticleSystem>();
			}
			if ((Object)(object)_tip != (Object)null)
			{
				_hitSphere = ((Component)_tip).gameObject.AddComponent<SphereCollider>();
				((Collider)_hitSphere).isTrigger = true;
				_hitSphere.radius = 0.12f;
				((Collider)_hitSphere).enabled = false;
			}
			CacheEffectsToSuppress();
			_lastPos = ((Component)this).transform.position;
			SuppressAllBatEffects();
		}

		private void CacheEffectsToSuppress()
		{
			_hurtColliders = ((Component)this).GetComponentsInChildren<HurtCollider>(true);
			_hurtColliders_cols = (Collider[])(object)new Collider[_hurtColliders.Length];
			for (int i = 0; i < _hurtColliders.Length; i++)
			{
				_hurtColliders_cols[i] = ((Component)_hurtColliders[i]).GetComponent<Collider>();
			}
			ParticleSystem[] componentsInChildren = ((Component)this).GetComponentsInChildren<ParticleSystem>(true);
			List<ParticleSystem> list = new List<ParticleSystem>();
			ParticleSystem[] array = componentsInChildren;
			foreach (ParticleSystem val in array)
			{
				if (!((Object)(object)_tip != (Object)null) || !((Component)val).transform.IsChildOf(((Component)_tip).transform))
				{
					list.Add(val);
				}
			}
			_foreignPs = list.ToArray();
			Renderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Renderer>(true);
			List<Renderer> list2 = new List<Renderer>();
			Renderer[] array2 = componentsInChildren2;
			foreach (Renderer val2 in array2)
			{
				if (!(((Object)((Component)val2).gameObject).name == "MagicWandMesh") && (!((Object)(object)_tip != (Object)null) || !((Component)val2).transform.IsChildOf(((Component)_tip).transform)))
				{
					list2.Add(val2);
				}
			}
			_foreignRenderers = list2.ToArray();
		}

		private void Update()
		{
			UpdateSwingDetection();
			UpdateSparkles();
			UpdateHitSphere();
		}

		private void LateUpdate()
		{
			SuppressAllBatEffects();
		}

		private void SuppressAllBatEffects()
		{
			for (int i = 0; i < _hurtColliders.Length; i++)
			{
				HurtCollider val = _hurtColliders[i];
				if (!((Object)(object)val == (Object)null))
				{
					if (((Behaviour)val).enabled)
					{
						((Behaviour)val).enabled = false;
					}
					Collider val2 = _hurtColliders_cols[i];
					if ((Object)(object)val2 != (Object)null && val2.enabled)
					{
						val2.enabled = false;
					}
				}
			}
			ParticleSystem[] foreignPs = _foreignPs;
			foreach (ParticleSystem val3 in foreignPs)
			{
				if (!((Object)(object)val3 == (Object)null) && (val3.isEmitting || val3.isPlaying))
				{
					val3.Stop(true, (ParticleSystemStopBehavior)0);
				}
			}
			Renderer[] foreignRenderers = _foreignRenderers;
			foreach (Renderer val4 in foreignRenderers)
			{
				if ((Object)(object)val4 != (Object)null && val4.enabled)
				{
					val4.enabled = false;
				}
			}
		}

		private void UpdateSwingDetection()
		{
			//IL_002e: 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_0015: 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)
			if ((Object)(object)_rb != (Object)null)
			{
				Vector3 angularVelocity = _rb.angularVelocity;
				_angularVelMag = ((Vector3)(ref angularVelocity)).magnitude;
			}
			else
			{
				float num = Vector3.Distance(((Component)this).transform.position, _lastPos);
				_angularVelMag = num / Time.deltaTime;
			}
		}

		private void UpdateHitSphere()
		{
			if (!((Object)(object)_hitSphere == (Object)null))
			{
				bool isMelee = GetIsMelee();
				((Collider)_hitSphere).enabled = isMelee;
				if (!isMelee)
				{
					_recentlyHit.Clear();
				}
			}
		}

		private void UpdateSparkles()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			float num = Vector3.Distance(((Component)this).transform.position, _lastPos);
			_lastPos = ((Component)this).transform.position;
			_soundCooldown -= Time.deltaTime;
			if (num < 0.004f)
			{
				return;
			}
			if ((Object)(object)_sparklePs != (Object)null)
			{
				_sparklePs.Emit(1);
			}
			if (!(_soundCooldown <= 0f))
			{
				return;
			}
			WandAssets.TryCacheSounds();
			AudioClip[] sounds = WandAssets.Sounds;
			if (sounds != null && sounds.Length != 0)
			{
				AudioClip val = sounds[Random.Range(0, sounds.Length)];
				if ((Object)(object)val != (Object)null && (Object)(object)_audio != (Object)null)
				{
					_audio.PlayOneShot(val, 0.15f);
				}
			}
			_soundCooldown = 0.25f + Random.Range(0f, 0.3f);
		}

		private void OnTriggerEnter(Collider other)
		{
			if (!GetIsMelee())
			{
				return;
			}
			PlayerAvatar componentInParent = ((Component)other).GetComponentInParent<PlayerAvatar>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)componentInParent).GetInstanceID();
			if (!_recentlyHit.Contains(instanceID))
			{
				_recentlyHit.Add(instanceID);
				if (!IsOwner(componentInParent))
				{
					Plugin.Log.LogInfo((object)("[MagicWand] Hit player " + ((Object)componentInParent).name + " — applying color effect."));
					PlayerColorEffect.Apply(componentInParent, 10f);
				}
			}
		}

		private bool GetIsMelee()
		{
			if ((Object)(object)_melee == (Object)null)
			{
				return false;
			}
			try
			{
				FieldInfo field = typeof(ItemMelee).GetField("isMelee", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					return (bool)field.GetValue(_melee);
				}
			}
			catch
			{
			}
			return _angularVelMag > 2.5f;
		}

		private bool IsOwner(PlayerAvatar candidate)
		{
			try
			{
				PhotonView val = ((Component)this).GetComponent<PhotonView>() ?? ((Component)this).GetComponentInParent<PhotonView>();
				if ((Object)(object)val != (Object)null && val.IsMine && (Object)(object)FindLocalPlayerAvatar() == (Object)(object)candidate)
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static PlayerAvatar? FindLocalPlayerAvatar()
		{
			try
			{
				PropertyInfo property = typeof(PlayerAvatar).GetProperty("local", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null)
				{
					object? value = property.GetValue(null);
					return (PlayerAvatar?)((value is PlayerAvatar) ? value : null);
				}
				FieldInfo field = typeof(PlayerAvatar).GetField("local", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					object? value2 = field.GetValue(null);
					return (PlayerAvatar?)((value2 is PlayerAvatar) ? value2 : null);
				}
			}
			catch
			{
			}
			return null;
		}
	}
	internal static class WandItemCreator
	{
		public static readonly Dictionary<string, GameObject> CustomPrefabs = new Dictionary<string, GameObject>();

		private static bool _registered;

		private static readonly string[] BaseWeaponHints = new string[9] { "sword", "stun baton", "baton", "inflatable hammer", "hammer", "frying pan", "frying", "baseball bat", "bat" };

		public static GameObject? WandPrefab { get; private set; }

		public static bool RegisteredViaREPOLib { get; private set; }

		public static bool TryCreateAndRegister()
		{
			if (_registered)
			{
				return true;
			}
			GameObject val = FindMeleeWeaponPrefab();
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[MagicWand] No ItemMelee prefab found yet — will retry later.");
				return false;
			}
			WandPrefab = BuildWandPrefab(val);
			Register(WandPrefab);
			_registered = true;
			Plugin.Log.LogInfo((object)"[MagicWand] Magic Wand registered successfully.");
			return true;
		}

		private static GameObject? FindMeleeWeaponPrefab()
		{
			ItemMelee[] array = Resources.FindObjectsOfTypeAll<ItemMelee>();
			string[] baseWeaponHints;
			if (array.Length != 0)
			{
				baseWeaponHints = BaseWeaponHints;
				foreach (string value in baseWeaponHints)
				{
					ItemMelee[] array2 = array;
					foreach (ItemMelee val in array2)
					{
						if (((Object)((Component)val).gameObject).name.ToLower().Contains(value))
						{
							return ((Component)val).gameObject;
						}
					}
				}
				return ((Component)array[0]).gameObject;
			}
			GameObject val2 = FindMeleeViaStatsManager();
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
			ItemAttributes[] array3 = Resources.FindObjectsOfTypeAll<ItemAttributes>();
			baseWeaponHints = BaseWeaponHints;
			ItemAttributes[] array4;
			foreach (string value2 in baseWeaponHints)
			{
				array4 = array3;
				foreach (ItemAttributes val3 in array4)
				{
					if (!((Object)(object)((Component)val3).GetComponent<ItemMelee>() == (Object)null) && ((Object)((Component)val3).gameObject).name.ToLower().Contains(value2))
					{
						return ((Component)val3).gameObject;
					}
				}
			}
			array4 = array3;
			foreach (ItemAttributes val4 in array4)
			{
				if ((Object)(object)((Component)val4).GetComponent<ItemMelee>() != (Object)null)
				{
					return ((Component)val4).gameObject;
				}
			}
			return null;
		}

		private static GameObject? FindMeleeViaStatsManager()
		{
			try
			{
				Type type = AccessTools.TypeByName("StatsManager");
				if (type == null)
				{
					return null;
				}
				object obj = GetStaticPropOrField(type, "instance") ?? GetStaticPropOrField(type, "Instance");
				if (obj == null)
				{
					return null;
				}
				FieldInfo fieldInfo = AccessTools.Field(type, "itemDictionary");
				if (fieldInfo == null)
				{
					return null;
				}
				object value = fieldInfo.GetValue(obj);
				if (value == null)
				{
					return null;
				}
				return TryFindMeleeInCollection(value);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[MagicWand] StatsManager search error: " + ex.Message));
			}
			return null;
		}

		private static GameObject? TryFindMeleeInCollection(object collection)
		{
			PropertyInfo property = collection.GetType().GetProperty("Values");
			if (!(((property != null) ? property.GetValue(collection) : collection) is IEnumerable enumerable))
			{
				return null;
			}
			List<GameObject> list = new List<GameObject>();
			foreach (object item in enumerable)
			{
				if (item != null)
				{
					GameObject val = ResolveItemPrefab(item);
					if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<ItemMelee>() != (Object)null)
					{
						list.Add(val);
					}
				}
			}
			string[] baseWeaponHints = BaseWeaponHints;
			foreach (string value in baseWeaponHints)
			{
				foreach (GameObject item2 in list)
				{
					if (((Object)item2).name.ToLower().Contains(value))
					{
						return item2;
					}
				}
			}
			if (list.Count > 0)
			{
				return list[0];
			}
			return null;
		}

		private static GameObject? ResolveItemPrefab(object item)
		{
			GameObject val = (GameObject)((item is GameObject) ? item : null);
			if (val != null)
			{
				return val;
			}
			Component val2 = (Component)((item is Component) ? item : null);
			if (val2 != null)
			{
				return val2.gameObject;
			}
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			Type type = item.GetType();
			while (type != null && type != typeof(object))
			{
				FieldInfo[] fields = type.GetFields(bindingAttr);
				foreach (FieldInfo fieldInfo in fields)
				{
					try
					{
						if (fieldInfo.FieldType == typeof(GameObject))
						{
							object? value = fieldInfo.GetValue(item);
							GameObject val3 = (GameObject)((value is GameObject) ? value : null);
							if (val3 != null)
							{
								return val3;
							}
						}
						else
						{
							if (fieldInfo.FieldType.IsPrimitive || fieldInfo.FieldType.IsEnum || !(fieldInfo.FieldType != typeof(string)) || !fieldInfo.FieldType.IsClass)
							{
								continue;
							}
							object value2 = fieldInfo.GetValue(item);
							if (value2 == null)
							{
								continue;
							}
							FieldInfo[] fields2 = fieldInfo.FieldType.GetFields(bindingAttr);
							foreach (FieldInfo fieldInfo2 in fields2)
							{
								if (fieldInfo2.FieldType == typeof(GameObject))
								{
									object? value3 = fieldInfo2.GetValue(value2);
									GameObject val4 = (GameObject)((value3 is GameObject) ? value3 : null);
									if (val4 != null)
									{
										return val4;
									}
								}
							}
							PropertyInfo[] properties = fieldInfo.FieldType.GetProperties(bindingAttr);
							foreach (PropertyInfo propertyInfo in properties)
							{
								if (!(propertyInfo.PropertyType == typeof(GameObject)))
								{
									continue;
								}
								try
								{
									object? value4 = propertyInfo.GetValue(value2);
									GameObject val5 = (GameObject)((value4 is GameObject) ? value4 : null);
									if (val5 != null)
									{
										return val5;
									}
								}
								catch
								{
								}
							}
							continue;
						}
					}
					catch
					{
					}
				}
				type = type.BaseType;
			}
			return null;
		}

		private static GameObject BuildWandPrefab(GameObject baseGO)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(baseGO);
			((Object)val).name = "Magic Wand";
			GameObject val2 = new GameObject("MagicWandPrefabHolder");
			Object.DontDestroyOnLoad((Object)(object)val2);
			val2.SetActive(false);
			val.transform.SetParent(val2.transform, false);
			Item val3 = CreateItemScriptableObject("Magic Wand", val, baseGO);
			ItemAttributes component = val.GetComponent<ItemAttributes>();
			if ((Object)(object)component != (Object)null && (Object)(object)val3 != (Object)null)
			{
				component.item = val3;
				FieldInfo field = GetField(((object)val3).GetType(), "itemName");
				if (string.IsNullOrEmpty(field?.GetValue(val3) as string))
				{
					field?.SetValue(val3, "Magic Wand");
				}
			}
			ItemMelee component2 = val.GetComponent<ItemMelee>();
			if ((Object)(object)component2 != (Object)null)
			{
				ZeroEnemyDamage(component2);
			}
			RemoveSpecialEffects(val);
			WandVisuals.Apply(val);
			val.AddComponent<WandHitDetector>();
			CustomPrefabs[((Object)val).name] = val;
			Plugin.Log.LogInfo((object)("[MagicWand] Prefab built from base '" + ((Object)baseGO).name + "'."));
			return val;
		}

		private static Item? CreateItemScriptableObject(string displayName, GameObject wandPrefab, GameObject baseGO)
		{
			try
			{
				Item val = baseGO.GetComponent<ItemAttributes>()?.item;
				Item val2;
				if ((Object)(object)val != (Object)null)
				{
					val2 = Object.Instantiate<Item>(val);
					((Object)val2).name = displayName;
				}
				else
				{
					val2 = ScriptableObject.CreateInstance<Item>();
				}
				SetFieldFuzzy(val2, displayName, "itemName", "_itemName", "displayName");
				UpdatePrefabRef(val2, wandPrefab);
				return val2;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[MagicWand] Could not create Item SO: " + ex.Message));
				return null;
			}
		}

		private static void UpdatePrefabRef(Item item, GameObject wandPrefab)
		{
			FieldInfo field = GetField(((object)item).GetType(), "prefab");
			if (field == null)
			{
				return;
			}
			object value = field.GetValue(item);
			if (value == null)
			{
				return;
			}
			string name = ((Object)wandPrefab).name;
			FieldInfo[] fields = value.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (!(fieldInfo.FieldType != typeof(string)) && (fieldInfo.Name == "prefabName" || fieldInfo.Name == "resourcePath"))
				{
					fieldInfo.SetValue(value, name);
				}
			}
		}

		private static void ZeroEnemyDamage(ItemMelee melee)
		{
			string[] array = new string[4] { "enemyDamage", "_damage", "damage", "meleeDamage" };
			foreach (string name in array)
			{
				FieldInfo field = GetField(((object)melee).GetType(), name);
				if (field == null)
				{
					continue;
				}
				try
				{
					if (field.FieldType == typeof(int))
					{
						field.SetValue(melee, 0);
					}
					else if (field.FieldType == typeof(float))
					{
						field.SetValue(melee, 0f);
					}
				}
				catch
				{
				}
			}
		}

		private static void RemoveSpecialEffects(GameObject go)
		{
			ItemBattery[] componentsInChildren = go.GetComponentsInChildren<ItemBattery>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			HurtCollider[] componentsInChildren2 = go.GetComponentsInChildren<HurtCollider>(true);
			foreach (HurtCollider obj in componentsInChildren2)
			{
				((Behaviour)obj).enabled = false;
				Collider component = ((Component)obj).GetComponent<Collider>();
				if ((Object)(object)component != (Object)null)
				{
					component.enabled = false;
				}
			}
			MonoBehaviour[] componentsInChildren3 = go.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren3)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string name = ((object)val).GetType().Name;
				switch (name)
				{
				case "ItemMelee":
				case "ItemAttributes":
				case "ItemEquippable":
				case "WandHitDetector":
				case "WandTipMarker":
					continue;
				}
				if (!name.StartsWith("Phys") && !name.StartsWith("Audio") && !(name == "HurtCollider") && (name.Contains("Stun") || name.Contains("Effect") || name.Contains("Smoke") || name.Contains("Trail") || name.Contains("Debris") || name.Contains("Special") || name.Contains("Hurt")))
				{
					try
					{
						((Behaviour)val).enabled = false;
					}
					catch
					{
					}
				}
			}
		}

		private static void Register(GameObject wandGO)
		{
			if (!TryRegisterViaREPOLib(wandGO))
			{
				Plugin.Log.LogInfo((object)"[MagicWand] REPOLib unavailable — injecting directly into StatsManager.");
				TryInjectDirectly(wandGO);
			}
		}

		private static bool TryRegisterViaREPOLib(GameObject wandGO)
		{
			try
			{
				Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "REPOLib");
				if (assembly == null)
				{
					return false;
				}
				Type type = assembly.GetType("REPOLib.Modules.Items") ?? assembly.GetType("REPOLib.API.Items");
				if (type == null)
				{
					return false;
				}
				MethodInfo method = type.GetMethod("RegisterItem", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(ItemAttributes) }, null);
				if (method == null)
				{
					return false;
				}
				ItemAttributes component = wandGO.GetComponent<ItemAttributes>();
				if ((Object)(object)component == (Object)null)
				{
					return false;
				}
				method.Invoke(null, new object[1] { component });
				Plugin.Log.LogInfo((object)"[MagicWand] Registered via REPOLib.");
				RegisteredViaREPOLib = true;
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[MagicWand] REPOLib registration failed: " + ex.Message));
				return false;
			}
		}

		private static void TryInjectDirectly(GameObject wandGO)
		{
			try
			{
				Type type = typeof(ItemAttributes).Assembly.GetType("StatsManager");
				if (type == null)
				{
					Plugin.Log.LogWarning((object)"[MagicWand] StatsManager type not found.");
					return;
				}
				object obj = GetStaticPropOrField(type, "instance") ?? GetStaticPropOrField(type, "Instance");
				if (obj == null)
				{
					Plugin.Log.LogWarning((object)"[MagicWand] StatsManager instance not available yet.");
					return;
				}
				ItemAttributes component = wandGO.GetComponent<ItemAttributes>();
				if ((Object)(object)component?.item == (Object)null)
				{
					return;
				}
				string[] array = new string[5] { "itemDictionary", "items", "_items", "itemList", "allItems" };
				foreach (string text in array)
				{
					FieldInfo field = GetField(type, text);
					if (field == null)
					{
						continue;
					}
					object value = field.GetValue(obj);
					if (value == null)
					{
						continue;
					}
					MethodInfo method = value.GetType().GetMethod("Add");
					if (!(method == null))
					{
						ParameterInfo[] parameters = method.GetParameters();
						if (parameters.Length == 1)
						{
							method.Invoke(value, new object[1] { component.item });
							Plugin.Log.LogInfo((object)("[MagicWand] Injected into StatsManager." + text + "."));
							return;
						}
						if (parameters.Length == 2)
						{
							method.Invoke(value, new object[2] { "Magic Wand", component.item });
							Plugin.Log.LogInfo((object)("[MagicWand] Injected into StatsManager." + text + " (keyed)."));
							return;
						}
					}
				}
				Plugin.Log.LogWarning((object)"[MagicWand] Could not find item collection in StatsManager.");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[MagicWand] Direct injection failed: " + ex.Message));
			}
		}

		private static void SetFieldFuzzy(object target, object value, params string[] candidates)
		{
			foreach (string name in candidates)
			{
				FieldInfo field = GetField(target.GetType(), name);
				if (!(field == null))
				{
					try
					{
						field.SetValue(target, value);
						break;
					}
					catch
					{
					}
				}
			}
		}

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

		private static object? GetStaticPropOrField(Type type, string name)
		{
			PropertyInfo property = type.GetProperty(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null)
			{
				try
				{
					return property.GetValue(null);
				}
				catch
				{
				}
			}
			FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				try
				{
					return field.GetValue(null);
				}
				catch
				{
				}
			}
			return null;
		}
	}
	internal static class EnumerableHelper
	{
		public static T? FirstOrDefault<T>(this T[] arr, Func<T, bool> pred) where T : class
		{
			foreach (T val in arr)
			{
				if (pred(val))
				{
					return val;
				}
			}
			return null;
		}
	}
	internal static class WandVisuals
	{
		private static readonly Vector3 MeshRelPos = new Vector3(0f, -0.251f, 0f);

		private static readonly Quaternion MeshRelRot = Quaternion.identity;

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

		private static readonly Vector3 TipRelPos = new Vector3(0f, 0.538f, 0f);

		private static readonly Quaternion TipRelRot = Quaternion.identity;

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

		public static void Apply(GameObject wandGO)
		{
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: 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_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: 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_024c: 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_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: 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_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: 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_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Expected O, but got Unknown
			MeshRenderer[] componentsInChildren = wandGO.GetComponentsInChildren<MeshRenderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Renderer)componentsInChildren[i]).enabled = false;
			}
			SkinnedMeshRenderer[] componentsInChildren2 = wandGO.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				((Renderer)componentsInChildren2[i]).enabled = false;
			}
			TrailRenderer[] componentsInChildren3 = wandGO.GetComponentsInChildren<TrailRenderer>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				((Renderer)componentsInChildren3[i]).enabled = false;
			}
			LineRenderer[] componentsInChildren4 = wandGO.GetComponentsInChildren<LineRenderer>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				((Renderer)componentsInChildren4[i]).enabled = false;
			}
			ParticleSystem[] componentsInChildren5 = wandGO.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val in componentsInChildren5)
			{
				val.Stop(true, (ParticleSystemStopBehavior)0);
				if ((Object)(object)((Component)val).gameObject != (Object)(object)wandGO)
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
			Transform[] componentsInChildren6 = wandGO.GetComponentsInChildren<Transform>(true);
			foreach (Transform val2 in componentsInChildren6)
			{
				if (!((Object)(object)val2 == (Object)(object)wandGO.transform))
				{
					string text = ((Object)((Component)val2).gameObject).name.ToLower();
					if (text.Contains("effect") || text.Contains("smoke") || text.Contains("vfx") || text.Contains("debris") || text.Contains("trail") || text.Contains("spark") || text.Contains("glow") || text.Contains("hit") || text.Contains("impact") || text.Contains("particle"))
					{
						((Component)val2).gameObject.SetActive(false);
					}
				}
			}
			if (!WandAssets.MeshReady)
			{
				Plugin.Log.LogWarning((object)"[MagicWand] Wand mesh not loaded — using original weapon model.");
				return;
			}
			GameObject val3 = new GameObject("MagicWandMesh");
			val3.transform.SetParent(wandGO.transform, false);
			val3.transform.localPosition = MeshRelPos;
			val3.transform.localRotation = MeshRelRot;
			Vector3 lossyScale = wandGO.transform.lossyScale;
			Vector3 meshScale = MeshScale;
			val3.transform.localScale = new Vector3((lossyScale.x > 0f) ? (meshScale.x / lossyScale.x) : meshScale.x, (lossyScale.y > 0f) ? (meshScale.y / lossyScale.y) : meshScale.y, (lossyScale.z > 0f) ? (meshScale.z / lossyScale.z) : meshScale.z);
			val3.AddComponent<MeshFilter>().sharedMesh = WandAssets.WandMesh;
			((Renderer)val3.AddComponent<MeshRenderer>()).sharedMaterial = WandAssets.WandMaterial;
			GameObject val4 = new GameObject("MagicWandTip");
			val4.transform.SetParent(wandGO.transform, false);
			val4.transform.localPosition = TipRelPos;
			val4.transform.localRotation = TipRelRot;
			val4.transform.localScale = TipScale;
			val4.AddComponent<WandTipMarker>();
			BuildProceduralSparkles(val4);
			AudioSource obj = wandGO.GetComponent<AudioSource>() ?? wandGO.AddComponent<AudioSource>();
			obj.spatialBlend = 1f;
			obj.rolloffMode = (AudioRolloffMode)1;
			obj.maxDistance = 10f;
		}

		private static void BuildProceduralSparkles(GameObject parent)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_005d: 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_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_00a2: 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_00b2: 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)
			ParticleSystem obj = parent.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.4f, 1.2f);
			((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.15f, 0.5f);
			((MainModule)(ref main)).startSize = new MinMaxCurve(0.02f, 0.07f);
			((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(1f, 0.95f, 0.3f), new Color(0.9f, 0.5f, 1f));
			((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.03f);
			EmissionModule emission = obj.emission;
			((EmissionModule)(ref emission)).enabled = false;
			ShapeModule shape = obj.shape;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
			((ShapeModule)(ref shape)).radius = 0.01f;
			ParticleSystemRenderer component = parent.GetComponent<ParticleSystemRenderer>();
			component.renderMode = (ParticleSystemRenderMode)0;
			((Renderer)component).material = BuildSparkMaterial();
		}

		private static Material BuildSparkMaterial()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_00ad: 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_00c8: 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_00da: 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)
			//IL_00f5: Expected O, but got Unknown
			Texture2D mainTexture = BuildGlowTexture();
			Shader val = Shader.Find("Particles/Additive") ?? Shader.Find("Legacy Shaders/Particles/Additive") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Transparent");
			if (!((Object)(object)val != (Object)null))
			{
				Material val2 = new Material(Shader.Find("Standard") ?? Shader.Find("Diffuse"));
				val2.SetInt("_SrcBlend", 5);
				val2.SetInt("_DstBlend", 1);
				val2.SetInt("_ZWrite", 0);
				val2.SetFloat("_Mode", 1f);
				val2.EnableKeyword("_ALPHAPREMULTIPLY_ON");
				val2.renderQueue = 3000;
				val2.mainTexture = (Texture)(object)mainTexture;
				val2.color = new Color(1f, 0.92f, 0.3f);
				return val2;
			}
			return new Material(val)
			{
				mainTexture = (Texture)(object)mainTexture,
				color = new Color(1f, 0.92f, 0.3f)
			};
		}

		private static Texture2D BuildGlowTexture()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false);
			float num = 15.5f;
			float num2 = 15.5f;
			float num3 = num;
			Color[] array = (Color[])(object)new Color[1024];
			for (int i = 0; i < 32; i++)
			{
				for (int j = 0; j < 32; j++)
				{
					float num4 = (float)j - num;
					float num5 = (float)i - num2;
					float num6 = Mathf.Clamp01(Mathf.Sqrt(num4 * num4 + num5 * num5) / num3);
					float num7 = (1f - num6) * (1f - num6);
					array[i * 32 + j] = new Color(1f, 1f, 1f, num7);
				}
			}
			val.SetPixels(array);
			val.Apply();
			return val;
		}
	}
	public class WandTipMarker : MonoBehaviour
	{
	}
}