Decompiled source of RandomJumps v1.0.0

Mods\RandomJumps.dll

Decompiled 20 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Il2CppFemur;
using Il2CppGB.Game;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using RandomJumps;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Mod), "Random Jumps", "1.0.1", "Red_guyteam", null)]
[assembly: MelonGame("Boneloaf", "Gang Beasts")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Red_guyteam")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Every jump gets a random height, from a tiny hop to a comically huge launch. Local play only.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("RandomJumps")]
[assembly: AssemblyTitle("RandomJumps")]
[assembly: AssemblyVersion("1.0.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 RandomJumps
{
	public static class Config
	{
		private static MelonPreferences_Category _cat;

		public static MelonPreferences_Entry<bool> Enabled;

		public static MelonPreferences_Entry<bool> LocalOnly;

		public static MelonPreferences_Entry<bool> DebugLog;

		public static MelonPreferences_Entry<float> MinMultiplier;

		public static MelonPreferences_Entry<float> MaxMultiplier;

		public static MelonPreferences_Entry<float> BoostSpeed;

		public static MelonPreferences_Entry<float> BoostSeconds;

		public static void Init()
		{
			_cat = MelonPreferences.CreateCategory("RandomJumps", "Random Jumps");
			Enabled = _cat.CreateEntry<bool>("Enabled", true, "Enabled", (string)null, false, false, (ValueValidator)null, (string)null);
			LocalOnly = _cat.CreateEntry<bool>("LocalOnly", true, "Only work in local play (disabled online)", (string)null, false, false, (ValueValidator)null, (string)null);
			DebugLog = _cat.CreateEntry<bool>("DebugLog", false, "Log every jump and its rolled multiplier", (string)null, false, false, (ValueValidator)null, (string)null);
			MinMultiplier = _cat.CreateEntry<float>("MinMultiplier", 0.15f, "Smallest jump multiplier (tiny hop)", (string)null, false, false, (ValueValidator)null, (string)null);
			MaxMultiplier = _cat.CreateEntry<float>("MaxMultiplier", 3f, "Biggest jump multiplier (comically huge)", (string)null, false, false, (ValueValidator)null, (string)null);
			BoostSpeed = _cat.CreateEntry<float>("BoostSpeed", 5f, "Base upward speed at multiplier 1.0", (string)null, false, false, (ValueValidator)null, (string)null);
			BoostSeconds = _cat.CreateEntry<float>("BoostSeconds", 0.2f, "How long each jump's launch is driven (seconds)", (string)null, false, false, (ValueValidator)null, (string)null);
			MelonPreferences.Save();
		}
	}
	public static class JumpRandomizer
	{
		private static readonly Random Rng = new Random();

		private static readonly Dictionary<IntPtr, ActorState> States = new Dictionary<IntPtr, ActorState>();

		private static readonly HashSet<IntPtr> Seen = new HashSet<IntPtr>();

		private static int _boostGeneration;

		private static bool _loggedError;

		public static void Update()
		{
			//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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Invalid comparison between Unknown and I4
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Invalid comparison between Unknown and I4
			try
			{
				if (!Config.Enabled.Value || (Config.LocalOnly.Value && !IsLocalGame()))
				{
					return;
				}
				List<Actor> cachedActors = Actor.CachedActors;
				if (cachedActors == null || cachedActors.Count == 0)
				{
					return;
				}
				Seen.Clear();
				for (int i = 0; i < cachedActors.Count; i++)
				{
					Actor val = cachedActors[i];
					if (!((Object)(object)val == (Object)null) && val.IsLocal)
					{
						IntPtr pointer = ((Il2CppObjectBase)val).Pointer;
						Seen.Add(pointer);
						ActorState actorState = val.actorState;
						ActorState value;
						bool num = States.TryGetValue(pointer, out value);
						States[pointer] = actorState;
						if (!num)
						{
							value = actorState;
						}
						if ((int)actorState == 16 && (int)value != 16)
						{
							OnJumpStarted(val);
						}
					}
				}
				PruneStates();
			}
			catch (Exception e)
			{
				LogOnce(e);
			}
		}

		private static void OnJumpStarted(Actor actor)
		{
			float multiplier = Roll();
			if (Config.DebugLog.Value)
			{
				Mod.Log.Msg("jump x" + multiplier.ToString("0.00") + " (" + ((Object)actor).name + ")");
			}
			Launch(actor, multiplier);
		}

		private static float Roll()
		{
			float num = Config.MinMultiplier.Value;
			float num2 = Config.MaxMultiplier.Value;
			if (num2 < num)
			{
				float num3 = num2;
				num2 = num;
				num = num3;
			}
			if (num2 <= num)
			{
				return num;
			}
			return num + (float)(Rng.NextDouble() * (double)(num2 - num));
		}

		private static void Launch(Actor actor, float multiplier)
		{
			try
			{
				BodyHandeler bodyHandeler = actor.bodyHandeler;
				if ((Object)(object)bodyHandeler == (Object)null)
				{
					return;
				}
				Il2CppReferenceArray<Rigidbody> allRigidbodies = bodyHandeler.GetAllRigidbodies();
				if (allRigidbodies == null || ((Il2CppArrayBase<Rigidbody>)(object)allRigidbodies).Count == 0)
				{
					return;
				}
				List<Rigidbody> list = new List<Rigidbody>(((Il2CppArrayBase<Rigidbody>)(object)allRigidbodies).Count);
				for (int i = 0; i < ((Il2CppArrayBase<Rigidbody>)(object)allRigidbodies).Count; i++)
				{
					Rigidbody val = ((Il2CppArrayBase<Rigidbody>)(object)allRigidbodies)[i];
					if ((Object)(object)val != (Object)null)
					{
						list.Add(val);
					}
				}
				if (list.Count != 0)
				{
					float up = Mathf.Max(0f, Config.BoostSpeed.Value) * Mathf.Max(0f, multiplier);
					MelonCoroutines.Start(LaunchCoroutine(list, up, ++_boostGeneration));
				}
			}
			catch (Exception e)
			{
				LogOnce(e);
			}
		}

		private static IEnumerator LaunchCoroutine(List<Rigidbody> rbs, float up, int gen)
		{
			float end = Time.time + Mathf.Max(0.05f, Config.BoostSeconds.Value);
			while (Time.time < end && gen == _boostGeneration)
			{
				try
				{
					for (int i = 0; i < rbs.Count; i++)
					{
						Rigidbody val = rbs[i];
						if (!((Object)(object)val == (Object)null))
						{
							Vector3 velocity = val.velocity;
							val.velocity = new Vector3(velocity.x, up, velocity.z);
						}
					}
				}
				catch
				{
					break;
				}
				yield return null;
			}
		}

		private static void PruneStates()
		{
			if (States.Count <= Seen.Count)
			{
				return;
			}
			List<IntPtr> list = new List<IntPtr>();
			foreach (IntPtr key in States.Keys)
			{
				if (!Seen.Contains(key))
				{
					list.Add(key);
				}
			}
			for (int i = 0; i < list.Count; i++)
			{
				States.Remove(list[i]);
			}
		}

		private static bool IsLocalGame()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameManagerNew instance = GameManagerNew.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return true;
				}
				long num = Convert.ToInt64(instance.CurrentGameType);
				return num == 0L || num == 1;
			}
			catch
			{
				return true;
			}
		}

		private static void LogOnce(Exception e)
		{
			if (!_loggedError)
			{
				_loggedError = true;
				Mod.Log.Error("Random Jumps error: " + e);
			}
		}
	}
	public class Mod : MelonMod
	{
		private bool _loggedError;

		public static Mod Instance { get; private set; }

		public static Instance Log => Melon<Mod>.Logger;

		public override void OnInitializeMelon()
		{
			Instance = this;
			try
			{
				Config.Init();
				Log.Msg("Random Jumps v1.0.1 initialized!");
				Log.Msg("Every local jump rolls a fresh height — from a tiny hop to a comically huge launch.");
				Log.Msg("Hook-free build: nothing is patched, so the jump crash is gone.");
				Log.Msg("Tune it in UserData/MelonPreferences.cfg  (MinMultiplier / MaxMultiplier / BoostSpeed).");
			}
			catch (Exception ex)
			{
				Log.Error("Random Jumps failed to initialize: " + ex);
			}
		}

		public override void OnUpdate()
		{
			if (Instance != this)
			{
				return;
			}
			try
			{
				JumpRandomizer.Update();
			}
			catch (Exception ex)
			{
				if (!_loggedError)
				{
					_loggedError = true;
					Log.Error("Random Jumps error in OnUpdate: " + ex);
				}
			}
		}
	}
}