using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Source-movement-ultrakill (bhop)")]
[assembly: AssemblyDescription("Source-movement-ultrakill (bhop) данунахуй")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Source-movement-ultrakill (bhop)")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("b8df1b2a-d2bd-4915-a3c1-e16f29388f80")]
[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")]
[BepInPlugin("com.lazurut.ultrakill.bhop", "Source-movement-ultrakill (bhop)", "0.0.1")]
public class BhopMod : BaseUnityPlugin
{
[HarmonyPatch(typeof(NewMovement), "Move")]
private static class Patch_Move
{
private static void Postfix(NewMovement __instance)
{
//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_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: 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_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_009e: 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_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_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: 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_00d5: 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_013e: 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_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_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_016b: Unknown result type (might be due to invalid IL or missing references)
if (!ModEnabled.Value)
{
return;
}
Rigidbody rb = __instance.rb;
GroundCheckGroup gc = __instance.gc;
Vector3 value = Traverse.Create((object)__instance).Field("inputDir").GetValue<Vector3>();
if (gc.onGround || ((Vector3)(ref value)).magnitude < 0.01f)
{
return;
}
Vector3 gravityDirection = PhysicsExtensions.GetGravityDirection(rb);
Vector3 val = Vector3.ProjectOnPlane(rb.velocity, gravityDirection);
float magnitude = ((Vector3)(ref val)).magnitude;
if (magnitude > MaxBhopSpeed.Value)
{
return;
}
Vector3 val2 = Vector3.ProjectOnPlane(value, gravityDirection);
Vector3 normalized = ((Vector3)(ref val2)).normalized;
float num = Mathf.Min(AirSpeedCap.Value, __instance.walkSpeed * Time.fixedDeltaTime * 2.75f);
float num2 = Vector3.Dot(val, normalized);
float num3 = num - num2;
if (!(num3 <= 0f))
{
float num4 = __instance.airAcceleration * AirAccelMultiplier.Value * num * Time.fixedDeltaTime * (1f / rb.mass);
num4 = Mathf.Min(num4, num3);
float num5 = Vector3.Dot(rb.velocity, gravityDirection);
Vector3 val3 = val + normalized * num4;
if (RemoveAirCap.Value)
{
rb.velocity = val3 + gravityDirection * num5;
}
else
{
rb.AddForce(normalized * num4, (ForceMode)2);
}
}
}
}
[HarmonyPatch(typeof(NewMovement), "FixedUpdate")]
private static class Patch_FixedUpdate
{
private static Vector3 s_velocityBeforeFixed;
private static void Prefix(NewMovement __instance)
{
//IL_0029: 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)
if (ModEnabled.Value && PreserveGroundSpeed.Value)
{
s_velocityBeforeFixed = __instance.rb.velocity;
}
}
private static void Postfix(NewMovement __instance)
{
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: 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_0065: 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_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: 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_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)
if (ModEnabled.Value && PreserveGroundSpeed.Value)
{
Rigidbody rb = __instance.rb;
GroundCheckGroup gc = __instance.gc;
bool value = Traverse.Create((object)__instance).Field("jumping").GetValue<bool>();
if (gc.onGround && value)
{
Vector3 gravityDirection = PhysicsExtensions.GetGravityDirection(rb);
Vector3 val = Vector3.ProjectOnPlane(s_velocityBeforeFixed, gravityDirection);
float num = Vector3.Dot(rb.velocity, gravityDirection);
rb.velocity = val + gravityDirection * num;
}
}
}
}
[HarmonyPatch(typeof(NewMovement), "FixedUpdate")]
private static class Patch_AutoBhop
{
private static void Prefix(NewMovement __instance)
{
if (!ModEnabled.Value || !AutoBhop.Value || !__instance.activated || GameStateManager.Instance.PlayerInputLocked)
{
return;
}
GroundCheckGroup gc = __instance.gc;
if (!gc.onGround)
{
return;
}
Traverse val = Traverse.Create((object)__instance);
if (!val.Field("jumpCooldown").GetValue<bool>())
{
InputManager instance = MonoSingleton<InputManager>.Instance;
if (!((Object)(object)instance == (Object)null) && instance.InputSource.Jump.Action.IsPressed())
{
__instance.Jump();
}
}
}
}
public static ConfigEntry<bool> ModEnabled;
public static ConfigEntry<float> AirAccelMultiplier;
public static ConfigEntry<float> MaxBhopSpeed;
public static ConfigEntry<float> AirSpeedCap;
public static ConfigEntry<bool> AutoBhop;
public static ConfigEntry<bool> PreserveGroundSpeed;
public static ConfigEntry<bool> RemoveAirCap;
public static BhopMod Instance;
private void Awake()
{
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Expected O, but got Unknown
Instance = this;
ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Включить/выключить bhop мод");
AirAccelMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "AirAccelMultiplier", 500f, "Множитель воздушного ускорения (1 = ванильное, 2-4 = bhop-friendly)");
MaxBhopSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "MaxBhopSpeed", 200f, "Максимальная горизонтальная скорость при bhopping (юниты/с). Source cs:go = ~320 ups, ULTRAKILL walkSpeed ~ 30-40 u/s * fixedDT");
AirSpeedCap = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "AirSpeedCap", 330f, "Кэп wishspeed — максимальная скорость которую можно добавить за один кадр в направлении инпута (аналог sv_airaccelerate wishspeed cap)");
AutoBhop = ((BaseUnityPlugin)this).Config.Bind<bool>("Movement", "AutoBhop", true, "Автоматический bhop — прыжок срабатывает при удержании кнопки");
PreserveGroundSpeed = ((BaseUnityPlugin)this).Config.Bind<bool>("Movement", "PreserveGroundSpeed", true, "Не применять наземное трение если прыгнули в этот физический кадр");
RemoveAirCap = ((BaseUnityPlugin)this).Config.Bind<bool>("Movement", "RemoveAirCap", true, "Убрать жёсткий кэп 16.5 u/s на воздушное ускорение (нужен для bhop)");
Harmony val = new Harmony("com.lazurut.ultrakill.bhop");
val.PatchAll();
SceneManager.sceneLoaded += OnSceneLoaded;
((BaseUnityPlugin)this).Logger.LogInfo((object)"[BhopMod] Загружен. F1 — переключить мод.");
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
((MonoBehaviour)this).StartCoroutine(TryInjectUI());
}
private IEnumerator TryInjectUI()
{
for (float elapsed = 0f; elapsed < 3f; elapsed += 0.1f)
{
GameObject pauseMenuObj = GameObject.Find("PauseMenu");
if ((Object)(object)pauseMenuObj != (Object)null)
{
yield break;
}
yield return (object)new WaitForSecondsRealtime(0.1f);
}
((BaseUnityPlugin)this).Logger.LogWarning((object)"[BhopMod] PauseMenu не найден на этой сцене — UI кнопка не создана.");
}
private void Update()
{
if (Input.GetKeyDown((KeyCode)282))
{
ModEnabled.Value = !ModEnabled.Value;
((BaseUnityPlugin)this).Logger.LogInfo((object)("[BhopMod] " + (ModEnabled.Value ? "Включён" : "Выключен")));
}
}
}