Decompiled source of NightWolfHawk v0.7.5

plugins/NightWolfHawk/NightWolfHawk.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FMOD;
using FMODUnity;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.Tables;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("NightWolfHawk")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+71efdebfbc8b9be62fa68a9147899d0dc6f137b0")]
[assembly: AssemblyProduct("NightWolfHawk")]
[assembly: AssemblyTitle("NightWolfHawk")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 NightWolfHawk
{
	public static class NightWolfHawkRules
	{
		public static float WeightForFiftyPercentChance(float existingPoolWeight)
		{
			return Math.Max(0f, existingPoolWeight);
		}

		public static bool ShouldRequestStartingItem(bool debugEnabled, bool alreadyRequested)
		{
			if (debugEnabled)
			{
				return !alreadyRequested;
			}
			return false;
		}

		public static bool ShouldDistractRecipient(bool isSender, bool isReady)
		{
			return !isSender && isReady;
		}

		public static bool ShouldSelfTarget(int opponentCount, bool debugEnabled)
		{
			if (debugEnabled)
			{
				return opponentCount == 0;
			}
			return false;
		}

		public static bool ShouldConsumeItem(int connectedPlayerCount, bool infiniteSoloUses)
		{
			if (infiniteSoloUses)
			{
				return connectedPlayerCount > 1;
			}
			return true;
		}
	}
	[BepInPlugin("com.shadowforce.sbg.nightwolfhawk", "Night Wolf Hawk", "0.7.5")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private enum ScreenEdge
		{
			Bottom,
			Top,
			Left,
			Right
		}

		[HarmonyPatch(typeof(BNetworkManager), "OnStartClient")]
		private static class NetworkRegistrationPatch
		{
			private static void Postfix()
			{
				RegisterNetworkMessages();
			}
		}

		[HarmonyPatch(typeof(ItemCollection), "Initialize")]
		private static class ItemCollectionPatch
		{
			private static readonly FieldInfo ItemsField = AccessTools.Field(typeof(ItemCollection), "items");

			private static readonly FieldInfo ItemDataField = AccessTools.Field(typeof(ItemCollection), "allItemData");

			private static void Postfix(ItemCollection __instance)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_0126: Unknown result type (might be due to invalid IL or missing references)
				//IL_013b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0145: Expected I4, but got Unknown
				Dictionary<ItemType, ItemData> dictionary = (Dictionary<ItemType, ItemData>)ItemDataField.GetValue(__instance);
				if (dictionary.ContainsKey(Item) || !dictionary.TryGetValue((ItemType)4, out var value))
				{
					return;
				}
				ItemData val = new ItemData();
				PropertyInfo[] properties = typeof(ItemData).GetProperties(BindingFlags.Instance | BindingFlags.Public);
				foreach (PropertyInfo propertyInfo in properties)
				{
					if (propertyInfo.CanRead && propertyInfo.CanWrite)
					{
						propertyInfo.SetValue(val, propertyInfo.GetValue(value));
					}
				}
				AccessTools.Property(typeof(ItemData), "Type").SetValue(val, Item);
				AccessTools.Property(typeof(ItemData), "MaxUses").SetValue(val, 1);
				AccessTools.Property(typeof(ItemData), "Icon").SetValue(val, Instance?._icon);
				val.Initialize();
				ItemData[] array = (ItemData[])ItemsField.GetValue(__instance);
				Array.Resize(ref array, array.Length + 1);
				array[^1] = val;
				ItemsField.SetValue(__instance, array);
				dictionary[Item] = val;
				Log.LogInfo((object)$"[Night Wolf Hawk] Registered item type {(int)Item}.");
			}
		}

		[HarmonyPatch(typeof(ItemSpawnerSettings), "ResetRuntimeData")]
		private static class ItemSpawnerPatch
		{
			private static readonly FieldInfo SpawnChancesField = AccessTools.Field(typeof(ItemPool), "spawnChances");

			private static readonly FieldInfo TotalWeightField = AccessTools.Field(typeof(ItemPool), "totalSpawnChanceWeight");

			private static void Postfix(ItemSpawnerSettings __instance)
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)__instance.AheadOfBallItemPool == (Object)null))
				{
					SpawnWeights[0] = Inject(__instance.AheadOfBallItemPool);
					for (int i = 0; i < __instance.ItemPools.Count && i + 1 < SpawnWeights.Length; i++)
					{
						SpawnWeights[i + 1] = Inject(__instance.ItemPools[i].pool);
					}
					Log.LogInfo((object)"[Night Wolf Hawk] Added to regular item pools (50% each; mobility: 0%).");
				}
			}

			private static float Inject(ItemPool pool)
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: 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_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)pool == (Object)null)
				{
					return 0f;
				}
				ItemSpawnChance[] array = ((ItemSpawnChance[])SpawnChancesField.GetValue(pool)) ?? Array.Empty<ItemSpawnChance>();
				ItemSpawnChance[] array2 = array;
				foreach (ItemSpawnChance val in array2)
				{
					if (val.item == Item)
					{
						return val.spawnChanceWeight;
					}
				}
				float num = 0f;
				array2 = array;
				foreach (ItemSpawnChance val2 in array2)
				{
					num += val2.spawnChanceWeight;
				}
				float num2 = NightWolfHawkRules.WeightForFiftyPercentChance(num);
				if (num2 <= 0f)
				{
					return 0f;
				}
				ItemSpawnChance[] array3 = (ItemSpawnChance[])(object)new ItemSpawnChance[array.Length + 1];
				Array.Copy(array, array3, array.Length);
				array3[^1] = new ItemSpawnChance
				{
					item = Item,
					spawnChanceWeight = num2
				};
				SpawnChancesField.SetValue(pool, array3);
				TotalWeightField.SetValue(pool, num + num2);
				return num2;
			}
		}

		[HarmonyPatch(typeof(MatchSetupRules), "GetWeight")]
		private static class MatchSetupWeightPatch
		{
			private static void Postfix(int poolIndex, ItemType itemType, ref float __result)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				if (itemType == Item && poolIndex >= 0 && poolIndex < SpawnWeights.Length)
				{
					__result = SpawnWeights[poolIndex];
				}
			}
		}

		[HarmonyPatch(typeof(MatchSetupRules), "GetDefaultWeight")]
		private static class MatchSetupDefaultWeightPatch
		{
			private static void Postfix(int poolIndex, ItemType itemType, ref float __result)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				if (itemType == Item && poolIndex >= 0 && poolIndex < SpawnWeights.Length)
				{
					__result = SpawnWeights[poolIndex];
				}
			}
		}

		[HarmonyPatch(typeof(MatchSetupRules), "GetDefaultItemFactor")]
		private static class MatchSetupDefaultFactorPatch
		{
			private static void Postfix(int poolIndex, ItemType itemType, ref float __result)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				if (itemType == Item)
				{
					__result = ((poolIndex >= 0 && poolIndex < SpawnWeights.Length) ? 0.5f : 0f);
				}
			}
		}

		[HarmonyPatch]
		private static class MatchSetupCustomWeightChangedPatch
		{
			private static readonly MethodInfo UpdateTotalWeightMethod = AccessTools.Method(typeof(MatchSetupRules), "UpdateTotalWeightForPool", (Type[])null, (Type[])null);

			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(typeof(MatchSetupRules), "OnSpawnChanceWeightsChangedInItemPool", new Type[1] { typeof(ItemPoolId) }, (Type[])null);
			}

			private static bool Prefix(MatchSetupRules __instance, ItemPoolId itemPoolId)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				if (itemPoolId.itemType != Item)
				{
					return true;
				}
				UpdateTotalWeightMethod.Invoke(__instance, new object[1] { itemPoolId.itemPoolIndex });
				return false;
			}
		}

		[HarmonyPatch(typeof(MatchSetupRules), "Update")]
		private static class MatchSetupUpdatePatch
		{
			private static readonly FieldInfo CurrentItemPoolDirtyField = AccessTools.Field(typeof(MatchSetupRules), "currentItemPoolDirty");

			private static readonly MethodInfo GetCurrentItemPoolMethod = AccessTools.Method(typeof(MatchSetupRules), "GetCurrentItemPool", (Type[])null, (Type[])null);

			private static readonly FieldInfo CurrentItemPoolIndexField = AccessTools.Field(typeof(MatchSetupRules), "currentItemPoolIndex");

			private static readonly FieldInfo SpawnChanceWeightsField = AccessTools.Field(typeof(MatchSetupRules), "spawnChanceWeights");

			private static readonly FieldInfo SpawnChanceSlidersField = AccessTools.Field(typeof(MatchSetupRules), "spawnChanceSliders");

			private static bool Prefix(MatchSetupRules __instance)
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Expected O, but got Unknown
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f4: Expected I4, but got Unknown
				//IL_0118: Unknown result type (might be due to invalid IL or missing references)
				//IL_011a: 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_0130: 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)
				if (!MatchSetupMenu.IsActive)
				{
					return false;
				}
				if (!(bool)CurrentItemPoolDirtyField.GetValue(__instance))
				{
					return false;
				}
				ItemPool val = (ItemPool)GetCurrentItemPoolMethod.Invoke(__instance, null);
				int num = (int)CurrentItemPoolIndexField.GetValue(__instance);
				IDictionary<ItemPoolId, float> dictionary = (IDictionary<ItemPoolId, float>)SpawnChanceWeightsField.GetValue(__instance);
				List<SliderOption> list = (List<SliderOption>)SpawnChanceSlidersField.GetValue(__instance);
				int[] itemOrderLookup = __instance.itemOrderLookup;
				float num2 = 0f;
				ItemSpawnChance[] spawnChances = val.SpawnChances;
				foreach (ItemSpawnChance val2 in spawnChances)
				{
					ItemPoolId key = ItemPoolId.Get(num, val2.item);
					if (dictionary.ContainsKey(key))
					{
						num2 += dictionary[key];
					}
				}
				spawnChances = val.SpawnChances;
				foreach (ItemSpawnChance val3 in spawnChances)
				{
					if (val3.item == Item)
					{
						continue;
					}
					int num3 = val3.item - 1;
					if (num3 >= 0 && num3 < itemOrderLookup.Length)
					{
						int num4 = itemOrderLookup[num3];
						if (num4 >= 0 && num4 < list.Count)
						{
							ItemPoolId key2 = ItemPoolId.Get(num, val3.item);
							float num5 = ((num2 > float.Epsilon && dictionary.ContainsKey(key2)) ? (dictionary[key2] / num2) : 0f);
							list[num4].SetValueText($"{num5 * 100f:0.#}%");
						}
					}
				}
				CurrentItemPoolDirtyField.SetValue(__instance, false);
				return false;
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static class ItemNamePatch
		{
			private static bool Prefix(ItemData __instance, ref string __result)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				if (__instance.Type != Item)
				{
					return true;
				}
				__result = "Night Wolf Hawk";
				return false;
			}
		}

		[HarmonyPatch(typeof(PlayerInventory), "ServerTryAddItem")]
		private static class AddItemPatch
		{
			private static readonly FieldInfo SlotsField = AccessTools.Field(typeof(PlayerInventory), "slots");

			private static bool Prefix(PlayerInventory __instance, ItemType itemToAdd, int remainingUses, ref bool __result)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				if (itemToAdd != Item)
				{
					return true;
				}
				int index = default(int);
				if (!NetworkServer.active || !__instance.HasSpaceForItem(ref index))
				{
					__result = false;
					return false;
				}
				((IList<InventorySlot>)SlotsField.GetValue(__instance))[index] = new InventorySlot(Item, Math.Max(1, remainingUses));
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(PlayerInventory), "GetEffectivelyEquippedItem")]
		private static class EquippedItemPatch
		{
			private static void Postfix(PlayerInventory __instance, bool ignoreEquipmentHiding, ref ItemType __result)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				if (!ignoreEquipmentHiding && __instance.GetEffectivelyEquippedItem(true) == Item)
				{
					__result = (ItemType)4;
				}
			}
		}

		[HarmonyPatch(typeof(PlayerInventory), "TryUseItem")]
		private static class UseItemPatch
		{
			private static bool Prefix(PlayerInventory __instance, ref bool shouldEatInput, ref bool __result)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				if (__instance.GetEffectivelyEquippedItem(true) != Item)
				{
					return true;
				}
				if (!NetworkClient.active || !NetworkClient.ready || __instance.EquippedItemIndex < 0)
				{
					__result = false;
					return false;
				}
				NetworkClient.Send<NightWolfHawkUseRequest>(new NightWolfHawkUseRequest
				{
					SlotIndex = __instance.EquippedItemIndex
				}, 0);
				shouldEatInput = true;
				__result = true;
				return false;
			}
		}

		public const string PluginGuid = "com.shadowforce.sbg.nightwolfhawk";

		public const string PluginName = "Night Wolf Hawk";

		public const string PluginVersion = "0.7.5";

		public const string ItemName = "Night Wolf Hawk";

		public static readonly ItemType Item = (ItemType)220;

		internal static Plugin? Instance;

		internal static ManualLogSource Log = null;

		internal static ConfigEntry<bool> GrantStartingItem = null;

		internal static ConfigEntry<bool> SelfTargetWhenAlone = null;

		internal static ConfigEntry<bool> AutoUseWhenAlone = null;

		internal static ConfigEntry<bool> InfiniteUsesWhenAlone = null;

		private Harmony? _harmony;

		private PlayerInventory? _announcedInventory;

		private bool _itemNameRegistered;

		private Texture2D? _image;

		private Sprite? _icon;

		private readonly List<string> _sounds = new List<string>();

		private float _distractionStartedAt = float.NegativeInfinity;

		private float _distractionDuration;

		private ScreenEdge _screenEdge;

		private const float SlideInSeconds = 0.45f;

		private const float SlideOutSeconds = 0.55f;

		private const float MinimumVisibleSeconds = 3.5f;

		private const float BottomCrop = 36f;

		private static readonly float[] SpawnWeights = new float[5];

		private string AssetDirectory => Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "assets");

		private void Awake()
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			GrantStartingItem = ((BaseUnityPlugin)this).Config.Bind<bool>("Testing", "GrantStartingItem", false, "Add Night Wolf Hawk to your inventory when joining for testing.");
			SelfTargetWhenAlone = ((BaseUnityPlugin)this).Config.Bind<bool>("Testing", "SelfTargetWhenAlone", false, "Echo the distraction to the user when no opponents are connected.");
			AutoUseWhenAlone = ((BaseUnityPlugin)this).Config.Bind<bool>("Testing", "AutoUseWhenAlone", false, "Automatically use Night Wolf Hawk after joining a solo session.");
			InfiniteUsesWhenAlone = ((BaseUnityPlugin)this).Config.Bind<bool>("Testing", "InfiniteUsesWhenAlone", true, "Do not consume Night Wolf Hawk when it is used in a solo session.");
			LoadImage();
			LoadSounds();
			_harmony = new Harmony("com.shadowforce.sbg.nightwolfhawk");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Night Wolf Hawk 0.7.5 loaded (no Issa dependency).");
		}

		private void OnDestroy()
		{
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			if ((Object)(object)_icon != (Object)null)
			{
				Object.Destroy((Object)(object)_icon);
			}
			if ((Object)(object)_image != (Object)null)
			{
				Object.Destroy((Object)(object)_image);
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void Update()
		{
			if (!_itemNameRegistered)
			{
				_itemNameRegistered = TryRegisterItemName();
			}
			if (!NetworkClient.active || !NetworkClient.ready)
			{
				_announcedInventory = null;
				return;
			}
			PlayerInventory localPlayerInventory = GameManager.LocalPlayerInventory;
			if (!((Object)(object)localPlayerInventory == (Object)null) && NightWolfHawkRules.ShouldRequestStartingItem(GrantStartingItem.Value, (Object)(object)localPlayerInventory == (Object)(object)_announcedInventory))
			{
				_announcedInventory = localPlayerInventory;
				NetworkClient.Send<NightWolfHawkReadyMessage>(default(NightWolfHawkReadyMessage), 0);
				if (AutoUseWhenAlone.Value && NetworkServer.active && NetworkServer.connections.Count <= 1)
				{
					((MonoBehaviour)this).StartCoroutine(AutoUse(localPlayerInventory));
				}
			}
		}

		private bool TryRegisterItemName()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected I4, but got Unknown
			try
			{
				StringTable table = ((LocalizedDatabase<StringTable, StringTableEntry>)(object)LocalizationSettings.StringDatabase).GetTable(TableReference.op_Implicit("Data"), (Locale)null);
				if ((Object)(object)table == (Object)null)
				{
					return false;
				}
				((DetailedLocalizationTable<StringTableEntry>)(object)table).AddEntry($"ITEM_{(int)Item}", "Night Wolf Hawk");
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[Night Wolf Hawk] Registered friendly item name 'Night Wolf Hawk'.");
				return true;
			}
			catch
			{
				return false;
			}
		}

		private IEnumerator AutoUse(PlayerInventory inventory)
		{
			yield return (object)new WaitForSecondsRealtime(1f);
			IList<InventorySlot> list = (IList<InventorySlot>)AccessTools.Field(typeof(PlayerInventory), "slots").GetValue(inventory);
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].itemType == Item)
				{
					NetworkClient.Send<NightWolfHawkUseRequest>(new NightWolfHawkUseRequest
					{
						SlotIndex = i
					}, 0);
					((BaseUnityPlugin)this).Logger.LogInfo((object)"[Night Wolf Hawk] Solo auto-use test requested.");
					yield break;
				}
			}
			((BaseUnityPlugin)this).Logger.LogWarning((object)"[Night Wolf Hawk] Solo auto-use could not find the item.");
		}

		private string ChooseSoundFileName()
		{
			if (_sounds.Count != 0)
			{
				return Path.GetFileName(_sounds[Random.Range(0, _sounds.Count)]);
			}
			return string.Empty;
		}

		internal void ShowDistraction(string soundFileName)
		{
			string text = _sounds.Find((string path) => string.Equals(Path.GetFileName(path), soundFileName, StringComparison.OrdinalIgnoreCase));
			float num = 0f;
			if (text != null)
			{
				num = PlaySound(text);
			}
			else if (!string.IsNullOrEmpty(soundFileName))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[Night Wolf Hawk] Server selected missing sound " + soundFileName + "."));
			}
			_screenEdge = (ScreenEdge)Random.Range(0, 4);
			_distractionStartedAt = Time.unscaledTime;
			_distractionDuration = Mathf.Max(3.5f, num + 0.55f);
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Night Wolf Hawk] Opponent distraction shown from {_screenEdge} using {soundFileName}.");
		}

		private float PlaySound(string path)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			System coreSystem = RuntimeManager.CoreSystem;
			Sound val2 = default(Sound);
			RESULT val = ((System)(ref coreSystem)).createSound(path, (MODE)16392, ref val2);
			if ((int)val != 0)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"[Night Wolf Hawk] FMOD could not open {Path.GetFileName(path)}: {val}.");
				return 0f;
			}
			uint num = default(uint);
			((Sound)(ref val2)).getLength(ref num, (TIMEUNIT)1);
			coreSystem = RuntimeManager.CoreSystem;
			Channel channel = default(Channel);
			val = ((System)(ref coreSystem)).playSound(val2, default(ChannelGroup), true, ref channel);
			if ((int)val != 0)
			{
				((Sound)(ref val2)).release();
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"[Night Wolf Hawk] FMOD could not play {Path.GetFileName(path)}: {val}.");
				return 0f;
			}
			((Channel)(ref channel)).setVolume(GetGameSfxVolume());
			((Channel)(ref channel)).setPaused(false);
			float num2 = (float)num / 1000f;
			((MonoBehaviour)this).StartCoroutine(MaintainSound(val2, channel, num2 + 0.25f));
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Night Wolf Hawk] FMOD playing {Path.GetFileName(path)} ({num2:0.0}s).");
			return num2;
		}

		private static float GetGameSfxVolume()
		{
			return Mathf.Clamp01(GameSettings.All.Audio.MasterVolume * GameSettings.All.Audio.SfxVolume);
		}

		private static IEnumerator MaintainSound(Sound sound, Channel channel, float duration)
		{
			//IL_0007: 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)
			//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)
			float endTime = Time.unscaledTime + duration;
			while (Time.unscaledTime < endTime)
			{
				((Channel)(ref channel)).setVolume(GetGameSfxVolume());
				yield return null;
			}
			((Sound)(ref sound)).release();
		}

		private void OnGUI()
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_image == (Object)null)
			{
				return;
			}
			float num = Time.unscaledTime - _distractionStartedAt;
			if (!(num < 0f) && !(num >= _distractionDuration))
			{
				float num2 = Mathf.Min(340f, (float)Screen.width * 0.22f);
				float num3 = num2 * (float)((Texture)_image).height / (float)((Texture)_image).width;
				float progress = 1f;
				if (num < 0.45f)
				{
					progress = Mathf.SmoothStep(0f, 1f, num / 0.45f);
				}
				else if (num > _distractionDuration - 0.55f)
				{
					progress = 1f - Mathf.SmoothStep(0f, 1f, (num - (_distractionDuration - 0.55f)) / 0.55f);
				}
				Vector2 imageCenter = GetImageCenter(_screenEdge, progress, num2, num3);
				float num4 = _screenEdge switch
				{
					ScreenEdge.Top => 180f, 
					ScreenEdge.Left => 90f, 
					ScreenEdge.Right => -90f, 
					_ => 0f, 
				};
				float num5 = 1f + 0.035f * Mathf.Abs(Mathf.Sin(num * 8f));
				float num6 = num4 + 1.75f * Mathf.Sin(num * 11f);
				num2 *= num5;
				num3 *= num5;
				Matrix4x4 matrix = GUI.matrix;
				GUIUtility.RotateAroundPivot(num6, imageCenter);
				GUI.DrawTexture(new Rect(imageCenter.x - num2 / 2f, imageCenter.y - num3 / 2f, num2, num3), (Texture)(object)_image, (ScaleMode)2, true);
				GUI.matrix = matrix;
			}
		}

		private static Vector2 GetImageCenter(ScreenEdge edge, float progress, float width, float height)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			return (Vector2)(edge switch
			{
				ScreenEdge.Top => new Vector2((float)Screen.width - width / 2f - 18f, Mathf.Lerp((0f - height) / 2f, height / 2f - 36f, progress)), 
				ScreenEdge.Left => new Vector2(Mathf.Lerp((0f - height) / 2f, height / 2f - 36f, progress), (float)Screen.height - width / 2f - 18f), 
				ScreenEdge.Right => new Vector2(Mathf.Lerp((float)Screen.width + height / 2f, (float)Screen.width - height / 2f + 36f, progress), (float)Screen.height - width / 2f - 18f), 
				_ => new Vector2((float)Screen.width - width / 2f - 18f, Mathf.Lerp((float)Screen.height + height / 2f, (float)Screen.height - height / 2f + 36f, progress)), 
			});
		}

		private void LoadImage()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_00be: 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)
			string text = Path.Combine(AssetDirectory, "night-wolf-hawk-person.png");
			if (!File.Exists(text))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[Night Wolf Hawk] Missing image: " + text));
				return;
			}
			_image = new Texture2D(2, 2, (TextureFormat)4, false)
			{
				name = "Night Wolf Hawk",
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			if (!ImageConversion.LoadImage(_image, File.ReadAllBytes(text), true))
			{
				Object.Destroy((Object)(object)_image);
				_image = null;
				((BaseUnityPlugin)this).Logger.LogError((object)("[Night Wolf Hawk] Could not decode image: " + text));
			}
			else
			{
				_icon = Sprite.Create(_image, new Rect(0f, 0f, (float)((Texture)_image).width, (float)((Texture)_image).height), new Vector2(0.5f, 0.5f), 100f);
				((Object)_icon).name = "Night Wolf Hawk Inventory Icon";
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Night Wolf Hawk] Loaded image {((Texture)_image).width}x{((Texture)_image).height}.");
			}
		}

		private void LoadSounds()
		{
			if (Directory.Exists(AssetDirectory))
			{
				string[] files = Directory.GetFiles(AssetDirectory, "*.mp3");
				foreach (string item in files)
				{
					_sounds.Add(item);
				}
				if (_sounds.Count == 0)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"[Night Wolf Hawk] No MP3 sounds were found.");
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Night Wolf Hawk] Found {_sounds.Count} MP3 sound(s).");
				}
			}
		}

		private static void RegisterNetworkMessages()
		{
			Writer<NightWolfHawkReadyMessage>.write = delegate
			{
			};
			Reader<NightWolfHawkReadyMessage>.read = (NetworkReader _) => default(NightWolfHawkReadyMessage);
			Writer<NightWolfHawkUseRequest>.write = delegate(NetworkWriter writer, NightWolfHawkUseRequest message)
			{
				NetworkWriterExtensions.WriteInt(writer, message.SlotIndex);
			};
			Reader<NightWolfHawkUseRequest>.read = (NetworkReader reader) => new NightWolfHawkUseRequest
			{
				SlotIndex = NetworkReaderExtensions.ReadInt(reader)
			};
			Writer<NightWolfHawkDistractionMessage>.write = delegate(NetworkWriter writer, NightWolfHawkDistractionMessage message)
			{
				NetworkWriterExtensions.WriteString(writer, message.SoundFileName);
			};
			Reader<NightWolfHawkDistractionMessage>.read = (NetworkReader reader) => new NightWolfHawkDistractionMessage
			{
				SoundFileName = NetworkReaderExtensions.ReadString(reader)
			};
			NetworkClient.RegisterHandler<NightWolfHawkDistractionMessage>((Action<NightWolfHawkDistractionMessage>)delegate(NightWolfHawkDistractionMessage message)
			{
				Instance?.ShowDistraction(message.SoundFileName);
			}, true);
			if (NetworkServer.active)
			{
				NetworkServer.RegisterHandler<NightWolfHawkReadyMessage>((Action<NetworkConnectionToClient, NightWolfHawkReadyMessage>)ServerGrantItem, true);
				NetworkServer.RegisterHandler<NightWolfHawkUseRequest>((Action<NetworkConnectionToClient, NightWolfHawkUseRequest>)ServerUseItem, true);
			}
			Log.LogInfo((object)"[Night Wolf Hawk] Network messages registered.");
		}

		private static void ServerGrantItem(NetworkConnectionToClient connection, NightWolfHawkReadyMessage _)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			NetworkIdentity identity = ((NetworkConnection)connection).identity;
			PlayerInventory val = ((identity != null) ? ((Component)identity).GetComponent<PlayerInventory>() : null);
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)"[Night Wolf Hawk] Could not find the joining player's inventory.");
			}
			else
			{
				Log.LogInfo((object)(val.ServerTryAddItem(Item, 1) ? "[Night Wolf Hawk] Added to a player's starting inventory." : "[Night Wolf Hawk] A player's inventory was full."));
			}
		}

		private static void ServerUseItem(NetworkConnectionToClient sender, NightWolfHawkUseRequest message)
		{
			//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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			NetworkIdentity identity = ((NetworkConnection)sender).identity;
			PlayerInventory val = ((identity != null) ? ((Component)identity).GetComponent<PlayerInventory>() : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			IList<InventorySlot> list = (IList<InventorySlot>)AccessTools.Field(typeof(PlayerInventory), "slots").GetValue(val);
			if (message.SlotIndex < 0 || message.SlotIndex >= list.Count || list[message.SlotIndex].itemType != Item)
			{
				Log.LogWarning((object)"[Night Wolf Hawk] Rejected an invalid use request.");
				return;
			}
			bool flag = NightWolfHawkRules.ShouldConsumeItem(NetworkServer.connections.Count, InfiniteUsesWhenAlone.Value);
			if (flag)
			{
				list[message.SlotIndex] = InventorySlot.Empty;
			}
			string text = Instance?.ChooseSoundFileName() ?? string.Empty;
			NightWolfHawkDistractionMessage nightWolfHawkDistractionMessage = new NightWolfHawkDistractionMessage
			{
				SoundFileName = text
			};
			int num = 0;
			foreach (NetworkConnectionToClient value in NetworkServer.connections.Values)
			{
				if (value != null && NightWolfHawkRules.ShouldDistractRecipient(value == sender, ((NetworkConnection)value).isReady))
				{
					((NetworkConnection)value).Send<NightWolfHawkDistractionMessage>(nightWolfHawkDistractionMessage, 0);
					num++;
				}
			}
			bool flag2 = NightWolfHawkRules.ShouldSelfTarget(num, SelfTargetWhenAlone.Value);
			if (flag2)
			{
				((NetworkConnection)sender).Send<NightWolfHawkDistractionMessage>(nightWolfHawkDistractionMessage, 0);
			}
			Log.LogInfo((object)$"[Night Wolf Hawk] Used {text}; distracted {num} opponent(s); solo self-test={flag2}; item consumed={flag}.");
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	public struct NightWolfHawkReadyMessage : NetworkMessage
	{
	}
	public struct NightWolfHawkUseRequest : NetworkMessage
	{
		public int SlotIndex;
	}
	public struct NightWolfHawkDistractionMessage : NetworkMessage
	{
		public string SoundFileName;
	}
}