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