using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BoneLib; using BoneLib.BoneMenu; using BoneLib.Notifications; using FistShooterNS; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.Data; using Il2CppSLZ.Marrow.Pool; using Il2CppSLZ.Marrow.Warehouse; using LabFusion.Marrow.Pool; using LabFusion.Network; using LabFusion.RPC; using MelonLoader; using MelonLoader.Preferences; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(FistShooterMod), "Fireball", "1.0.0", "Y119", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: AssemblyTitle("Fireball")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Fireball")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("75ea7173-a6e0-4232-b83b-d0a7217605e7")] [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 FistShooterNS; public class FistShooterMod : MelonMod { private const string BARCODE_FIREBALL = "c1534c5a-355a-4734-8103-5ded46697265"; private const string BARCODE_VOIDBALL = "SLZ.BONELAB.Content.Spawnable.ProjectileVoidBall"; private static readonly string[] PROJECTILE_NAMES = new string[2] { "Fireball", "Void Ball" }; private static readonly string[] PROJECTILE_BARCODES = new string[2] { "c1534c5a-355a-4734-8103-5ded46697265", "SLZ.BONELAB.Content.Spawnable.ProjectileVoidBall" }; private static bool _enabled = false; private static float _shootSpeed = 20f; private static float _fireRate = 0.3f; private static int _handMode = 0; private static int _leftProjectile = 0; private static int _rightProjectile = 0; private static float _projectileSize = 1f; private static float _lastYTime = -999f; private static bool _yWasPressed = false; private const float DOUBLE_CLICK_WINDOW = 0.35f; private static float _leftCooldown = 0f; private static float _rightCooldown = 0f; private static FunctionElement _statusElement = null; private static FunctionElement _handElement = null; private static FunctionElement _leftProjElement = null; private static FunctionElement _rightProjElement = null; private static readonly string[] HAND_LABELS = new string[3] { "Left Hand", "Right Hand", "Both Hands" }; private static bool _fusionChecked = false; private static bool _fusionReady = false; private static MelonPreferences_Category _cat; private static MelonPreferences_Entry _prefSpeed; private static MelonPreferences_Entry _prefRate; private static Vector3 _flingDir = Vector3.forward; public override void OnInitializeMelon() { //IL_0075: 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_00bb: 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_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) _cat = MelonPreferences.CreateCategory("Fireball"); _prefSpeed = _cat.CreateEntry("ShootSpeed", 20f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); _prefRate = _cat.CreateEntry("FireRate", 0.3f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); _shootSpeed = _prefSpeed.Value; _fireRate = _prefRate.Value; Page obj = Page.Root.CreatePage("Fireball", Color.red, 0, true); _statusElement = obj.CreateFunction("Status: OFF", Color.red, (Action)delegate { }); _handElement = obj.CreateFunction("Hand: Left Hand", Color.cyan, (Action)delegate { _handMode = (_handMode + 1) % 3; ((Element)_handElement).ElementName = "Hand: " + HAND_LABELS[_handMode]; }); _leftProjElement = obj.CreateFunction("Left: " + PROJECTILE_NAMES[_leftProjectile], Color.yellow, (Action)delegate { _leftProjectile = (_leftProjectile + 1) % PROJECTILE_NAMES.Length; ((Element)_leftProjElement).ElementName = "Left: " + PROJECTILE_NAMES[_leftProjectile]; }); _rightProjElement = obj.CreateFunction("Right: " + PROJECTILE_NAMES[_rightProjectile], Color.magenta, (Action)delegate { _rightProjectile = (_rightProjectile + 1) % PROJECTILE_NAMES.Length; ((Element)_rightProjElement).ElementName = "Right: " + PROJECTILE_NAMES[_rightProjectile]; }); obj.CreateFloat("Shoot Speed", Color.yellow, _shootSpeed, 5f, 5f, 200f, (Action)delegate(float v) { _shootSpeed = v; _prefSpeed.Value = v; MelonPreferences.Save(); }); obj.CreateFloat("Fire Rate", Color.white, _fireRate, 0.05f, 0.05f, 2f, (Action)delegate(float v) { _fireRate = v; _prefRate.Value = v; MelonPreferences.Save(); }); obj.CreateFloat("Projectile Size", Color.white, _projectileSize, 0.5f, 0.5f, 10f, (Action)delegate(float v) { _projectileSize = v; }); MelonLogger.Msg("[Fireball] Loaded — double-tap Y to toggle"); } public override void OnLateInitializeMelon() { try { CacheFusion(); } catch { } } public override void OnUpdate() { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_00d3: 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) if (_leftCooldown > 0f) { _leftCooldown -= Time.deltaTime; } if (_rightCooldown > 0f) { _rightCooldown -= Time.deltaTime; } bool flag = false; try { Hand leftHand = Player.LeftHand; if ((Object)(object)leftHand != (Object)null && (Object)(object)leftHand.Controller != (Object)null) { flag = leftHand.Controller._bButtonDown; } } catch { } if (flag && !_yWasPressed) { float time = Time.time; if (time - _lastYTime < 0.35f) { _enabled = !_enabled; if (_statusElement != null) { ((Element)_statusElement).ElementName = (_enabled ? "Status: ON" : "Status: OFF"); ((Element)_statusElement).ElementColor = (_enabled ? Color.green : Color.red); } Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Fireball"), Message = NotificationText.op_Implicit(_enabled ? "ENABLED" : "DISABLED"), PopupLength = 1.5f, ShowTitleOnPopup = true }); MelonLogger.Msg("[Fireball] " + (_enabled ? "ON" : "OFF")); _lastYTime = -999f; } else { _lastYTime = time; } } _yWasPressed = flag; if (!_enabled) { return; } try { if (_handMode == 0 || _handMode == 2) { ProcessHand(Player.LeftHand, ref _leftCooldown, PROJECTILE_BARCODES[_leftProjectile]); } if (_handMode == 1 || _handMode == 2) { ProcessHand(Player.RightHand, ref _rightCooldown, PROJECTILE_BARCODES[_rightProjectile]); } } catch { } } private static void ProcessHand(Hand hand, ref float cooldown, string barcode) { //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_006a: 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_0075: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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) if ((Object)(object)hand == (Object)null || (Object)(object)hand.m_CurrentAttachedGO != (Object)null || cooldown > 0f) { return; } float num = 0f; try { if ((Object)(object)hand.Controller != (Object)null) { num = hand.Controller._primaryAxis; } } catch { return; } if (!(num < 0.7f)) { cooldown = _fireRate; Vector3 forward = ((Component)hand).transform.forward; Vector3 pos = ((Component)hand).transform.position + forward * 0.5f; Quaternion rot = Quaternion.LookRotation(forward); SpawnAndFling(pos, rot, forward, barcode); } } private static void SpawnAndFling(Vector3 pos, Quaternion rot, Vector3 dir, string barcode) { //IL_0041: 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_0043: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) bool flag = false; if (_fusionReady) { try { flag = HasServer(); } catch { } } if (flag && _fusionReady) { try { NetworkSpawn(pos, rot, dir, barcode); return; } catch (Exception ex) { MelonLogger.Warning("[Fireball] Net spawn fail: " + ex.Message); return; } } LocalSpawn(pos, rot, dir, barcode); } [MethodImpl(MethodImplOptions.NoInlining)] private static void LocalSpawn(Vector3 pos, Quaternion rot, Vector3 dir, string barcode) { //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) //IL_000d: 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) //IL_001e: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0024: 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) //IL_0037: Expected O, but got Unknown try { Spawnable val = new Spawnable { crateRef = new SpawnableCrateReference(barcode) }; LocalAssetSpawner.Register(val); LocalAssetSpawner.Spawn(val, pos, rot, (Action)delegate(Poolee poolee) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)poolee == (Object)null)) { FlingObject(((Component)poolee).gameObject, dir); } }); } catch (Exception ex) { MelonLogger.Warning("[Fireball] Local spawn: " + ex.Message); } } [MethodImpl(MethodImplOptions.NoInlining)] private static void NetworkSpawn(Vector3 pos, Quaternion rot, Vector3 dir, string barcode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_002a: 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_0032: 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_0066: Unknown result type (might be due to invalid IL or missing references) Spawnable val = new Spawnable(); val.crateRef = new SpawnableCrateReference(barcode); _flingDir = dir; SpawnRequestInfo val2 = default(SpawnRequestInfo); val2.Spawnable = val; val2.Position = pos; val2.Rotation = rot; val2.SpawnEffect = false; val2.SpawnCallback = delegate(SpawnCallbackInfo info) { //IL_0000: 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) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)info.Spawned != (Object)null) { FlingObject(info.Spawned, _flingDir); } }; NetworkAssetSpawner.Spawn(val2); } private static void FlingObject(GameObject go, Vector3 dir) { //IL_0012: 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_0045: 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_0056: Unknown result type (might be due to invalid IL or missing references) if (_projectileSize != 1f) { go.transform.localScale = Vector3.one * _projectileSize; } Rigidbody componentInChildren = go.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.isKinematic = false; componentInChildren.useGravity = false; componentInChildren.velocity = dir * _shootSpeed; componentInChildren.angularVelocity = Vector3.zero; } try { PhysicsRig physicsRig = Player.RigManager.physicsRig; if (!((Object)(object)physicsRig != (Object)null)) { return; } Il2CppArrayBase componentsInChildren = go.GetComponentsInChildren(); Il2CppArrayBase componentsInChildren2 = ((Component)physicsRig).GetComponentsInChildren(); foreach (Collider item in componentsInChildren) { foreach (Collider item2 in componentsInChildren2) { Physics.IgnoreCollision(item, item2, true); } } } catch { } } [MethodImpl(MethodImplOptions.NoInlining)] private static void CacheFusion() { if (!_fusionChecked) { _fusionChecked = true; if (typeof(NetworkAssetSpawner) != null) { _fusionReady = true; } MelonLogger.Msg(_fusionReady ? "[Fireball] Fusion ready — networked spawning enabled" : "[Fireball] Fusion not found — local only"); } } [MethodImpl(MethodImplOptions.NoInlining)] private static bool HasServer() { return NetworkInfo.HasServer; } }