Decompiled source of Mjolnir v1.15.7

BepInEx/plugins/Mjolnir/Mjolnir.dll

Decompiled 16 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MyceliumNetworking;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
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: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FedMjolnir
{
	public enum UltBinding
	{
		Mouse5,
		Mouse4,
		MiddleMouse,
		Q,
		E,
		R,
		F,
		G,
		T,
		V,
		C,
		X,
		Z,
		B,
		LeftShift,
		LeftCtrl,
		LeftAlt,
		Space
	}
	[BepInPlugin("fed.straftat.mjolnir", "Mjolnir", "1.15.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class MjolnirPlugin : BaseUnityPlugin
	{
		[HarmonyPatch]
		private static class MjolnirOffhandPickupGuard
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				Type type = AccessTools.TypeByName("PlayerPickup");
				if (type == null)
				{
					return Enumerable.Empty<MethodBase>();
				}
				return (from m in type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
					where m.Name == "LeftHandPickup"
					select m).Cast<MethodBase>();
			}

			[HarmonyPrefix]
			private static bool Prefix()
			{
				if (!((Object)(object)Instance == (Object)null))
				{
					return !Instance.IsHoldingMjolnir();
				}
				return true;
			}
		}

		[HarmonyPatch]
		private static class MyceliumSteamStartupGuard
		{
			private static MethodBase TargetMethod()
			{
				Type type = AccessTools.TypeByName("MyceliumNetworking.PersistentGameObject");
				if (!(type != null))
				{
					return null;
				}
				return AccessTools.Method(type, "Update", (Type[])null, (Type[])null);
			}

			[HarmonyPrefix]
			private static bool Prefix()
			{
				return IsSteamClientReady();
			}
		}

		[HarmonyPatch(typeof(SpawnerManager), "PopulateAllWeapons")]
		private static class RegisterPatch
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				Instance?.TryBuildWeapon();
			}
		}

		[HarmonyPatch(typeof(SpawnerManager), "GetRandomSpawnableWeapon")]
		private static class RandomWeaponPickerPatch
		{
			[HarmonyPostfix]
			private static void Postfix(ref GameObject __result)
			{
				MjolnirPlugin instance = Instance;
				if (!((Object)(object)instance == (Object)null) && instance.ShouldSubstituteMjolnir())
				{
					GameObject mjolnirPrefab = instance.GetMjolnirPrefab();
					if ((Object)(object)mjolnirPrefab != (Object)null)
					{
						__result = mjolnirPrefab;
					}
				}
			}
		}

		[HarmonyPatch(typeof(WeaponRandomizationMenu), "PopulateMenu")]
		private static class WeaponMenuPatch
		{
			[HarmonyPostfix]
			private static void Postfix(WeaponRandomizationMenu __instance)
			{
				Instance?.TryAddMjolnirMenuRow(__instance);
			}
		}

		internal static MjolnirPlugin Instance;

		internal const uint MOD_ID = 2817742601u;

		internal const string WeaponName = "Mjolnir";

		internal const BindingFlags BF = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private Harmony _harmony;

		private GameObject _prefab;

		private bool _building;

		private bool _fishnetRegistered;

		private bool _myceliumRegistered;

		private AudioClip _swing;

		private AudioClip _smash;

		private AudioClip _thunder;

		private AudioClip _flight;

		private AudioClip _hum;

		private ConfigEntry<float> _smashRadius;

		private ConfigEntry<float> _smashDamage;

		private ConfigEntry<float> _smashKnockback;

		private ConfigEntry<float> _smashCooldown;

		private ConfigEntry<float> _flightForce;

		private ConfigEntry<float> _flightCooldown;

		private ConfigEntry<float> _ultRadius;

		private ConfigEntry<float> _ultDamage;

		private ConfigEntry<float> _ultKnockback;

		private ConfigEntry<float> _ultCooldown;

		private ConfigEntry<UltBinding> _ultBinding;

		private ConfigEntry<bool> _friendlySelfKnockback;

		private ConfigEntry<bool> _f8TestSpawn;

		internal ConfigEntry<bool> SpawnEnabled;

		internal ConfigEntry<float> SpawnWeight;

		private GameObject _customMenuRow;

		private readonly Dictionary<ulong, float> _nextSmash = new Dictionary<ulong, float>();

		private readonly Dictionary<ulong, float> _nextFlight = new Dictionary<ulong, float>();

		private readonly Dictionary<ulong, float> _nextUlt = new Dictionary<ulong, float>();

		private float _localNextFlightInput;

		private float _localNextUltInput;

		private float _netSmashRadius = 4.5f;

		private float _netSmashDamage = 2.75f;

		private float _netSmashKnockback = 125f;

		private float _netSmashCooldown = 2.2f;

		private float _netFlightForce = 65f;

		private float _netFlightCooldown = 1f;

		private float _netUltRadius = 8.5f;

		private float _netUltDamage = 3.5f;

		private float _netUltKnockback = 165f;

		private float _netUltCooldown = 30f;

		private bool _lastHostState;

		private float _nextSettingsBroadcast;

		private int _lastSettingsHash = int.MinValue;

		private float _nextLocalRefresh;

		internal float NativeRandomizerTotalWeight = 100f;

		internal bool GlobalRandomizerEnabled = true;

		private float _nextGlobalRandomizerRead;

		private float _nextOffhandEnforce;

		private readonly Dictionary<ulong, PlayerHealth> _playerHealthCache = new Dictionary<ulong, PlayerHealth>();

		private float _nextPlayerHealthCacheRefresh;

		private ulong _localSteamId;

		private FirstPersonController _localFpc;

		private GameObject _localHeld;

		private Camera _localCamera;

		private float _rememberedNormalFov = -1f;

		private bool _presetHooksInstalled;

		private void Awake()
		{
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Expected O, but got Unknown
			Instance = this;
			_smashRadius = ((BaseUnityPlugin)this).Config.Bind<float>("01 - Smash", "Radius", 4.5f, "HOST ONLY. AoE radius.");
			_smashDamage = ((BaseUnityPlugin)this).Config.Bind<float>("01 - Smash", "CenterDamage", 2.75f, "HOST ONLY. Damage at the center. Direct hammer/head impact adds a small bonus.");
			_smashKnockback = ((BaseUnityPlugin)this).Config.Bind<float>("01 - Smash", "Knockback", 125f, "HOST ONLY. Radial player knockback.");
			_smashCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("01 - Smash", "CooldownSeconds", 2.2f, "HOST ONLY.");
			_flightForce = ((BaseUnityPlugin)this).Config.Bind<float>("02 - Flight", "LaunchForce", 65f, "HOST ONLY. Upward launch strength.");
			_flightCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("02 - Flight", "CooldownSeconds", 1f, "HOST ONLY.");
			_friendlySelfKnockback = ((BaseUnityPlugin)this).Config.Bind<bool>("02 - Flight", "SmashBoostsHolder", true, "Deprecated compatibility option. Mjolnir never damages or launches its holder.");
			_ultRadius = ((BaseUnityPlugin)this).Config.Bind<float>("04 - ULT", "Radius", 8.5f, "HOST ONLY. M5 lightning-storm radius.");
			_ultDamage = ((BaseUnityPlugin)this).Config.Bind<float>("04 - ULT", "CenterDamage", 3.5f, "HOST ONLY. ULT center damage.");
			_ultKnockback = ((BaseUnityPlugin)this).Config.Bind<float>("04 - ULT", "Knockback", 165f, "HOST ONLY. ULT radial knockback.");
			_ultCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("04 - ULT", "CooldownSeconds", 30f, "HOST ONLY.");
			_ultBinding = ((BaseUnityPlugin)this).Config.Bind<UltBinding>("00 - Client Controls", "ULT Binding", UltBinding.Mouse5, "CLIENT SIDE ONLY. Choose the button/key used for Mjolnir's ULT. Each player can use a different binding.");
			_f8TestSpawn = ((BaseUnityPlugin)this).Config.Bind<bool>("99 - Testing", "HostF8SpawnsMjolnir", true, "HOST ONLY. F8 spawns Mjolnir in front of the host for testing.");
			SpawnEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("03 - Weapon Selection", "EnabledInRandomPool", true, "Internal fallback; default Weapon Customization row is user-facing.");
			SpawnWeight = ((BaseUnityPlugin)this).Config.Bind<float>("03 - Weapon Selection", "SpawnWeight", 100f, "Backing value for Mjolnir's normal Weapon Customization weight (0-100).");
			LoadRuntimeSettingsFromLocalConfig();
			HideGameplayConfigFromSettingsMenu();
			string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? Paths.PluginPath, "assets");
			_swing = WavLoader.Load(Path.Combine(path, "mjolnir_swing.wav"));
			_smash = WavLoader.Load(Path.Combine(path, "mjolnir_smash.wav"));
			_thunder = WavLoader.Load(Path.Combine(path, "mjolnir_thunder.wav"));
			_flight = WavLoader.Load(Path.Combine(path, "mjolnir_flight.wav"));
			_hum = WavLoader.Load(Path.Combine(path, "mjolnir_hum.wav"));
			_harmony = new Harmony("fed.straftat.mjolnir");
			_harmony.PatchAll();
			SceneManager.sceneLoaded += OnSceneLoadedResetCooldowns;
			((MonoBehaviour)this).StartCoroutine(RegisterMycelium());
			((MonoBehaviour)this).StartCoroutine(WaitForWeaponTable());
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Mjolnir 1.15.4 loaded. Client-side configurable ULT binding active.");
		}

		private void OnDestroy()
		{
			try
			{
				SceneManager.sceneLoaded -= OnSceneLoadedResetCooldowns;
			}
			catch
			{
			}
			try
			{
				Harmony harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch
			{
			}
			try
			{
				if (_myceliumRegistered)
				{
					MyceliumNetwork.DeregisterNetworkObject((object)this, 2817742601u, 0);
				}
			}
			catch
			{
			}
			if ((Object)(object)_prefab != (Object)null)
			{
				Object.Destroy((Object)(object)_prefab);
			}
			if (Instance == this)
			{
				Instance = null;
			}
		}

		internal static bool IsSteamClientReady()
		{
			try
			{
				Type type = FindType("SteamManager");
				if (type != null && GetStatic(type, "Initialized", "initialized", "IsInitialized", "isInitialized") is bool result)
				{
					return result;
				}
				MethodInfo methodInfo = FindType("Steamworks.SteamUser")?.GetMethod("GetSteamID", BindingFlags.Static | BindingFlags.Public);
				if (methodInfo == null)
				{
					return false;
				}
				object obj = methodInfo.Invoke(null, null);
				if (obj == null)
				{
					return false;
				}
				object member = GetMember(obj, "m_SteamID", "Value", "value");
				if (member != null && ulong.TryParse(Convert.ToString(member), out var result2))
				{
					return result2 != 0;
				}
				ulong result3;
				return ulong.TryParse(Convert.ToString(obj), out result3) && result3 != 0;
			}
			catch
			{
				return false;
			}
		}

		private IEnumerator RegisterMycelium()
		{
			for (int i = 0; i < 120; i++)
			{
				if (IsSteamClientReady())
				{
					break;
				}
				yield return (object)new WaitForSecondsRealtime(0.1f);
			}
			if (!IsSteamClientReady())
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Steamworks was not ready after 12 seconds; Mjolnir networking will keep retrying safely.");
			}
			for (int i = 0; i < 160; i++)
			{
				if (_myceliumRegistered)
				{
					break;
				}
				if (!IsSteamClientReady())
				{
					yield return (object)new WaitForSecondsRealtime(0.1f);
					continue;
				}
				try
				{
					MyceliumNetwork.RegisterNetworkObject((object)this, 2817742601u, 0);
					_myceliumRegistered = true;
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Mjolnir Mycelium networking registered after Steamworks became ready.");
				}
				catch (Exception ex)
				{
					if (i == 0 || i % 25 == 0)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)("Mjolnir waiting for Mycelium/Steam readiness: " + ex.Message));
					}
				}
				if (!_myceliumRegistered)
				{
					yield return (object)new WaitForSecondsRealtime(0.15f);
				}
			}
		}

		private void HideGameplayConfigFromSettingsMenu()
		{
			object[] array = new object[14]
			{
				_smashRadius, _smashDamage, _smashKnockback, _smashCooldown, _flightForce, _flightCooldown, _friendlySelfKnockback, _ultRadius, _ultDamage, _ultKnockback,
				_ultCooldown, _f8TestSpawn, SpawnEnabled, SpawnWeight
			};
			foreach (object obj in array)
			{
				if (obj == null)
				{
					continue;
				}
				try
				{
					object obj2 = obj.GetType().GetProperty("Description", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj);
					if (obj2 == null)
					{
						continue;
					}
					Type type = Type.GetType("System.ComponentModel.BrowsableAttribute, System");
					if (!(type == null))
					{
						object obj3 = Activator.CreateInstance(type, new object[1] { false });
						PropertyInfo property = obj2.GetType().GetProperty("Tags", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
						if (property != null && property.CanWrite)
						{
							object[] first = (property.GetValue(obj2) as object[]) ?? Array.Empty<object>();
							property.SetValue(obj2, first.Concat(new object[1] { obj3 }).ToArray());
						}
					}
				}
				catch
				{
				}
			}
		}

		private void LoadRuntimeSettingsFromLocalConfig()
		{
			_netSmashRadius = _smashRadius.Value;
			_netSmashDamage = _smashDamage.Value;
			_netSmashKnockback = _smashKnockback.Value;
			_netSmashCooldown = _smashCooldown.Value;
			_netFlightForce = _flightForce.Value;
			_netFlightCooldown = _flightCooldown.Value;
			_netUltRadius = _ultRadius.Value;
			_netUltDamage = _ultDamage.Value;
			_netUltKnockback = _ultKnockback.Value;
			_netUltCooldown = _ultCooldown.Value;
		}

		private void UpdateHostSettingsSync()
		{
			bool flag = IsHost();
			if (flag)
			{
				LoadRuntimeSettingsFromLocalConfig();
				int num = ComputeRuntimeSettingsHash();
				bool flag2 = num != _lastSettingsHash;
				bool flag3 = Time.unscaledTime >= _nextSettingsBroadcast;
				if (!_lastHostState || flag2 || flag3)
				{
					_lastSettingsHash = num;
					_nextSettingsBroadcast = Time.unscaledTime + 10f;
					BroadcastHostSettings();
				}
			}
			_lastHostState = flag;
		}

		private int ComputeRuntimeSettingsHash()
		{
			return (((((((((17 * 31 + _netSmashRadius.GetHashCode()) * 31 + _netSmashDamage.GetHashCode()) * 31 + _netSmashKnockback.GetHashCode()) * 31 + _netSmashCooldown.GetHashCode()) * 31 + _netFlightForce.GetHashCode()) * 31 + _netFlightCooldown.GetHashCode()) * 31 + _netUltRadius.GetHashCode()) * 31 + _netUltDamage.GetHashCode()) * 31 + _netUltKnockback.GetHashCode()) * 31 + _netUltCooldown.GetHashCode();
		}

		private void BroadcastHostSettings()
		{
			if (!_myceliumRegistered || !IsHost())
			{
				return;
			}
			string text = string.Join("|", _netSmashRadius.ToString("R", CultureInfo.InvariantCulture), _netSmashDamage.ToString("R", CultureInfo.InvariantCulture), _netSmashKnockback.ToString("R", CultureInfo.InvariantCulture), _netSmashCooldown.ToString("R", CultureInfo.InvariantCulture), _netFlightForce.ToString("R", CultureInfo.InvariantCulture), _netFlightCooldown.ToString("R", CultureInfo.InvariantCulture), _netUltRadius.ToString("R", CultureInfo.InvariantCulture), _netUltDamage.ToString("R", CultureInfo.InvariantCulture), _netUltKnockback.ToString("R", CultureInfo.InvariantCulture), _netUltCooldown.ToString("R", CultureInfo.InvariantCulture));
			HostSettingsSync(text);
			try
			{
				MyceliumNetwork.RPC(2817742601u, "HostSettingsSync", (ReliableType)1, new object[1] { text });
			}
			catch
			{
			}
		}

		[CustomRPC]
		public void HostSettingsSync(string payload)
		{
			try
			{
				string[] array = payload.Split('|');
				if (array.Length == 10)
				{
					_netSmashRadius = float.Parse(array[0], CultureInfo.InvariantCulture);
					_netSmashDamage = float.Parse(array[1], CultureInfo.InvariantCulture);
					_netSmashKnockback = float.Parse(array[2], CultureInfo.InvariantCulture);
					_netSmashCooldown = float.Parse(array[3], CultureInfo.InvariantCulture);
					_netFlightForce = float.Parse(array[4], CultureInfo.InvariantCulture);
					_netFlightCooldown = float.Parse(array[5], CultureInfo.InvariantCulture);
					_netUltRadius = float.Parse(array[6], CultureInfo.InvariantCulture);
					_netUltDamage = float.Parse(array[7], CultureInfo.InvariantCulture);
					_netUltKnockback = float.Parse(array[8], CultureInfo.InvariantCulture);
					_netUltCooldown = float.Parse(array[9], CultureInfo.InvariantCulture);
				}
			}
			catch
			{
			}
		}

		private IEnumerator WaitForWeaponTable()
		{
			for (int i = 0; i < 120; i++)
			{
				if (!((Object)(object)_prefab == (Object)null))
				{
					break;
				}
				TryBuildWeapon();
				if ((Object)(object)_prefab == (Object)null)
				{
					yield return (object)new WaitForSecondsRealtime(0.25f);
				}
			}
			if ((Object)(object)_prefab == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Mjolnir could not find a safe vanilla melee shell.");
			}
		}

		private void Update()
		{
			if (Time.unscaledTime >= _nextLocalRefresh)
			{
				_nextLocalRefresh = Time.unscaledTime + 0.1f;
				RefreshLocalHolder();
			}
			UpdateHostSettingsSync();
			if (Time.unscaledTime >= _nextGlobalRandomizerRead)
			{
				_nextGlobalRandomizerRead = Time.unscaledTime + 0.2f;
				GlobalRandomizerEnabled = ReadGlobalRandomizerEnabled();
			}
			if (IsHoldingMjolnir())
			{
				SuppressAimAndZoom();
				if (Time.unscaledTime >= _nextOffhandEnforce)
				{
					_nextOffhandEnforce = Time.unscaledTime + 0.1f;
					EnforceMjolnirOffhandLock();
				}
				Mouse current = Mouse.current;
				if (current != null && current.leftButton.wasPressedThisFrame)
				{
					LocalSmash();
				}
				if (current != null && current.rightButton.wasPressedThisFrame)
				{
					LocalFlight();
				}
				if (UltBindingPressedThisFrame())
				{
					LocalUltimate();
				}
			}
			if (_f8TestSpawn.Value && IsHost())
			{
				Keyboard current2 = Keyboard.current;
				if (current2 != null && ((ButtonControl)current2.f8Key).wasPressedThisFrame)
				{
					SpawnTestMjolnir();
				}
			}
		}

		private void LateUpdate()
		{
			if (IsHoldingMjolnir())
			{
				SuppressAimAndZoom();
			}
		}

		internal void TryBuildWeapon()
		{
			if ((Object)(object)_prefab != (Object)null || _building)
			{
				return;
			}
			_building = true;
			try
			{
				try
				{
					SpawnerManager.PopulateAllWeapons();
				}
				catch
				{
				}
				GameObject val = FindSafeMeleeShell();
				if ((Object)(object)val == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Mjolnir: no melee shell found yet. " + DescribeWeaponSources()));
					return;
				}
				_prefab = CreateSafeInactiveClone(val);
				if ((Object)(object)_prefab == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Mjolnir safe-clone failed for " + ((Object)val).name + "."));
					return;
				}
				((Object)_prefab).name = "Mjolnir";
				_prefab.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)_prefab);
				Renderer[] componentsInChildren = _prefab.GetComponentsInChildren<Renderer>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].enabled = false;
				}
				AudioSource[] componentsInChildren2 = _prefab.GetComponentsInChildren<AudioSource>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					componentsInChildren2[i].mute = true;
				}
				ItemBehaviour val2 = _prefab.GetComponent<ItemBehaviour>() ?? _prefab.GetComponentInChildren<ItemBehaviour>(true);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.weaponName = "Mjolnir";
					val2.aimWeapon = false;
					val2.aimFOV = 75f;
				}
				MjolnirBehaviour mjolnirBehaviour = _prefab.AddComponent<MjolnirBehaviour>();
				mjolnirBehaviour.Plugin = this;
				mjolnirBehaviour.SwingClip = _swing;
				mjolnirBehaviour.SmashClip = _smash;
				mjolnirBehaviour.ThunderClip = _thunder;
				mjolnirBehaviour.FlightClip = _flight;
				mjolnirBehaviour.HumClip = _hum;
				BuildHammerVisual(mjolnirBehaviour);
				ApplyMjolnirIdentity(_prefab);
				ApplySpawnMetadata(_prefab);
				((MonoBehaviour)this).StartCoroutine(RegisterFishnetWhenReady());
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Mjolnir registered using melee shell: " + ((Object)val).name));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Mjolnir build failed: " + ex));
				if ((Object)(object)_prefab != (Object)null)
				{
					Object.Destroy((Object)(object)_prefab);
					_prefab = null;
				}
			}
			finally
			{
				_building = false;
			}
		}

		private void ApplyMjolnirIdentity(GameObject go)
		{
			if ((Object)(object)go == (Object)null)
			{
				return;
			}
			((Object)go).name = "Mjolnir";
			Component[] componentsInChildren = go.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					SetStringMember(val, "weaponName", "Mjolnir");
					SetStringMember(val, "displayName", "Mjolnir");
					SetStringMember(val, "itemName", "Mjolnir");
					SetStringMember(val, "weaponDisplayName", "Mjolnir");
				}
			}
		}

		private void ConfigureTwoHandedMetadata(GameObject go)
		{
			if ((Object)(object)go == (Object)null)
			{
				return;
			}
			Component[] componentsInChildren = go.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Type type = ((object)val).GetType();
				FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo in fields)
				{
					try
					{
						string text = fieldInfo.Name.ToLowerInvariant();
						if (fieldInfo.FieldType.IsEnum && !fieldInfo.IsInitOnly && (text.Contains("hand") || fieldInfo.FieldType.Name.ToLowerInvariant().Contains("hand")))
						{
							string text2 = Enum.GetNames(fieldInfo.FieldType).FirstOrDefault((string x) => x.Equals("TwoHanded", StringComparison.OrdinalIgnoreCase)) ?? Enum.GetNames(fieldInfo.FieldType).FirstOrDefault((string x) => x.Equals("DoubleHanded", StringComparison.OrdinalIgnoreCase));
							if (text2 != null)
							{
								fieldInfo.SetValue(val, Enum.Parse(fieldInfo.FieldType, text2));
							}
						}
						else if (fieldInfo.FieldType == typeof(bool) && !fieldInfo.IsInitOnly)
						{
							if (text.Contains("twohand") || text.Contains("doublehand"))
							{
								fieldInfo.SetValue(val, true);
							}
							else if (text.Contains("singlehand"))
							{
								fieldInfo.SetValue(val, false);
							}
						}
					}
					catch
					{
					}
				}
				PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (PropertyInfo propertyInfo in properties)
				{
					if (!propertyInfo.CanWrite)
					{
						continue;
					}
					try
					{
						string text3 = propertyInfo.Name.ToLowerInvariant();
						if (propertyInfo.PropertyType.IsEnum && (text3.Contains("hand") || propertyInfo.PropertyType.Name.ToLowerInvariant().Contains("hand")))
						{
							string text4 = Enum.GetNames(propertyInfo.PropertyType).FirstOrDefault((string x) => x.Equals("TwoHanded", StringComparison.OrdinalIgnoreCase)) ?? Enum.GetNames(propertyInfo.PropertyType).FirstOrDefault((string x) => x.Equals("DoubleHanded", StringComparison.OrdinalIgnoreCase));
							if (text4 != null)
							{
								propertyInfo.SetValue(val, Enum.Parse(propertyInfo.PropertyType, text4));
							}
						}
						else if (propertyInfo.PropertyType == typeof(bool))
						{
							if (text3.Contains("twohand") || text3.Contains("doublehand"))
							{
								propertyInfo.SetValue(val, true);
							}
							else if (text3.Contains("singlehand"))
							{
								propertyInfo.SetValue(val, false);
							}
						}
					}
					catch
					{
					}
				}
			}
		}

		private void ApplySpawnMetadata(GameObject go)
		{
			if ((Object)(object)go == (Object)null)
			{
				return;
			}
			Component[] componentsInChildren = go.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					SetBoolMember(val, "isSpawnable", value: true);
					SetFloatMemberIfPresent(val, "spawnChance", 1f);
					SetFloatMemberIfPresent(val, "weightedSpawnChance", 1f);
				}
			}
		}

		private void SetStringMember(object obj, string name, string value)
		{
			if (obj == null)
			{
				return;
			}
			Type type = obj.GetType();
			try
			{
				FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && field.FieldType == typeof(string) && !field.IsInitOnly)
				{
					field.SetValue(obj, value);
					return;
				}
				PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.CanWrite && property.PropertyType == typeof(string))
				{
					property.SetValue(obj, value);
				}
			}
			catch
			{
			}
		}

		private void SetBoolMember(object obj, string name, bool value)
		{
			if (obj == null)
			{
				return;
			}
			Type type = obj.GetType();
			try
			{
				FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && field.FieldType == typeof(bool) && !field.IsInitOnly)
				{
					field.SetValue(obj, value);
					return;
				}
				PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.CanWrite && property.PropertyType == typeof(bool))
				{
					property.SetValue(obj, value);
				}
			}
			catch
			{
			}
		}

		private void SetFloatMemberIfPresent(object obj, string name, float value)
		{
			if (obj == null)
			{
				return;
			}
			Type type = obj.GetType();
			try
			{
				FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && !field.IsInitOnly)
				{
					if (field.FieldType == typeof(float))
					{
						field.SetValue(obj, value);
					}
					else if (field.FieldType == typeof(double))
					{
						field.SetValue(obj, (double)value);
					}
				}
				PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.CanWrite)
				{
					if (property.PropertyType == typeof(float))
					{
						property.SetValue(obj, value);
					}
					else if (property.PropertyType == typeof(double))
					{
						property.SetValue(obj, (double)value);
					}
				}
			}
			catch
			{
			}
		}

		private void InstallWeaponPresetHooks()
		{
		}

		private static void PresetSystemPostfix()
		{
			try
			{
				Instance?.InjectIntoWeaponPresetSystem();
			}
			catch
			{
			}
		}

		private void InjectIntoWeaponPresetSystem()
		{
		}

		private void InjectPrefabIntoMembers(object obj, Type t)
		{
			FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				bool isStatic = fieldInfo.IsStatic;
				if ((obj == null && !isStatic) || (obj != null && isStatic) || !fieldInfo.Name.ToLowerInvariant().Contains("weapon"))
				{
					continue;
				}
				try
				{
					object value = fieldInfo.GetValue(obj);
					if (fieldInfo.FieldType == typeof(GameObject[]))
					{
						GameObject[] array = (value as GameObject[]) ?? Array.Empty<GameObject>();
						if (!array.Contains(_prefab))
						{
							fieldInfo.SetValue(obj, array.Concat((IEnumerable<GameObject>)(object)new GameObject[1] { _prefab }).ToArray());
						}
					}
					else if (value is IList list)
					{
						Type type = value.GetType();
						if ((type.IsGenericType ? type.GetGenericArguments().FirstOrDefault() : null) == typeof(GameObject) && !list.Contains(_prefab))
						{
							list.Add(_prefab);
						}
					}
					else if (value is IDictionary dictionary)
					{
						Type type2 = value.GetType();
						Type[] array2 = (type2.IsGenericType ? type2.GetGenericArguments() : Type.EmptyTypes);
						if (array2.Length == 2 && array2[0] == typeof(string) && array2[1] == typeof(GameObject))
						{
							dictionary["Mjolnir"] = _prefab;
						}
					}
				}
				catch
				{
				}
			}
		}

		private void SuppressAimAndZoom()
		{
			if ((Object)(object)_localFpc == (Object)null)
			{
				return;
			}
			if ((Object)(object)_localHeld != (Object)null)
			{
				ItemBehaviour val = _localHeld.GetComponent<ItemBehaviour>() ?? _localHeld.GetComponentInChildren<ItemBehaviour>(true);
				if ((Object)(object)val != (Object)null)
				{
					val.aimWeapon = false;
					val.aimFOV = 75f;
					val.weaponName = "Mjolnir";
				}
			}
			SetBoolMember(_localFpc, "isAiming", value: false);
			SetBoolMember(_localFpc, "isScopeAiming", value: false);
			SetBoolMember(_localFpc, "aimWeapon", value: false);
			SetBoolMember(_localFpc, "canScopeAim", value: false);
			SetBoolMember(_localFpc, "isZooming", value: false);
			try
			{
				if ((Object)(object)_localFpc.playerCameraHolder != (Object)null)
				{
					_localCamera = _localFpc.playerCameraHolder.GetComponentInChildren<Camera>(true);
				}
				if ((Object)(object)_localCamera == (Object)null)
				{
					_localCamera = Camera.main;
				}
				if ((Object)(object)_localCamera != (Object)null)
				{
					if (_rememberedNormalFov < 1f)
					{
						_rememberedNormalFov = ReadFloatMember(_localFpc, "normalFovValue", ReadFloatMember(_localFpc, "defaultFOV", _localCamera.fieldOfView));
					}
					if (_rememberedNormalFov > 1f && Math.Abs(_localCamera.fieldOfView - _rememberedNormalFov) > 0.05f)
					{
						_localCamera.fieldOfView = _rememberedNormalFov;
					}
				}
			}
			catch
			{
			}
		}

		private float ReadFloatMember(object obj, string name, float fallback)
		{
			if (obj == null)
			{
				return fallback;
			}
			try
			{
				Type type = obj.GetType();
				FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					return Convert.ToSingle(field.GetValue(obj), CultureInfo.InvariantCulture);
				}
				PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.CanRead)
				{
					return Convert.ToSingle(property.GetValue(obj), CultureInfo.InvariantCulture);
				}
			}
			catch
			{
			}
			return fallback;
		}

		private ulong GetSteamIdForPlayerHealth(PlayerHealth target)
		{
			if ((Object)(object)target == (Object)null)
			{
				return 0uL;
			}
			try
			{
				if (!(GetStatic(FindType("ClientInstance"), "playerInstances", "PlayerInstances") is IDictionary dictionary))
				{
					return 0uL;
				}
				foreach (DictionaryEntry item in dictionary)
				{
					object value = item.Value;
					ulong steamId = GetSteamId(value);
					if (steamId != 0L)
					{
						if (GetMember(value, "PlayerHealth", "playerHealth") == target)
						{
							return steamId;
						}
						Component val = (Component)((value is Component) ? value : null);
						if (val != null && (Object)(object)val.GetComponentInChildren<PlayerHealth>(true) == (Object)(object)target)
						{
							return steamId;
						}
						object member = GetMember(GetMember(value, "PlayerManager", "playerManager"), "SpawnedObject", "spawnedObject", "PlayerObject", "playerObject");
						object obj = ((member is GameObject) ? member : null);
						if (obj == null)
						{
							object obj2 = ((member is Component) ? member : null);
							obj = ((obj2 != null) ? ((Component)obj2).gameObject : null);
						}
						GameObject val2 = (GameObject)obj;
						if ((Object)(object)val2 != (Object)null && ((Object)(object)val2.GetComponentInChildren<PlayerHealth>(true) == (Object)(object)target || ((Component)target).transform.IsChildOf(val2.transform) || val2.transform.IsChildOf(((Component)target).transform.root)))
						{
							return steamId;
						}
					}
				}
			}
			catch
			{
			}
			return 0uL;
		}

		private GameObject CreateSafeInactiveClone(GameObject source)
		{
			if ((Object)(object)source == (Object)null)
			{
				return null;
			}
			bool active = false;
			try
			{
				active = source.activeSelf;
			}
			catch
			{
			}
			GameObject val = null;
			try
			{
				source.SetActive(false);
				val = Object.Instantiate<GameObject>(source);
				val.SetActive(false);
				StripUnsafeCloneComponents(val);
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Created inactive Mjolnir shell clone from " + ((Object)source).name + " and stripped unsafe presentation components before activation."));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Safe inactive clone failed: " + ex));
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
				val = null;
			}
			finally
			{
				try
				{
					source.SetActive(active);
				}
				catch
				{
				}
			}
			return val;
		}

		private void StripUnsafeCloneComponents(GameObject clone)
		{
			if ((Object)(object)clone == (Object)null)
			{
				return;
			}
			MonoBehaviour[] array = clone.GetComponentsInChildren<MonoBehaviour>(true).ToArray();
			foreach (MonoBehaviour val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string name = ((object)val).GetType().Name;
					string text = name.ToLowerInvariant();
					bool num = name == "SetEffectVolume" || text.Contains("effectvolume") || text.Contains("networkaudiosource") || text.Contains("networkaudioclips") || text.Contains("scope") || text.Contains("zoom") || text.Contains("aimweapon");
					bool flag = val is ItemBehaviour || val is Weapon || val is MeleeWeapon || text.Contains("networkobject") || text.Contains("networkbehaviour") || text.Contains("pickup") || text.Contains("player");
					if (num && !flag)
					{
						((BaseUnityPlugin)this).Logger.LogInfo((object)("Stripping clone component before activation: " + name));
						Object.DestroyImmediate((Object)(object)val);
					}
				}
			}
			AudioSource[] componentsInChildren = clone.GetComponentsInChildren<AudioSource>(true);
			foreach (AudioSource val2 in componentsInChildren)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
			}
		}

		private bool ReadGlobalRandomizerEnabled()
		{
			try
			{
				SpawnerManager val = ((IEnumerable<SpawnerManager>)Resources.FindObjectsOfTypeAll<SpawnerManager>()).FirstOrDefault((Func<SpawnerManager, bool>)delegate(SpawnerManager x)
				{
					//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)
					if ((Object)(object)x != (Object)null && (Object)(object)((Component)x).gameObject != (Object)null)
					{
						Scene scene = ((Component)x).gameObject.scene;
						return ((Scene)(ref scene)).IsValid();
					}
					return false;
				});
				if ((Object)(object)val == (Object)null)
				{
					return true;
				}
				MethodInfo methodInfo = ((object)val).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "sync___get_value_randomiseWeapons" && m.GetParameters().Length == 0);
				if (methodInfo != null && methodInfo.Invoke(val, null) is bool result)
				{
					return result;
				}
				if (GetMember(val, "randomiseWeapons", "syncVar___randomiseWeapons") is bool result2)
				{
					return result2;
				}
			}
			catch
			{
			}
			return true;
		}

		internal GameObject GetMjolnirPrefab()
		{
			return _prefab;
		}

		internal bool ShouldSubstituteMjolnir()
		{
			if ((Object)(object)_prefab == (Object)null || SpawnEnabled == null || SpawnWeight == null || !SpawnEnabled.Value || !GlobalRandomizerEnabled)
			{
				return false;
			}
			float num = Mathf.Clamp(SpawnWeight.Value, 0f, 100f);
			if (num <= 0f)
			{
				return false;
			}
			float num2 = Mathf.Max(num, NativeRandomizerTotalWeight);
			return Random.value < num / num2;
		}

		internal void TryAddMjolnirMenuRow(WeaponRandomizationMenu menu)
		{
			if ((Object)(object)menu == (Object)null || (Object)(object)_customMenuRow != (Object)null)
			{
				return;
			}
			try
			{
				Component val = ((IEnumerable<Component>)((Component)menu).GetComponentsInChildren<Component>(true)).FirstOrDefault((Func<Component, bool>)((Component c) => (Object)(object)c != (Object)null && ((object)c).GetType().Name == "WeaponRow"));
				if ((Object)(object)val == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Mjolnir menu row: no vanilla WeaponRow was found after PopulateMenu.");
					return;
				}
				GameObject gameObject = val.gameObject;
				Transform parent = gameObject.transform.parent;
				_customMenuRow = Object.Instantiate<GameObject>(gameObject, parent);
				((Object)_customMenuRow).name = "WeaponRow_Mjolnir";
				_customMenuRow.SetActive(true);
				Component val2 = ((IEnumerable<Component>)_customMenuRow.GetComponents<Component>()).FirstOrDefault((Func<Component, bool>)((Component c) => (Object)(object)c != (Object)null && ((object)c).GetType().Name == "WeaponRow"));
				if ((Object)(object)val2 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
				Component val3 = null;
				Component val4 = null;
				Component[] componentsInChildren = _customMenuRow.GetComponentsInChildren<Component>(true);
				foreach (Component val5 in componentsInChildren)
				{
					if (!((Object)(object)val5 == (Object)null))
					{
						string name = ((object)val5).GetType().Name;
						if (name == "Toggle" && (Object)(object)val3 == (Object)null)
						{
							val3 = val5;
							ClearUnityEvent(val5, "onValueChanged");
						}
						else if (name == "Slider" && (Object)(object)val4 == (Object)null)
						{
							val4 = val5;
							ClearUnityEvent(val5, "onValueChanged");
						}
					}
				}
				RenameRowText(_customMenuRow, "Mjolnir");
				MjolnirMenuRowBinding mjolnirMenuRowBinding = _customMenuRow.AddComponent<MjolnirMenuRowBinding>();
				mjolnirMenuRowBinding.Plugin = this;
				mjolnirMenuRowBinding.Toggle = val3;
				mjolnirMenuRowBinding.Slider = val4;
				mjolnirMenuRowBinding.Initialize();
				SortMjolnirRowAlphabetically(parent, _customMenuRow);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Added Mjolnir to default Weapon Customization in alphabetical position.");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not add isolated Mjolnir menu row: " + ex.Message));
			}
		}

		private void SortMjolnirRowAlphabetically(Transform parent, GameObject mjRow)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			if ((Object)(object)parent == (Object)null || (Object)(object)mjRow == (Object)null)
			{
				return;
			}
			List<Tuple<Transform, string>> list = new List<Tuple<Transform, string>>();
			foreach (Transform item in parent)
			{
				Transform val = item;
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)(object)mjRow))
				{
					string text = ReadBestRowLabel(((Component)val).gameObject);
					if (!string.IsNullOrWhiteSpace(text))
					{
						list.Add(Tuple.Create<Transform, string>(val, text.Trim()));
					}
				}
			}
			int num = parent.childCount - 1;
			for (int i = 0; i < list.Count; i++)
			{
				if (string.Compare("Mjolnir", list[i].Item2, StringComparison.OrdinalIgnoreCase) < 0)
				{
					num = list[i].Item1.GetSiblingIndex();
					break;
				}
			}
			mjRow.transform.SetSiblingIndex(Mathf.Clamp(num, 0, parent.childCount - 1));
		}

		private string ReadBestRowLabel(GameObject row)
		{
			if ((Object)(object)row == (Object)null)
			{
				return "";
			}
			string result = "";
			int num = int.MinValue;
			Component[] componentsInChildren = row.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				PropertyInfo property = ((object)val).GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property == null || !property.CanRead || property.PropertyType != typeof(string))
				{
					continue;
				}
				try
				{
					string text = ((string)property.GetValue(val)) ?? "";
					int num2 = 0;
					if (text.Length >= 2 && text.Length <= 30)
					{
						num2 += 20;
					}
					if (text.Any(char.IsLetter))
					{
						num2 += 40;
					}
					if (text.Contains("%"))
					{
						num2 -= 60;
					}
					if (text.All((char ch) => char.IsDigit(ch) || ch == '.' || ch == '%' || char.IsWhiteSpace(ch)))
					{
						num2 -= 80;
					}
					if (num2 > num)
					{
						num = num2;
						result = text;
					}
				}
				catch
				{
				}
			}
			return result;
		}

		private void ClearUnityEvent(Component component, string propertyName)
		{
			try
			{
				object obj = ((object)component).GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(component);
				(obj?.GetType().GetMethod("RemoveAllListeners", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))?.Invoke(obj, null);
			}
			catch
			{
			}
		}

		private void RenameRowText(GameObject row, string name)
		{
			if ((Object)(object)row == (Object)null)
			{
				return;
			}
			Component val = null;
			int num = int.MinValue;
			Component[] componentsInChildren = row.GetComponentsInChildren<Component>(true);
			foreach (Component val2 in componentsInChildren)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				PropertyInfo property = ((object)val2).GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property == null || !property.CanRead || !property.CanWrite || property.PropertyType != typeof(string))
				{
					continue;
				}
				try
				{
					string text = ((string)property.GetValue(val2)) ?? "";
					int num2 = 0;
					if (text.Length >= 2 && text.Length <= 40)
					{
						num2 += 20;
					}
					if (text.Any(char.IsLetter))
					{
						num2 += 30;
					}
					if (text.Contains("%"))
					{
						num2 -= 50;
					}
					if (text.All((char ch) => char.IsDigit(ch) || ch == '.' || ch == '%'))
					{
						num2 -= 60;
					}
					if (num2 > num)
					{
						num = num2;
						val = val2;
					}
				}
				catch
				{
				}
			}
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			try
			{
				((object)val).GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(val, name);
			}
			catch
			{
			}
		}

		internal static float GetFloatProperty(Component c, string name, float fallback)
		{
			if ((Object)(object)c == (Object)null)
			{
				return fallback;
			}
			try
			{
				PropertyInfo property = ((object)c).GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.CanRead)
				{
					return Convert.ToSingle(property.GetValue(c), CultureInfo.InvariantCulture);
				}
			}
			catch
			{
			}
			return fallback;
		}

		internal static void SetFloatProperty(Component c, string name, float value)
		{
			if ((Object)(object)c == (Object)null)
			{
				return;
			}
			try
			{
				PropertyInfo property = ((object)c).GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.CanWrite)
				{
					property.SetValue(c, value);
				}
			}
			catch
			{
			}
		}

		internal static bool GetBoolProperty(Component c, string name, bool fallback)
		{
			if ((Object)(object)c == (Object)null)
			{
				return fallback;
			}
			try
			{
				PropertyInfo property = ((object)c).GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.CanRead)
				{
					return Convert.ToBoolean(property.GetValue(c));
				}
			}
			catch
			{
			}
			return fallback;
		}

		internal static void SetBoolProperty(Component c, string name, bool value)
		{
			if ((Object)(object)c == (Object)null)
			{
				return;
			}
			try
			{
				PropertyInfo property = ((object)c).GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.CanWrite)
				{
					property.SetValue(c, value);
				}
			}
			catch
			{
			}
		}

		private GameObject FindSafeMeleeShell()
		{
			List<GameObject> list = new List<GameObject>();
			try
			{
				if (SpawnerManager.NameToWeaponDict != null)
				{
					list.AddRange(SpawnerManager.NameToWeaponDict.Values.Where((GameObject x) => (Object)(object)x != (Object)null));
				}
			}
			catch
			{
			}
			try
			{
				if (SpawnerManager.AllWeapons != null)
				{
					list.AddRange(SpawnerManager.AllWeapons.Where((GameObject x) => (Object)(object)x != (Object)null));
				}
			}
			catch
			{
			}
			try
			{
				GameObject[] array = Resources.LoadAll<GameObject>("RandomWeapons");
				if (array != null)
				{
					list.AddRange(array.Where((GameObject x) => (Object)(object)x != (Object)null));
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("RandomWeapons resource scan failed: " + ex.Message));
			}
			list = list.Distinct().ToList();
			if (list.Count == 0)
			{
				return null;
			}
			GameObject val = null;
			int num = int.MinValue;
			foreach (GameObject item in list)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				int num2 = 0;
				string text = (((Object)item).name ?? "").ToLowerInvariant();
				try
				{
					if ((Object)(object)(item.GetComponent<MeleeWeapon>() ?? item.GetComponentInChildren<MeleeWeapon>(true)) != (Object)null)
					{
						num2 += 1000;
					}
				}
				catch
				{
				}
				try
				{
					if ((Object)(object)(item.GetComponent<ItemBehaviour>() ?? item.GetComponentInChildren<ItemBehaviour>(true)) != (Object)null)
					{
						num2 += 100;
					}
				}
				catch
				{
				}
				if (text.Contains("bat"))
				{
					num2 += 90;
				}
				if (text.Contains("katana"))
				{
					num2 += 90;
				}
				if (text.Contains("sword"))
				{
					num2 += 80;
				}
				if (text.Contains("knife"))
				{
					num2 += 80;
				}
				if (text.Contains("cleaver"))
				{
					num2 += 80;
				}
				if (text.Contains("couperet"))
				{
					num2 += 80;
				}
				if (text.Contains("hammer"))
				{
					num2 += 100;
				}
				if (text.Contains("axe"))
				{
					num2 += 80;
				}
				if (text.Contains("mace"))
				{
					num2 += 80;
				}
				if (text.Contains("melee"))
				{
					num2 += 75;
				}
				if (text.Contains("pistol") || text.Contains("rifle") || text.Contains("shotgun") || text.Contains("smg") || text.Contains("launcher") || text.Contains("grenade") || text.Contains("mine") || text.Contains("bomb"))
				{
					num2 -= 700;
				}
				try
				{
					Component[] componentsInChildren = item.GetComponentsInChildren<Component>(true);
					foreach (Component val2 in componentsInChildren)
					{
						if (!((Object)(object)val2 == (Object)null))
						{
							string text2 = ((object)val2).GetType().Name.ToLowerInvariant();
							if (text2 == "meleeweapon")
							{
								num2 += 500;
							}
							if (text2.Contains("scope") || text2.Contains("gun") || text2.Contains("firearm") || text2.Contains("projectile") || text2.Contains("launcher"))
							{
								num2 -= 250;
							}
						}
					}
				}
				catch
				{
				}
				if (num2 > num)
				{
					num = num2;
					val = item;
				}
			}
			if ((Object)(object)val != (Object)null && num >= 500)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Mjolnir shell selected: " + ((Object)val).name + " (score " + num + ")"));
				return val;
			}
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Best Mjolnir shell candidate was " + (((Object)(object)val != (Object)null) ? ((Object)val).name : "<none>") + " with insufficient score " + num + "."));
			return null;
		}

		private string DescribeWeaponSources()
		{
			try
			{
				List<string> list = new List<string>();
				int num = ((SpawnerManager.NameToWeaponDict != null) ? SpawnerManager.NameToWeaponDict.Count : 0);
				string text = ((SpawnerManager.NameToWeaponDict != null) ? string.Join(", ", SpawnerManager.NameToWeaponDict.Keys.Take(20)) : "<null>");
				list.Add("NameToWeaponDict=" + num + " [" + text + "]");
				int num2 = ((SpawnerManager.AllWeapons != null) ? SpawnerManager.AllWeapons.Length : 0);
				string text2 = ((SpawnerManager.AllWeapons != null) ? string.Join(", ", from x in SpawnerManager.AllWeapons.Where((GameObject x) => (Object)(object)x != (Object)null).Take(20)
					select ((Object)x).name) : "<null>");
				list.Add("AllWeapons=" + num2 + " [" + text2 + "]");
				GameObject[] array = null;
				try
				{
					array = Resources.LoadAll<GameObject>("RandomWeapons");
				}
				catch
				{
				}
				int num3 = ((array != null) ? array.Length : 0);
				string text3 = ((array != null) ? string.Join(", ", from x in array.Where((GameObject x) => (Object)(object)x != (Object)null).Take(30)
					select ((Object)x).name) : "<null>");
				list.Add("Resources/RandomWeapons=" + num3 + " [" + text3 + "]");
				return string.Join(" | ", list);
			}
			catch (Exception ex)
			{
				return "weapon-source diagnostics failed: " + ex.Message;
			}
		}

		private void BuildHammerVisual(MjolnirBehaviour behaviour)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0028: 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_0057: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			//IL_0101: 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_0147: Expected O, but got Unknown
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_054e: Unknown result type (might be due to invalid IL or missing references)
			//IL_056d: Unknown result type (might be due to invalid IL or missing references)
			//IL_058c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Mjolnir_SwingPivot");
			val.transform.SetParent(_prefab.transform, false);
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.Euler(-90f, 0f, 90f);
			val.transform.localScale = Vector3.one * 0.54f;
			Material val2 = new Material(Shader.Find("Standard"));
			((Object)val2).name = "Weathered Uru";
			val2.color = new Color(0.68f, 0.69f, 0.71f, 1f);
			val2.SetFloat("_Metallic", 0.82f);
			val2.SetFloat("_Glossiness", 0.24f);
			val2.mainTexture = (Texture)(object)CreateBrushedMetalTexture();
			Material val3 = new Material(Shader.Find("Standard"));
			((Object)val3).name = "Uru Edge";
			val3.color = new Color(0.58f, 0.59f, 0.61f, 1f);
			val3.SetFloat("_Metallic", 0.86f);
			val3.SetFloat("_Glossiness", 0.22f);
			val3.mainTexture = (Texture)(object)CreateBrushedMetalTexture();
			Material val4 = new Material(Shader.Find("Standard"));
			((Object)val4).name = "Aged Leather";
			val4.color = new Color(0.33f, 0.12f, 0.045f, 1f);
			val4.SetFloat("_Metallic", 0f);
			val4.SetFloat("_Glossiness", 0.12f);
			val4.mainTexture = (Texture)(object)CreateLeatherTexture();
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)obj).name = "Mjolnir_Uru_Head";
			obj.transform.SetParent(val.transform, false);
			obj.transform.localPosition = new Vector3(0f, 0f, 0.62f);
			obj.transform.localScale = new Vector3(0.92f, 0.42f, 0.34f);
			Collider component = obj.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			obj.GetComponent<Renderer>().sharedMaterial = val2;
			float[] array = new float[2] { -0.5f, 0.5f };
			foreach (float num in array)
			{
				GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)3);
				((Object)obj2).name = "Mjolnir_EndCap";
				obj2.transform.SetParent(val.transform, false);
				obj2.transform.localPosition = new Vector3(num, 0f, 0.62f);
				obj2.transform.localScale = new Vector3(0.11f, 0.36f, 0.29f);
				Collider component2 = obj2.GetComponent<Collider>();
				if ((Object)(object)component2 != (Object)null)
				{
					Object.Destroy((Object)(object)component2);
				}
				obj2.GetComponent<Renderer>().sharedMaterial = val3;
			}
			array = new float[2] { 0.795f, 0.445f };
			foreach (float num2 in array)
			{
				GameObject obj3 = GameObject.CreatePrimitive((PrimitiveType)3);
				((Object)obj3).name = "Mjolnir_HeadBand";
				obj3.transform.SetParent(val.transform, false);
				obj3.transform.localPosition = new Vector3(0f, 0f, num2);
				obj3.transform.localScale = new Vector3(0.72f, 0.43f, 0.035f);
				Collider component3 = obj3.GetComponent<Collider>();
				if ((Object)(object)component3 != (Object)null)
				{
					Object.Destroy((Object)(object)component3);
				}
				obj3.GetComponent<Renderer>().sharedMaterial = val3;
			}
			GameObject obj4 = GameObject.CreatePrimitive((PrimitiveType)2);
			((Object)obj4).name = "Mjolnir_Leather_Handle";
			obj4.transform.SetParent(val.transform, false);
			obj4.transform.localPosition = Vector3.zero;
			obj4.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
			obj4.transform.localScale = new Vector3(0.082f, 0.48f, 0.082f);
			Collider component4 = obj4.GetComponent<Collider>();
			if ((Object)(object)component4 != (Object)null)
			{
				Object.Destroy((Object)(object)component4);
			}
			obj4.GetComponent<Renderer>().sharedMaterial = val4;
			array = new float[2] { 0.48f, -0.48f };
			foreach (float num3 in array)
			{
				GameObject obj5 = GameObject.CreatePrimitive((PrimitiveType)2);
				((Object)obj5).name = "Mjolnir_Collar";
				obj5.transform.SetParent(val.transform, false);
				obj5.transform.localPosition = new Vector3(0f, 0f, num3);
				obj5.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
				obj5.transform.localScale = new Vector3(0.105f, 0.055f, 0.105f);
				Collider component5 = obj5.GetComponent<Collider>();
				if ((Object)(object)component5 != (Object)null)
				{
					Object.Destroy((Object)(object)component5);
				}
				obj5.GetComponent<Renderer>().sharedMaterial = val3;
			}
			for (int j = 0; j < 6; j++)
			{
				GameObject obj6 = GameObject.CreatePrimitive((PrimitiveType)2);
				((Object)obj6).name = "Mjolnir_GripRing";
				obj6.transform.SetParent(val.transform, false);
				obj6.transform.localPosition = new Vector3(0f, 0f, 0.32f - (float)j * 0.13f);
				obj6.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
				obj6.transform.localScale = new Vector3(0.09f, 0.012f, 0.09f);
				Collider component6 = obj6.GetComponent<Collider>();
				if ((Object)(object)component6 != (Object)null)
				{
					Object.Destroy((Object)(object)component6);
				}
				obj6.GetComponent<Renderer>().sharedMaterial = val2;
			}
			AudioSource val5 = _prefab.AddComponent<AudioSource>();
			val5.playOnAwake = false;
			val5.spatialBlend = 1f;
			val5.volume = 0.95f;
			val5.minDistance = 1f;
			val5.maxDistance = 65f;
			behaviour.Visual = val.transform;
			behaviour.Audio = val5;
			MonoBehaviour[] componentsInChildren = _prefab.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val6 in componentsInChildren)
			{
				if (!((Object)(object)val6 == (Object)null) && !((Object)(object)val6 == (Object)(object)behaviour) && !(val6 is ItemBehaviour))
				{
					string text = ((object)val6).GetType().Name.ToLowerInvariant();
					if (text.Contains("aim") || text.Contains("scope") || text.Contains("zoom") || text.Contains("ads"))
					{
						((Behaviour)val6).enabled = false;
					}
				}
			}
		}

		private Texture2D CreateBrushedMetalTexture()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(128, 128, (TextureFormat)3, true);
			((Object)val).name = "Mjolnir_Brushed_Uru_Texture";
			((Texture)val).wrapMode = (TextureWrapMode)0;
			((Texture)val).filterMode = (FilterMode)1;
			Random random = new Random(91731);
			for (int i = 0; i < 128; i++)
			{
				float num = (float)(random.NextDouble() * 0.1 - 0.05);
				for (int j = 0; j < 128; j++)
				{
					float num2 = (float)(random.NextDouble() * 0.09 - 0.045);
					float num3 = Mathf.Sin((float)j * 0.34f + (float)i * 0.035f) * 0.025f;
					float num4 = Mathf.Clamp01(0.78f + num + num2 + num3);
					val.SetPixel(j, i, new Color(num4 * 0.95f, num4 * 0.97f, num4, 1f));
				}
			}
			val.Apply(true, false);
			return val;
		}

		private Texture2D CreateLeatherTexture()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(128, 128, (TextureFormat)3, true);
			((Object)val).name = "Mjolnir_Aged_Leather_Texture";
			((Texture)val).wrapMode = (TextureWrapMode)0;
			((Texture)val).filterMode = (FilterMode)1;
			Random random = new Random(41377);
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					float num = (float)(random.NextDouble() * 0.18 - 0.09);
					float num2 = Mathf.Sin((float)i * 0.42f + (float)j * 0.035f) * 0.035f;
					float num3 = Mathf.Clamp01(0.34f + num + num2);
					val.SetPixel(j, i, new Color(num3 * 0.72f, num3 * 0.27f, num3 * 0.1f, 1f));
				}
			}
			val.Apply(true, false);
			return val;
		}

		private IEnumerator RegisterFishnetWhenReady()
		{
			for (int i = 0; i < 100; i++)
			{
				if (_fishnetRegistered)
				{
					break;
				}
				bool flag = false;
				bool flag2 = false;
				try
				{
					if ((Object)(object)_prefab == (Object)null)
					{
						flag2 = true;
					}
					else
					{
						object obj = GetStatic(FindType("FishNet.InstanceFinder"), "NetworkManager");
						if (obj == null)
						{
							flag = true;
						}
						else
						{
							object member = GetMember(obj, "SpawnablePrefabs");
							Type type = FindType("FishNet.Object.NetworkObject");
							Component nob = ((type == null) ? null : _prefab.GetComponent(type));
							if (member == null || (Object)(object)nob == (Object)null)
							{
								flag = true;
							}
							else
							{
								TrySetMember(nob, "PrefabId", (ushort)0);
								TrySetMember(nob, "SpawnableCollectionId", (ushort)0);
								MethodInfo methodInfo = member.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "AddObject" && m.GetParameters().Length >= 1 && m.GetParameters()[0].ParameterType.IsAssignableFrom(((object)nob).GetType()));
								if (methodInfo != null)
								{
									ParameterInfo[] parameters = methodInfo.GetParameters();
									object[] array = new object[parameters.Length];
									array[0] = nob;
									for (int num = 1; num < parameters.Length; num++)
									{
										array[num] = (parameters[num].HasDefaultValue ? parameters[num].DefaultValue : (parameters[num].ParameterType.IsValueType ? Activator.CreateInstance(parameters[num].ParameterType) : null));
									}
									methodInfo.Invoke(member, array);
									_fishnetRegistered = true;
									((BaseUnityPlugin)this).Logger.LogInfo((object)"Mjolnir registered with FishNet spawnable prefab collection.");
								}
								else
								{
									((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find FishNet AddObject method; will retry.");
									flag = true;
								}
							}
						}
					}
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("FishNet registration retry: " + ex.Message));
					flag = true;
				}
				if (flag2)
				{
					yield break;
				}
				if (!_fishnetRegistered)
				{
					yield return (object)new WaitForSecondsRealtime(flag ? 0.25f : 0.1f);
				}
			}
			if (!_fishnetRegistered)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Mjolnir FishNet registration timed out.");
			}
		}

		private void RefreshLocalHolder()
		{
			try
			{
				_localSteamId = GetOwnSteamId();
				object member = GetMember(GetStatic(typeof(Settings), "Instance"), "localPlayer", "LocalPlayer");
				_localFpc = (FirstPersonController)((member is FirstPersonController) ? member : null);
				if ((Object)(object)_localFpc == (Object)null)
				{
					Component val = (Component)((member is Component) ? member : null);
					if (val != null)
					{
						_localFpc = val.GetComponent<FirstPersonController>();
					}
				}
				if ((Object)(object)_localFpc == (Object)null)
				{
					_localHeld = null;
					return;
				}
				object member2 = GetMember(_localFpc, "playerPickupScript", "PlayerPickupScript");
				object obj = GetMember(member2, "objInHand", "ObjInHand");
				if (obj == null)
				{
					MethodInfo methodInfo = member2?.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name.Contains("sync___get_value_objInHand") && m.GetParameters().Length == 0);
					if (methodInfo != null)
					{
						obj = methodInfo.Invoke(member2, null);
					}
				}
				GameObject val2 = (GameObject)((obj is GameObject) ? obj : null);
				if (val2 != null)
				{
					_localHeld = val2;
					return;
				}
				Component val3 = (Component)((obj is Component) ? obj : null);
				if (val3 != null)
				{
					_localHeld = val3.gameObject;
				}
				else
				{
					_localHeld = null;
				}
			}
			catch
			{
				_localHeld = null;
			}
		}

		private void EnforceMjolnirOffhandLock()
		{
			if ((Object)(object)_localFpc == (Object)null)
			{
				return;
			}
			try
			{
				object member = GetMember(_localFpc, "playerPickupScript", "PlayerPickupScript");
				if (member == null)
				{
					return;
				}
				bool flag = GetMember(member, "objInLeftHand", "ObjInLeftHand", "syncVar___objInLeftHand") != null;
				if (GetMember(member, "hasObjectInLeftHand", "syncVar___hasObjectInLeftHand") is bool flag2)
				{
					flag = flag || flag2;
				}
				if (flag)
				{
					member.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "LeftHandDrop" && m.GetParameters().Length == 0)?.Invoke(member, null);
				}
			}
			catch
			{
			}
		}

		private bool IsHoldingMjolnir()
		{
			if ((Object)(object)_localHeld == (Object)null)
			{
				return false;
			}
			if (!((Object)(object)_localHeld.GetComponentInParent<MjolnirBehaviour>() != (Object)null))
			{
				return (Object)(object)_localHeld.GetComponentInChildren<MjolnirBehaviour>(true) != (Object)null;
			}
			return true;
		}

		private void LocalSmash()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			(_localHeld.GetComponentInParent<MjolnirBehaviour>() ?? _localHeld.GetComponentInChildren<MjolnirBehaviour>(true))?.PlaySwing();
			if ((Object)(object)_localFpc != (Object)null)
			{
				PlayWorldSound(((Component)_localFpc).transform.position, _thunder, 0.72f);
			}
			Vector3 val = FindSmashPoint();
			Vector3 val2 = (((Object)(object)_localFpc != (Object)null) ? ((Component)_localFpc).transform.position : Vector3.zero);
			string text = string.Join("|", _localSteamId.ToString(), val.x.ToString("R", CultureInfo.InvariantCulture), val.y.ToString("R", CultureInfo.InvariantCulture), val.z.ToString("R", CultureInfo.InvariantCulture), val2.x.ToString("R", CultureInfo.InvariantCulture), val2.y.ToString("R", CultureInfo.InvariantCulture), val2.z.ToString("R", CultureInfo.InvariantCulture));
			if (IsHost())
			{
				SmashRequest(text);
				return;
			}
			try
			{
				MyceliumNetwork.RPC(2817742601u, "SmashRequest", (ReliableType)1, new object[1] { text });
			}
			catch
			{
			}
		}

		private Vector3 FindSmashPoint()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_localFpc == (Object)null)
			{
				return Vector3.zero;
			}
			Transform obj = (((Object)(object)_localFpc.playerCameraHolder != (Object)null) ? _localFpc.playerCameraHolder.transform : ((Component)_localFpc).transform);
			Vector3 position = obj.position;
			Vector3 forward = obj.forward;
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(position, forward, ref val, 4f, -1, (QueryTriggerInteraction)1))
			{
				return ((RaycastHit)(ref val)).point;
			}
			Vector3 val2 = position + forward * 2.35f;
			RaycastHit val3 = default(RaycastHit);
			if (Physics.Raycast(val2 + Vector3.up * 1.5f, Vector3.down, ref val3, 4f, -1, (QueryTriggerInteraction)1))
			{
				return ((RaycastHit)(ref val3)).point;
			}
			return val2 - Vector3.up * 0.8f;
		}

		private void LocalFlight()
		{
			//IL_004a: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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)
			if (_localSteamId == 0L || (Object)(object)_localFpc == (Object)null)
			{
				return;
			}
			float unscaledTime = Time.unscaledTime;
			if (unscaledTime < _localNextFlightInput)
			{
				return;
			}
			_localNextFlightInput = unscaledTime + Mathf.Clamp(_netFlightCooldown, 0.5f, 15f);
			Vector3 forward = GetForward(_localFpc);
			float force = Mathf.Clamp(_netFlightForce, 20f, 240f);
			((MonoBehaviour)this).StartCoroutine(ApplyMjolnirFlightImpulse(forward, forward, force));
			(_localHeld.GetComponentInParent<MjolnirBehaviour>() ?? _localHeld.GetComponentInChildren<MjolnirBehaviour>(true))?.PlayFlight();
			CreateFlightFx(((Component)_localFpc).transform.position);
			string text = _localSteamId.ToString();
			if (IsHost())
			{
				FlightRequest(text);
				return;
			}
			try
			{
				MyceliumNetwork.RPC(2817742601u, "FlightRequest", (ReliableType)1, new object[1] { text });
			}
			catch
			{
			}
		}

		private void ResetRoundCooldowns()
		{
			_nextUlt.Clear();
			_localNextUltInput = 0f;
			_nextSmash.Clear();
			_nextFlight.Clear();
			_localNextFlightInput = 0f;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Mjolnir round cooldowns reset.");
		}

		private void OnSceneLoadedResetCooldowns(Scene scene, LoadSceneMode mode)
		{
			ResetRoundCooldowns();
		}

		private bool UltBindingPressedThisFrame()
		{
			if (_ultBinding == null)
			{
				return false;
			}
			Mouse current = Mouse.current;
			Keyboard current2 = Keyboard.current;
			switch (_ultBinding.Value)
			{
			case UltBinding.Mouse5:
				if (current != null)
				{
					return current.forwardButton.wasPressedThisFrame;
				}
				return false;
			case UltBinding.Mouse4:
				if (current != null)
				{
					return current.backButton.wasPressedThisFrame;
				}
				return false;
			case UltBinding.MiddleMouse:
				if (current != null)
				{
					return current.middleButton.wasPressedThisFrame;
				}
				return false;
			case UltBinding.Q:
				if (current2 != null)
				{
					return ((ButtonControl)current2.qKey).wasPressedThisFrame;
				}
				return false;
			case UltBinding.E:
				if (current2 != null)
				{
					return ((ButtonControl)current2.eKey).wasPressedThisFrame;
				}
				return false;
			case UltBinding.R:
				if (current2 != null)
				{
					return ((ButtonControl)current2.rKey).wasPressedThisFrame;
				}
				return false;
			case UltBinding.F:
				if (current2 != null)
				{
					return ((ButtonControl)current2.fKey).wasPressedThisFrame;
				}
				return false;
			case UltBinding.G:
				if (current2 != null)
				{
					return ((ButtonControl)current2.gKey).wasPressedThisFrame;
				}
				return false;
			case UltBinding.T:
				if (current2 != null)
				{
					return ((ButtonControl)current2.tKey).wasPressedThisFrame;
				}
				return false;
			case UltBinding.V:
				if (current2 != null)
				{
					return ((ButtonControl)current2.vKey).wasPressedThisFrame;
				}
				return false;
			case UltBinding.C:
				if (current2 != null)
				{
					return ((ButtonControl)current2.cKey).wasPressedThisFrame;
				}
				return false;
			case UltBinding.X:
				if (current2 != null)
				{
					return ((ButtonControl)current2.xKey).wasPressedThisFrame;
				}
				return false;
			case UltBinding.Z:
				if (current2 != null)
				{
					return ((ButtonControl)current2.zKey).wasPressedThisFrame;
				}
				return false;
			case UltBinding.B:
				if (current2 != null)
				{
					return ((ButtonControl)current2.bKey).wasPressedThisFrame;
				}
				return false;
			case UltBinding.LeftShift:
				if (current2 != null)
				{
					return ((ButtonControl)current2.leftShiftKey).wasPressedThisFrame;
				}
				return false;
			case UltBinding.LeftCtrl:
				if (current2 != null)
				{
					return ((ButtonControl)current2.leftCtrlKey).wasPressedThisFrame;
				}
				return false;
			case UltBinding.LeftAlt:
				if (current2 != null)
				{
					return ((ButtonControl)current2.leftAltKey).wasPressedThisFrame;
				}
				return false;
			case UltBinding.Space:
				if (current2 != null)
				{
					return ((ButtonControl)current2.spaceKey).wasPressedThisFrame;
				}
				return false;
			default:
				return false;
			}
		}

		private void LocalUltimate()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (_localSteamId == 0L || (Object)(object)_localFpc == (Object)null)
			{
				return;
			}
			float unscaledTime = Time.unscaledTime;
			if (unscaledTime < _localNextUltInput)
			{
				return;
			}
			_localNextUltInput = unscaledTime + Mathf.Clamp(_netUltCooldown, 3f, 30f);
			Vector3 position = ((Component)_localFpc).transform.position;
			PlayWorldSound(position, _thunder, 1f);
			string text = string.Join("|", _localSteamId.ToString(), position.x.ToString("R", CultureInfo.InvariantCulture), position.y.ToString("R", CultureInfo.InvariantCulture), position.z.ToString("R", CultureInfo.InvariantCulture));
			if (IsHost())
			{
				UltimateRequest(text);
				return;
			}
			try
			{
				MyceliumNetwork.RPC(2817742601u, "UltimateRequest", (ReliableType)1, new object[1] { text });
			}
			catch
			{
			}
		}

		[CustomRPC]
		public void UltimateRequest(string payload)
		{
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHost())
			{
				return;
			}
			try
			{
				string[] array = payload.Split('|');
				if (array.Length != 4)
				{
					return;
				}
				ulong num = ulong.Parse(array[0]);
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(float.Parse(array[1], CultureInfo.InvariantCulture), float.Parse(array[2], CultureInfo.InvariantCulture), float.Parse(array[3], CultureInfo.InvariantCulture));
				float unscaledTime = Time.unscaledTime;
				if (_nextUlt.TryGetValue(num, out var value) && unscaledTime < value)
				{
					return;
				}
				_nextUlt[num] = unscaledTime + Mathf.Clamp(_netUltCooldown, 3f, 30f);
				float radius = Mathf.Clamp(_netUltRadius, 3f, 14f);
				float centerDamage = Mathf.Clamp(_netUltDamage, 0f, 20f);
				float knock = Mathf.Clamp(_netUltKnockback, 0f, 300f);
				ApplyAreaEffect(num, val, radius, centerDamage, knock, val);
				string text = string.Join("|", num.ToString(), val.x.ToString("R", CultureInfo.InvariantCulture), val.y.ToString("R", CultureInfo.InvariantCulture), val.z.ToString("R", CultureInfo.InvariantCulture), radius.ToString("R", CultureInfo.InvariantCulture), knock.ToString("R", CultureInfo.InvariantCulture));
				UltimateFx(text);
				try
				{
					MyceliumNetwork.RPC(2817742601u, "UltimateFx", (ReliableType)1, new object[1] { text });
				}
				catch
				{
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("UltimateRequest failed: " + ex.Message));
			}
		}

		[CustomRPC]
		public void SmashRequest(string payload)
		{
			//IL_00cc: 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)
			if (!IsHost())
			{
				return;
			}
			try
			{
				string[] array = payload.Split('|');
				if (array.Length != 7)
				{
					return;
				}
				ulong num = ulong.Parse(array[0]);
				Vector3 point = default(Vector3);
				((Vector3)(ref point))..ctor(float.Parse(array[1], CultureInfo.InvariantCulture), float.Parse(array[2], CultureInfo.InvariantCulture), float.Parse(array[3], CultureInfo.InvariantCulture));
				Vector3 ownerPos = default(Vector3);
				((Vector3)(ref ownerPos))..ctor(float.Parse(array[4], CultureInfo.InvariantCulture), float.Parse(array[5], CultureInfo.InvariantCulture), float.Parse(array[6], CultureInfo.InvariantCulture));
				float unscaledTime = Time.unscaledTime;
				if (_nextSmash.TryGetValue(num, out var value) && unscaledTime < value)
				{
					return;
				}
				_nextSmash[num] = unscaledTime + Mathf.Clamp(_netSmashCooldown, 0.4f, 10f);
				ApplySmashAuthoritative(num, ownerPos, point);
				string text = string.Join("|", num.ToString(), point.x.ToString("R", CultureInfo.InvariantCulture), point.y.ToString("R", CultureInfo.InvariantCulture), point.z.ToString("R", CultureInfo.InvariantCulture), Mathf.Clamp(_netSmashRadius, 1.5f, 9f).ToString("R", CultureInfo.InvariantCulture), Mathf.Clamp(_netSmashKnockback, 0f, 260f).ToString("R", CultureInfo.InvariantCulture));
				SmashFx(text);
				try
				{
					MyceliumNetwork.RPC(2817742601u, "SmashFx", (ReliableType)1, new object[1] { text });
				}
				catch
				{
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("SmashRequest failed: " + ex.Message));
			}
		}

		[CustomRPC]
		public void FlightRequest(string payload)
		{
			if (!IsHost() || !ulong.TryParse(payload, out var result))
			{
				return;
			}
			float unscaledTime = Time.unscaledTime;
			if (_nextFlight.TryGetValue(result, out var value) && unscaledTime < value)
			{
				return;
			}
			_nextFlight[result] = unscaledTime + Mathf.Clamp(_netFlightCooldown, 0.5f, 15f);
			string text = result + "|" + Mathf.Clamp(_netFlightForce, 20f, 240f).ToString("R", CultureInfo.InvariantCulture);
			FlightApprove(text);
			try
			{
				MyceliumNetwork.RPC(2817742601u, "FlightApprove", (ReliableType)1, new object[1] { text });
			}
			catch
			{
			}
		}

		[CustomRPC]
		public void FlightApprove(string payload)
		{
		}

		private IEnumerator ApplyMjolnirFlightImpulse(Vector3 dir, Vector3 look, float force)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_localFpc == (Object)null)
			{
				yield break;
			}
			Vector3 launchDir = ((Vector3)(ref look)).normalized;
			if (Mathf.Abs(launchDir.y) < 0.16f)
			{
				Vector3 val = launchDir + Vector3.up * 0.16f;
				launchDir = ((Vector3)(ref val)).normalized;
			}
			ForceAirborneState(_localFpc);
			_localFpc.CustomAddForce(launchDir, force);
			for (int i = 0; i < 3; i++)
			{
				yield return (object)new WaitForFixedUpdate();
				if ((Object)(object)_localFpc == (Object)null)
				{
					break;
				}
				ForceAirborneState(_localFpc);
				_localFpc.CustomAddForce(launchDir, force * i switch
				{
					1 => 0.24f, 
					0 => 0.38f, 
					_ => 0.14f, 
				});
				if (look.y < -0.22f)
				{
					AddMoveDirectionAssist(_localFpc, launchDir * force * 0.013f);
					ApplyDiveTranslationAssist(_localFpc, launchDir, force);
				}
			}
		}

		private void ApplyDiveTranslationAssist(FirstPersonController fpc, Vector3 dir, float force)
		{
			//IL_0009: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)fpc == (Object)null || dir.y >= -0.15f)
			{
				return;
			}
			try
			{
				CharacterController component = ((Component)fpc).GetComponent<CharacterController>();
				if ((Object)(object)component != (Object)null && ((Collider)component).enabled)
				{
					float num = Mathf.Clamp(force * 0.00065f, 0.035f, 0.11f);
					component.Move(((Vector3)(ref dir)).normalized * num);
				}
			}
			catch
			{
			}
		}

		private void WriteDirectMovementVelocity(FirstPersonController fpc, Vector3 velocity)
		{
			//IL_012c: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)fpc == (Object)null)
			{
				return;
			}
			bool flag = false;
			string[] array = new string[4] { "moveDirection", "playerVelocity", "velocity", "_velocity" };
			foreach (string text in array)
			{
				try
				{
					FieldInfo field = ((object)fpc).GetType().GetField(text, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (!(field != null) || !(field.FieldType == typeof(Vector3)) || field.IsInitOnly)
					{
						goto IL_0098;
					}
					field.SetValue(fpc, velocity);
					flag = true;
					if (!(text == "moveDirection"))
					{
						goto IL_0098;
					}
					goto end_IL_003e;
					IL_0098:
					PropertyInfo property = ((object)fpc).GetType().GetProperty(text, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (property != null && property.CanWrite && property.PropertyType == typeof(Vector3))
					{
						property.SetValue(fpc, velocity);
						flag = true;
						if (!(text == "moveDirection"))
						{
							continue;
						}
						break;
					}
					continue;
					end_IL_003e:;
				}
				catch
				{
					continue;
				}
				break;
			}
			try
			{
				Rigidbody component = ((Component)fpc).GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					component.velocity = velocity;
					flag = true;
				}
			}
			catch
			{
			}
			if (!flag)
			{
				fpc.CustomAddForce(((Vector3)(ref velocity)).normalized, ((Vector3)(ref velocity)).magnitude * 7f);
			}
		}

		private void ForceAirborneState(FirstPersonController fpc)
		{
			if ((Object)(object)fpc == (Object)null)
			{
				return;
			}
			string[] array = new string[4] { "isGrounded", "grounded", "onGround", "isOnGround" };
			foreach (string name in array)
			{
				try
				{
					FieldInfo field = ((object)fpc).GetType().GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (field != null && field.FieldType == typeof(bool) && !field.IsInitOnly)
					{
						field.SetValue(fpc, false);
					}
					PropertyInfo property = ((object)fpc).GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (property != null && property.CanWrite && property.PropertyType == typeof(bool))
					{
						property.SetValue(fpc, false);
					}
				}
				catch
				{
				}
			}
		}

		private void AddMoveDirectionAssist(FirstPersonController fpc, Vector3 delta)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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)
			if ((Object)(object)fpc == (Object)null)
			{
				return;
			}
			string[] array = new string[4] { "moveDirection", "velocity", "playerVelocity", "_velocity" };
			foreach (string name in array)
			{
				try
				{
					FieldInfo field = ((object)fpc).GetType().GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (field != null && field.FieldType == typeof(Vector3) && !field.IsInitOnly)
					{
						Vector3 val = (Vector3)field.GetValue(fpc);
						field.SetValue(fpc, val + delta);
						break;
					}
					PropertyInfo property = ((object)fpc).GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (property != null && property.CanRead && property.CanWrite && property.PropertyType == typeof(Vector3))
					{
						Vector3 val2 = (Vector3)property.GetValue(fpc);
						property.SetValue(fpc, val2 + delta);
						break;
					}
				}
				catch
				{
				}
			}
		}

		private void ApplySmashAuthoritative(ulong ownerSid, Vector3 ownerPos, Vector3 point)
		{
			//IL_0044: 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)
			float radius = Mathf.Clamp(_netSmashRadius, 1.5f, 9f);
			float centerDamage = Mathf.Clamp(_netSmashDamage, 0f, 8f);
			float knock = Mathf.Clamp(_netSmashKnockback, 0f, 260f);
			ApplyAreaEffect(ownerSid, point, radius, centerDamage, knock, ownerPos);
		}

		private void ApplyAreaEffect(ulong ownerSid, Vector3 point, float radius, float centerDamage, float knock)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			ApplyAreaEffect(ownerSid, point, radius, centerDamage, knock, Vector3.zero);
		}

		private void ApplyAreaEffect(ulong ownerSid, Vector3 point, float radius, float centerDamage, float knock, Vector3 ownerPos)
		{
			//IL_0002: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			PlayerHealth val = ResolveSmashOwner(ownerSid, ownerPos);
			Transform val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform.root : null);
			Transform val3 = (((Object)(object)val != (Object)null && (Object)(object)val.controller != (Object)null) ? ((Component)val.controller).transform : null);
			Collider[] source = Physics.OverlapSphere(point, radius);
			bool flag = false;
			foreach (PlayerHealth item in (from c in source
				select ((Component)c).GetComponentInParent<PlayerHealth>() into x
				where (Object)(object)x != (Object)null
				select x).Distinct())
			{
				if (item.sync___get_value_isKilled())
				{
					continue;
				}
				ulong steamIdForPlayerHealth = GetSteamIdForPlayerHealth(item);
				if ((Object)(object)item == (Object)(object)val || steamIdForPlayerHealth == ownerSid || ((Object)(object)val2 != (Object)null && (Object)(object)((Component)item).transform.root == (Object)(object)val2) || (Object)(object)item.controller == (Object)null)
				{
					continue;
				}
				Vector3 val4 = ((Component)item.controller).transform.position - point;
				float num = Mathf.Clamp(((Vector3)(ref val4)).magnitude, 0f, radius);
				float num2 = 0.35f + 0.65f * (1f - num / radius);
				if (centerDamage > 0f)
				{
					float num3 = centerDamage * num2;
					if (num <= 1.1f)
					{
						num3 += 0.45f * (1f - Mathf.Clamp01(num / 1.1f));
					}
					if (num <= 1.35f && IsHeadImpact(item, point))
					{
						num3 += 0.75f;
					}
					item.RemoveHealth(num3);
					if ((Object)(object)val3 != (Object)null)
					{
						try
						{
							item.SetKiller(val3);
						}
						catch
						{
						}
					}
				}
				flag = true;
			}
			if (flag)
			{
				SendHitmarker(ownerSid);
			}
			foreach (Rigidbody item2 in (from c in source
				select c.attachedRigidbody into r
				where (Object)(object)r != (Object)null
				select r).Distinct())
			{
				if ((Object)(object)val2 != (Object)null && ((Component)item2).transform.IsChildOf(val2))
				{
					continue;
				}
				PlayerHealth componentInParent = ((Component)item2).GetComponentInParent<PlayerHealth>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					ulong steamIdForPlayerHealth2 = GetSteamIdForPlayerHealth(componentInParent);
					if ((Object)(object)componentInParent == (Object)(object)val || steamIdForPlayerHealth2 == ownerSid || ((Object)(object)val2 != (Object)null && (Object)(object)((Component)componentInParent).transform.root == (Object)(object)val2))
					{
						continue;
					}
				}
				Vector3 val5 = item2.worldCenterOfMass - point;
				float num4 = Mathf.Max(0.5f, ((Vector3)(ref val5)).magnitude);
				Vector3 val6 = ((Vector3)(ref val5)).normalized + Vector3.up * 0.25f;
				item2.AddForce(((Vector3)(ref val6)).normalized * (knock * 0.75f / Mathf.Max(1f, num4 * 0.3f)), (ForceMode)1);
			}
		}

		private bool IsHeadImpact(PlayerHealth ph, Vector3 impactPoint)
		{
			//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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ph == (Object)null)
			{
				return false;
			}
			try
			{
				Collider[] componentsInChildren = ((Component)ph).GetComponentsInChildren<Collider>(true);
				foreach (Collider val in componentsInChildren)
				{
					if (!((Object)(object)val == (Object)null))
					{
						string text = (((Object)val).name ?? "").ToLowerInvariant();
						string text2 = (((Object)(object)((Component)val).transform.parent != (Object)null) ? (((Object)((Component)val).transform.parent).name ?? "").ToLowerInvariant() : "");
						if ((text.Contains("head") || text2.Contains("head")) && Vector3.Distance(val.ClosestPoint(impactPoint), impactPoint) <= 0.42f)
						{
							return true;
						}
					}
				}
				Transform[] componentsInChildren2 = ((Component)ph).GetComponentsInChildren<Transform>(true);
				foreach (Transform val2 in componentsInChildren2)
				{
					if (!((Object)(object)val2 == (Object)null) && (((Object)val2).name ?? "").ToLowerInvariant().Contains("head") && Vector3.Distance(val2.position, impactPoint) <= 0.52f)
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private PlayerHealth ResolveSmashOwner(ulong ownerSid, Vector3 ownerPos)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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)
			PlayerHealth playerHealthForSteamId = GetPlayerHealthForSteamId(ownerSid);
			if ((Object)(object)playerHealthForSteamId != (Object)null)
			{
				return playerHealthForSteamId;
			}
			PlayerHealth result = null;
			float num = float.MaxValue;
			PlayerHealth[] array = Resources.FindObjectsOfTypeAll<PlayerHealth>();
			foreach (PlayerHealth val in array)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val.controller == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null)
				{
					continue;
				}
				Scene scene = ((Component)val).gameObject.scene;
				if (((Scene)(ref scene)).IsValid())
				{
					Vector3 val2 = ((Component)val.controller).transform.position - ownerPos;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
						result = val;
					}
				}
			}
			if (!(num <= 9f))
			{
				return null;
			}
			return result;
		}

		private void SendPlayerKnockback(ulong victimSid, Vector3 victimPos, Vector3 dir, float force)
		{
			string text = string.Join("|", victimSid.ToString(), victimPos.x.ToString("R", CultureInfo.InvariantCulture), victimPos.y.ToString("R", CultureInfo.InvariantCulture), victimPos.z.ToString("R", CultureInfo.InvariantCulture), dir.x.ToString("R", CultureInfo.InvariantCulture), dir.y.ToString("R", CultureInfo.InvariantCulture), dir.z.ToString("R", CultureInfo.InvariantCulture), force.ToString("R", CultureInfo.InvariantCulture));
			KnockbackApprove(text);
			try
			{
				MyceliumNetwork.RPC(2817742601u, "KnockbackApprove", (ReliableType)1, new object[1] { text });
			}
			catch
			{
			}
		}

		[CustomRPC]
		public void KnockbackApprove(string payload)
		{
			//IL_0073: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string[] array = payload.Split('|');
				if (array.Length != 8)
				{
					return;
				}
				ulong num = ulong.Parse(array[0]);
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(float.Parse(array[1], CultureInfo.InvariantCulture), float.Parse(array[2], CultureInfo.InvariantCulture), float.Parse(array[3], CultureInfo.InvariantCulture));
				Vector3 val2 = new Vector3(float.Parse(array[4], CultureInfo.InvariantCulture), float.Parse(array[5], CultureInfo.InvariantCulture), float.Parse(array[6], CultureInfo.InvariantCulture));
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				float num2 = float.Parse(array[7], CultureInfo.InvariantCulture);
				RefreshLocalHolder();
				if (!((Object)(object)_localFpc == (Object)null))
				{
					ulong ownSteamId = GetOwnSteamId();
					float num3 = Vector3.Distance(((Component)_localFpc).transform.position, val);
					if ((num != 0L && ownSteamId == num) || num3 < 1.75f)
					{
						_localFpc.CustomAddForce(normalized, num2);
						((MonoBehaviour)this).StartCoroutine(ReinforceReceivedKnockback(normalized, num2));
					}
				}
			}
			catch
			{
			}
		}

		private IEnumerator ReinforceReceivedKnockback(Vector3 dir, float force)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			yield return (object)new WaitForFixedUpdate();
			if ((Object)(object)_localFpc != (Object)null)
			{
				_localFpc.CustomAddForce(dir, force * 0.22f);
			}
		}

		private void SendHitmarker(ulong attackerSid)
		{
			string text = attackerSid.ToString();
			HitmarkerApprove(text);
			try
			{
				MyceliumNetwork.RPC(2817742601u, "HitmarkerApprove", (ReliableType)1, new object[1] { text });
			}
			catch
			{
			}
		}

		[CustomRPC]
		public void HitmarkerApprove(string payload)
		{
			if (ulong.TryParse(payload, out var result) && GetOwnSteamId() == result)
			{
				((MonoBehaviour)this).StartCoroutine(ShowHitmarker());
			}
		}

		private IEnumerator ShowHitmarker()
		{
			Camera val = null;
			try
			{
				RefreshLocalHolder();
				if ((Object)(object)_localFpc != (Object)null && (Object)(object)_localFpc.playerCameraHolder != (Object)null)
				{
					val = _localFpc.playerCameraHolder.GetComponentInChildren<Camera>(true);
				}
				if ((Object)(object)val == (Object)null)
				{
					val = Camera.main;
				}
			}
			catch
			{
			}
			if (!((Object)(object)val == (Object)null))
			{
				GameObject root = new GameObject("Mjolnir_AOE_Hitmarker");
				root.transform.SetParent(((Component)val).transform, false);
				root.transform.localPosition = new Vector3(0f, 0f, 0.55f);
				root.transform.localRotation = Quaternion.identity;
				Material val2 = new Material(Shader.Find("Sprites/Default") ?? Shader.Find("Standard"));
				val2.color = Color.white;
				Vector3[] array = (Vector3[])(object)new Vector3[8]
				{
					new Vector3(-0.03f, 0.03f, 0f),
					new Vector3(-0.01f, 0.01f, 0f),
					new Vector3(0.03f, 0.03f, 0f),
					new Vector3(0.01f, 0.01f, 0f),
					new Vector3(-0.03f, -0.03f, 0f),
					new Vector3(-0.01f, -0.01f, 0f),
					new Vector3(0.03f, -0.03f, 0f),
					new Vector3(0.01f, -0.01f, 0f)
				};
				for (int i = 0; i < 4; i++)
				{
					GameObject val3 = new GameObject("HitmarkerStroke");
					val3.transform.SetParent(root.transform, false);
					LineRenderer obj2 = val3.AddComponent<LineRenderer>();
					obj2.useWorldSpace = false;
					obj2.positionCount = 2;
					obj2.startWidth = 0.0045f;
					obj2.endWidth = 0.0045f;
					((Renderer)obj2).sharedMaterial = val2;
					obj2.SetPosition(0, array[i * 2]);
					obj2.SetPosition(1, array[i * 2 + 1]);
				}
				yield return (object)new WaitForSecondsRealtime(0.12f);
				if ((Object)(object)root != (Object)null)
				{
					Object.Destroy((Object)(object)root);
				}
			}
		}

		[CustomRPC]
		public void SmashFx(string payload)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string[] array = payload.Split('|');
				if (array.Length == 6)
				{
					ulong ownerSid = ulong.Parse(array[0]);
					Vector3 point = default(Vector3);
					((Vector3)(ref point))..ctor(float.Parse(array[1], CultureInfo.InvariantCulture), float.Parse(array[2], CultureInfo.InvariantCulture), float.Parse(array[3], CultureInfo.InvariantCulture));
					float radius = float.Parse(array[4], CultureInfo.InvariantCulture);
					float knock = float.Parse(array[5], CultureInfo.InvariantCulture);
					((MonoBehaviour)this).StartCoroutine(LightningFx(point));
					ApplyLocalAoeKnockback(ownerSid, point, radius, knock);
				}
			}
			catch
			{
			}
		}

		private void ApplyLocalAoeKnockback(ulong ownerSid, Vector3 point, float radius, float knock)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//