using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using Virtuoso.Audio;
using Virtuoso.Behaviour;
using Virtuoso.Config;
using Virtuoso.Data;
using Virtuoso.Event;
using Virtuoso.Input;
using Virtuoso.Runtime;
using Virtuoso.UI;
[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.mondash.Virtuoso")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.1.0")]
[assembly: AssemblyInformationalVersion("0.3.1+3c45e2ed3eef365c1b2beae79cb6154ed4f13559")]
[assembly: AssemblyProduct("com.github.mondash.Virtuoso")]
[assembly: AssemblyTitle("Virtuoso")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.1.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 Virtuoso
{
[BepInPlugin("com.github.mondash.Virtuoso", "Virtuoso", "0.3.1")]
public class Plugin : BaseUnityPlugin
{
private Harmony? _harmony;
public const string Id = "com.github.mondash.Virtuoso";
internal static ManualLogSource Log { get; private set; }
public static string Name => "Virtuoso";
public static string Version => "0.3.1";
private void Awake()
{
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Expected O, but got Unknown
//IL_0060: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
Log.LogInfo((object)"Plugin waking...");
Log.LogDebug((object)"Loading configuration...");
BugleConfig.Bind(((BaseUnityPlugin)this).Config);
Log.LogDebug((object)"Applying harmony patches...");
Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
Harmony val2 = val;
_harmony = val;
val2.PatchAll();
Log.LogDebug((object)"Adding runtime components...");
((Component)this).gameObject.AddComponent<BugleUILoader>();
Log.LogInfo((object)"Plugin awake!");
}
private void OnDestroy()
{
Log.LogInfo((object)"Plugin destroying...");
Log.LogDebug((object)"Disconnecting custom bugle behaviour...");
BugleBehaviour.DisconnectAll();
Log.LogDebug((object)"Removing harmony patches...");
Harmony? harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
Log.LogInfo((object)"Plugin destroyed!");
}
}
}
namespace Virtuoso.UI
{
internal class BugleNote
{
private static readonly string[] NoteNames = new string[12]
{
"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A",
"A#", "B"
};
public static string FromSemitone(float semitone)
{
int num = Mathf.RoundToInt(semitone) + 69;
num = Mathf.Clamp(num, 0, 127);
int num2 = num / 12 - 1;
int num3 = num % 12;
return $"{NoteNames[num3]}{num2}";
}
}
internal class BugleUI : MonoBehaviour
{
private static BugleUI? _instance;
private static bool _visible = true;
private static KeyCode ToggleUIKey => BugleConfig.ToggleUIKey.Value;
private static bool IsPaused => GUIManager.instance.pauseMenu.activeSelf;
public static void Initialize(GameObject gameObject)
{
if (!Object.op_Implicit((Object)(object)_instance))
{
_instance = gameObject.AddComponent<BugleUI>();
Plugin.Log.LogInfo((object)"BugleUI initialized");
}
}
public static void DestroyInstance()
{
if (Object.op_Implicit((Object)(object)_instance))
{
Object.Destroy((Object)(object)_instance);
_instance = null;
Plugin.Log.LogInfo((object)"BugleUI destroyed");
}
}
private void Update()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
if (Input.GetKeyDown(ToggleUIKey))
{
_visible = !_visible;
}
}
private void OnGUI()
{
if (!_visible || IsPaused)
{
return;
}
Character localCharacter = Character.localCharacter;
if (!Object.op_Implicit((Object)(object)localCharacter))
{
return;
}
Item currentItem = localCharacter.data.currentItem;
BugleSFX val = default(BugleSFX);
if (!Object.op_Implicit((Object)(object)currentItem) || !((Component)currentItem).TryGetComponent<BugleSFX>(ref val))
{
return;
}
Camera main = Camera.main;
if (!Object.op_Implicit((Object)(object)main))
{
return;
}
float maxAngle = BuglePartial.MaxAngle;
int partials = BuglePartial.Partials;
int num = partials - 1;
float y = localCharacter.data.lookValues.y;
float fieldOfView = main.fieldOfView;
float num2 = fieldOfView * 0.5f * (MathF.PI / 180f);
float num3 = Screen.height;
float num4 = Screen.width;
for (int i = 1; i <= num; i++)
{
float num5 = (float)i / (float)partials;
float num6 = Mathf.Lerp(0f - maxAngle, maxAngle, num5);
float num7 = num6 - y;
float num8 = num7 * (MathF.PI / 180f);
if (!(Mathf.Abs(num8) > num2))
{
float num9 = 0.5f - Mathf.Tan(num8) / Mathf.Tan(num2);
float y2 = num9 * num3;
float x = (num4 - 20f) * 0.5f;
DrawLine(x, y2, 20f);
}
}
}
private static void DrawLine(float x, float y, float width)
{
//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_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
Color color = GUI.color;
GUI.color = Color.white;
GUI.DrawTexture(new Rect(x, y, width, 5f), (Texture)(object)Texture2D.whiteTexture);
GUI.color = color;
}
}
}
namespace Virtuoso.Runtime
{
internal class BugleUILoader : MonoBehaviour
{
[CompilerGenerated]
private sealed class <LoadUI>d__3 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public BugleUILoader <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <LoadUI>d__3(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
int num = <>1__state;
BugleUILoader bugleUILoader = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
Plugin.Log.LogInfo((object)"Bugle UI loader routine started");
<>2__current = (object)new WaitUntil((Func<bool>)bugleUILoader.ReadyOrDisabled);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if (((Behaviour)bugleUILoader).isActiveAndEnabled)
{
BugleUI.Initialize(((Component)bugleUILoader).gameObject);
}
Plugin.Log.LogInfo((object)"Bugle UI loader routine finished");
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private void OnEnable()
{
((MonoBehaviour)this).StartCoroutine(LoadUI());
}
private void OnDisable()
{
BugleUI.DestroyInstance();
}
private bool ReadyOrDisabled()
{
if (!Object.op_Implicit((Object)(object)Character.localCharacter))
{
return !((Behaviour)this).isActiveAndEnabled;
}
return true;
}
[IteratorStateMachine(typeof(<LoadUI>d__3))]
private IEnumerator LoadUI()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <LoadUI>d__3(0)
{
<>4__this = this
};
}
}
}
namespace Virtuoso.Patching
{
[HarmonyPatch(typeof(BugleSFX))]
internal static class BugleSFX_Patch
{
private static void SetTooting(BugleSFX instance)
{
((object)instance).GetType().GetField("t", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(instance, true);
}
[HarmonyPatch("RPC_StartToot")]
[HarmonyPostfix]
private static void RPC_StartToot_Postfix(BugleSFX __instance, int clip, float pitch)
{
SetTooting(__instance);
BugleBehaviour.Connect(__instance);
BugleHub.RaiseTootStarted(__instance);
}
[HarmonyPatch("RPC_EndToot")]
[HarmonyPostfix]
private static void RPC_EndToot_Postfix(BugleSFX __instance)
{
BugleHub.RaiseTootStopped(__instance);
}
}
}
namespace Virtuoso.Input
{
public static class BugleBend
{
private static float? _initialAngle;
private static float MaxAngle => BugleConfig.MaxBendAngle.Value;
private static float MaxSemitones => BugleConfig.MaxBendSemitones.Value;
private static float CurrentAngle
{
get
{
if (!Object.op_Implicit((Object)(object)Character.localCharacter))
{
return 0f;
}
return Character.localCharacter.data.lookValues.x;
}
}
public static float Semitones()
{
if (!_initialAngle.HasValue)
{
return 0f;
}
float num = Mathf.DeltaAngle(_initialAngle.Value, CurrentAngle);
float num2 = Mathf.Clamp(num / MaxAngle, -1f, 1f);
return num2 * MaxSemitones;
}
public static void Reset()
{
_initialAngle = null;
}
public static void SetInitialAngle()
{
_initialAngle = CurrentAngle;
}
}
internal static class BuglePartial
{
private const float SmoothStrength = 300f;
private static readonly float[] RealisticHarmonics = new float[7] { 12f, 19.02f, 24f, 27.86f, 31.02f, 33.69f, 36f };
private static readonly float[] IdealHarmonics = new float[7] { 12f, 19f, 24f, 28f, 31f, 34f, 36f };
private static float? _smoothAngle;
private static float SmoothSpeed => 300f * BugleConfig.HarmonicSmoothMult.Value;
public static float MaxAngle => BugleConfig.MaxPartialAngle.Value;
private static bool Ideal => BugleConfig.UseIdealHarmonics.Value;
private static float[] Harmonics
{
get
{
if (!Ideal)
{
return RealisticHarmonics;
}
return IdealHarmonics;
}
}
public static int Partials => Harmonics.Length;
private static float CurrentAngle
{
get
{
if (!Object.op_Implicit((Object)(object)Character.localCharacter))
{
return 0f;
}
return Character.localCharacter.data.lookValues.y;
}
}
public static float Semitones()
{
float num = _smoothAngle ?? CurrentAngle;
float num2 = Mathf.InverseLerp(0f - MaxAngle, MaxAngle, num);
int num3 = Mathf.FloorToInt(num2 * (float)Partials);
int num4 = Mathf.Clamp(num3, 0, Partials - 1);
return Harmonics[num4];
}
public static void Reset()
{
_smoothAngle = null;
}
public static void Smooth(float delta)
{
_smoothAngle = (_smoothAngle.HasValue ? Mathf.MoveTowards(_smoothAngle.Value, CurrentAngle, delta * SmoothSpeed) : CurrentAngle);
}
}
internal static class TrumpetValves
{
private static readonly Dictionary<int, float> RealisticOffsets = new Dictionary<int, float>
{
[0] = -0f,
[2] = -1f,
[1] = -2f,
[4] = -2.95f,
[3] = -3f,
[6] = -4f,
[5] = -5.35f,
[7] = -6.75f
};
private static readonly Dictionary<int, float> IdealOffsets = new Dictionary<int, float>
{
[0] = -0f,
[2] = -1f,
[1] = -2f,
[4] = -3f,
[3] = -3f,
[6] = -4f,
[5] = -5f,
[7] = -6f
};
private static bool Ideal => BugleConfig.UseIdealValves.Value;
private static KeyCode Valve1Key => BugleConfig.Valve1Key.Value;
private static KeyCode Valve2Key => BugleConfig.Valve2Key.Value;
private static KeyCode Valve3Key => BugleConfig.Valve3Key.Value;
private static Dictionary<int, float> Offsets
{
get
{
if (!Ideal)
{
return RealisticOffsets;
}
return IdealOffsets;
}
}
public static float Semitones()
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
int num = 0;
if (Input.GetKey(Valve1Key))
{
num |= 1;
}
if (Input.GetKey(Valve2Key))
{
num |= 2;
}
if (Input.GetKey(Valve3Key))
{
num |= 4;
}
return Offsets.GetValueOrDefault(num, 0f);
}
}
}
namespace Virtuoso.Event
{
internal sealed class BugleHub
{
private readonly HashSet<IBugleListener> _listeners = new HashSet<IBugleListener>();
private static readonly ConditionalWeakTable<BugleSFX, BugleHub> Registry = new ConditionalWeakTable<BugleSFX, BugleHub>();
private event Action? TootStarted;
private event Action? TootStopped;
private event Action<BuglePitchFrame>? Frame;
public Action Subscribe(IBugleListener listener)
{
IBugleListener listener2 = listener;
if (!_listeners.Add(listener2))
{
return delegate
{
};
}
TootStarted += listener2.HandleTootStarted;
TootStopped += listener2.HandleTootStopped;
Frame += listener2.HandleFrame;
return delegate
{
Unsubscribe(listener2);
};
}
private void Unsubscribe(IBugleListener listener)
{
if (_listeners.Remove(listener))
{
TootStarted -= listener.HandleTootStarted;
TootStopped -= listener.HandleTootStopped;
Frame -= listener.HandleFrame;
}
}
private void RaiseTootStarted()
{
this.TootStarted?.Invoke();
}
private void RaiseTootStopped()
{
this.TootStopped?.Invoke();
}
public void RaiseFrame(BuglePitchFrame frame)
{
this.Frame?.Invoke(frame);
}
public static BugleHub Get(BugleSFX sfx)
{
return Registry.GetValue(sfx, (BugleSFX _) => new BugleHub());
}
public static void RaiseTootStarted(BugleSFX sfx)
{
Get(sfx).RaiseTootStarted();
}
public static void RaiseTootStopped(BugleSFX sfx)
{
Get(sfx).RaiseTootStopped();
}
}
internal interface IBugleListener
{
void HandleTootStarted();
void HandleTootStopped();
void HandleFrame(BuglePitchFrame frame);
}
}
namespace Virtuoso.Data
{
internal readonly struct BuglePitchFrame
{
public readonly float Valves;
public readonly float Partial;
public readonly float Bend;
public object Data => new object[3] { Valves, Partial, Bend };
public float Semitone => Valves + Partial + Bend;
public float Pitch => Mathf.Pow(2f, Semitone / 12f);
public BuglePitchFrame(float valves, float partial, float bend)
{
Valves = valves;
Partial = partial;
Bend = bend;
}
public BuglePitchFrame()
: this(TrumpetValves.Semitones(), BuglePartial.Semitones(), BugleBend.Semitones())
{
}
public BuglePitchFrame(object[] data)
: this((float)data[0], (float)data[1], (float)data[2])
{
}
public bool Approximately(BuglePitchFrame other, float bendThreshold = 0.05f)
{
if (Mathf.Approximately(Valves, other.Valves) && Mathf.Approximately(Partial, other.Partial))
{
return Mathf.Abs(Bend - other.Bend) < bendThreshold;
}
return false;
}
public float Smooth(float current, float delta, float speed = 100f)
{
return Mathf.MoveTowards(current, Pitch, delta * speed);
}
}
}
namespace Virtuoso.Config
{
internal static class BugleConfig
{
public static ConfigEntry<float> MaxBendAngle;
public static ConfigEntry<float> MaxBendSemitones;
public static ConfigEntry<bool> UseIdealHarmonics;
public static ConfigEntry<float> MaxPartialAngle;
public static ConfigEntry<float> HarmonicSmoothMult;
public static ConfigEntry<float> PitchSmoothMult;
public static ConfigEntry<float> SyncInterval;
public static ConfigEntry<KeyCode> ToggleUIKey;
public static ConfigEntry<bool> UseIdealValves;
public static ConfigEntry<KeyCode> Valve1Key;
public static ConfigEntry<KeyCode> Valve2Key;
public static ConfigEntry<KeyCode> Valve3Key;
public static void Bind(ConfigFile config)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Expected O, but got Unknown
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Expected O, but got Unknown
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Expected O, but got Unknown
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Expected O, but got Unknown
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Expected O, but got Unknown
MaxBendAngle = config.Bind<float>("Bend", "MaxBendAngle", 80f, new ConfigDescription("Maximum left/right view angle (in degrees) allowed to bend pitch", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 170f), Array.Empty<object>()));
MaxBendSemitones = config.Bind<float>("Bend", "MaxBendSemitones", 2f, new ConfigDescription("Maximum pitch bending amount in semitones", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 12f), Array.Empty<object>()));
UseIdealHarmonics = config.Bind<bool>("Harmonics", "UseIdealHarmonics", true, "If true, uses mathematically ideal harmonics");
MaxPartialAngle = config.Bind<float>("Harmonics", "MaxPartialAngle", 80f, new ConfigDescription("Vertical angle span (in degrees) allocated to partial selection", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 90f), Array.Empty<object>()));
HarmonicSmoothMult = config.Bind<float>("Smoothing", "HarmonicSmoothMult", 1f, new ConfigDescription("How quickly harmonic partials react, higher values reacting quicker", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.125f, 8f), Array.Empty<object>()));
PitchSmoothMult = config.Bind<float>("Smoothing", "PitchSmoothMult", 1f, new ConfigDescription("How quickly pitch changes are smoothed, higher values smoothing quicker", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.125f, 8f), Array.Empty<object>()));
SyncInterval = config.Bind<float>("Sync", "SyncInterval", 0.1f, new ConfigDescription("Time (in seconds) between bugle sync frames", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>()));
ToggleUIKey = config.Bind<KeyCode>("UI", "ToggleUIKey", (KeyCode)117, "Keyboard shortcut to toggle the bugle UI visibility");
UseIdealValves = config.Bind<bool>("Valves", "UseIdealValves", true, "If true, uses mathematically ideal tuning offsets for valve combinations");
Valve1Key = config.Bind<KeyCode>("Valves", "Valve1Key", (KeyCode)122, "Keyboard key for Valve 1");
Valve2Key = config.Bind<KeyCode>("Valves", "Valve2Key", (KeyCode)120, "Keyboard key for Valve 2");
Valve3Key = config.Bind<KeyCode>("Valves", "Valve3Key", (KeyCode)99, "Keyboard key for Valve 3");
}
}
}
namespace Virtuoso.Behaviour
{
[DefaultExecutionOrder(2)]
internal class BugleAudio : BugleBehaviour
{
[CompilerGenerated]
private sealed class <StopRoutine>d__11 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public BugleAudio <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <StopRoutine>d__11(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Expected O, but got Unknown
int num = <>1__state;
BugleAudio bugleAudio = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitWhile((Func<bool>)bugleAudio.SourceActive);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if (Object.op_Implicit((Object)(object)bugleAudio.Source) && bugleAudio.Source.isPlaying)
{
bugleAudio.Source.Stop();
}
bugleAudio._stopRoutine = null;
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private const float VolumeEpsilon = 0.001f;
private const float SmoothStrength = 100f;
private bool _newToot;
private BuglePitchFrame _frame;
private Coroutine? _stopRoutine;
private static float SmoothSpeed => 100f * BugleConfig.PitchSmoothMult.Value;
private AudioSource Source => base.Sfx.buglePlayer;
protected override bool ShouldUpdate
{
get
{
if (!base.ShouldUpdate)
{
return Source.isPlaying;
}
return true;
}
}
protected override void OnTootStarted()
{
Source.clip = BugleClip.Pinched();
Source.loop = true;
_newToot = true;
}
private bool SourceActive()
{
if (((Behaviour)this).isActiveAndEnabled)
{
AudioSource source = Source;
if (source != null && source.isPlaying)
{
return source.volume > 0.001f;
}
return false;
}
return false;
}
[IteratorStateMachine(typeof(<StopRoutine>d__11))]
private IEnumerator StopRoutine()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <StopRoutine>d__11(0)
{
<>4__this = this
};
}
protected override void OnTootStopped()
{
if (_stopRoutine == null)
{
_stopRoutine = ((MonoBehaviour)this).StartCoroutine(StopRoutine());
}
}
protected override void OnFrame(BuglePitchFrame frame)
{
_frame = frame;
}
private bool Pause()
{
if (Time.timeScale != 0f)
{
return false;
}
if (Source.isPlaying)
{
Source.Stop();
}
return true;
}
protected override void OnUpdate()
{
if (!Pause())
{
Source.pitch = (_newToot ? _frame.Pitch : _frame.Smooth(Source.pitch, Time.deltaTime, SmoothSpeed));
if (!Source.isPlaying)
{
Source.Play();
}
_newToot = false;
}
}
}
[RequireComponent(typeof(BugleSFX))]
internal abstract class BugleBehaviour : MonoBehaviour, IBugleListener
{
private Action? _unsubscribe;
private bool _implementsOnTootStarted;
private bool _implementsOnTootStopped;
private bool _implementsOnFrame;
private bool _implementsOnUpdate;
protected string Name { get; private set; }
protected BugleSFX Sfx { get; private set; }
protected BugleHub Hub { get; private set; }
protected bool IsMine => ((MonoBehaviourPun)Sfx).photonView.IsMine;
protected int ViewID => ((MonoBehaviourPun)Sfx).photonView.ViewID;
protected virtual bool ShouldHandleTootStarted => true;
protected virtual bool ShouldHandleTootStopped => true;
protected virtual bool ShouldHandleFrame => true;
protected virtual bool ShouldUpdate
{
get
{
if (Sfx.hold)
{
return Time.timeScale > 0f;
}
return false;
}
}
private static T Connect<T>(BugleSFX sfx) where T : BugleBehaviour
{
T result = default(T);
if (!((Component)sfx).TryGetComponent<T>(ref result))
{
return ((Component)sfx).gameObject.AddComponent<T>();
}
return result;
}
public static void Connect(BugleSFX sfx)
{
Connect<BugleInput>(sfx);
Connect<BugleAudio>(sfx);
Connect<BugleSync>(sfx);
Connect<BugleDrop>(sfx);
}
protected static void Disconnect(BugleSFX sfx)
{
((Component)sfx).GetComponents<BugleBehaviour>().ToList().ForEach((Action<BugleBehaviour>)Object.Destroy);
}
public static void DisconnectAll()
{
Object.FindObjectsByType<BugleBehaviour>((FindObjectsSortMode)0).ToList().ForEach((Action<BugleBehaviour>)Object.Destroy);
}
private static bool ImplementsHandler(Type type, string name)
{
MethodInfo method = type.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (method != null)
{
return method.DeclaringType != typeof(BugleBehaviour);
}
return false;
}
private void Awake()
{
Type type = ((object)this).GetType();
_implementsOnTootStarted = ImplementsHandler(type, "OnTootStarted");
_implementsOnTootStopped = ImplementsHandler(type, "OnTootStopped");
_implementsOnFrame = ImplementsHandler(type, "OnFrame");
_implementsOnUpdate = ImplementsHandler(type, "OnUpdate");
Name = type.Name;
Sfx = ((Component)this).GetComponent<BugleSFX>();
Hub = BugleHub.Get(Sfx);
}
protected virtual void OnEnable()
{
if (_unsubscribe == null)
{
_unsubscribe = Hub.Subscribe(this);
}
Plugin.Log.LogInfo((object)$"Enabled {Name} for view {ViewID}");
}
protected virtual void OnDisable()
{
_unsubscribe?.Invoke();
_unsubscribe = null;
Plugin.Log.LogInfo((object)$"Disabled {Name} for view {ViewID}");
}
protected virtual void OnTootStarted()
{
}
protected virtual void OnTootStopped()
{
}
protected virtual void OnFrame(BuglePitchFrame f)
{
}
protected virtual void OnUpdate()
{
}
void IBugleListener.HandleTootStarted()
{
if (_implementsOnTootStarted && ShouldHandleTootStarted)
{
Plugin.Log.LogDebug((object)$"{Name} handling toot start for view {ViewID}");
OnTootStarted();
}
}
void IBugleListener.HandleTootStopped()
{
if (_implementsOnTootStopped && ShouldHandleTootStopped)
{
Plugin.Log.LogDebug((object)$"{Name} handling toot stop for view {ViewID}");
OnTootStopped();
}
}
void IBugleListener.HandleFrame(BuglePitchFrame frame)
{
if (_implementsOnFrame && ShouldHandleFrame)
{
Plugin.Log.LogDebug((object)$"{Name} handling frame for view {ViewID}");
OnFrame(frame);
}
}
private void Update()
{
if (_implementsOnUpdate && ShouldUpdate)
{
Plugin.Log.LogDebug((object)$"{Name} handling update for view {ViewID}");
OnUpdate();
}
}
}
[DefaultExecutionOrder(4)]
internal class BugleDrop : BugleBehaviour
{
protected override void OnEnable()
{
Item item = base.Sfx.item;
item.OnStateChange = (Action<ItemState>)Delegate.Combine(item.OnStateChange, new Action<ItemState>(DisconnectOnDrop));
base.OnEnable();
}
protected override void OnDisable()
{
Item item = base.Sfx.item;
item.OnStateChange = (Action<ItemState>)Delegate.Remove(item.OnStateChange, new Action<ItemState>(DisconnectOnDrop));
base.OnDisable();
}
private void DisconnectOnDrop(ItemState state)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Invalid comparison between Unknown and I4
if ((int)state != 1)
{
BugleBehaviour.Disconnect(base.Sfx);
}
}
}
[DefaultExecutionOrder(1)]
internal class BugleInput : BugleBehaviour
{
protected override bool ShouldHandleTootStarted
{
get
{
if (base.ShouldHandleTootStarted)
{
return base.IsMine;
}
return false;
}
}
protected override bool ShouldHandleTootStopped
{
get
{
if (base.ShouldHandleTootStopped)
{
return base.IsMine;
}
return false;
}
}
protected override bool ShouldUpdate
{
get
{
if (base.ShouldUpdate)
{
return base.IsMine;
}
return false;
}
}
protected override void OnTootStarted()
{
BugleBend.SetInitialAngle();
base.Hub.RaiseFrame(new BuglePitchFrame());
}
protected override void OnTootStopped()
{
BugleBend.Reset();
BuglePartial.Reset();
}
protected override void OnUpdate()
{
BuglePartial.Smooth(Time.deltaTime);
base.Hub.RaiseFrame(new BuglePitchFrame());
}
}
[DefaultExecutionOrder(3)]
internal class BugleSync : BugleBehaviour
{
private float _since;
private BuglePitchFrame _lastLocal;
private BuglePitchFrame _lastSent;
private static float SyncInterval => BugleConfig.SyncInterval.Value;
protected override bool ShouldHandleFrame
{
get
{
if (base.ShouldHandleFrame)
{
return base.IsMine;
}
return false;
}
}
protected override bool ShouldUpdate
{
get
{
if (base.ShouldUpdate)
{
return base.IsMine;
}
return false;
}
}
protected override void OnFrame(BuglePitchFrame frame)
{
_lastLocal = frame;
}
protected override void OnUpdate()
{
_since += Time.deltaTime;
if (!(_since < SyncInterval) || !_lastSent.Approximately(_lastLocal))
{
SyncBuglePitchFrame(_lastLocal);
}
}
private void SyncBuglePitchFrame(BuglePitchFrame frame)
{
((MonoBehaviourPun)base.Sfx).photonView.RPC("RPC_SyncBuglePitchFrame", (RpcTarget)1, new object[1] { frame.Data });
Plugin.Log.LogDebug((object)$"Sent frame sync from view {base.ViewID}");
_lastSent = frame;
_since = 0f;
}
[PunRPC]
private void RPC_SyncBuglePitchFrame(object[] data, PhotonMessageInfo info)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
Plugin.Log.LogDebug((object)$"Received frame sync from actor {info.Sender.ActorNumber}");
base.Hub.RaiseFrame(new BuglePitchFrame(data));
}
}
}
namespace Virtuoso.Audio
{
internal static class BugleClip
{
private const float Frequency = 58.27f;
private static AudioClip? _clip;
public static AudioClip Brass()
{
if (Object.op_Implicit((Object)(object)_clip))
{
return _clip;
}
Plugin.Log.LogInfo((object)"Generating bugle brass clip");
float[] array = new float[7568];
for (int i = 0; i < 7568; i++)
{
float num = 366.12122f * (float)i / 44100f;
float num2 = (Mathf.Sin(num) + 0.7f * Mathf.Sin(2f * num) + 0.5f * Mathf.Sin(3f * num) + 0.4f * Mathf.Sin(4f * num) + 0.3f * Mathf.Sin(5f * num) + 0.2f * Mathf.Sin(6f * num) + 0.15f * Mathf.Sin(7f * num) + 0.1f * Mathf.Sin(8f * num)) * 0.2f;
float num3 = 0.02f * (Random.value - 0.5f);
array[i] = num2 + num3;
}
_clip = AudioClip.Create("BugleBrassClip", 7568, 1, 44100, false);
_clip.SetData(array, 0);
return _clip;
}
public static AudioClip Brassier()
{
if (Object.op_Implicit((Object)(object)_clip))
{
return _clip;
}
Plugin.Log.LogInfo((object)"Generating brassier clip");
float[] array = new float[7568];
for (int i = 0; i < 7568; i++)
{
float num = 366.12122f * (float)i / 44100f;
float num2 = 1f * Mathf.Sin(num) + 0.8f * Mathf.Sin(2f * num) + 1.2f * Mathf.Sin(3f * num) + 0.6f * Mathf.Sin(4f * num) + 0.4f * Mathf.Sin(5f * num) + 0.8f * Mathf.Sin(6f * num) + 0.2f * Mathf.Sin(7f * num) + 0.1f * Mathf.Sin(8f * num);
num2 *= 0.15f;
float num3 = 0.01f * (Random.value - 0.5f);
array[i] = num2 + num3;
}
_clip = AudioClip.Create("BugleBrassierClip", 7568, 1, 44100, false);
_clip.SetData(array, 0);
return _clip;
}
public static AudioClip Sawtooth()
{
if (Object.op_Implicit((Object)(object)_clip))
{
return _clip;
}
Plugin.Log.LogInfo((object)"Generating sawtooth clip");
float[] array = new float[7568];
for (int i = 0; i < 7568; i++)
{
float num = 366.12122f * (float)i / 44100f;
float num2 = 366.85345f * (float)i / 44100f;
float num3 = 0f;
for (int j = 1; j <= 20; j++)
{
float num4 = 1f / (float)j * Mathf.Exp(-0.05f * (float)j);
if (j >= 5 && j <= 7)
{
num4 *= 1.5f;
}
float num5 = (float)i / 7568f;
float num6 = 1f + 0.05f * Mathf.Sin(MathF.PI * 2f * (float)j * num5);
num3 += num4 * num6 * (Mathf.Sin((float)j * num) + 0.3f * Mathf.Sin((float)j * num2));
}
num3 *= 0.2f;
float num7 = 0.01f * (Random.value - 0.5f);
array[i] = num3 + num7;
}
_clip = AudioClip.Create("BugleSawtoothClip", 7568, 1, 44100, false);
_clip.SetData(array, 0);
return _clip;
}
public static AudioClip Pinched()
{
if (Object.op_Implicit((Object)(object)_clip))
{
return _clip;
}
Plugin.Log.LogInfo((object)"Generating fixed pinched brass clip");
float[] array = new float[7568];
for (int i = 0; i < 7568; i++)
{
float num = (float)i / 44100f;
float num2 = 366.12122f * num;
float num3 = 0f;
for (int j = 1; j <= 20; j++)
{
float num4 = num2 * (float)j;
float num5 = Mathf.Sin(num4);
float num6 = Mathf.Sign(num5) * Mathf.Pow(Mathf.Abs(num5), 1.1f);
float num7 = 1f / (float)j * Mathf.Exp(-0.045f * (float)j);
if (j >= 5 && j <= 7)
{
num7 *= 1.5f;
}
num3 += num7 * num6;
}
num3 += 0.15f * Mathf.Pow(num3, 3f);
float num8 = 0.005f * (Random.value - 0.5f);
array[i] = num3 * 0.3f + num8;
}
_clip = AudioClip.Create("BuglePinchedClip", 7568, 1, 44100, false);
_clip.SetData(array, 0);
return _clip;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}