Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Instruments v0.2.0
BepInEx/plugins/Instruments/Instruments.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
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.Text; using BepInEx; using HarmonyLib; using Instruments.Content; using Instruments.Performance; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Instruments")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.0.0")] [assembly: AssemblyInformationalVersion("0.2.0+8d150ac7af5086147b4e3dc6d3099c9dfbfac8b2")] [assembly: AssemblyProduct("Instruments")] [assembly: AssemblyTitle("Instruments")] [assembly: AssemblyVersion("0.2.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Instruments { [BepInPlugin("com.igentuman.instruments", "Instruments", "0.2.0")] [BepInDependency("com.jotunn.jotunn", "2.30.2")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.igentuman.instruments"; public const string PluginName = "Instruments"; public const string PluginVersion = "0.2.0"; private Harmony? harmony; private void Awake() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown InstrumentAudio.Initialize(delegate(string message) { ((BaseUnityPlugin)this).Logger.LogWarning((object)message); }); InstrumentLocalization.Register(); InstrumentRegistry.Register(); PerformanceRegistry.Initialize(); harmony = new Harmony("com.igentuman.instruments"); harmony.PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Instruments 0.2.0 loaded."); } private void OnDestroy() { InstrumentRegistry.Unregister(); InstrumentPlayer[] array = Object.FindObjectsByType<InstrumentPlayer>((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { Object.DestroyImmediate((Object)(object)array[i]); } PerformanceRegistry.Clear(); InstrumentAudio.Clear(); Harmony? obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } } namespace Instruments.Performance { internal sealed class BowedPerformance : IInstrumentPerformance, IDisposable, IPitchedInstrumentPerformance, ITremoloInstrumentPerformance { private const float FadeInDuration = 0.04f; private const float FadeOutDuration = 0.08f; private const float AttackBend = 0.012f; private const float ReleaseBend = -0.018f; private const float AttackRelaxDuration = 0.1f; private const float TremoloDepth = 0.25f; private const float TremoloBlendDuration = 0.08f; private const float TremoloRateDuration = 0.06f; private const float BowChangeDuration = 0.055f; private readonly GameObject audio; private readonly AudioSource[] sources = (AudioSource[])(object)new AudioSource[3]; private readonly BowedVoiceFilter[] filters = new BowedVoiceFilter[3]; private readonly bool[] held = new bool[3]; private readonly float[] gains = new float[3]; private readonly float[] bends = new float[3]; private readonly BowedPose pose; private float pitch = 1f; private float targetTremoloRate; private float tremoloRate = 4f; private float tremoloDepth; private float tremoloPhase; private float bowElapsed; private float bowDuration = 1.15f; private float bowTime; private bool bowForward = true; private bool disposed; internal BowedPerformance(Player player) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown pose = new BowedPose(player); AudioClip[] array = (AudioClip[])(object)new AudioClip[3] { InstrumentAudio.Load("bowed/violin.wav"), InstrumentAudio.Load("bowed/violin2.wav"), InstrumentAudio.Load("bowed/violin3.wav") }; audio = new GameObject("Instruments_BowedAudio"); audio.transform.SetParent(((Component)player).transform, false); audio.transform.localPosition = new Vector3(0f, 1.2f, 0.4f); for (int i = 0; i < sources.Length; i++) { GameObject val = new GameObject("Voice_" + i); val.transform.SetParent(audio.transform, false); AudioSource val2 = val.AddComponent<AudioSource>(); val2.playOnAwake = false; val2.clip = array[i]; val2.loop = true; val2.volume = 0f; val2.spatialBlend = 1f; val2.reverbZoneMix = 0.28f; val2.rolloffMode = (AudioRolloffMode)1; val2.minDistance = 5f; val2.maxDistance = 35f; val2.dopplerLevel = 0f; sources[i] = val2; filters[i] = val.AddComponent<BowedVoiceFilter>(); filters[i].Initialize(i); } } public void SetPitch(float offset) { pitch = 1f + offset; } public void SetTremolo(float rate) { targetTremoloRate = rate; } public void OnNote(NoteEvent kind, int note) { switch (kind) { case NoteEvent.Release: held[note] = false; break; case NoteEvent.Press: { if (held[note]) { break; } held[note] = true; if (sources[note].isPlaying) { break; } bool flag = false; AudioSource[] array = sources; foreach (AudioSource val in array) { flag |= val.isPlaying; } if (!flag) { tremoloPhase = (tremoloDepth = 0f); bowElapsed = (bowTime = 0f); bowDuration = 1.15f; bowForward = true; if (targetTremoloRate > 0f) { tremoloRate = targetTremoloRate; } } gains[note] = 0f; bends[note] = 0.012f; sources[note].volume = 0f; sources[note].pitch = pitch * (1f + bends[note]); sources[note].Play(); break; } } } public void LateUpdate() { UpdateAudio(); } internal bool UpdateAudio() { float unscaledDeltaTime = Time.unscaledDeltaTime; bool flag = false; bool flag2 = false; for (int i = 0; i < sources.Length; i++) { flag |= held[i]; flag2 |= sources[i].isPlaying; } if (!flag2) { return false; } bowTime += unscaledDeltaTime; bowElapsed += unscaledDeltaTime; while (bowElapsed >= bowDuration) { bowElapsed -= bowDuration; bowForward = !bowForward; bowDuration = (bowForward ? 1.15f : 1.32f) + 0.06f * Mathf.Sin(bowTime * 1.7f); } float num = bowElapsed / bowDuration; float num2 = Mathf.SmoothStep(0f, 1f, Mathf.Min(bowElapsed, bowDuration - bowElapsed) / 0.055f); float num3 = 0.9f + 0.08f * Mathf.Sin(num * MathF.PI); float num4 = 0.008f * Mathf.Sin(bowTime * 43.7f) + 0.006f * Mathf.Sin(bowTime * 71.3f); float num5 = Mathf.Lerp(0.82f, 1f, num2) * (num3 + num4); float num6 = 0.0015f * Mathf.Sin(num * MathF.PI) + (bowForward ? 0.002f : (-0.002f)) * (1f - num2); float contactNoise = (flag ? (0.06f + 0.25f * (1f - num2)) : 0f); bool flag3 = targetTremoloRate > 0f; if (flag3) { tremoloRate = Mathf.MoveTowards(tremoloRate, targetTremoloRate, 6f * unscaledDeltaTime / 0.06f); } tremoloDepth = Mathf.MoveTowards(tremoloDepth, flag3 ? 0.25f : 0f, 0.25f * unscaledDeltaTime / 0.08f); tremoloPhase = Mathf.Repeat(tremoloPhase + tremoloRate * unscaledDeltaTime, 1f); float num7 = 1f - tremoloDepth * (0.5f - 0.5f * Mathf.Cos(tremoloPhase * 2f * MathF.PI)); float num8 = Mathf.Sqrt(AudioMan.GetSFXVolume()) * num7 * num5; bool result = false; for (int j = 0; j < sources.Length; j++) { AudioSource val = sources[j]; if (val.isPlaying) { filters[j].SetBow(num3 + (bowForward ? 0.04f : (-0.04f)), contactNoise); float num9 = (held[j] ? 0.04f : 0.08f); gains[j] = Mathf.MoveTowards(gains[j], (float)(held[j] ? 1 : 0), unscaledDeltaTime / num9); bends[j] = Mathf.MoveTowards(bends[j], held[j] ? 0f : (-0.018f), unscaledDeltaTime * (held[j] ? 0.12f : 0.375f)); val.pitch = pitch * (1f + bends[j] + num6 + num4 * 0.06f); val.volume = num8 * Mathf.SmoothStep(0f, 1f, gains[j]); if (!held[j] && gains[j] == 0f) { val.Stop(); } else { result = true; } } } return result; } public void OnAnimatorIK() { bool flag = false; for (int i = 0; i < held.Length; i++) { flag |= held[i]; } pose.Apply(flag, bowElapsed / bowDuration, bowForward); } public void Dispose() { if (!disposed) { disposed = true; pose.Dispose(); for (int i = 0; i < held.Length; i++) { held[i] = false; } targetTremoloRate = 0f; if (Object.op_Implicit((Object)(object)audio)) { audio.AddComponent<BowedRelease>().Initialize(this); } } } } internal sealed class BowedRelease : MonoBehaviour { private BowedPerformance performance; internal void Initialize(BowedPerformance performer) { performance = performer; } private void LateUpdate() { if (!performance.UpdateAudio()) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } internal sealed class BowedPose : IDisposable { private const float ContactDuration = 0.18f; private const float RecoveryDuration = 0.26f; private static readonly Vector3 ShoulderRest = new Vector3(0f, 0.045f, 0.018f); private static readonly Vector3 BowGrip = new Vector3(0f, 0.04f, 0f); private static readonly Quaternion AcrossStrings = Quaternion.LookRotation(Vector3.down, Vector3.right); private static readonly Quaternion BowRoll = Quaternion.Euler(0f, 180f, 0f); private static readonly FieldRef<VisEquipment, GameObject> HeldItem = AccessTools.FieldRefAccess<VisEquipment, GameObject>("m_rightItemInstance"); private static readonly FieldRef<VisEquipment, int> HeldHash = AccessTools.FieldRefAccess<VisEquipment, int>("m_currentRightItemHash"); private static readonly int InstrumentHash = StringExtensionMethods.GetStableHashCode("Instruments_BowedInstrument"); private readonly Player player; private readonly Animator animator; private readonly AnimatorCullingMode cullingMode; private readonly Transform visual; private readonly Transform? chest; private readonly Transform? head; private readonly Quaternion headNeutralRotation; private readonly InstrumentArm left; private readonly InstrumentArm right; private readonly InstrumentFingerPose fingers; private Transform? attach; private Transform? model; private Transform? bow; private InstrumentBowHandVisual? bowVisual; private Transform? originalParent; private Vector3 originalPosition; private Quaternion originalRotation; private Vector3 originalScale; private Vector3 originalModelPosition; private Quaternion originalModelRotation; private float contact; private float stroke; private int lastFrame = -1; internal BowedPose(Player player) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) this.player = player; animator = ((Component)player).GetComponentInChildren<Animator>(); visual = ((Component)animator).transform; cullingMode = animator.cullingMode; animator.cullingMode = (AnimatorCullingMode)0; if (animator.isHuman) { chest = animator.GetBoneTransform((HumanBodyBones)8); head = animator.GetBoneTransform((HumanBodyBones)10); } headNeutralRotation = NeutralHeadRotation(); left = new InstrumentArm(animator, left: true); right = new InstrumentArm(animator, left: false); fingers = new InstrumentFingerPose(animator, -0.55f, -0.25f); } internal void Apply(bool playing, float progress, bool forward) { //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_046e: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) //IL_0478: Unknown result type (might be due to invalid IL or missing references) //IL_047d: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_0489: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Unknown result type (might be due to invalid IL or missing references) //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) //IL_04a9: Unknown result type (might be due to invalid IL or missing references) InstrumentAnimationPatch.ClearHandIK(animator); VisEquipment visEquipment = ((Humanoid)player).GetVisEquipment(); GameObject val = (Object.op_Implicit((Object)(object)visEquipment) ? HeldItem.Invoke(visEquipment) : null); if (!Object.op_Implicit((Object)(object)head) || !Object.op_Implicit((Object)(object)chest) || !Object.op_Implicit((Object)(object)val) || !val.activeInHierarchy || HeldHash.Invoke(visEquipment) != InstrumentHash || ((Character)player).IsDead() || ((Character)player).InCutscene() || ((Character)player).IsTeleporting() || ((Character)player).InBed() || ((Character)player).InDodge() || ((Character)player).IsStaggering() || ((Character)player).IsSwimming() || ((Character)player).IsAttached() || ((Character)player).InEmote()) { RestoreAttachment(); contact = (stroke = 0f); return; } if ((Object)(object)attach != (Object)(object)val.transform) { Bind(val.transform); } if (Object.op_Implicit((Object)(object)attach) && Object.op_Implicit((Object)(object)model) && Object.op_Implicit((Object)(object)bow)) { if (lastFrame != Time.frameCount) { lastFrame = Time.frameCount; float unscaledDeltaTime = Time.unscaledDeltaTime; contact = Mathf.MoveTowards(contact, (float)(playing ? 1 : 0), unscaledDeltaTime / (playing ? 0.18f : 0.26f)); float num = Mathf.SmoothStep(0f, 1f, progress); float num2 = ((!playing) ? 0f : (forward ? num : (1f - num))); stroke = Mathf.MoveTowards(stroke, num2, unscaledDeltaTime * (playing ? 1.8f : 3.846154f)); } float num3 = Mathf.SmoothStep(0f, 1f, contact); animator.SetLookAtWeight(0f); Quaternion val2 = visual.rotation * Quaternion.Euler(8f, 16f, -10f) * headNeutralRotation; animator.SetBoneLocalRotation((HumanBodyBones)10, Quaternion.Inverse(head.parent.rotation) * val2); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(0.62f, 0f, 0.78f); Quaternion val4 = visual.rotation * Quaternion.LookRotation(Vector3.down, val3) * Quaternion.Euler(Mathf.Lerp(9f, 6f, num3), 0f, 0f); Vector3 val5 = head.position + visual.rotation * new Vector3(0.08f, -0.135f, 0.1f); attach.SetPositionAndRotation(val5, val4); right.Pose(model, new Vector3(0.035f, 0.265f, 0.005f), Quaternion.LookRotation(Vector3.down, Vector3.back), new Vector3(0.13f, 0.18f, 0.17f)); Quaternion val6 = model.rotation * AcrossStrings * Quaternion.Euler(0f, 0f, -10f * (1f - num3)) * BowRoll; Vector3 val7 = model.TransformPoint(new Vector3(0f, 0.135f + 0.025f * (1f - num3), -0.031f - 0.025f * (1f - num3))); Vector3 val8 = default(Vector3); ((Vector3)(ref val8))..ctor(0.011f, Mathf.Lerp(0.13f, 0.25f, stroke), 0f); Vector3 val9 = val7 - val6 * Vector3.Scale(val8, bow.lossyScale); if (Object.op_Implicit((Object)(object)bowVisual)) { bowVisual.SetPerformancePose(val9, val6); } else { bow.SetPositionAndRotation(val9, val6); } Quaternion val10 = Quaternion.Inverse(BowRoll); left.Pose(bow, val10 * (BowGrip + new Vector3(0.012f, 0f, 0.018f)), val10 * Quaternion.LookRotation(Vector3.left, Vector3.back), val10 * new Vector3(-0.13f, -0.04f, 0.11f)); fingers.Apply(animator); } } private void Bind(Transform held) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) RestoreAttachment(); Transform val = held.Find("model"); Transform val2 = (Object.op_Implicit((Object)(object)val) ? val.Find("bow") : null); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2)) { attach = held; model = val; bow = val2; bowVisual = ((Component)bow).GetComponent<InstrumentBowHandVisual>(); originalParent = held.parent; originalPosition = held.localPosition; originalRotation = held.localRotation; originalScale = held.localScale; originalModelPosition = val.localPosition; originalModelRotation = val.localRotation; held.SetParent(chest, true); val.localRotation = Quaternion.identity; val.localPosition = -Vector3.Scale(ShoulderRest, val.localScale); } } private Quaternion NeutralHeadRotation() { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) VisEquipment visEquipment = ((Humanoid)player).GetVisEquipment(); SkinnedMeshRenderer val = (Object.op_Implicit((Object)(object)visEquipment) ? visEquipment.m_bodyModel : null); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)head)) { Transform[] bones = val.bones; Matrix4x4[] bindposes = val.sharedMesh.bindposes; for (int i = 0; i < bones.Length && i < bindposes.Length; i++) { if ((Object)(object)bones[i] == (Object)(object)head) { Matrix4x4 val2 = visual.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix * ((Matrix4x4)(ref bindposes[i])).inverse; return ((Matrix4x4)(ref val2)).rotation; } } } if (!Object.op_Implicit((Object)(object)head)) { return Quaternion.identity; } return Quaternion.Inverse(visual.rotation) * head.rotation; } private void RestoreAttachment() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)attach) && Object.op_Implicit((Object)(object)originalParent)) { attach.SetParent(originalParent, false); attach.localPosition = originalPosition; attach.localRotation = originalRotation; attach.localScale = originalScale; } if (Object.op_Implicit((Object)(object)model)) { model.localPosition = originalModelPosition; model.localRotation = originalModelRotation; } if (Object.op_Implicit((Object)(object)bowVisual)) { bowVisual.ClearPerformancePose(); } attach = (model = (bow = (originalParent = null))); bowVisual = null; } public void Dispose() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) RestoreAttachment(); if (Object.op_Implicit((Object)(object)animator)) { animator.cullingMode = cullingMode; } } } internal sealed class BowedVoiceFilter : MonoBehaviour { private readonly float[] body = new float[8]; private readonly float[] energy = new float[8]; private volatile float targetPressure; private volatile float targetScrape; private volatile bool initialized; private float pressure; private float scrape; private float noiseLow; private float noiseHigh; private float bodyCoefficient; private float noiseLowCoefficient; private float noiseHighCoefficient; private float smoothing; private uint random; internal void Initialize(int note) { int outputSampleRate = AudioSettings.outputSampleRate; bodyCoefficient = Coefficient(900f, outputSampleRate); noiseLowCoefficient = Coefficient(5500f, outputSampleRate); noiseHighCoefficient = Coefficient(1200f, outputSampleRate); smoothing = 1f - (float)Math.Exp(-1.0 / (0.012 * (double)outputSampleRate)); random = (uint)(-1640531527 + note); initialized = true; } private static float Coefficient(float frequency, int rate) { return 1f - (float)Math.Exp(Math.PI * -2.0 * (double)frequency / (double)rate); } internal void SetBow(float bowPressure, float contactNoise) { targetPressure = bowPressure; targetScrape = contactNoise; } private void OnAudioFilterRead(float[] data, int channels) { if (!initialized || channels < 1 || channels > body.Length) { return; } float num = targetPressure; float num2 = targetScrape; for (int i = 0; i < data.Length; i += channels) { pressure += (num - pressure) * smoothing; scrape += (num2 - scrape) * smoothing; random ^= random << 13; random ^= random >> 17; random ^= random << 5; float num3 = (float)(random & 0xFFFFFF) / 8388608f - 1f; noiseLow += (num3 - noiseLow) * noiseLowCoefficient; noiseHigh += (num3 - noiseHigh) * noiseHighCoefficient; for (int j = 0; j < channels; j++) { int num4 = i + j; float num5 = data[num4]; energy[j] += (num5 * num5 - energy[j]) * smoothing; float num6 = (noiseLow - noiseHigh) * 3f * (float)Math.Sqrt(Math.Max(0f, energy[j])) * scrape; body[j] += (num5 - body[j]) * bodyCoefficient; float num7 = num5 + (num5 - body[j]) * (0.08f + 0.12f * pressure); float num8 = num7 * (1.2f + 0.3f * pressure); float num9 = num8 / (1f + Math.Abs(num8)); data[num4] = num7 * 0.75f + num9 * 0.25f + num6; } } } } internal static class CameraPitch { internal const float StepAngle = 10f; internal const float MaxOffset = 0.25f; internal static float FromElevation(float degrees) { if (!(degrees < -10f)) { if (!(degrees > 10f)) { return 0f; } return 0.25f; } return -0.25f; } internal static bool IsValid(float offset) { if (offset != -0.25f && offset != 0f) { return offset == 0.25f; } return true; } } internal static class CameraTremolo { internal const float FastRate = 10f; internal const float SlowRate = 4f; private const float MinimumAngularSpeed = 12f; internal static float FromMovement(float previousYaw, float yaw, float deltaTime) { if (deltaTime <= 0f) { return 0f; } float num = Mathf.DeltaAngle(previousYaw, yaw) / deltaTime; if (Mathf.Abs(num) < 12f) { return 0f; } if (!(num < 0f)) { return 4f; } return 10f; } internal static bool IsValid(float rate) { if (rate != 0f && rate != 4f) { return rate == 10f; } return true; } } internal sealed class DrumArm { private readonly InstrumentArm arm; private readonly bool isLeft; internal DrumArm(Animator animator, bool left) { arm = new InstrumentArm(animator, left); isLeft = left; } internal void Pose(Transform drum, float x, float lift) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) arm.Pose(drum, new Vector3(x, 0.24f + lift, -0.04f - lift * 0.2f), Quaternion.LookRotation(Vector3.forward, isLeft ? Vector3.left : Vector3.right), new Vector3(isLeft ? (-0.42f) : 0.42f, 0.35f + lift * 0.5f, -0.2f)); } } internal sealed class DrumPerformance : IInstrumentPerformance, IDisposable { private const float WindupDuration = 0.2f; private const float DownstrokeDuration = 0.09f; private const float StrikeDelay = 0.29000002f; private const float RecoveryDuration = 0.18f; private const float RestLift = 0.08f; private const float SwingLift = 0.38f; private const float HitGain = 1.5f; private static readonly FieldRef<VisEquipment, GameObject> HeldItem = AccessTools.FieldRefAccess<VisEquipment, GameObject>("m_rightItemInstance"); private static readonly FieldRef<VisEquipment, int> HeldHash = AccessTools.FieldRefAccess<VisEquipment, int>("m_currentRightItemHash"); private static readonly int DrumHash = StringExtensionMethods.GetStableHashCode("Instruments_Drum"); private readonly Player player; private readonly AudioSource source; private readonly AudioClip[] clips; private readonly Animator animator; private readonly AnimatorCullingMode cullingMode; private readonly DrumArm left; private readonly DrumArm right; private readonly InstrumentFingerPose fists; private readonly List<(float Impact, int Note)> pendingHits = new List<(float, int)>(); private float leftContact = float.NegativeInfinity; private float rightContact = float.NegativeInfinity; internal DrumPerformance(Player player) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) this.player = player; clips = (AudioClip[])(object)new AudioClip[3] { InstrumentAudio.Load("drum/drum_hit.wav"), InstrumentAudio.Load("drum/drum-hit-hi.wav"), InstrumentAudio.Load("drum/drum-hit-low.wav") }; GameObject val = new GameObject("Instruments_DrumAudio"); val.transform.SetParent(((Component)player).transform, false); val.transform.localPosition = new Vector3(0f, 1.2f, 0.4f); source = val.AddComponent<AudioSource>(); source.playOnAwake = false; source.volume = Mathf.Sqrt(AudioMan.GetSFXVolume()); source.spatialBlend = 1f; source.reverbZoneMix = 0.28f; source.rolloffMode = (AudioRolloffMode)1; source.minDistance = 5f; source.maxDistance = 35f; source.dopplerLevel = 0f; source.pitch = 1f; animator = ((Component)player).GetComponentInChildren<Animator>(); cullingMode = animator.cullingMode; animator.cullingMode = (AnimatorCullingMode)0; left = new DrumArm(animator, left: true); right = new DrumArm(animator, left: false); fists = new InstrumentFingerPose(animator); } public void OnNote(NoteEvent kind, int note) { if (kind != NoteEvent.Release) { pendingHits.Add((Time.time + 0.29000002f, note)); } } public void LateUpdate() { source.volume = Mathf.Sqrt(AudioMan.GetSFXVolume()); while (pendingHits.Count > 0 && Time.time >= pendingHits[0].Impact) { (float, int) tuple = pendingHits[0]; source.PlayOneShot(clips[tuple.Item2], 1.5f); if (UsesHand(tuple.Item2, left: true)) { (leftContact, _) = tuple; } if (UsesHand(tuple.Item2, left: false)) { (rightContact, _) = tuple; } pendingHits.RemoveAt(0); } } public void OnAnimatorIK() { InstrumentAnimationPatch.ClearHandIK(animator); if (!((Character)player).IsDead() && !((Character)player).InCutscene() && !((Character)player).InDodge() && !((Character)player).IsStaggering() && !((Character)player).IsSwimming() && !((Character)player).IsAttached()) { VisEquipment visEquipment = ((Humanoid)player).GetVisEquipment(); GameObject val = HeldItem.Invoke(visEquipment); if (HeldHash.Invoke(visEquipment) == DrumHash && Object.op_Implicit((Object)(object)val) && !(((Object)val.transform.parent).name != "Spine")) { left.Pose(val.transform, -0.11f, Lift(leftHand: true, leftContact)); right.Pose(val.transform, 0.11f, Lift(leftHand: false, rightContact)); fists.Apply(animator); } } } private static bool UsesHand(int note, bool left) { if (note != 2) { return note == ((!left) ? 1 : 0); } return true; } private float Lift(bool leftHand, float lastContact) { foreach (var pendingHit in pendingHits) { if (UsesHand(pendingHit.Note, leftHand)) { if (Time.time >= pendingHit.Impact) { return RecoveryLift(Time.time - pendingHit.Impact); } float num = Mathf.Max(pendingHit.Impact - 0.29000002f, lastContact); float num2 = pendingHit.Impact - num; float num3 = num2 * 0.6896551f; float num4 = Time.time - num; float num5 = 0.38f * Mathf.Clamp01(num2 / 0.29000002f); if (num4 < num3) { return Mathf.Lerp(RecoveryLift(num - lastContact), num5, Mathf.SmoothStep(0f, 1f, num4 / num3)); } return Mathf.Lerp(num5, 0f, Mathf.SmoothStep(0f, 1f, (num4 - num3) / (num2 - num3))); } } return RecoveryLift(Time.time - lastContact); } private static float RecoveryLift(float elapsed) { return 0.08f * Mathf.SmoothStep(0f, 1f, elapsed / 0.18f); } public void Dispose() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) pendingHits.Clear(); if (Object.op_Implicit((Object)(object)animator)) { animator.cullingMode = cullingMode; } if (Object.op_Implicit((Object)(object)source)) { Object.Destroy((Object)(object)((Component)source).gameObject, Mathf.Max(new float[3] { clips[0].length, clips[1].length, clips[2].length })); } } } internal sealed class GusliArm { private const float StrumDuration = 0.16f; private const float RecoveryDuration = 0.24f; private readonly InstrumentArm arm; private readonly Vector3 ready; private readonly Vector3 contact; private readonly Vector3 elbow; private readonly Quaternion readyRotation; private readonly Quaternion contactRotation; private Vector3 start; private Quaternion startRotation; private Vector3 end; private Quaternion endRotation; private float started = float.NegativeInfinity; internal GusliArm(Animator animator, bool left) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) arm = new InstrumentArm(animator, left); float num = ((!left) ? 1 : (-1)); ready = new Vector3(0.12f, num * 0.22f, -0.12f); contact = new Vector3(0.06f, num * 0.07f, -0.085f); elbow = new Vector3(0.28f, num * 0.44f, 0.18f); readyRotation = Quaternion.LookRotation(new Vector3(-1f, (0f - num) * 0.35f, 0f), Vector3.back); contactRotation = Quaternion.LookRotation(new Vector3(-1f, num * 0.15f, 0f), Vector3.back); end = contact; endRotation = contactRotation; } internal void Strum(bool continuous = false, bool reverse = false) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) Evaluate(out start, out startRotation); if (continuous) { end = (Vector3)(reverse ? new Vector3(contact.x, ready.y, contact.z) : contact); endRotation = (reverse ? readyRotation : contactRotation); } else { end = contact; endRotation = contactRotation; } started = Time.time; } internal void Pose(Transform instrument) { //IL_0011: 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_0014: Unknown result type (might be due to invalid IL or missing references) Evaluate(out var wrist, out var rotation); arm.Pose(instrument, wrist, rotation, elbow); } private void Evaluate(out Vector3 wrist, out Quaternion rotation) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) float num = Time.time - started; if (num < 0.16f) { float num2 = Mathf.SmoothStep(0f, 1f, num / 0.16f); wrist = Vector3.Lerp(start, end, num2); rotation = Quaternion.Slerp(startRotation, endRotation, num2); } else { float num3 = Mathf.Clamp01((num - 0.16f) / 0.24f); float num4 = Mathf.SmoothStep(0f, 1f, num3); wrist = Vector3.Lerp(end, ready, num4); wrist.z -= 0.04f * Mathf.Sin(num3 * MathF.PI); rotation = Quaternion.Slerp(endRotation, readyRotation, num4); } } } internal sealed class GusliPerformance : IInstrumentPerformance, IDisposable, IPitchedInstrumentPerformance { private const double BlockStrumInterval = 0.16; private readonly AudioSource source; private readonly AudioClip[] clips; private readonly AudioClip reverseBlockClip; private readonly float tailDuration; private readonly GusliPose pose; private float pitch = 1f; private int heldMask; private double nextBlockStrum; private bool nextBlockReverse; internal GusliPerformance(Player player) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) pose = new GusliPose(player); clips = (AudioClip[])(object)new AudioClip[3] { InstrumentAudio.Load("gusli/gusli-C.wav"), InstrumentAudio.Load("gusli/gusli-F.wav"), InstrumentAudio.Load("gusli/gusli-G.wav") }; reverseBlockClip = InstrumentAudio.Load("gusli/gusli-F-reverse.wav"); tailDuration = Mathf.Max(new float[4] { clips[0].length, clips[1].length, clips[2].length, reverseBlockClip.length }); GameObject val = new GameObject("Instruments_GusliAudio"); val.transform.SetParent(((Component)player).transform, false); val.transform.localPosition = new Vector3(0f, 1f, 0.4f); source = val.AddComponent<AudioSource>(); source.playOnAwake = false; source.volume = Mathf.Sqrt(AudioMan.GetSFXVolume()); source.spatialBlend = 1f; source.reverbZoneMix = 0.28f; source.rolloffMode = (AudioRolloffMode)1; source.minDistance = 5f; source.maxDistance = 35f; source.dopplerLevel = 0f; source.pitch = 1f; } public void SetPitch(float offset) { pitch = 1f + offset; if (heldMask != 0) { source.pitch = pitch; } } public void OnNote(NoteEvent kind, int note) { if ((uint)note >= clips.Length) { return; } if (kind == NoteEvent.Release) { heldMask &= ~(1 << note); return; } bool flag = (heldMask & (1 << note)) != 0; heldMask |= 1 << note; if (note == 1) { if (flag) { return; } nextBlockStrum = Time.timeAsDouble + 0.16; nextBlockReverse = true; } Strum(note); } private void Strum(int note, bool reverse = false) { source.pitch = pitch; source.PlayOneShot((note == 1 && reverse) ? reverseBlockClip : clips[note], (note == 1) ? 0.8f : 1f); pose.Strum(note, reverse); } public void LateUpdate() { source.volume = Mathf.Sqrt(AudioMan.GetSFXVolume()); if ((heldMask & 2) != 0 && !(Time.timeAsDouble < nextBlockStrum)) { double timeAsDouble = Time.timeAsDouble; nextBlockStrum += (Math.Floor((timeAsDouble - nextBlockStrum) / 0.16) + 1.0) * 0.16; Strum(1, nextBlockReverse); nextBlockReverse = !nextBlockReverse; } } public void OnAnimatorIK() { pose.Apply(); } public void Dispose() { pose.Dispose(); if (Object.op_Implicit((Object)(object)source)) { Object.Destroy((Object)(object)((Component)source).gameObject, tailDuration / source.pitch); } } } internal sealed class GusliPose : IDisposable { private static readonly FieldRef<VisEquipment, GameObject> HeldItem = AccessTools.FieldRefAccess<VisEquipment, GameObject>("m_rightItemInstance"); private static readonly FieldRef<VisEquipment, int> HeldHash = AccessTools.FieldRefAccess<VisEquipment, int>("m_currentRightItemHash"); private static readonly int GusliHash = StringExtensionMethods.GetStableHashCode("Instruments_Gusli"); private readonly Player player; private readonly Animator animator; private readonly AnimatorCullingMode cullingMode; private readonly GusliArm left; private readonly GusliArm right; private readonly InstrumentFingerPose fingers; internal GusliPose(Player player) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) this.player = player; animator = ((Component)player).GetComponentInChildren<Animator>(); cullingMode = animator.cullingMode; animator.cullingMode = (AnimatorCullingMode)0; left = new GusliArm(animator, left: true); right = new GusliArm(animator, left: false); fingers = new InstrumentFingerPose(animator, 0.2f, 0.1f); } internal void Strum(int note, bool reverse = false) { if ((note == 0 || note == 2) ? true : false) { left.Strum(); } if ((uint)(note - 1) <= 1u) { right.Strum(note == 1, reverse); } } internal void Apply() { InstrumentAnimationPatch.ClearHandIK(animator); if (((Character)player).IsDead() || ((Character)player).InCutscene() || ((Character)player).IsTeleporting() || ((Character)player).InBed() || ((Character)player).InDodge() || ((Character)player).IsStaggering() || ((Character)player).IsSwimming() || ((Character)player).IsAttached() || ((Character)player).InEmote()) { return; } VisEquipment visEquipment = ((Humanoid)player).GetVisEquipment(); if (visEquipment != null && Object.op_Implicit((Object)(object)visEquipment)) { GameObject val = HeldItem.Invoke(visEquipment); if (Object.op_Implicit((Object)(object)val) && val.activeInHierarchy && HeldHash.Invoke(visEquipment) == GusliHash && Object.op_Implicit((Object)(object)val.transform.parent) && !(((Object)val.transform.parent).name != "Spine")) { left.Pose(val.transform); right.Pose(val.transform); fingers.Apply(animator); } } } public void Dispose() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)animator)) { animator.cullingMode = cullingMode; } } } internal sealed class HornPerformance : IInstrumentPerformance, IDisposable, IPitchedInstrumentPerformance { private const float FadeInDuration = 0.04f; private const float FadeOutDuration = 0.06f; private readonly GameObject audio; private readonly AudioSource[] sources = (AudioSource[])(object)new AudioSource[3]; private readonly bool[] held = new bool[3]; private readonly float[] gains = new float[3]; private readonly HornPose pose; internal HornPerformance(Player player) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) pose = new HornPose(player); AudioClip[] array = (AudioClip[])(object)new AudioClip[3] { InstrumentAudio.Load("horn/horn1.wav"), InstrumentAudio.Load("horn/horn2.wav"), InstrumentAudio.Load("horn/horn3.wav") }; audio = new GameObject("Instruments_HornAudio"); audio.transform.SetParent(((Component)player).transform, false); audio.transform.localPosition = new Vector3(0f, 1.5f, 0.4f); for (int i = 0; i < sources.Length; i++) { AudioSource val = audio.AddComponent<AudioSource>(); val.playOnAwake = false; val.clip = array[i]; val.loop = true; val.volume = 0f; val.spatialBlend = 1f; val.reverbZoneMix = 0.28f; val.rolloffMode = (AudioRolloffMode)1; val.minDistance = 5f; val.maxDistance = 35f; val.dopplerLevel = 0f; val.pitch = 1f; sources[i] = val; } } public void SetPitch(float offset) { AudioSource[] array = sources; for (int i = 0; i < array.Length; i++) { array[i].pitch = 1f + offset; } } public void OnNote(NoteEvent kind, int note) { switch (kind) { case NoteEvent.Release: held[note] = false; break; case NoteEvent.Press: if (!held[note]) { held[note] = true; if (!sources[note].isPlaying) { gains[note] = 0f; sources[note].volume = 0f; sources[note].Play(); } } break; } } public void LateUpdate() { float num = Mathf.Sqrt(AudioMan.GetSFXVolume()); for (int i = 0; i < sources.Length; i++) { float num2 = (held[i] ? 0.04f : 0.06f); gains[i] = Mathf.MoveTowards(gains[i], (float)(held[i] ? 1 : 0), Time.unscaledDeltaTime / num2); sources[i].volume = num * gains[i]; if (!held[i] && gains[i] == 0f) { sources[i].Stop(); } } } public void OnAnimatorIK() { bool flag = false; for (int i = 0; i < held.Length; i++) { flag |= held[i]; } pose.Apply(flag); } public void Dispose() { pose.Dispose(); if (Object.op_Implicit((Object)(object)audio)) { audio.AddComponent<HornFadeOut>().Initialize(sources, 0.06f); } } } internal sealed class HornFadeOut : MonoBehaviour { private AudioSource[] sources; private float[] volumes; private float duration; private float elapsed; internal void Initialize(AudioSource[] voices, float fadeDuration) { sources = voices; duration = fadeDuration; volumes = new float[voices.Length]; for (int i = 0; i < voices.Length; i++) { volumes[i] = voices[i].volume; } } private void Update() { elapsed += Time.unscaledDeltaTime; float num = Mathf.Clamp01(1f - elapsed / duration); for (int i = 0; i < sources.Length; i++) { sources[i].volume = volumes[i] * num; } if (elapsed >= duration) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } internal sealed class HornPose : IDisposable { private const float RaiseDuration = 0.2f; private const float LowerDuration = 0.24f; private const float HeadPitch = 8f; private static readonly Vector3 Mouthpiece = new Vector3(-0.224f, 0.138f, 0f); private static readonly Vector3 MouthOffset = new Vector3(0f, 0.025f, 0.1f); private static readonly Vector3 ReadyOffset = new Vector3(0.03f, -0.08f, 0.18f); private static readonly FieldRef<VisEquipment, GameObject> HeldItem = AccessTools.FieldRefAccess<VisEquipment, GameObject>("m_rightItemInstance"); private static readonly FieldRef<VisEquipment, int> HeldHash = AccessTools.FieldRefAccess<VisEquipment, int>("m_currentRightItemHash"); private static readonly int HornHash = StringExtensionMethods.GetStableHashCode("Instruments_Horn"); private readonly Player player; private readonly Animator animator; private readonly AnimatorCullingMode cullingMode; private readonly Transform visual; private readonly Transform? chest; private readonly Transform? head; private readonly Quaternion headNeutralRotation; private readonly InstrumentArm left; private readonly InstrumentArm right; private readonly InstrumentFingerPose fingers; private Transform? attach; private Transform? model; private Transform? originalParent; private Vector3 originalPosition; private Quaternion originalRotation; private Vector3 originalScale; private Vector3 originalModelPosition; private Quaternion originalModelRotation; private float raised; private int lastFrame = -1; internal HornPose(Player player) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) this.player = player; animator = ((Component)player).GetComponentInChildren<Animator>(); visual = ((Component)animator).transform; cullingMode = animator.cullingMode; animator.cullingMode = (AnimatorCullingMode)0; if (animator.isHuman) { chest = animator.GetBoneTransform((HumanBodyBones)8); head = animator.GetBoneTransform((HumanBodyBones)10); } headNeutralRotation = NeutralHeadRotation(); left = new InstrumentArm(animator, left: true); right = new InstrumentArm(animator, left: false); fingers = new InstrumentFingerPose(animator, -0.65f, -0.35f); } internal void Apply(bool playing) { //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) InstrumentAnimationPatch.ClearHandIK(animator); VisEquipment visEquipment = ((Humanoid)player).GetVisEquipment(); GameObject val = (Object.op_Implicit((Object)(object)visEquipment) ? HeldItem.Invoke(visEquipment) : null); int num = (Object.op_Implicit((Object)(object)visEquipment) ? HeldHash.Invoke(visEquipment) : 0); if (!Object.op_Implicit((Object)(object)head) || !Object.op_Implicit((Object)(object)chest) || !Object.op_Implicit((Object)(object)val) || !val.activeInHierarchy || num != HornHash || ((Character)player).IsDead() || ((Character)player).InCutscene() || ((Character)player).InDodge() || ((Character)player).IsStaggering() || ((Character)player).IsSwimming() || ((Character)player).IsAttached() || ((Character)player).InBed() || ((Character)player).InEmote()) { RestoreAttachment(); raised = 0f; return; } if ((Object)(object)attach != (Object)(object)val.transform) { Bind(val.transform); } if (Object.op_Implicit((Object)(object)attach) && Object.op_Implicit((Object)(object)model)) { if (lastFrame != Time.frameCount) { lastFrame = Time.frameCount; raised = Mathf.MoveTowards(raised, (float)(playing ? 1 : 0), Time.deltaTime / (playing ? 0.2f : 0.24f)); } float num2 = Mathf.SmoothStep(0f, 1f, raised); Quaternion val2 = Quaternion.Euler(-8f * num2, 0f, 0f); if (playing || raised > 0f) { animator.SetLookAtWeight(0f); Quaternion val3 = visual.rotation * val2 * headNeutralRotation; animator.SetBoneLocalRotation((HumanBodyBones)10, Quaternion.Inverse(head.parent.rotation) * val3); } Vector3 val4 = head.position + visual.rotation * ReadyOffset; Vector3 val5 = head.position + visual.rotation * val2 * MouthOffset; Quaternion val6 = visual.rotation * Quaternion.Euler(Mathf.Lerp(3f, -8f, num2), 22f, 0f) * Quaternion.Euler(0f, -90f, 0f); attach.SetPositionAndRotation(Vector3.Lerp(val4, val5, num2), val6); right.Pose(model, new Vector3(-0.14f, 0.035f, -0.04f), Quaternion.LookRotation(Vector3.up, Vector3.back), new Vector3(-0.2f, -0.16f, -0.23f)); left.Pose(model, new Vector3(-0.025f, -0.005f, 0.045f), Quaternion.LookRotation(Vector3.up, Vector3.forward), new Vector3(-0.19f, -0.17f, 0.24f)); fingers.Apply(animator); } } private void Bind(Transform held) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) RestoreAttachment(); Transform val = held.Find("model"); if (Object.op_Implicit((Object)(object)val)) { attach = held; model = val; originalParent = held.parent; originalPosition = held.localPosition; originalRotation = held.localRotation; originalScale = held.localScale; originalModelPosition = val.localPosition; originalModelRotation = val.localRotation; held.SetParent(chest, true); val.localRotation = Quaternion.identity; val.localPosition = -Vector3.Scale(Mouthpiece, val.localScale); } } private Quaternion NeutralHeadRotation() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) SkinnedMeshRenderer bodyModel = ((Humanoid)player).GetVisEquipment().m_bodyModel; if (Object.op_Implicit((Object)(object)bodyModel) && Object.op_Implicit((Object)(object)head)) { Transform[] bones = bodyModel.bones; Matrix4x4[] bindposes = bodyModel.sharedMesh.bindposes; for (int i = 0; i < bones.Length && i < bindposes.Length; i++) { if ((Object)(object)bones[i] == (Object)(object)head) { Matrix4x4 val = visual.worldToLocalMatrix * ((Component)bodyModel).transform.localToWorldMatrix * ((Matrix4x4)(ref bindposes[i])).inverse; return ((Matrix4x4)(ref val)).rotation; } } } if (!Object.op_Implicit((Object)(object)head)) { return Quaternion.identity; } return Quaternion.Inverse(visual.rotation) * head.rotation; } private void RestoreAttachment() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)attach) && Object.op_Implicit((Object)(object)originalParent)) { attach.SetParent(originalParent, false); attach.localPosition = originalPosition; attach.localRotation = originalRotation; attach.localScale = originalScale; } if (Object.op_Implicit((Object)(object)model)) { model.localPosition = originalModelPosition; model.localRotation = originalModelRotation; } attach = null; model = null; originalParent = null; } public void Dispose() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) RestoreAttachment(); if (Object.op_Implicit((Object)(object)animator)) { animator.cullingMode = cullingMode; } } } internal sealed class InstrumentArm { private readonly Animator animator; private readonly Transform hand; private readonly Transform? fingers; private readonly Transform? index; private readonly Transform? pinky; private readonly bool isLeft; internal InstrumentArm(Animator animator, bool left) { isLeft = left; this.animator = animator; hand = Utils.GetBoneTransform(animator, (HumanBodyBones)(left ? 17 : 18)); fingers = Utils.FindChild(((Component)animator).transform, left ? "LeftHandMiddle1" : "RightHandMiddle1", (IterativeSearchType)0); index = Utils.FindChild(((Component)animator).transform, left ? "LeftHandIndex1" : "RightHandIndex1", (IterativeSearchType)0); pinky = Utils.FindChild(((Component)animator).transform, left ? "LeftHandPinky1" : "RightHandPinky1", (IterativeSearchType)0); } internal void Pose(Transform instrument, Vector3 wrist, Quaternion palmFrame, Vector3 elbow) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)hand) || !animator.isHuman) { return; } AvatarIKGoal val = (AvatarIKGoal)(isLeft ? 2 : 3); AvatarIKHint val2 = (AvatarIKHint)(isLeft ? 2 : 3); Vector3 val3 = instrument.TransformPoint(wrist); Vector3 iKPosition = animator.GetIKPosition(val); Quaternion iKRotation = animator.GetIKRotation(val); Quaternion val4 = Quaternion.identity; if (Object.op_Implicit((Object)(object)fingers) && Object.op_Implicit((Object)(object)index) && Object.op_Implicit((Object)(object)pinky)) { Vector3 val5 = fingers.position - hand.position; Vector3 val6 = Vector3.Cross(val5, index.position - pinky.position) * (float)(isLeft ? 1 : (-1)); if (((Vector3)(ref val5)).sqrMagnitude > 1E-06f && ((Vector3)(ref val6)).sqrMagnitude > 1E-06f) { val4 = instrument.rotation * palmFrame * Quaternion.Inverse(Quaternion.LookRotation(val5, val6)); } } animator.SetIKPositionWeight(val, 1f); animator.SetIKPosition(val, val3 + val4 * (iKPosition - hand.position)); animator.SetIKHintPositionWeight(val2, 1f); animator.SetIKHintPosition(val2, instrument.TransformPoint(elbow)); animator.SetIKRotationWeight(val, 1f); animator.SetIKRotation(val, val4 * iKRotation); } } internal static class InstrumentAudio { private static readonly Dictionary<string, AudioClip> Clips = new Dictionary<string, AudioClip>(); private static InstrumentSoundFiles files = null; private static Action<string> warn = null; internal static void Initialize(Action<string> logWarning) { warn = logWarning; files = new InstrumentSoundFiles(Path.Combine(Paths.ConfigPath, "Instruments", "sounds"), typeof(Plugin).Assembly, warn); files.ExtractDefaults(); } internal static AudioClip Load(string resource) { if (Clips.TryGetValue(resource, out AudioClip value)) { return value; } string path = files.GetPath(resource); AudioClip val; try { using Stream stream = files.Open(resource); val = Decode(stream, resource); } catch (Exception ex) when (ex is IOException || ex is InvalidDataException || ex is UnauthorizedAccessException || ex is OverflowException) { using Stream stream2 = files.OpenDefault(resource); if (stream2 == null) { throw new InvalidDataException("Cannot load instrument sample: " + path, ex); } warn("Cannot load sound '" + path + "': " + ex.Message + ". Using the bundled sample; the file was left unchanged. Expected mono PCM 16-bit WAV."); val = Decode(stream2, resource); } Clips.Add(resource, val); return val; } private static AudioClip Decode(Stream stream, string resource) { using BinaryReader binaryReader = new BinaryReader(stream); if (new string(binaryReader.ReadChars(4)) != "RIFF") { throw new InvalidDataException(resource); } binaryReader.ReadUInt32(); if (new string(binaryReader.ReadChars(4)) != "WAVE") { throw new InvalidDataException(resource); } int num = 0; int num2 = 0; byte[] array = null; while (stream.Position + 8 <= stream.Length) { string text = new string(binaryReader.ReadChars(4)); uint num3 = binaryReader.ReadUInt32(); long num4 = stream.Position + num3; if (num4 > stream.Length) { throw new InvalidDataException(resource); } if (text == "fmt ") { if (num3 < 16 || binaryReader.ReadUInt16() != 1) { throw new InvalidDataException("Expected PCM: " + resource); } num = binaryReader.ReadUInt16(); num2 = binaryReader.ReadInt32(); binaryReader.ReadUInt32(); binaryReader.ReadUInt16(); if (binaryReader.ReadUInt16() != 16) { throw new InvalidDataException("Expected 16-bit WAV: " + resource); } } else if (text == "data") { array = binaryReader.ReadBytes(checked((int)num3)); } stream.Position = num4 + (num3 & 1); } if (array == null || array.Length == 0 || num != 1 || num2 <= 0 || array.Length % 2 != 0) { throw new InvalidDataException("Expected mono WAV: " + resource); } float[] array2 = new float[array.Length / 2]; for (int i = 0; i < array2.Length; i++) { array2[i] = (float)(short)(array[i * 2] | (array[i * 2 + 1] << 8)) / 32768f; } AudioClip obj = AudioClip.Create(resource, array2.Length, num, num2, false); obj.SetData(array2, 0); return obj; } internal static void Clear() { foreach (AudioClip value in Clips.Values) { Object.Destroy((Object)(object)value); } Clips.Clear(); } } internal sealed class InstrumentFingerPose { private readonly List<(HumanBodyBones Bone, Quaternion Rotation)> rotations = new List<(HumanBodyBones, Quaternion)>(); internal InstrumentFingerPose(Animator animator, float fingerStretch = -1f, float thumbStretch = -0.5f) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if (!animator.isHuman) { return; } HumanPoseHandler val = new HumanPoseHandler(animator.avatar, ((Component)animator).transform); try { HumanPose val2 = default(HumanPose); val.GetHumanPose(ref val2); HumanPose val3 = val2; val3.muscles = (float[])val2.muscles.Clone(); string[] muscleName = HumanTrait.MuscleName; for (int i = 0; i < muscleName.Length; i++) { if (muscleName[i].EndsWith(" Stretched", StringComparison.Ordinal)) { val3.muscles[i] = ((muscleName[i].IndexOf("Thumb", StringComparison.Ordinal) >= 0) ? thumbStretch : fingerStretch); } else if (muscleName[i].EndsWith(" Spread", StringComparison.Ordinal)) { val3.muscles[i] = 0f; } } try { val.SetHumanPose(ref val3); for (int j = 24; j <= 53; j++) { HumanBodyBones val4 = (HumanBodyBones)j; Transform boneTransform = animator.GetBoneTransform(val4); if (Object.op_Implicit((Object)(object)boneTransform)) { rotations.Add((val4, boneTransform.localRotation)); } } } finally { val.SetHumanPose(ref val2); } } finally { ((IDisposable)val)?.Dispose(); } } internal void Apply(Animator animator) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) foreach (var (val, val2) in rotations) { animator.SetBoneLocalRotation(val, val2); } } } internal sealed class InstrumentPlayer : MonoBehaviour { internal const string RpcName = "Instruments_Note_v2"; internal const string PitchRpcName = "Instruments_Pitch_v1"; internal const string BowedNoteRpcName = "Instruments_BowedNote_v1"; internal const string ExpressionRpcName = "Instruments_Expression_v1"; private const float PitchSendInterval = 0.05f; private const float PitchSendThreshold = 0.001f; private static readonly Func<PlayerController, bool, bool> TakeInput = AccessTools.MethodDelegate<Func<PlayerController, bool, bool>>(AccessTools.Method(typeof(PlayerController), "TakeInput", (Type[])null, (Type[])null), (object)null, true); private static readonly Func<PlayerController, bool> InInventory = AccessTools.MethodDelegate<Func<PlayerController, bool>>(AccessTools.Method(typeof(PlayerController), "InInventoryEtc", (Type[])null, (Type[])null), (object)null, true); private Player player; private ZNetView view; private PlayerController? controller; private PerformanceDefinition? definition; private IInstrumentPerformance? performance; private NoteInput? input; private bool wasOwner; private float lastReceived; private bool resetHandIK; private float pitch; private float sentPitch; private float lastPitchSent; private float tremolo; private float sentTremolo; private float previousYaw; private bool hasPreviousYaw; private float lastCameraMovement; private const float CameraMovementGrace = 0.06f; internal void Initialize(Player target, ZNetView network) { player = target; view = network; controller = ((Component)target).GetComponent<PlayerController>(); wasOwner = view.IsOwner(); view.Register<int, int, int, float>("Instruments_Note_v2", (Method<int, int, int, float>)Receive); view.Register<int, float>("Instruments_Pitch_v1", (Action<long, int, float>)ReceivePitch); view.Register<int, int, int, float, float>("Instruments_BowedNote_v1", (Method<int, int, int, float, float>)ReceiveBowedNote); view.Register<int, float, float>("Instruments_Expression_v1", (Action<long, int, float, float>)ReceiveExpression); } private void Update() { //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)view) || !view.IsValid()) { Reset(); return; } bool flag = view.IsOwner(); if (wasOwner != flag) { Reset(); wasOwner = flag; } int num = ((!flag) ? view.GetZDO().GetInt(ZDOVars.s_rightItem, 0) : (Object.op_Implicit((Object)(object)((Humanoid)player).RightItem?.m_dropPrefab) ? StringExtensionMethods.GetStableHashCode(((Object)((Humanoid)player).RightItem.m_dropPrefab).name) : 0)); if (flag || definition == null || num == definition.PrefabHash || Time.time - lastReceived > 1f) { Select(PerformanceRegistry.Find(num)); } if (!flag || input == null) { return; } bool flag2 = CanPlay(); int num2 = (flag2 ? ReadButtons() : 0); if (flag2 && definition.UsesCameraPitch) { float degrees = Mathf.Asin(Mathf.Clamp(((Character)player).m_eye.forward.y, -1f, 1f)) * 57.29578f; pitch = CameraPitch.FromElevation(degrees); (performance as IPitchedInstrumentPerformance)?.SetPitch(pitch); } if (definition.UsesCameraTremolo) { if (flag2) { Quaternion rotation = ((Character)player).m_eye.rotation; float y = ((Quaternion)(ref rotation)).eulerAngles.y; float num3 = (hasPreviousYaw ? CameraTremolo.FromMovement(previousYaw, y, Time.unscaledDeltaTime) : 0f); previousYaw = y; hasPreviousYaw = true; if (num3 > 0f) { tremolo = num3; lastCameraMovement = Time.unscaledTime; } else if (Time.unscaledTime - lastCameraMovement >= 0.06f) { tremolo = 0f; } } else { hasPreviousYaw = false; tremolo = 0f; } (performance as ITremoloInstrumentPerformance)?.SetTremolo(tremolo); } input.Update(num2, Time.timeAsDouble); if (num2 != 0 && definition.UsesCameraPitch && Time.unscaledTime - lastPitchSent >= 0.05f && (Mathf.Abs(pitch - sentPitch) >= 0.001f || tremolo != sentTremolo)) { if (definition.UsesCameraTremolo) { view.InvokeRPC(ZNetView.Everybody, "Instruments_Expression_v1", new object[3] { definition.PrefabHash, pitch, tremolo }); } else { view.InvokeRPC(ZNetView.Everybody, "Instruments_Pitch_v1", new object[2] { definition.PrefabHash, pitch }); } sentPitch = pitch; sentTremolo = tremolo; lastPitchSent = Time.unscaledTime; } } private bool CanPlay() { if ((Object)(object)player == (Object)(object)Player.m_localPlayer && Object.op_Implicit((Object)(object)controller) && ((Behaviour)controller).isActiveAndEnabled && Application.isFocused && !PlayerController.HasInputDelay && TakeInput(controller, arg2: false) && !InInventory(controller) && !Hud.InRadial() && !((Character)player).IsDead() && !((Character)player).InCutscene() && !((Character)player).IsTeleporting() && !((Character)player).InBed() && !((Character)player).InDodge() && !((Character)player).IsStaggering() && !((Character)player).IsSwimming() && !((Character)player).IsAttached()) { return !((Character)player).InEmote(); } return false; } private static int ReadButtons() { int num = 0; if (ZInput.GetButton("Attack") || ZInput.GetButton("JoyAttack")) { num |= 1; } if (ZInput.GetButton("Block") || ZInput.GetButton("JoyBlock")) { num |= 2; } if (ZInput.GetButton("SecondaryAttack") || ZInput.GetButton("JoySecondaryAttack")) { num |= 4; } return num; } private void Select(PerformanceDefinition? next) { if (definition == next) { return; } Reset(); definition = next; if (next != null) { if (!ZNet.instance.IsDedicated()) { performance = next.Create(player); } input = new NoteInput(next.RepeatInterval, Send); } } private void Send(NoteEvent kind, int note) { if (definition != null && Object.op_Implicit((Object)(object)view) && view.IsValid() && view.IsOwner()) { performance?.OnNote(kind, note); if (definition.UsesCameraTremolo) { view.InvokeRPC(ZNetView.Everybody, "Instruments_BowedNote_v1", new object[5] { definition.PrefabHash, (int)kind, note, pitch, tremolo }); } else { view.InvokeRPC(ZNetView.Everybody, "Instruments_Note_v2", new object[4] { definition.PrefabHash, (int)kind, note, pitch }); } sentPitch = pitch; sentTremolo = tremolo; lastPitchSent = Time.unscaledTime; } } private void Receive(long sender, int hash, int kind, int note, float offset) { ReceiveNote(sender, hash, kind, note, offset, 0f); } private void ReceiveBowedNote(long sender, int hash, int kind, int note, float offset, float rate) { if (CameraTremolo.IsValid(rate)) { PerformanceDefinition? performanceDefinition = PerformanceRegistry.Find(hash); if (performanceDefinition != null && performanceDefinition.UsesCameraTremolo) { ReceiveNote(sender, hash, kind, note, offset, rate); } } } private void ReceiveNote(long sender, int hash, int kind, int note, float offset, float rate) { if (view.IsValid() && !view.IsOwner() && sender == view.GetZDO().GetOwner() && (uint)note < 3u && (uint)kind <= 2u && CameraPitch.IsValid(offset)) { PerformanceDefinition performanceDefinition = PerformanceRegistry.Find(hash); if (performanceDefinition != null && (kind != 2 || definition == performanceDefinition)) { lastReceived = Time.time; Select(performanceDefinition); (performance as IPitchedInstrumentPerformance)?.SetPitch(offset); (performance as ITremoloInstrumentPerformance)?.SetTremolo(rate); performance?.OnNote((NoteEvent)kind, note); } } } private void ReceiveExpression(long sender, int hash, float offset, float rate) { if (view.IsValid() && !view.IsOwner() && sender == view.GetZDO().GetOwner() && definition != null && definition.PrefabHash == hash && definition.UsesCameraTremolo && CameraPitch.IsValid(offset) && CameraTremolo.IsValid(rate)) { lastReceived = Time.time; (performance as IPitchedInstrumentPerformance)?.SetPitch(offset); (performance as ITremoloInstrumentPerformance)?.SetTremolo(rate); } } private void ReceivePitch(long sender, int hash, float offset) { if (view.IsValid() && !view.IsOwner() && sender == view.GetZDO().GetOwner() && definition != null && definition.PrefabHash == hash && definition.UsesCameraPitch && CameraPitch.IsValid(offset)) { lastReceived = Time.time; (performance as IPitchedInstrumentPerformance)?.SetPitch(offset); } } private void LateUpdate() { performance?.LateUpdate(); } internal void ApplyAnimationIK(Animator animator) { if (resetHandIK) { InstrumentAnimationPatch.ClearHandIK(animator); resetHandIK = false; } performance?.OnAnimatorIK(); } private void Reset() { input?.ReleaseAll(); input = null; if (performance != null) { resetHandIK = true; } performance?.Dispose(); performance = null; definition = null; pitch = (sentPitch = (lastPitchSent = 0f)); tremolo = (sentTremolo = (previousYaw = (lastCameraMovement = 0f))); hasPreviousYaw = false; } private void OnDisable() { Reset(); } private void OnDestroy() { Reset(); if (Object.op_Implicit((Object)(object)view)) { view.Unregister("Instruments_Note_v2"); view.Unregister("Instruments_Pitch_v1"); view.Unregister("Instruments_BowedNote_v1"); view.Unregister("Instruments_Expression_v1"); } } } [HarmonyPatch(typeof(CharacterAnimEvent), "OnAnimatorIK")] internal static class InstrumentAnimationPatch { internal static void ClearHandIK(Animator animator) { animator.SetIKPositionWeight((AvatarIKGoal)2, 0f); animator.SetIKPositionWeight((AvatarIKGoal)3, 0f); animator.SetIKRotationWeight((AvatarIKGoal)2, 0f); animator.SetIKRotationWeight((AvatarIKGoal)3, 0f); animator.SetIKHintPositionWeight((AvatarIKHint)2, 0f); animator.SetIKHintPositionWeight((AvatarIKHint)3, 0f); } private static void Postfix(Character ___m_character, Animator ___m_animator) { Player val = (Player)(object)((___m_character is Player) ? ___m_character : null); if (val != null) { ((Component)val).GetComponent<InstrumentPlayer>()?.ApplyAnimationIK(___m_animator); } } } [HarmonyPatch(typeof(Player), "Awake")] internal static class InstrumentPlayerPatch { private static void Postfix(Player __instance, ZNetView ___m_nview) { if (Object.op_Implicit((Object)(object)___m_nview) && ___m_nview.IsValid()) { ((Component)__instance).gameObject.AddComponent<InstrumentPlayer>().Initialize(__instance, ___m_nview); } } } internal sealed class InstrumentSoundFiles { internal const string ResourcePrefix = "Instruments.Sounds/"; private readonly string root; private readonly Assembly assembly; private readonly Action<string> warn; internal InstrumentSoundFiles(string root, Assembly assembly, Action<string> warn) { this.root = Path.GetFullPath(root); this.assembly = assembly; this.warn = warn; } internal void ExtractDefaults() { string[] manifestResourceNames = assembly.GetManifestResourceNames(); foreach (string text in manifestResourceNames) { if (text.StartsWith("Instruments.Sounds/", StringComparison.Ordinal)) { string relativePath = text.Substring("Instruments.Sounds/".Length); try { EnsureDefault(relativePath); } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException) { warn("Cannot extract sound '" + GetPath(relativePath) + "': " + ex.Message); } } } } internal string GetPath(string relativePath) { if (string.IsNullOrWhiteSpace(relativePath) || Path.IsPathRooted(relativePath) || relativePath.IndexOf('\\') >= 0 || relativePath.IndexOf(':') >= 0 || !relativePath.EndsWith(".wav", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException("Expected a relative WAV path: " + relativePath, "relativePath"); } string[] array = relativePath.Split('/'); foreach (string text in array) { if (text.Length == 0 || text == "." || text == "..") { throw new ArgumentException("Invalid sound path: " + relativePath, "relativePath"); } } return Path.Combine(root, relativePath.Replace('/', Path.DirectorySeparatorChar)); } internal Stream Open(string relativePath) { EnsureDefault(relativePath); return File.OpenRead(GetPath(relativePath)); } internal Stream? OpenDefault(string relativePath) { GetPath(relativePath); return assembly.GetManifestResourceStream("Instruments.Sounds/" + relativePath); } private void EnsureDefault(string relativePath) { string path = GetPath(relativePath); if (File.Exists(path)) { return; } using Stream stream = OpenDefault(relativePath); if (stream == null) { return; } Directory.CreateDirectory(Path.GetDirectoryName(path)); string text = path + "." + Guid.NewGuid().ToString("N") + ".tmp"; try { using (FileStream destination = new FileStream(text, FileMode.CreateNew, FileAccess.Write)) { stream.CopyTo(destination); } try { File.Move(text, path); } catch (IOException) when (File.Exists(path)) { } } finally { if (File.Exists(text)) { File.Delete(text); } } } } internal enum NoteEvent { Press, Repeat, Release } internal sealed class NoteInput { internal const int NoteCount = 3; private readonly bool[] held = new bool[3]; private readonly double[] next = new double[3]; private readonly double? interval; private readonly Action<NoteEvent, int> emit; internal NoteInput(double? interval, Action<NoteEvent, int> emit) { if (interval.HasValue && (interval.Value <= 0.0 || double.IsNaN(interval.Value) || double.IsInfinity(interval.Value))) { throw new ArgumentOutOfRangeException("interval"); } this.interval = interval; this.emit = emit; } internal void Update(int mask, double time) { for (int i = 0; i < 3; i++) { bool flag = (mask & (1 << i)) != 0; if (flag != held[i]) { held[i] = flag; next[i] = time + interval.GetValueOrDefault(); emit((!flag) ? NoteEvent.Release : NoteEvent.Press, i); } else if (flag && interval.HasValue && time >= next[i]) { next[i] += (Math.Floor((time - next[i]) / interval.Value) + 1.0) * interval.Value; emit(NoteEvent.Repeat, i); } } } internal void ReleaseAll() { Update(0, 0.0); } } internal interface IInstrumentPerformance : IDisposable { void OnNote(NoteEvent kind, int note); void OnAnimatorIK(); void LateUpdate(); } internal interface IPitchedInstrumentPerformance { void SetPitch(float offset); } internal interface ITremoloInstrumentPerformance { void SetTremolo(float rate); } internal sealed class PerformanceDefinition { internal readonly int PrefabHash; internal readonly double? RepeatInterval; internal readonly Func<Player, IInstrumentPerformance> Create; internal readonly bool UsesCameraPitch; internal readonly bool UsesCameraTremolo; internal PerformanceDefinition(string prefab, double? repeatInterval, Func<Player, IInstrumentPerformance> create, bool usesCameraPitch = false, bool usesCameraTremolo = false) { PrefabHash = StringExtensionMethods.GetStableHashCode(prefab); RepeatInterval = repeatInterval; Create = create; UsesCameraPitch = usesCameraPitch; UsesCameraTremolo = usesCameraTremolo; } } internal static class PerformanceRegistry { private static readonly Dictionary<int, PerformanceDefinition> Definitions = new Dictionary<int, PerformanceDefinition>(); internal static void Register(PerformanceDefinition definition) { Definitions.Add(definition.PrefabHash, definition); } internal static PerformanceDefinition? Find(int hash) { if (!Definitions.TryGetValue(hash, out PerformanceDefinition value)) { return null; } return value; } internal static void Initialize() { Register(new PerformanceDefinition("Instruments_Drum", 1.0, (Player player) => new DrumPerformance(player))); Register(new PerformanceDefinition("Instruments_Gusli", 0.5, (Player player) => new GusliPerformance(player), usesCameraPitch: true)); Register(new PerformanceDefinition("Instruments_Horn", null, (Player player) => new HornPerformance(player), usesCameraPitch: true)); Register(new PerformanceDefinition("Instruments_BowedInstrument", null, (Player player) => new BowedPerformance(player), usesCameraPitch: true, usesCameraTremolo: true)); } internal static void Clear() { Definitions.Clear(); } } } namespace Instruments.Content { [HarmonyPatch(typeof(VisEquipment), "AttachItem")] internal static class BowedInstrumentEquipmentPatch { private static readonly int InstrumentHash = StringExtensionMethods.GetStableHashCode("Instruments_BowedInstrument"); private static void Postfix(VisEquipment __instance, int itemHash, Transform joint, bool backAttach, GameObject? __result) { if (!(itemHash != InstrumentHash || backAttach) && !((Object)(object)joint != (Object)(object)__instance.m_rightHand) && __instance.m_isPlayer && Object.op_Implicit((Object)(object)__instance.m_leftHand) && Object.op_Implicit((Object)(object)__result)) { Transform val = __result.transform.Find("model/bow"); if (Object.op_Implicit((Object)(object)val)) { ((Component)val).gameObject.AddComponent<InstrumentBowHandVisual>().Bind(__instance.m_leftHand); } } } } internal sealed class InstrumentBowHandVisual : MonoBehaviour { private Transform? hand; private float scale; private bool performancePose; private static readonly Vector3 Grip = new Vector3(0f, 0.04f, 0f); private static readonly Quaternion GripRotation = Quaternion.Euler(90f, 0f, 0f) * Quaternion.Euler(0f, 180f, 0f); internal void Bind(Transform target) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) hand = target; scale = ((Component)this).transform.lossyScale.x; LateUpdate(); } internal void SetPerformancePose(Vector3 position, Quaternion rotation) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) performancePose = true; ((Component)this).transform.SetPositionAndRotation(position, rotation); } internal void ClearPerformancePose() { performancePose = false; LateUpdate(); } private void LateUpdate() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)hand) && !performancePose) { Quaternion val = hand.rotation * GripRotation; ((Component)this).transform.SetPositionAndRotation(hand.position - val * Grip * scale, val); } } } internal sealed class InstrumentAssets { private readonly List<(Mesh Mesh, Material Material)> parts = new List<(Mesh, Material)>(); private static readonly Dictionary<string, Texture2D> Textures = new Dictionary<string, Texture2D>(); internal Bounds Bounds { get; private set; } internal InstrumentAssets(string model, Shader shader) { //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to inval