using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BoneLib;
using BoneLib.BoneMenu;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Combat;
using Il2CppSLZ.Marrow.Data;
using LabFusion.Network;
using LabFusion.Network.Serialization;
using LabFusion.SDK.Modules;
using LabFusion.Utilities;
using MelonLoader;
using MelonLoader.Preferences;
using ThunderClapNS;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(ThunderClapMod), "ThunderClap", "2.0.0", "Dave", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: AssemblyTitle("FingerGun")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FingerGun")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("ebaec34e-ce68-4a24-a6b0-f18b9a726e8b")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ThunderClapNS
{
public class ThunderClapMod : MelonMod
{
[CompilerGenerated]
private sealed class <PlayTinnitusCoroutine>d__30 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
private GameObject <tempObj>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PlayTinnitusCoroutine>d__30(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<tempObj>5__2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Expected O, but got Unknown
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
{
<>1__state = -1;
AudioClip val = WavUtility.ToAudioClip(_tinnitusWavBytes, "tinnitus");
if ((Object)(object)val == (Object)null)
{
return false;
}
<tempObj>5__2 = new GameObject("ThunderClap_TinnitusTemp");
AudioSource obj = <tempObj>5__2.AddComponent<AudioSource>();
obj.spatialBlend = 0f;
obj.volume = 1f;
obj.clip = val;
obj.Play();
MelonLogger.Msg("[ThunderClap] Tinnitus playing in headphones");
<>2__current = (object)new WaitForSeconds(val.length);
<>1__state = 1;
return true;
}
case 1:
<>1__state = -1;
Object.Destroy((Object)(object)<tempObj>5__2);
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
internal static bool Enabled = false;
internal static float ExplosionForce = 30f;
internal static float ExplosionRadius = 8f;
internal static float NpcDamage = 200f;
internal static float Cooldown = 1f;
internal static float ClapThreshold = 0.15f;
internal static float MinClapSpeed = 2f;
internal static bool ShowShockwave = true;
internal static float UpwardsMod = 0.3f;
internal static bool TinnitusEnabled = true;
internal static int TinnitusThreshold = 4;
internal static float TinnitusWindow = 3f;
private static List<float> _clapTimestamps = new List<float>();
private static byte[] _tinnitusWavBytes = null;
private static float _lastDist = 999f;
private static float _cooldownTimer = 0f;
private static bool _fusionReady = false;
private static MelonPreferences_Category _cat;
private static MelonPreferences_Entry<bool> _prefEnabled;
private static MelonPreferences_Entry<float> _prefForce;
private static MelonPreferences_Entry<float> _prefRadius;
private static MelonPreferences_Entry<float> _prefDamage;
public override void OnInitializeMelon()
{
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_019c: Unknown result type (might be due to invalid IL or missing references)
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_0224: Unknown result type (might be due to invalid IL or missing references)
//IL_0268: Unknown result type (might be due to invalid IL or missing references)
//IL_029d: Unknown result type (might be due to invalid IL or missing references)
//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
_cat = MelonPreferences.CreateCategory("ThunderClap");
_prefEnabled = _cat.CreateEntry<bool>("Enabled", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
_prefForce = _cat.CreateEntry<float>("Force", 30f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
_prefRadius = _cat.CreateEntry<float>("Radius", 8f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
_prefDamage = _cat.CreateEntry<float>("Damage", 200f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
Enabled = _prefEnabled.Value;
ExplosionForce = _prefForce.Value;
ExplosionRadius = _prefRadius.Value;
NpcDamage = _prefDamage.Value;
Page obj = Page.Root.CreatePage("Thunder Clap", Color.yellow, 0, true);
obj.CreateBool("Enabled", Color.green, Enabled, (Action<bool>)delegate(bool v)
{
Enabled = v;
_prefEnabled.Value = v;
Save();
});
obj.CreateFloat("Explosion Force", Color.yellow, ExplosionForce, 5f, 5f, 200f, (Action<float>)delegate(float v)
{
ExplosionForce = v;
_prefForce.Value = v;
Save();
});
obj.CreateFloat("Radius", Color.white, ExplosionRadius, 1f, 2f, 30f, (Action<float>)delegate(float v)
{
ExplosionRadius = v;
_prefRadius.Value = v;
Save();
});
obj.CreateFloat("NPC Damage", Color.red, NpcDamage, 50f, 0f, 5000f, (Action<float>)delegate(float v)
{
NpcDamage = v;
_prefDamage.Value = v;
Save();
});
obj.CreateFloat("Cooldown", Color.white, Cooldown, 0.25f, 0.25f, 5f, (Action<float>)delegate(float v)
{
Cooldown = v;
});
obj.CreateFloat("Min Clap Speed", Color.white, MinClapSpeed, 0.5f, 0.5f, 10f, (Action<float>)delegate(float v)
{
MinClapSpeed = v;
});
obj.CreateBool("Shockwave Visual", Color.cyan, ShowShockwave, (Action<bool>)delegate(bool v)
{
ShowShockwave = v;
});
obj.CreateBool("Tinnitus Effect", Color.magenta, TinnitusEnabled, (Action<bool>)delegate(bool v)
{
TinnitusEnabled = v;
});
obj.CreateFloat("Tinnitus Claps Needed", Color.white, (float)TinnitusThreshold, 1f, 2f, 10f, (Action<float>)delegate(float v)
{
TinnitusThreshold = (int)v;
});
MelonLogger.Msg("[ThunderClap] Loaded");
}
public override void OnLateInitializeMelon()
{
MelonLogger.Msg("[ThunderClap] OnLateInit starting...");
try
{
MelonLogger.Msg("[ThunderClap] Calling LoadTinnitusClip...");
LoadTinnitusClip();
}
catch (Exception arg)
{
MelonLogger.Error($"[ThunderClap] WAV CRASH: {arg}");
}
try
{
RegisterFusion();
}
catch
{
MelonLogger.Msg("[ThunderClap] Fusion not found — local only");
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void RegisterFusion()
{
ModuleMessageManager.RegisterHandler<ThunderClapMessage>();
_fusionReady = true;
MelonLogger.Msg("[ThunderClap] Fusion synced");
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool HasFusionServer()
{
return NetworkInfo.HasServer;
}
private static void Save()
{
MelonPreferences.Save();
}
private static void LoadTinnitusClip()
{
MelonLogger.Msg("[ThunderClap] === LoadTinnitusClip entered ===");
string text = "ThunderClap.wav.ThunderClap_tinnitus.wav";
try
{
Assembly executingAssembly = Assembly.GetExecutingAssembly();
string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
MelonLogger.Msg($"[ThunderClap] Embedded resources ({manifestResourceNames.Length}):");
string[] array = manifestResourceNames;
foreach (string text2 in array)
{
MelonLogger.Msg("[ThunderClap] -> " + text2);
}
Stream manifestResourceStream = executingAssembly.GetManifestResourceStream(text);
if (manifestResourceStream == null)
{
array = manifestResourceNames;
foreach (string text3 in array)
{
if (text3.EndsWith(".wav"))
{
text = text3;
manifestResourceStream = executingAssembly.GetManifestResourceStream(text3);
break;
}
}
}
if (manifestResourceStream == null)
{
MelonLogger.Error("[ThunderClap] No WAV embedded!");
return;
}
_tinnitusWavBytes = new byte[manifestResourceStream.Length];
manifestResourceStream.Read(_tinnitusWavBytes, 0, _tinnitusWavBytes.Length);
manifestResourceStream.Close();
MelonLogger.Msg($"[ThunderClap] Tinnitus WAV cached: {_tinnitusWavBytes.Length} bytes from {text}");
}
catch (Exception arg)
{
MelonLogger.Error($"[ThunderClap] WAV load error: {arg}");
}
}
private static void OnClapOccurred(Vector3 clapPos)
{
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
if (!TinnitusEnabled)
{
return;
}
if (_tinnitusWavBytes == null)
{
MelonLogger.Warning("[ThunderClap] No WAV data cached");
return;
}
float now = Time.time;
_clapTimestamps.Add(now);
_clapTimestamps.RemoveAll((float t) => now - t > TinnitusWindow);
MelonLogger.Msg($"[ThunderClap] Clap #{_clapTimestamps.Count}/{TinnitusThreshold}");
if (_clapTimestamps.Count < TinnitusThreshold)
{
return;
}
_clapTimestamps.Clear();
if (_fusionReady)
{
try
{
if (HasFusionServer())
{
SendTinnitusToNetwork(clapPos);
}
}
catch
{
}
}
MelonLogger.Msg("[ThunderClap] TINNITUS sent to other players!");
}
internal static void PlayTinnitus()
{
if (_tinnitusWavBytes != null)
{
MelonCoroutines.Start(PlayTinnitusCoroutine());
}
}
[IteratorStateMachine(typeof(<PlayTinnitusCoroutine>d__30))]
private static IEnumerator PlayTinnitusCoroutine()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PlayTinnitusCoroutine>d__30(0);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void SendTinnitusToNetwork(Vector3 pos)
{
//IL_0006: 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_001e: 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)
ThunderClapData obj = new ThunderClapData
{
X = pos.x,
Y = pos.y,
Z = pos.z,
Mult = 0f,
Radius = 0f
};
MessageRoute val = default(MessageRoute);
((MessageRoute)(ref val))..ctor((RelayType)3, (NetworkChannel)0);
MessageRelay.RelayModule<ThunderClapMessage, ThunderClapData>(obj, val);
}
public override void OnUpdate()
{
if (!Enabled)
{
return;
}
if (_cooldownTimer > 0f)
{
_cooldownTimer -= Time.deltaTime;
}
ShockwaveVisual.Tick();
try
{
DetectClap();
}
catch
{
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void DetectClap()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: 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_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: 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_0080: 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_008f: 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_00b3: 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)
Hand leftHand = Player.LeftHand;
Hand rightHand = Player.RightHand;
if ((Object)(object)leftHand == (Object)null || (Object)(object)rightHand == (Object)null)
{
return;
}
Vector3 position = ((Component)leftHand).transform.position;
Vector3 position2 = ((Component)rightHand).transform.position;
float num = Vector3.Distance(position, position2);
float num2 = (_lastDist - num) / Time.deltaTime;
_lastDist = num;
if (!(num < ClapThreshold) || !(num2 > MinClapSpeed) || !(_cooldownTimer <= 0f))
{
return;
}
Vector3 val = (position + position2) / 2f;
float num3 = Mathf.Clamp(num2 / MinClapSpeed, 1f, 5f);
DoExplosion(val, num3);
OnClapOccurred(val);
if (_fusionReady)
{
try
{
if (HasFusionServer())
{
SendToNetwork(val, num3);
}
}
catch
{
}
}
_cooldownTimer = Cooldown;
_lastDist = 999f;
MelonLogger.Msg($"[ThunderClap] BOOM! {num2:F1} m/s x{num3:F1}");
}
internal static void DoExplosion(Vector3 center, float mult)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: 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_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: 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_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Expected O, but got Unknown
float num = ExplosionForce * mult;
Collider[] array = Il2CppArrayBase<Collider>.op_Implicit((Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(center, ExplosionRadius, -1, (QueryTriggerInteraction)1));
if (array == null)
{
return;
}
HashSet<int> hashSet = new HashSet<int>();
Collider[] array2 = array;
foreach (Collider val in array2)
{
if ((Object)(object)val == (Object)null || val.isTrigger)
{
continue;
}
RigManager componentInParent = ((Component)val).GetComponentInParent<RigManager>();
if ((Object)(object)componentInParent != (Object)null)
{
try
{
if (FusionPlayer.IsLocalPlayer(componentInParent))
{
continue;
}
}
catch
{
}
}
Rigidbody componentInParent2 = ((Component)val).GetComponentInParent<Rigidbody>();
if ((Object)(object)componentInParent2 != (Object)null && !componentInParent2.isKinematic && hashSet.Add(((Object)componentInParent2).GetInstanceID()))
{
componentInParent2.AddExplosionForce(num, center, ExplosionRadius, UpwardsMod, (ForceMode)1);
}
if (!(NpcDamage > 0f))
{
continue;
}
PlayerDamageReceiver componentInParent3 = ((Component)val).GetComponentInParent<PlayerDamageReceiver>();
if ((Object)(object)componentInParent3 != (Object)null && hashSet.Add(((Object)componentInParent3).GetInstanceID() + 100000))
{
float num2 = 1f - Mathf.Clamp01(Vector3.Distance(center, ((Component)val).transform.position) / ExplosionRadius);
try
{
Attack val2 = new Attack
{
damage = NpcDamage * mult * num2
};
Vector3 val3 = ((Component)val).transform.position - center;
val2.normal = ((Vector3)(ref val3)).normalized;
val2.origin = center;
val2.backFacing = false;
val2.attackType = (AttackType)2;
componentInParent3.ReceiveAttack(val2);
}
catch
{
}
}
}
if (ShowShockwave)
{
ShockwaveVisual.Spawn(center, ExplosionRadius);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void SendToNetwork(Vector3 pos, float mult)
{
//IL_0006: 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_001e: 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)
ThunderClapData obj = new ThunderClapData
{
X = pos.x,
Y = pos.y,
Z = pos.z,
Mult = mult,
Radius = ExplosionRadius
};
MessageRoute val = default(MessageRoute);
((MessageRoute)(ref val))..ctor((RelayType)3, (NetworkChannel)0);
MessageRelay.RelayModule<ThunderClapMessage, ThunderClapData>(obj, val);
}
}
public class ThunderClapData : INetSerializable
{
public float X;
public float Y;
public float Z;
public float Mult;
public float Radius;
public int? GetSize()
{
return 20;
}
public void Serialize(INetSerializer s)
{
s.SerializeValue(ref X);
s.SerializeValue(ref Y);
s.SerializeValue(ref Z);
s.SerializeValue(ref Mult);
s.SerializeValue(ref Radius);
}
}
public class ThunderClapMessage : ModuleMessageHandler
{
protected override void OnHandleMessage(ReceivedMessage received)
{
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: 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_004c: 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)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
ThunderClapData thunderClapData = ((ReceivedMessage)(ref received)).ReadData<ThunderClapData>();
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(thunderClapData.X, thunderClapData.Y, thunderClapData.Z);
if (thunderClapData.Mult == 0f && thunderClapData.Radius == 0f)
{
if (ThunderClapMod.TinnitusEnabled)
{
ThunderClapMod.PlayTinnitus();
}
MelonLogger.Msg($"[ThunderClap] Remote TINNITUS at ({val.x:F1}, {val.y:F1}, {val.z:F1})");
}
else
{
if (ThunderClapMod.ShowShockwave)
{
ShockwaveVisual.Spawn(val, thunderClapData.Radius);
}
MelonLogger.Msg($"[ThunderClap] Remote shockwave at ({val.x:F1}, {val.y:F1}, {val.z:F1})");
}
}
}
public static class ShockwaveVisual
{
private static GameObject _obj = null;
private static float _timer = 0f;
private static float _scale = 0f;
private static float _targetRadius = 8f;
public static void Spawn(Vector3 pos, float radius)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: 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_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Expected O, but got Unknown
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_obj != (Object)null)
{
Object.Destroy((Object)(object)_obj);
}
_obj = GameObject.CreatePrimitive((PrimitiveType)0);
((Object)_obj).name = "ThunderClap_Wave";
_obj.transform.position = pos;
_obj.transform.localScale = Vector3.one * 0.1f;
Collider component = _obj.GetComponent<Collider>();
if ((Object)(object)component != (Object)null)
{
Object.Destroy((Object)(object)component);
}
MeshRenderer component2 = _obj.GetComponent<MeshRenderer>();
if ((Object)(object)component2 != (Object)null)
{
Material val = new Material(Shader.Find("Sprites/Default"));
val.color = new Color(0.6f, 0.8f, 1f, 0.4f);
val.SetFloat("_Mode", 3f);
val.SetInt("_SrcBlend", 5);
val.SetInt("_DstBlend", 10);
val.SetInt("_ZWrite", 0);
val.EnableKeyword("_ALPHABLEND_ON");
val.renderQueue = 3000;
((Renderer)component2).material = val;
}
_scale = 0.1f;
_timer = 0.3f;
_targetRadius = radius;
}
public static void Tick()
{
//IL_0050: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
if (_timer <= 0f)
{
return;
}
_timer -= Time.deltaTime;
_scale += Time.deltaTime * _targetRadius * 3f;
if ((Object)(object)_obj != (Object)null)
{
_obj.transform.localScale = Vector3.one * _scale;
MeshRenderer component = _obj.GetComponent<MeshRenderer>();
if ((Object)(object)component != (Object)null)
{
float num = Mathf.Clamp01(_timer / 0.3f) * 0.4f;
((Renderer)component).material.color = new Color(0.6f, 0.8f, 1f, num);
}
}
if (_timer <= 0f && (Object)(object)_obj != (Object)null)
{
Object.Destroy((Object)(object)_obj);
_obj = null;
}
}
}
public static class WavUtility
{
public static AudioClip ToAudioClip(byte[] wav, string name = "WavClip")
{
try
{
if (wav == null || wav.Length < 44)
{
MelonLogger.Error("[WavUtility] WAV too small or null");
return null;
}
if (wav[0] != 82 || wav[1] != 73 || wav[2] != 70 || wav[3] != 70)
{
MelonLogger.Error("[WavUtility] Not a valid WAV file (no RIFF header)");
return null;
}
int num = BitConverter.ToInt16(wav, 22);
int num2 = BitConverter.ToInt32(wav, 24);
int num3 = BitConverter.ToInt16(wav, 34);
MelonLogger.Msg($"[WavUtility] {num}ch, {num2}Hz, {num3}bit");
int num4 = -1;
int num5 = 0;
for (int i = 12; i < wav.Length - 8; i++)
{
if (wav[i] == 100 && wav[i + 1] == 97 && wav[i + 2] == 116 && wav[i + 3] == 97)
{
num5 = BitConverter.ToInt32(wav, i + 4);
num4 = i + 8;
break;
}
}
if (num4 < 0)
{
MelonLogger.Error("[WavUtility] No data chunk found");
return null;
}
if (num4 + num5 > wav.Length)
{
num5 = wav.Length - num4;
}
float[] array;
switch (num3)
{
case 16:
array = Convert16BitToFloat(wav, num4, num5);
break;
case 8:
array = Convert8BitToFloat(wav, num4, num5);
break;
case 32:
array = Convert32BitToFloat(wav, num4, num5);
break;
default:
MelonLogger.Error($"[WavUtility] Unsupported bit depth: {num3}");
return null;
}
int num6 = array.Length / num;
MelonLogger.Msg($"[WavUtility] {array.Length} samples, {num6} frames");
AudioClip val = AudioClip.Create(name, num6, num, num2, false);
if ((Object)(object)val == (Object)null)
{
MelonLogger.Error("[WavUtility] AudioClip.Create returned null");
return null;
}
val.SetData(Il2CppStructArray<float>.op_Implicit(array), 0);
MelonLogger.Msg($"[WavUtility] AudioClip created: {val.length:F2}s");
return val;
}
catch (Exception arg)
{
MelonLogger.Error($"[WavUtility] {arg}");
return null;
}
}
private static float[] Convert16BitToFloat(byte[] wav, int offset, int dataSize)
{
int num = dataSize / 2;
float[] array = new float[num];
for (int i = 0; i < num; i++)
{
int num2 = offset + i * 2;
if (num2 + 1 >= wav.Length)
{
break;
}
short num3 = (short)(wav[num2] | (wav[num2 + 1] << 8));
array[i] = (float)num3 / 32768f;
}
return array;
}
private static float[] Convert8BitToFloat(byte[] wav, int offset, int dataSize)
{
float[] array = new float[dataSize];
for (int i = 0; i < dataSize && offset + i < wav.Length; i++)
{
array[i] = (float)(wav[offset + i] - 128) / 128f;
}
return array;
}
private static float[] Convert32BitToFloat(byte[] wav, int offset, int dataSize)
{
int num = dataSize / 4;
float[] array = new float[num];
for (int i = 0; i < num; i++)
{
int num2 = offset + i * 4;
if (num2 + 3 >= wav.Length)
{
break;
}
array[i] = BitConverter.ToSingle(wav, num2);
}
return array;
}
}
}
namespace ThunderClapNS.Impl
{
public class ThunderClapMod : MelonMod
{
[CompilerGenerated]
private sealed class <PlayTinnitusCoroutine>d__30 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public bool localPlayer;
public Vector3 pos;
private GameObject <tempObj>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PlayTinnitusCoroutine>d__30(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<tempObj>5__2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Expected O, but got Unknown
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
{
<>1__state = -1;
<tempObj>5__2 = new GameObject("ThunderClap_TinnitusTemp");
AudioSource val = <tempObj>5__2.AddComponent<AudioSource>();
val.spatialBlend = (localPlayer ? 0f : 1f);
val.volume = 1f;
val.clip = _tinnitusClip;
if (!localPlayer)
{
<tempObj>5__2.transform.position = pos;
val.minDistance = 1f;
val.maxDistance = 15f;
val.rolloffMode = (AudioRolloffMode)1;
}
val.Play();
MelonLogger.Msg($"[ThunderClap] Playing tinnitus (local={localPlayer}, length={_tinnitusClip.length:F1}s)");
<>2__current = (object)new WaitForSeconds(_tinnitusClip.length);
<>1__state = 1;
return true;
}
case 1:
<>1__state = -1;
Object.Destroy((Object)(object)<tempObj>5__2);
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
internal static bool Enabled = false;
internal static float ExplosionForce = 30f;
internal static float ExplosionRadius = 8f;
internal static float NpcDamage = 200f;
internal static float Cooldown = 1f;
internal static float ClapThreshold = 0.15f;
internal static float MinClapSpeed = 2f;
internal static bool ShowShockwave = true;
internal static float UpwardsMod = 0.3f;
internal static bool TinnitusEnabled = true;
internal static int TinnitusThreshold = 4;
internal static float TinnitusWindow = 3f;
private static List<float> _clapTimestamps = new List<float>();
private static AudioClip _tinnitusClip = null;
private static float _lastDist = 999f;
private static float _cooldownTimer = 0f;
private static bool _fusionReady = false;
private static MelonPreferences_Category _cat;
private static MelonPreferences_Entry<bool> _prefEnabled;
private static MelonPreferences_Entry<float> _prefForce;
private static MelonPreferences_Entry<float> _prefRadius;
private static MelonPreferences_Entry<float> _prefDamage;
public override void OnInitializeMelon()
{
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_019c: Unknown result type (might be due to invalid IL or missing references)
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_0224: Unknown result type (might be due to invalid IL or missing references)
//IL_0268: Unknown result type (might be due to invalid IL or missing references)
//IL_029d: Unknown result type (might be due to invalid IL or missing references)
//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
_cat = MelonPreferences.CreateCategory("ThunderClap");
_prefEnabled = _cat.CreateEntry<bool>("Enabled", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
_prefForce = _cat.CreateEntry<float>("Force", 30f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
_prefRadius = _cat.CreateEntry<float>("Radius", 8f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
_prefDamage = _cat.CreateEntry<float>("Damage", 200f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
Enabled = _prefEnabled.Value;
ExplosionForce = _prefForce.Value;
ExplosionRadius = _prefRadius.Value;
NpcDamage = _prefDamage.Value;
Page obj = Page.Root.CreatePage("Thunder Clap", Color.yellow, 0, true);
obj.CreateBool("Enabled", Color.green, Enabled, (Action<bool>)delegate(bool v)
{
Enabled = v;
_prefEnabled.Value = v;
Save();
});
obj.CreateFloat("Explosion Force", Color.yellow, ExplosionForce, 5f, 5f, 200f, (Action<float>)delegate(float v)
{
ExplosionForce = v;
_prefForce.Value = v;
Save();
});
obj.CreateFloat("Radius", Color.white, ExplosionRadius, 1f, 2f, 30f, (Action<float>)delegate(float v)
{
ExplosionRadius = v;
_prefRadius.Value = v;
Save();
});
obj.CreateFloat("NPC Damage", Color.red, NpcDamage, 50f, 0f, 5000f, (Action<float>)delegate(float v)
{
NpcDamage = v;
_prefDamage.Value = v;
Save();
});
obj.CreateFloat("Cooldown", Color.white, Cooldown, 0.25f, 0.25f, 5f, (Action<float>)delegate(float v)
{
Cooldown = v;
});
obj.CreateFloat("Min Clap Speed", Color.white, MinClapSpeed, 0.5f, 0.5f, 10f, (Action<float>)delegate(float v)
{
MinClapSpeed = v;
});
obj.CreateBool("Shockwave Visual", Color.cyan, ShowShockwave, (Action<bool>)delegate(bool v)
{
ShowShockwave = v;
});
obj.CreateBool("Tinnitus Effect", Color.magenta, TinnitusEnabled, (Action<bool>)delegate(bool v)
{
TinnitusEnabled = v;
});
obj.CreateFloat("Tinnitus Claps Needed", Color.white, (float)TinnitusThreshold, 1f, 2f, 10f, (Action<float>)delegate(float v)
{
TinnitusThreshold = (int)v;
});
MelonLogger.Msg("[ThunderClap] Loaded");
}
public override void OnLateInitializeMelon()
{
try
{
LoadTinnitusClip();
}
catch (Exception arg)
{
MelonLogger.Error($"[ThunderClap] WAV init error: {arg}");
}
try
{
RegisterFusion();
}
catch
{
MelonLogger.Msg("[ThunderClap] Fusion not found — local only");
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void RegisterFusion()
{
ModuleMessageManager.RegisterHandler<ThunderClapMessage>();
_fusionReady = true;
MelonLogger.Msg("[ThunderClap] Fusion synced");
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool HasFusionServer()
{
return NetworkInfo.HasServer;
}
private static void Save()
{
MelonPreferences.Save();
}
private static void LoadTinnitusClip()
{
string text = "ThunderClapNS.ThunderClap_tinnitus.wav";
try
{
Assembly executingAssembly = Assembly.GetExecutingAssembly();
string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
MelonLogger.Msg($"[ThunderClap] Embedded resources ({manifestResourceNames.Length}):");
string[] array = manifestResourceNames;
foreach (string text2 in array)
{
MelonLogger.Msg("[ThunderClap] -> " + text2);
}
using (Stream stream = executingAssembly.GetManifestResourceStream(text))
{
if (stream == null)
{
array = manifestResourceNames;
foreach (string text3 in array)
{
if (text3.EndsWith(".wav"))
{
text = text3;
MelonLogger.Msg("[ThunderClap] Using found WAV resource: " + text);
break;
}
}
using Stream stream2 = executingAssembly.GetManifestResourceStream(text);
if (stream2 == null)
{
MelonLogger.Error("[ThunderClap] No WAV resource found! Add the WAV to your project and set Build Action = Embedded Resource");
return;
}
byte[] array2 = new byte[stream2.Length];
stream2.Read(array2, 0, array2.Length);
_tinnitusClip = WavUtility.ToAudioClip(array2);
}
else
{
byte[] array3 = new byte[stream.Length];
stream.Read(array3, 0, array3.Length);
MelonLogger.Msg($"[ThunderClap] Loaded {array3.Length} bytes from {text}");
_tinnitusClip = WavUtility.ToAudioClip(array3);
}
}
if ((Object)(object)_tinnitusClip != (Object)null)
{
MelonLogger.Msg($"[ThunderClap] Tinnitus audio READY: {_tinnitusClip.length:F1}s");
}
else
{
MelonLogger.Error("[ThunderClap] WavUtility returned null clip");
}
}
catch (Exception arg)
{
MelonLogger.Error($"[ThunderClap] WAV load error: {arg}");
}
}
private static void OnClapOccurred(Vector3 clapPos)
{
//IL_00c1: 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)
if (!TinnitusEnabled)
{
return;
}
if ((Object)(object)_tinnitusClip == (Object)null)
{
MelonLogger.Warning("[ThunderClap] Tinnitus clip null — WAV not loaded");
return;
}
float now = Time.time;
_clapTimestamps.Add(now);
_clapTimestamps.RemoveAll((float t) => now - t > TinnitusWindow);
MelonLogger.Msg($"[ThunderClap] Clap #{_clapTimestamps.Count}/{TinnitusThreshold} (need {TinnitusThreshold} in {TinnitusWindow}s)");
if (_clapTimestamps.Count < TinnitusThreshold)
{
return;
}
_clapTimestamps.Clear();
PlayTinnitus(clapPos, localPlayer: true);
if (_fusionReady)
{
try
{
if (HasFusionServer())
{
SendTinnitusToNetwork(clapPos);
}
}
catch
{
}
}
MelonLogger.Msg($"[ThunderClap] TINNITUS triggered after {TinnitusThreshold} rapid claps!");
}
internal static void PlayTinnitus(Vector3 pos, bool localPlayer = false)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_tinnitusClip == (Object)null)
{
MelonLogger.Warning("[ThunderClap] Tinnitus clip is null!");
}
else
{
MelonCoroutines.Start(PlayTinnitusCoroutine(pos, localPlayer));
}
}
[IteratorStateMachine(typeof(<PlayTinnitusCoroutine>d__30))]
private static IEnumerator PlayTinnitusCoroutine(Vector3 pos, bool localPlayer)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PlayTinnitusCoroutine>d__30(0)
{
pos = pos,
localPlayer = localPlayer
};
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void SendTinnitusToNetwork(Vector3 pos)
{
//IL_0006: 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_001e: 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)
ThunderClapData obj = new ThunderClapData
{
X = pos.x,
Y = pos.y,
Z = pos.z,
Mult = 0f,
Radius = 0f
};
MessageRoute val = default(MessageRoute);
((MessageRoute)(ref val))..ctor((RelayType)3, (NetworkChannel)0);
MessageRelay.RelayModule<ThunderClapMessage, ThunderClapData>(obj, val);
}
public override void OnUpdate()
{
if (!Enabled)
{
return;
}
if (_cooldownTimer > 0f)
{
_cooldownTimer -= Time.deltaTime;
}
ShockwaveVisual.Tick();
try
{
DetectClap();
}
catch
{
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void DetectClap()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: 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_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: 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_0080: 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_008f: 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_00b3: 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)
Hand leftHand = Player.LeftHand;
Hand rightHand = Player.RightHand;
if ((Object)(object)leftHand == (Object)null || (Object)(object)rightHand == (Object)null)
{
return;
}
Vector3 position = ((Component)leftHand).transform.position;
Vector3 position2 = ((Component)rightHand).transform.position;
float num = Vector3.Distance(position, position2);
float num2 = (_lastDist - num) / Time.deltaTime;
_lastDist = num;
if (!(num < ClapThreshold) || !(num2 > MinClapSpeed) || !(_cooldownTimer <= 0f))
{
return;
}
Vector3 val = (position + position2) / 2f;
float num3 = Mathf.Clamp(num2 / MinClapSpeed, 1f, 5f);
DoExplosion(val, num3);
OnClapOccurred(val);
if (_fusionReady)
{
try
{
if (HasFusionServer())
{
SendToNetwork(val, num3);
}
}
catch
{
}
}
_cooldownTimer = Cooldown;
_lastDist = 999f;
MelonLogger.Msg($"[ThunderClap] BOOM! {num2:F1} m/s x{num3:F1}");
}
internal static void DoExplosion(Vector3 center, float mult)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: 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_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: 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_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Expected O, but got Unknown
float num = ExplosionForce * mult;
Collider[] array = Il2CppArrayBase<Collider>.op_Implicit((Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(center, ExplosionRadius, -1, (QueryTriggerInteraction)1));
if (array == null)
{
return;
}
HashSet<int> hashSet = new HashSet<int>();
Collider[] array2 = array;
foreach (Collider val in array2)
{
if ((Object)(object)val == (Object)null || val.isTrigger)
{
continue;
}
RigManager componentInParent = ((Component)val).GetComponentInParent<RigManager>();
if ((Object)(object)componentInParent != (Object)null)
{
try
{
if (FusionPlayer.IsLocalPlayer(componentInParent))
{
continue;
}
}
catch
{
}
}
Rigidbody componentInParent2 = ((Component)val).GetComponentInParent<Rigidbody>();
if ((Object)(object)componentInParent2 != (Object)null && !componentInParent2.isKinematic && hashSet.Add(((Object)componentInParent2).GetInstanceID()))
{
componentInParent2.AddExplosionForce(num, center, ExplosionRadius, UpwardsMod, (ForceMode)1);
}
if (!(NpcDamage > 0f))
{
continue;
}
PlayerDamageReceiver componentInParent3 = ((Component)val).GetComponentInParent<PlayerDamageReceiver>();
if ((Object)(object)componentInParent3 != (Object)null && hashSet.Add(((Object)componentInParent3).GetInstanceID() + 100000))
{
float num2 = 1f - Mathf.Clamp01(Vector3.Distance(center, ((Component)val).transform.position) / ExplosionRadius);
try
{
Attack val2 = new Attack
{
damage = NpcDamage * mult * num2
};
Vector3 val3 = ((Component)val).transform.position - center;
val2.normal = ((Vector3)(ref val3)).normalized;
val2.origin = center;
val2.backFacing = false;
val2.attackType = (AttackType)2;
componentInParent3.ReceiveAttack(val2);
}
catch
{
}
}
}
if (ShowShockwave)
{
ShockwaveVisual.Spawn(center, ExplosionRadius);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void SendToNetwork(Vector3 pos, float mult)
{
//IL_0006: 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_001e: 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)
ThunderClapData obj = new ThunderClapData
{
X = pos.x,
Y = pos.y,
Z = pos.z,
Mult = mult,
Radius = ExplosionRadius
};
MessageRoute val = default(MessageRoute);
((MessageRoute)(ref val))..ctor((RelayType)3, (NetworkChannel)0);
MessageRelay.RelayModule<ThunderClapMessage, ThunderClapData>(obj, val);
}
}
public class ThunderClapData : INetSerializable
{
public float X;
public float Y;
public float Z;
public float Mult;
public float Radius;
public int? GetSize()
{
return 20;
}
public void Serialize(INetSerializer s)
{
s.SerializeValue(ref X);
s.SerializeValue(ref Y);
s.SerializeValue(ref Z);
s.SerializeValue(ref Mult);
s.SerializeValue(ref Radius);
}
}
public class ThunderClapMessage : ModuleMessageHandler
{
protected override void OnHandleMessage(ReceivedMessage received)
{
//IL_0092: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: 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_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: 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)
ThunderClapData thunderClapData = ((ReceivedMessage)(ref received)).ReadData<ThunderClapData>();
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(thunderClapData.X, thunderClapData.Y, thunderClapData.Z);
if (thunderClapData.Mult == 0f && thunderClapData.Radius == 0f)
{
if (ThunderClapMod.TinnitusEnabled)
{
ThunderClapMod.PlayTinnitus(val);
}
MelonLogger.Msg($"[ThunderClap] Remote TINNITUS at ({val.x:F1}, {val.y:F1}, {val.z:F1})");
}
else
{
if (ThunderClapMod.ShowShockwave)
{
ShockwaveVisual.Spawn(val, thunderClapData.Radius);
}
MelonLogger.Msg($"[ThunderClap] Remote shockwave at ({val.x:F1}, {val.y:F1}, {val.z:F1})");
}
}
}
public static class ShockwaveVisual
{
private static GameObject _obj = null;
private static float _timer = 0f;
private static float _scale = 0f;
private static float _targetRadius = 8f;
public static void Spawn(Vector3 pos, float radius)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: 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_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Expected O, but got Unknown
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_obj != (Object)null)
{
Object.Destroy((Object)(object)_obj);
}
_obj = GameObject.CreatePrimitive((PrimitiveType)0);
((Object)_obj).name = "ThunderClap_Wave";
_obj.transform.position = pos;
_obj.transform.localScale = Vector3.one * 0.1f;
Collider component = _obj.GetComponent<Collider>();
if ((Object)(object)component != (Object)null)
{
Object.Destroy((Object)(object)component);
}
MeshRenderer component2 = _obj.GetComponent<MeshRenderer>();
if ((Object)(object)component2 != (Object)null)
{
Material val = new Material(Shader.Find("Sprites/Default"));
val.color = new Color(0.6f, 0.8f, 1f, 0.4f);
val.SetFloat("_Mode", 3f);
val.SetInt("_SrcBlend", 5);
val.SetInt("_DstBlend", 10);
val.SetInt("_ZWrite", 0);
val.EnableKeyword("_ALPHABLEND_ON");
val.renderQueue = 3000;
((Renderer)component2).material = val;
}
_scale = 0.1f;
_timer = 0.3f;
_targetRadius = radius;
}
public static void Tick()
{
//IL_0050: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
if (_timer <= 0f)
{
return;
}
_timer -= Time.deltaTime;
_scale += Time.deltaTime * _targetRadius * 3f;
if ((Object)(object)_obj != (Object)null)
{
_obj.transform.localScale = Vector3.one * _scale;
MeshRenderer component = _obj.GetComponent<MeshRenderer>();
if ((Object)(object)component != (Object)null)
{
float num = Mathf.Clamp01(_timer / 0.3f) * 0.4f;
((Renderer)component).material.color = new Color(0.6f, 0.8f, 1f, num);
}
}
if (_timer <= 0f && (Object)(object)_obj != (Object)null)
{
Object.Destroy((Object)(object)_obj);
_obj = null;
}
}
}
public static class WavUtility
{
public static AudioClip ToAudioClip(byte[] wav)
{
try
{
if (wav == null || wav.Length < 44)
{
MelonLogger.Error("[WavUtility] WAV too small or null");
return null;
}
if (wav[0] != 82 || wav[1] != 73 || wav[2] != 70 || wav[3] != 70)
{
MelonLogger.Error("[WavUtility] Not a valid WAV file (no RIFF header)");
return null;
}
int num = BitConverter.ToInt16(wav, 22);
int num2 = BitConverter.ToInt32(wav, 24);
int num3 = BitConverter.ToInt16(wav, 34);
MelonLogger.Msg($"[WavUtility] {num}ch, {num2}Hz, {num3}bit");
int num4 = -1;
int num5 = 0;
for (int i = 12; i < wav.Length - 8; i++)
{
if (wav[i] == 100 && wav[i + 1] == 97 && wav[i + 2] == 116 && wav[i + 3] == 97)
{
num5 = BitConverter.ToInt32(wav, i + 4);
num4 = i + 8;
break;
}
}
if (num4 < 0)
{
MelonLogger.Error("[WavUtility] No data chunk found");
return null;
}
if (num4 + num5 > wav.Length)
{
num5 = wav.Length - num4;
}
float[] array;
switch (num3)
{
case 16:
array = Convert16BitToFloat(wav, num4, num5);
break;
case 8:
array = Convert8BitToFloat(wav, num4, num5);
break;
case 32:
array = Convert32BitToFloat(wav, num4, num5);
break;
default:
MelonLogger.Error($"[WavUtility] Unsupported bit depth: {num3}");
return null;
}
int num6 = array.Length / num;
MelonLogger.Msg($"[WavUtility] {array.Length} samples, {num6} frames");
AudioClip val = AudioClip.Create("WavClip", num6, num, num2, false);
if ((Object)(object)val == (Object)null)
{
MelonLogger.Error("[WavUtility] AudioClip.Create returned null");
return null;
}
val.SetData(Il2CppStructArray<float>.op_Implicit(array), 0);
MelonLogger.Msg($"[WavUtility] AudioClip created: {val.length:F2}s");
return val;
}
catch (Exception arg)
{
MelonLogger.Error($"[WavUtility] {arg}");
return null;
}
}
private static float[] Convert16BitToFloat(byte[] wav, int offset, int dataSize)
{
int num = dataSize / 2;
float[] array = new float[num];
for (int i = 0; i < num; i++)
{
int num2 = offset + i * 2;
if (num2 + 1 >= wav.Length)
{
break;
}
short num3 = (short)(wav[num2] | (wav[num2 + 1] << 8));
array[i] = (float)num3 / 32768f;
}
return array;
}
private static float[] Convert8BitToFloat(byte[] wav, int offset, int dataSize)
{
float[] array = new float[dataSize];
for (int i = 0; i < dataSize && offset + i < wav.Length; i++)
{
array[i] = (float)(wav[offset + i] - 128) / 128f;
}
return array;
}
private static float[] Convert32BitToFloat(byte[] wav, int offset, int dataSize)
{
int num = dataSize / 4;
float[] array = new float[num];
for (int i = 0; i < num; i++)
{
int num2 = offset + i * 4;
if (num2 + 3 >= wav.Length)
{
break;
}
array[i] = BitConverter.ToSingle(wav, num2);
}
return array;
}
}
}