Decompiled source of BugleMaestro v1.0.2

com.github.alexandria-p.BugleMaestro.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Logging;
using BugleMaestro.Helpers;
using BugleMaestro.MonoBehaviors;
using BugleMaestro.Patches;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.Networking;

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

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BugleMaestro
{
	[BepInPlugin("com.github.alexandria-p.BugleMaestro", "BugleMaestro", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony? _harmonyInstance;

		public static readonly string TEAM_NAME = "alexandria_p";

		public static readonly string MOD_NAME = "BugleMaestro";

		public static readonly string LOG_PREFIX = MOD_NAME;

		public static readonly string DEFAULT_CHARACTER_NAME = "DEFAULT_NAME";

		public Dictionary<ScaleEnum, AudioClip> baseBugleClips = new Dictionary<ScaleEnum, AudioClip>();

		public GUIManager guiManager;

		public TextMeshProUGUI itemInfoDisplayTextMesh;

		public Dictionary<string, string> fontColors = new Dictionary<string, string>();

		public float fontSize;

		public float outlineWidth;

		public float lineSpacing;

		public float sizeDeltaX;

		public const string Id = "com.github.alexandria-p.BugleMaestro";

		public static Plugin Instance { get; private set; } = null;


		internal static ManualLogSource Log { get; private set; } = null;


		public static string Name => "BugleMaestro";

		public static string Version => "1.0.0";

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			UIHelper.SetupUIElements();
			ClipHelper.SetupBaseBugleClips();
			_harmonyInstance = Harmony.CreateAndPatchAll(typeof(CharacterMovementPatch), (string)null);
			_harmonyInstance = Harmony.CreateAndPatchAll(typeof(BugleSFXPatch), (string)null);
			_harmonyInstance = Harmony.CreateAndPatchAll(typeof(CharacterItemsPatch), (string)null);
			Log.LogInfo((object)(LOG_PREFIX + ": Plugin " + Name + " is loaded!"));
		}

		private void OnDestroy()
		{
			Log.LogInfo((object)(LOG_PREFIX + ": Plugin destroying..."));
			Log.LogDebug((object)(LOG_PREFIX + ": Removing harmony patches..."));
			if (_harmonyInstance != null)
			{
				_harmonyInstance.UnpatchSelf();
			}
			else
			{
				Log.LogInfo((object)(LOG_PREFIX + ": null harmony instance OnDestroy"));
			}
			Log.LogInfo((object)(LOG_PREFIX + ": Plugin destroyed!"));
		}
	}
}
namespace BugleMaestro.Patches
{
	[HarmonyPatch(typeof(BugleSFX))]
	public class BugleSFXPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void Start_Postfix(BugleSFX __instance)
		{
			if (!Object.op_Implicit((Object)(object)((Component)__instance.item).gameObject.GetComponent<BugleMaestroBehaviour>()))
			{
				((Component)__instance.item).gameObject.AddComponent<BugleMaestroBehaviour>();
			}
		}

		[HarmonyPatch("RPC_StartToot")]
		[HarmonyPostfix]
		private static void RPC_StartToot_Postfix(BugleSFX __instance, int clip, float pitch)
		{
			BugleMaestroBehaviour component = ((Component)__instance.item).gameObject.GetComponent<BugleMaestroBehaviour>();
			__instance.bugle = (AudioClip[])(object)new AudioClip[1] { ClipHelper.ChangePitch(component.RPC_CurrentNote) };
			__instance.currentClip = 0;
			__instance.currentPitch = 1f;
			Item item = __instance.item;
			object obj;
			if (item == null)
			{
				obj = null;
			}
			else
			{
				Character holderCharacter = item.holderCharacter;
				obj = ((holderCharacter != null) ? holderCharacter.characterName : null);
			}
			if (obj == null)
			{
				obj = Plugin.DEFAULT_CHARACTER_NAME;
			}
			string text = (string)obj;
			Plugin.Log.LogInfo((object)(Plugin.LOG_PREFIX + ": " + text + " made a TOOOOOT! " + component.RPC_CurrentNote));
		}

		[HarmonyPatch("RPC_EndToot")]
		[HarmonyPostfix]
		private static void RPC_EndToot_Postfix(BugleSFX __instance)
		{
			Item item = __instance.item;
			object obj;
			if (item == null)
			{
				obj = null;
			}
			else
			{
				Character holderCharacter = item.holderCharacter;
				obj = ((holderCharacter != null) ? holderCharacter.characterName : null);
			}
			if (obj == null)
			{
				obj = Plugin.DEFAULT_CHARACTER_NAME;
			}
			string text = (string)obj;
			Plugin.Log.LogInfo((object)(Plugin.LOG_PREFIX + ": " + text + " ended toot now."));
		}
	}
	[HarmonyPatch(typeof(CharacterItems))]
	public class CharacterItemsPatch
	{
		[HarmonyPatch("DropItemRpc")]
		[HarmonyPrefix]
		private static bool DropItemRpc_Prefix(ref CharacterItems __instance, float throwCharge, byte slotID, Vector3 spawnPos, Vector3 velocity, Quaternion rotation, ItemInstanceData itemInstanceData)
		{
			Item currentItem = __instance.character.data.currentItem;
			BugleMaestroBehaviour bugleMaestroBehaviour = ((currentItem != null) ? ((Component)currentItem).gameObject.GetComponent<BugleMaestroBehaviour>() : null);
			BugleSFX val = ((currentItem != null) ? ((Component)currentItem).gameObject.GetComponent<BugleSFX>() : null);
			if (!Object.op_Implicit((Object)(object)currentItem) || (Object)(object)bugleMaestroBehaviour == (Object)null || (Object)(object)val == (Object)null)
			{
				return true;
			}
			if (val.item.holderCharacter.IsLocal)
			{
				UIHelper.HideUI();
			}
			return true;
		}

		[HarmonyPatch("DoUsing")]
		[HarmonyPrefix]
		private static bool DoUsing_Prefix(ref CharacterItems __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if ((Object)(object)__instance.character == (Object)null || (Object)(object)__instance.character.data == (Object)null || (Object)(object)__instance.character.data.currentItem == (Object)null)
			{
				return true;
			}
			BugleMaestroBehaviour buglemb = ((Component)__instance.character.data.currentItem).gameObject.GetComponent<BugleMaestroBehaviour>();
			BugleSFX buglesfx = ((Component)__instance.character.data.currentItem).gameObject.GetComponent<BugleSFX>();
			if ((Object)(object)buglemb == (Object)null || (Object)(object)buglesfx == (Object)null)
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)buglesfx.magicBugle) && buglesfx.magicBugle.currentFuel <= 0.02f)
			{
				CancelBugle();
				return true;
			}
			if (buglesfx.item.holderCharacter.data.passedOut || buglesfx.item.holderCharacter.data.fullyPassedOut)
			{
				CancelBugle();
				return true;
			}
			bool rPC_IsANoteInputBeingPressedByThePlayer = buglemb.RPC_IsANoteInputBeingPressedByThePlayer;
			bool isUsingPrimary = buglesfx.item.isUsingPrimary;
			if (buglemb.IsANewNoteChangePendingForLocalPlayer && isUsingPrimary)
			{
				CancelBugle();
			}
			if (rPC_IsANoteInputBeingPressedByThePlayer)
			{
				if (!isUsingPrimary && buglesfx.item.holderCharacter.data.currentItem.CanUsePrimary())
				{
					StartBugle();
					return false;
				}
				if (isUsingPrimary && buglesfx.item.holderCharacter.data.currentItem.CanUsePrimary())
				{
					ContinueBugle();
					return false;
				}
			}
			else if (!rPC_IsANoteInputBeingPressedByThePlayer && isUsingPrimary)
			{
				CancelBugle();
				return false;
			}
			return true;
			void CancelBugle()
			{
				if (buglesfx.item.holderCharacter.IsLocal)
				{
					UIHelper.HideUI();
				}
				buglesfx.item.CancelUsePrimary();
			}
			void ContinueBugle()
			{
				buglesfx.item.ContinueUsePrimary();
			}
			void StartBugle()
			{
				if (buglesfx.item.holderCharacter.IsLocal)
				{
					UIHelper.DisplayBugleNote(buglemb.RPC_CurrentNote);
				}
				buglesfx.item.StartUsePrimary();
				buglemb.UpdateLocalIsNotePending(newValue: false);
			}
		}
	}
	[HarmonyPatch(typeof(CharacterMovement))]
	public class CharacterMovementPatch
	{
		[HarmonyPatch("SetMovementState")]
		[HarmonyPrefix]
		private static bool SetMovementState_Prefix(ref CharacterMovement __instance)
		{
			//IL_006d: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.character.refs.view.IsMine)
			{
				return true;
			}
			Character character = __instance.character;
			object obj;
			if (character == null)
			{
				obj = null;
			}
			else
			{
				CharacterData data = character.data;
				obj = ((data != null) ? data.currentItem : null);
			}
			Item val = (Item)obj;
			BugleMaestroBehaviour bugleMaestroBehaviour = default(BugleMaestroBehaviour);
			if ((Object)(object)__instance.character == (Object)null || (Object)(object)val == (Object)null || !((Component)val).TryGetComponent<BugleMaestroBehaviour>(ref bugleMaestroBehaviour) || !bugleMaestroBehaviour.RPC_IsANoteInputBeingPressedByThePlayer)
			{
				return true;
			}
			bool flag = false;
			Enumerator<InputBinding> enumerator = CharacterInput.action_move.bindings.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					InputBinding current = enumerator.Current;
					InputControl val2 = InputSystem.FindControl(((InputBinding)(ref current)).path);
					ButtonControl val3 = (ButtonControl)(object)((val2 is ButtonControl) ? val2 : null);
					if (val3 != null && val3.isPressed && ((InputBinding)(ref current)).path != "<Keyboard>/upArrow" && ((InputBinding)(ref current)).path != "<Keyboard>/downArrow" && ((InputBinding)(ref current)).path != "<Keyboard>/leftArrow" && ((InputBinding)(ref current)).path != "<Keyboard>/rightArrow")
					{
						flag = true;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			if (!flag)
			{
				__instance.character.input.movementInput = Vector2.zero;
			}
			return true;
		}
	}
}
namespace BugleMaestro.MonoBehaviors
{
	internal class BugleMaestroBehaviour : MonoBehaviourPun
	{
		private Item? _bugleItemInstance;

		public bool IsPlaying => RPC_IsANoteInputBeingPressedByThePlayer;

		public ScaleEnum RPC_CurrentNote { get; private set; } = ScaleHelper.DEFAULT_NOTE;


		public bool RPC_IsANoteInputBeingPressedByThePlayer { get; private set; }

		public bool IsANewNoteChangePendingForLocalPlayer { get; private set; }

		public RawNoteInputEnum Local_CurrentRawNote { get; set; } = ScaleHelper.DEFAULT_RAW_NOTE;


		private OctaveEnum Local_CurrentOctave { get; set; } = ScaleHelper.DEFAULT_OCTAVE;


		private SemitoneModifierEnum Local_CurrentSemitoneModifier { get; set; } = ScaleHelper.DEFAULT_SEMITONE_MODIFIER;


		private HashSet<OctaveEnum> Local_LastFrameOctaveInput { get; set; } = new HashSet<OctaveEnum>();


		private HashSet<SemitoneModifierEnum> Local_LastFrameSemitoneInput { get; set; } = new HashSet<SemitoneModifierEnum>();


		private List<RawNoteInputEnum> Local_LastFrameRawNoteInput { get; set; } = new List<RawNoteInputEnum>();


		private void LocalPlayerSetsNote(ScaleEnum newNote)
		{
			if (((MonoBehaviourPun)this).photonView.IsMine)
			{
				((MonoBehaviourPun)this).photonView.RPC("RPC_UpdateNotePlaying", (RpcTarget)0, new object[1] { newNote });
			}
		}

		[PunRPC]
		private void RPC_UpdateNotePlaying(ScaleEnum newNote)
		{
			if (!RPC_IsANoteInputBeingPressedByThePlayer || RPC_CurrentNote != newNote)
			{
				RPC_CurrentNote = newNote;
				IsANewNoteChangePendingForLocalPlayer = true;
			}
			RPC_IsANoteInputBeingPressedByThePlayer = true;
			Item? bugleItemInstance = _bugleItemInstance;
			object obj;
			if (bugleItemInstance == null)
			{
				obj = null;
			}
			else
			{
				Character holderCharacter = bugleItemInstance.holderCharacter;
				obj = ((holderCharacter != null) ? holderCharacter.characterName : null);
			}
			if (obj == null)
			{
				obj = Plugin.DEFAULT_CHARACTER_NAME;
			}
			string text = (string)obj;
		}

		private void LocalStopInput()
		{
			if (((MonoBehaviourPun)this).photonView.IsMine && IsPlaying)
			{
				((MonoBehaviourPun)this).photonView.RPC("RPC_StopNotePlaying", (RpcTarget)0, Array.Empty<object>());
			}
		}

		[PunRPC]
		private void RPC_StopNotePlaying()
		{
			if (IsPlaying)
			{
				ResetBugleState();
			}
		}

		public void ResetBugleState()
		{
			IsANewNoteChangePendingForLocalPlayer = false;
			ResetToDefaultPitch();
			RPC_CurrentNote = ScaleHelper.DEFAULT_NOTE;
			RPC_IsANoteInputBeingPressedByThePlayer = false;
		}

		public void UpdateLocalIsNotePending(bool newValue)
		{
			IsANewNoteChangePendingForLocalPlayer = newValue;
		}

		private void Awake()
		{
			_bugleItemInstance = ((Component)this).gameObject.GetComponent<BugleSFX>()?.item;
		}

		private void Update()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Invalid comparison between Unknown and I4
			if ((Object)(object)_bugleItemInstance == (Object)null)
			{
				_bugleItemInstance = ((Component)this).gameObject.GetComponent<BugleSFX>()?.item;
				return;
			}
			if (!_bugleItemInstance.isUsingPrimary && IsPlaying)
			{
				ResetBugleState();
			}
			if ((int)_bugleItemInstance.itemState != 1 || (Object)(object)_bugleItemInstance.holderCharacter == (Object)null || !_bugleItemInstance.holderCharacter.IsLocal)
			{
				return;
			}
			HashSet<OctaveEnum> octavesBeingPressedThisFrame = new HashSet<OctaveEnum>();
			HashSet<SemitoneModifierEnum> semitonesBeingPressedThisFrame = new HashSet<SemitoneModifierEnum>();
			HashSet<RawNoteInputEnum> rawNotesBeingPressedThisFrame = new HashSet<RawNoteInputEnum>();
			if (Input.GetKey((KeyCode)274))
			{
				octavesBeingPressedThisFrame.Add(OctaveEnum.Lowest);
				SetOctave(OctaveEnum.Lowest);
			}
			if (Input.GetKey((KeyCode)273))
			{
				octavesBeingPressedThisFrame.Add(OctaveEnum.Highest);
				SetOctave(OctaveEnum.Highest);
			}
			if (!Input.GetKey((KeyCode)273) && !Input.GetKey((KeyCode)274))
			{
				octavesBeingPressedThisFrame.Add(OctaveEnum.Neutral);
				SetOctave(OctaveEnum.Neutral);
			}
			if (Input.GetKey((KeyCode)276))
			{
				semitonesBeingPressedThisFrame.Add(SemitoneModifierEnum.Flat);
				SetSemitoneModifier(SemitoneModifierEnum.Flat);
			}
			if (Input.GetKey((KeyCode)275))
			{
				semitonesBeingPressedThisFrame.Add(SemitoneModifierEnum.Sharp);
				SetSemitoneModifier(SemitoneModifierEnum.Sharp);
			}
			if (!Input.GetKey((KeyCode)276) && !Input.GetKey((KeyCode)275))
			{
				semitonesBeingPressedThisFrame.Add(SemitoneModifierEnum.Natural);
				SetSemitoneModifier(SemitoneModifierEnum.Natural);
			}
			if (Input.GetKey((KeyCode)122))
			{
				rawNotesBeingPressedThisFrame.Add(RawNoteInputEnum.C);
			}
			if (Input.GetKey((KeyCode)120))
			{
				rawNotesBeingPressedThisFrame.Add(RawNoteInputEnum.D);
			}
			if (Input.GetKey((KeyCode)99))
			{
				rawNotesBeingPressedThisFrame.Add(RawNoteInputEnum.E);
			}
			if (Input.GetKey((KeyCode)118))
			{
				rawNotesBeingPressedThisFrame.Add(RawNoteInputEnum.F);
			}
			if (Input.GetKey((KeyCode)98))
			{
				rawNotesBeingPressedThisFrame.Add(RawNoteInputEnum.G);
			}
			if (Input.GetKey((KeyCode)110))
			{
				rawNotesBeingPressedThisFrame.Add(RawNoteInputEnum.A);
			}
			if (Input.GetKey((KeyCode)109))
			{
				rawNotesBeingPressedThisFrame.Add(RawNoteInputEnum.B);
			}
			if (!Input.GetKey((KeyCode)122) && !Input.GetKey((KeyCode)120) && !Input.GetKey((KeyCode)99) && !Input.GetKey((KeyCode)118) && !Input.GetKey((KeyCode)98) && !Input.GetKey((KeyCode)110) && !Input.GetKey((KeyCode)109))
			{
				LocalStopInput();
				return;
			}
			RawNoteInputEnum? rawNoteInputEnum = FindNewTootRawNote();
			if (rawNoteInputEnum.HasValue)
			{
				SetRawNote(rawNoteInputEnum.Value);
				ScaleEnum newNote = ScaleHelper.CalculateScaleNote(Local_CurrentRawNote, Local_CurrentOctave, Local_CurrentSemitoneModifier);
				LocalPlayerSetsNote(newNote);
			}
			UpdateKeyInputTracking();
			RawNoteInputEnum? FindNewTootRawNote()
			{
				if (!rawNotesBeingPressedThisFrame.Any())
				{
					return null;
				}
				foreach (RawNoteInputEnum item in rawNotesBeingPressedThisFrame)
				{
					if (!RPC_IsANoteInputBeingPressedByThePlayer || !Local_LastFrameRawNoteInput.Contains(item))
					{
						return item;
					}
				}
				if (Local_LastFrameOctaveInput.SetEquals(octavesBeingPressedThisFrame) && Local_LastFrameSemitoneInput.SetEquals(semitonesBeingPressedThisFrame))
				{
					if (rawNotesBeingPressedThisFrame.Contains(Local_CurrentRawNote))
					{
						return null;
					}
					for (int num = Local_LastFrameRawNoteInput.Count - 1; num >= 0; num--)
					{
						RawNoteInputEnum rawNoteInputEnum2 = Local_LastFrameRawNoteInput[num];
						if (rawNotesBeingPressedThisFrame.Contains(rawNoteInputEnum2))
						{
							return rawNoteInputEnum2;
						}
					}
				}
				else if (rawNotesBeingPressedThisFrame.Any())
				{
					if (rawNotesBeingPressedThisFrame.Contains(Local_CurrentRawNote))
					{
						return Local_CurrentRawNote;
					}
					for (int num2 = Local_LastFrameRawNoteInput.Count - 1; num2 >= 0; num2--)
					{
						RawNoteInputEnum rawNoteInputEnum3 = Local_LastFrameRawNoteInput[num2];
						if (rawNotesBeingPressedThisFrame.Contains(rawNoteInputEnum3))
						{
							return rawNoteInputEnum3;
						}
					}
				}
				return null;
			}
			void UpdateKeyInputTracking()
			{
				Local_LastFrameOctaveInput.RemoveWhere((OctaveEnum _) => !octavesBeingPressedThisFrame.Contains(_));
				Local_LastFrameSemitoneInput.RemoveWhere((SemitoneModifierEnum _) => !semitonesBeingPressedThisFrame.Contains(_));
				Local_LastFrameRawNoteInput.RemoveAll((RawNoteInputEnum _) => !rawNotesBeingPressedThisFrame.Contains(_));
				foreach (OctaveEnum item2 in octavesBeingPressedThisFrame)
				{
					Local_LastFrameOctaveInput.Add(item2);
				}
				foreach (SemitoneModifierEnum item3 in semitonesBeingPressedThisFrame)
				{
					Local_LastFrameSemitoneInput.Add(item3);
				}
				foreach (RawNoteInputEnum item4 in rawNotesBeingPressedThisFrame)
				{
					if (!Local_LastFrameRawNoteInput.Contains(item4))
					{
						Local_LastFrameRawNoteInput.Add(item4);
					}
				}
			}
		}

		private void SetOctave(OctaveEnum newOctave)
		{
			if (Local_CurrentOctave != newOctave)
			{
				Local_CurrentOctave = newOctave;
			}
		}

		private void SetSemitoneModifier(SemitoneModifierEnum newModifier)
		{
			if (Local_CurrentSemitoneModifier != newModifier)
			{
				Local_CurrentSemitoneModifier = newModifier;
			}
		}

		private void SetRawNote(RawNoteInputEnum newNote)
		{
			if (Local_CurrentRawNote != newNote)
			{
				Local_CurrentRawNote = newNote;
			}
		}

		private void ResetToDefaultPitch()
		{
			Local_CurrentRawNote = ScaleHelper.DEFAULT_RAW_NOTE;
			Local_CurrentOctave = ScaleHelper.DEFAULT_OCTAVE;
			Local_CurrentSemitoneModifier = ScaleHelper.DEFAULT_SEMITONE_MODIFIER;
		}
	}
}
namespace BugleMaestro.Helpers
{
	public class ClipHelper
	{
		public static AudioClip ChangePitch(ScaleEnum targetScaleNote)
		{
			foreach (KeyValuePair<ScaleEnum, AudioClip> baseBugleClip in Plugin.Instance.baseBugleClips)
			{
				if (targetScaleNote == baseBugleClip.Key)
				{
					return baseBugleClip.Value;
				}
			}
			AudioClip baseClipToModify = Plugin.Instance.baseBugleClips.GetValueOrDefault(ScaleHelper.HIGHEST_NOTE);
			int num = targetScaleNote - ScaleHelper.HIGHEST_NOTE;
			foreach (KeyValuePair<ScaleEnum, AudioClip> baseBugleClip2 in Plugin.Instance.baseBugleClips)
			{
				int num2 = targetScaleNote - baseBugleClip2.Key;
				if (num2 <= 6)
				{
					baseClipToModify = baseBugleClip2.Value;
					num = num2;
					break;
				}
			}
			return CreateNewAudioClipByPitchShifting(baseClipToModify, num);
		}

		private static AudioClip CreateNewAudioClipByPitchShifting(AudioClip baseClipToModify, float numOfSemitoneDifferenceFromBaseClip)
		{
			float num = Mathf.Pow(2f, 1f * numOfSemitoneDifferenceFromBaseClip / 12f);
			int channels = baseClipToModify.channels;
			int num2 = Mathf.CeilToInt((float)baseClipToModify.samples / num);
			float[] array = new float[baseClipToModify.samples * channels];
			baseClipToModify.GetData(array, 0);
			float[] array2 = new float[num2 * channels];
			for (int i = 0; i < num2; i++)
			{
				float num3 = (float)i * num;
				int num4 = (int)num3;
				int num5 = Mathf.Min(num4 + 1, baseClipToModify.samples - 1);
				float num6 = num3 - (float)num4;
				for (int j = 0; j < channels; j++)
				{
					float num7 = array[num4 * channels + j];
					float num8 = array[num5 * channels + j];
					array2[i * channels + j] = Mathf.Lerp(num7, num8, num6);
				}
			}
			AudioClip val = AudioClip.Create(((Object)baseClipToModify).name + "_Pitched", num2, channels, baseClipToModify.frequency, false);
			val.SetData(array2, 0);
			return val;
		}

		public static async void SetupBaseBugleClips()
		{
			Dictionary<ScaleEnum, string> dictionary = new Dictionary<ScaleEnum, string>();
			dictionary.Add(ScaleEnum.C2, "c2_bugle.mp3");
			dictionary.Add(ScaleEnum.C3, "c3_bugle.mp3");
			dictionary.Add(ScaleEnum.C4, "c4_bugle.mp3");
			dictionary.Add(ScaleEnum.B4, "b4_bugle.mp3");
			foreach (KeyValuePair<ScaleEnum, string> item in dictionary)
			{
				AudioClip value = await CreateAudioClipFromMp3(item.Value);
				Plugin.Instance.baseBugleClips.Add(item.Key, value);
			}
		}

		public static async Task<AudioClip> CreateAudioClipFromMp3(string filename)
		{
			string mp3Path = Path.Combine(Paths.PluginPath, Plugin.TEAM_NAME + "-" + Plugin.MOD_NAME, filename);
			Plugin.Log.LogInfo((object)(Plugin.LOG_PREFIX + ": " + Paths.PluginPath));
			string text = "file:///" + mp3Path;
			UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)13);
			Awaiter val = AsyncOperationAwaitableExtensions.GetAwaiter((AsyncOperation)(object)www.SendWebRequest());
			if (!((Awaiter)(ref val)).IsCompleted)
			{
				await val;
				Awaiter val2 = default(Awaiter);
				val = val2;
			}
			((Awaiter)(ref val)).GetResult();
			if ((int)www.result != 1)
			{
				Plugin.Log.LogError((object)(Plugin.LOG_PREFIX + ": Error loading " + filename + " MP3 from " + mp3Path + ". Check whether the MP3 file from the mod exists at this filepath. Full error: " + www.error));
			}
			AudioClip content = DownloadHandlerAudioClip.GetContent(www);
			float[] array = new float[content.samples * content.channels];
			content.GetData(array, 0);
			AudioClip val3 = AudioClip.Create("EditableBugleClip", content.samples, content.channels, content.frequency, false);
			val3.SetData(array, 0);
			Plugin.Log.LogInfo((object)(Plugin.LOG_PREFIX + ": " + filename + " MP3 loaded into editable AudioClip with " + val3.samples + " samples, " + val3.channels + " channels, " + val3.frequency + " Hz"));
			return val3;
		}
	}
	public class ScaleHelper
	{
		public static readonly ScaleEnum DEFAULT_NOTE = ScaleEnum.C3;

		public const float FundamentalFrequency = 130.813f;

		public static readonly RawNoteInputEnum DEFAULT_RAW_NOTE = RawNoteInputEnum.C;

		public static readonly OctaveEnum DEFAULT_OCTAVE = OctaveEnum.Neutral;

		public static readonly SemitoneModifierEnum DEFAULT_SEMITONE_MODIFIER = SemitoneModifierEnum.Natural;

		public static ScaleEnum LOWEST_NOTE => (from ScaleEnum x in Enum.GetValues(typeof(ScaleEnum))
			orderby x
			select x).First();

		public static ScaleEnum HIGHEST_NOTE => (from ScaleEnum x in Enum.GetValues(typeof(ScaleEnum))
			orderby x
			select x).Last();

		public static ScaleEnum CalculateScaleNote(RawNoteInputEnum rawInput, OctaveEnum octaveInput, SemitoneModifierEnum semitoneInput)
		{
			ScaleEnum scaleEnumFromAttributes = GetScaleEnumFromAttributes(rawInput, octaveInput);
			switch (semitoneInput)
			{
			case SemitoneModifierEnum.Natural:
				return scaleEnumFromAttributes;
			case SemitoneModifierEnum.Flat:
				if (scaleEnumFromAttributes == LOWEST_NOTE)
				{
					return LOWEST_NOTE;
				}
				return scaleEnumFromAttributes - 1;
			case SemitoneModifierEnum.Sharp:
				if (scaleEnumFromAttributes == HIGHEST_NOTE)
				{
					return HIGHEST_NOTE;
				}
				return scaleEnumFromAttributes + 1;
			default:
				Plugin.Log.LogError((object)$"{Plugin.LOG_PREFIX}: Could not find scale enum for RawNoteInputEnum {rawInput} and Semitone Modifier {semitoneInput} and Octave {octaveInput}.");
				return DEFAULT_NOTE;
			}
		}

		public static ScaleEnum GetScaleEnumFromAttributes(RawNoteInputEnum note, OctaveEnum octave)
		{
			Type typeFromHandle = typeof(ScaleEnum);
			FieldInfo[] fields = typeFromHandle.GetFields(BindingFlags.Static | BindingFlags.Public);
			foreach (FieldInfo fieldInfo in fields)
			{
				OctaveAttribute customAttribute = fieldInfo.GetCustomAttribute<OctaveAttribute>();
				NamedNoteAttribute customAttribute2 = fieldInfo.GetCustomAttribute<NamedNoteAttribute>();
				if (customAttribute != null && customAttribute.Octave == octave && customAttribute2 != null && customAttribute2.RawNote == note)
				{
					return (ScaleEnum)fieldInfo.GetValue(null);
				}
			}
			Plugin.Log.LogError((object)$"{Plugin.LOG_PREFIX}: Could not find scale enum for RawNoteInputEnum {note} and OctaveEnum {octave}.");
			return DEFAULT_NOTE;
		}

		public static TAttribute GetAttributeOfScaleNote<TAttribute>(ScaleEnum value) where TAttribute : Attribute
		{
			Type type = value.GetType();
			string name = Enum.GetName(type, value);
			return type.GetField(name).GetCustomAttributes(inherit: false).OfType<TAttribute>()
				.Single();
		}
	}
	public enum RawNoteInputEnum
	{
		C,
		D,
		E,
		F,
		G,
		A,
		B
	}
	public enum OctaveEnum
	{
		Lowest,
		Neutral,
		Highest
	}
	public enum SemitoneModifierEnum
	{
		Flat,
		Sharp,
		Natural
	}
	public class NamedNoteAttribute : Attribute
	{
		public RawNoteInputEnum RawNote { get; private set; }

		public NamedNoteAttribute(RawNoteInputEnum note)
		{
			RawNote = note;
		}
	}
	public class OctaveAttribute : Attribute
	{
		public OctaveEnum Octave { get; private set; }

		public OctaveAttribute(OctaveEnum oct)
		{
			Octave = oct;
		}
	}
	public class FrequencyAttribute : Attribute
	{
		public float Frequency { get; private set; }

		public FrequencyAttribute(float freq)
		{
			Frequency = freq;
		}
	}
	public class UIDisplayNameAttribute : Attribute
	{
		public string UIDisplayName { get; private set; }

		public UIDisplayNameAttribute(string name)
		{
			UIDisplayName = name;
		}
	}
	public enum ScaleEnum
	{
		[Octave(OctaveEnum.Lowest)]
		[NamedNote(RawNoteInputEnum.C)]
		[Frequency(65.406f)]
		[UIDisplayName("C2")]
		C2 = 1,
		[Frequency(69.296f)]
		[UIDisplayName("C♯2")]
		CSharp2,
		[Octave(OctaveEnum.Lowest)]
		[NamedNote(RawNoteInputEnum.D)]
		[Frequency(73.416f)]
		[UIDisplayName("D2")]
		D2,
		[Frequency(77.782f)]
		[UIDisplayName("Eâ™­2")]
		EFlat2,
		[Octave(OctaveEnum.Lowest)]
		[NamedNote(RawNoteInputEnum.E)]
		[Frequency(82.406f)]
		[UIDisplayName("E2")]
		E2,
		[Octave(OctaveEnum.Lowest)]
		[NamedNote(RawNoteInputEnum.F)]
		[Frequency(87.308f)]
		[UIDisplayName("F2")]
		F2,
		[Frequency(92.498f)]
		[UIDisplayName("F♯2")]
		FSharp2,
		[Octave(OctaveEnum.Lowest)]
		[NamedNote(RawNoteInputEnum.G)]
		[Frequency(97.998f)]
		[UIDisplayName("G2")]
		G2,
		[Frequency(103.826f)]
		[UIDisplayName("Aâ™­2")]
		AFlat2,
		[Octave(OctaveEnum.Lowest)]
		[NamedNote(RawNoteInputEnum.A)]
		[Frequency(110f)]
		[UIDisplayName("A2")]
		A2,
		[Frequency(116.541f)]
		[UIDisplayName("Bâ™­2")]
		BFlat2,
		[Octave(OctaveEnum.Lowest)]
		[NamedNote(RawNoteInputEnum.B)]
		[Frequency(123.471f)]
		[UIDisplayName("B2")]
		B2,
		[Octave(OctaveEnum.Neutral)]
		[NamedNote(RawNoteInputEnum.C)]
		[Frequency(261.626f)]
		[UIDisplayName("C3")]
		C3,
		[Frequency(138.592f)]
		[UIDisplayName("C♯3")]
		CSharp3,
		[Octave(OctaveEnum.Neutral)]
		[NamedNote(RawNoteInputEnum.D)]
		[Frequency(146.832f)]
		[UIDisplayName("D3")]
		D3,
		[Frequency(155.563f)]
		[UIDisplayName("Eâ™­3")]
		EFlat3,
		[Octave(OctaveEnum.Neutral)]
		[NamedNote(RawNoteInputEnum.E)]
		[Frequency(164.814f)]
		[UIDisplayName("E3")]
		E3,
		[Octave(OctaveEnum.Neutral)]
		[NamedNote(RawNoteInputEnum.F)]
		[Frequency(174.614f)]
		[UIDisplayName("F3")]
		F3,
		[Frequency(184.997f)]
		[UIDisplayName("F♯3")]
		FSharp3,
		[Octave(OctaveEnum.Neutral)]
		[NamedNote(RawNoteInputEnum.G)]
		[Frequency(195.998f)]
		[UIDisplayName("G3")]
		G3,
		[Frequency(207.652f)]
		[UIDisplayName("Aâ™­3")]
		AFlat3,
		[Octave(OctaveEnum.Neutral)]
		[NamedNote(RawNoteInputEnum.A)]
		[Frequency(220f)]
		[UIDisplayName("A3")]
		A3,
		[Frequency(233.082f)]
		[UIDisplayName("Bâ™­3")]
		BFlat3,
		[Octave(OctaveEnum.Neutral)]
		[NamedNote(RawNoteInputEnum.B)]
		[Frequency(246.942f)]
		[UIDisplayName("B3")]
		B3,
		[Octave(OctaveEnum.Highest)]
		[NamedNote(RawNoteInputEnum.C)]
		[Frequency(261.626f)]
		[UIDisplayName("C4")]
		C4,
		[Frequency(277.182f)]
		[UIDisplayName("C♯4")]
		CSharp4,
		[Octave(OctaveEnum.Highest)]
		[NamedNote(RawNoteInputEnum.D)]
		[Frequency(293.664f)]
		[UIDisplayName("D4")]
		D4,
		[Frequency(311.126f)]
		[UIDisplayName("Eâ™­4")]
		EFlat4,
		[Octave(OctaveEnum.Highest)]
		[NamedNote(RawNoteInputEnum.E)]
		[Frequency(329.628f)]
		[UIDisplayName("E4")]
		E4,
		[Octave(OctaveEnum.Highest)]
		[NamedNote(RawNoteInputEnum.F)]
		[Frequency(349.228f)]
		[UIDisplayName("F4")]
		F4,
		[Frequency(369.994f)]
		[UIDisplayName("F♯4")]
		FSharp4,
		[Octave(OctaveEnum.Highest)]
		[NamedNote(RawNoteInputEnum.G)]
		[Frequency(391.996f)]
		[UIDisplayName("G4")]
		G4,
		[Frequency(415.304f)]
		[UIDisplayName("Aâ™­4")]
		AFlat4,
		[Octave(OctaveEnum.Highest)]
		[NamedNote(RawNoteInputEnum.A)]
		[Frequency(440f)]
		[UIDisplayName("A4")]
		A4,
		[Frequency(466.164f)]
		[UIDisplayName("Bâ™­4")]
		BFlat4,
		[Octave(OctaveEnum.Highest)]
		[NamedNote(RawNoteInputEnum.B)]
		[Frequency(493.884f)]
		[UIDisplayName("B4")]
		B4
	}
	public class UIHelper
	{
		public static readonly float DEFAULT_FONTSIZE = 35f;

		public static readonly float DEFAULT_OUTLINEWIDTH = 0.08f;

		public static readonly float DEFAULT_LINESPACING = -35f;

		public static readonly float DEFAULT_SIZEDELTAX = 650f;

		public static void AddDisplayObject()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.Find("GAME/GUIManager");
			Plugin.Instance.guiManager = val.GetComponent<GUIManager>();
			TMP_FontAsset font = ((TMP_Text)Plugin.Instance.guiManager.heroDayText).font;
			GameObject gameObject = ((Component)val.transform.Find("Canvas_HUD/Prompts/ItemPromptLayout")).gameObject;
			GameObject val2 = new GameObject("BugleMaestroDisplay");
			val2.transform.SetParent(gameObject.transform);
			Plugin.Instance.itemInfoDisplayTextMesh = val2.AddComponent<TextMeshProUGUI>();
			RectTransform rectTransform = ((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).rectTransform;
			rectTransform.sizeDelta = new Vector2(Plugin.Instance.sizeDeltaX, 0f);
			((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).font = font;
			((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).fontSize = Plugin.Instance.fontSize;
			((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).alignment = (TextAlignmentOptions)260;
			((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).lineSpacing = Plugin.Instance.lineSpacing;
			((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).text = "";
			((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).outlineWidth = Plugin.Instance.outlineWidth;
		}

		public static void SetupUIElements()
		{
			InitEffectColors(Plugin.Instance.fontColors);
			Plugin.Instance.fontSize = DEFAULT_FONTSIZE;
			Plugin.Instance.outlineWidth = DEFAULT_OUTLINEWIDTH;
			Plugin.Instance.lineSpacing = DEFAULT_LINESPACING;
			Plugin.Instance.sizeDeltaX = DEFAULT_SIZEDELTAX;
		}

		public static void InitEffectColors(Dictionary<string, string> dict)
		{
			dict.Add("Note", "<#FFBD16>");
		}

		public static void DisplayBugleNote(ScaleEnum note)
		{
			string uIDisplayName = ScaleHelper.GetAttributeOfScaleNote<UIDisplayNameAttribute>(note).UIDisplayName;
			string message = "Currently playing: " + uIDisplayName;
			DisplayMessage(message, "Note");
		}

		public static void HideUI()
		{
			if ((Object)(object)Plugin.Instance.guiManager == (Object)null)
			{
				AddDisplayObject();
			}
			if (((Component)Plugin.Instance.itemInfoDisplayTextMesh).gameObject.activeSelf)
			{
				((Component)Plugin.Instance.itemInfoDisplayTextMesh).gameObject.SetActive(false);
			}
		}

		public static void DisplayMessage(string message, string colourKey)
		{
			if ((Object)(object)Plugin.Instance.guiManager == (Object)null)
			{
				AddDisplayObject();
			}
			if (!((Component)Plugin.Instance.itemInfoDisplayTextMesh).gameObject.activeSelf)
			{
				((Component)Plugin.Instance.itemInfoDisplayTextMesh).gameObject.SetActive(true);
			}
			((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).text = "";
			TextMeshProUGUI itemInfoDisplayTextMesh = Plugin.Instance.itemInfoDisplayTextMesh;
			((TMP_Text)itemInfoDisplayTextMesh).text = ((TMP_Text)itemInfoDisplayTextMesh).text + Plugin.Instance.fontColors[colourKey] + " " + message + "</color>\n";
			((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).text = ((TMP_Text)Plugin.Instance.itemInfoDisplayTextMesh).text.Replace("\n\n\n", "\n\n");
		}
	}
}