Decompiled source of FireBallShooter v1.0.0

Mods/Fireball.dll

Decompiled 20 hours ago
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<float> _prefSpeed;

	private static MelonPreferences_Entry<float> _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<float>("ShootSpeed", 20f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		_prefRate = _cat.CreateEntry<float>("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<float>)delegate(float v)
		{
			_shootSpeed = v;
			_prefSpeed.Value = v;
			MelonPreferences.Save();
		});
		obj.CreateFloat("Fire Rate", Color.white, _fireRate, 0.05f, 0.05f, 2f, (Action<float>)delegate(float v)
		{
			_fireRate = v;
			_prefRate.Value = v;
			MelonPreferences.Save();
		});
		obj.CreateFloat("Projectile Size", Color.white, _projectileSize, 0.5f, 0.5f, 10f, (Action<float>)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<Poolee>)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<Rigidbody>();
		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<Collider> componentsInChildren = go.GetComponentsInChildren<Collider>();
			Il2CppArrayBase<Collider> componentsInChildren2 = ((Component)physicsRig).GetComponentsInChildren<Collider>();
			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;
	}
}