Compare commits

..

No commits in common. "mb-physics" and "main" have entirely different histories.

3 changed files with 6 additions and 337 deletions

View file

@ -1,8 +0,0 @@
namespace Sandbox
{
internal class Config
{
public static bool uncapVelocity = false;
public static bool diagonalMovement = false;
}
}

View file

@ -1,53 +1,16 @@
using MIU;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Sandbox
{
internal class ConsoleCommands
{
[ConsoleCommand(description = "Enable/disable velocity cap")]
public static string mbuncapvelocity(params string[] args)
[ConsoleCommand(description = "Simple hello world testing command")]
public static string hello(params string[] args)
{
if (args.Length != 1)
return "Expected 1 argument: 0, 1, or show";
switch (args[0])
{
case "show":
return Config.uncapVelocity ? "Velocity is currently uncapped" : "Velocity is currently capped";
case "0":
case "false":
Config.uncapVelocity = false;
return "Velocity has been capped";
case "1":
case "true":
Config.uncapVelocity = true;
return "Velocity has been uncapped";
default:
return "Unknown value. Expected 0, 1, or show";
}
}
[ConsoleCommand(description = "Enable/disable diagonal movement")]
public static string mbdiagonal(params string[] args)
{
if (args.Length != 1)
return "Expected 1 argument: 0, 1, or show";
switch (args[0])
{
case "show":
return Config.diagonalMovement ? "Diagonal movement is currently disabled" : "Diagonal movement is currently enabled";
case "0":
case "false":
Config.diagonalMovement = false;
return "Diagonal movement has been disabled";
case "1":
case "true":
Config.diagonalMovement = true;
return "Diagonal movement has been enabled";
default:
return "Unknown value. Expected 0, 1, or show";
}
return "Hello, World!";
}
}
}

View file

@ -1,286 +0,0 @@
/*
* Ever wanted to play with diagonal movement and no speedcap?
*/
using HarmonyLib;
using MIU;
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
namespace Sandbox.Patches
{
/*
* Turn on the rewind flag if you're using these, so you don't submit any scores
*/
[HarmonyPatch(typeof(MarbleManager), "FixedUpdate")]
internal class MarbleManagerFixedUpdatePatch
{
static bool Prefix()
{
if (Config.diagonalMovement || Config.uncapVelocity)
MarbleManager.usedRewind = true;
return true;
}
}
/*
* Reimplement MoveNormal except don't normalize the input.
* Wish I didn't have to do this to remove one function call...
*/
[HarmonyPatch(typeof(MarbleController), "MoveNormal")]
internal class MarbleControllerMoveNormalPatch
{
static bool Prefix(MarbleController __instance, float dT, GameMove move)
{
if (!Config.diagonalMovement)
return true; // Run original method
if (move == null)
{
move = new GameMove();
}
Assembly miuuAsm = typeof(MarbleController).Assembly;
Type marbleControllerType = miuuAsm.GetType("MarbleController");
FieldInfo marbleControllerRespawnCounterField = marbleControllerType.GetField("respawnCounter", BindingFlags.Instance | BindingFlags.NonPublic);
int respawnCounter = (int)marbleControllerRespawnCounterField.GetValue(__instance);
if (respawnCounter > 0)
{
respawnCounter--;
marbleControllerRespawnCounterField.SetValue(__instance, respawnCounter);
if (respawnCounter <= 0)
{
marbleControllerType.GetField("respawnCounter", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(__instance, true);
return false; // Skip original method
}
}
if (__instance.InMode(256))
{
if (__instance.GrinderEffects != null)
{
__instance.GrinderEffects.AdvanceCrush(__instance, dT);
}
return false; // Skip original method
}
if (__instance.GrinderEffects != null)
{
__instance.GrinderEffects.Reset();
}
FieldInfo marbleControllerContactsField = marbleControllerType.GetField("Contacts", BindingFlags.Instance | BindingFlags.NonPublic);
List<Contact> contacts = (List<Contact>)marbleControllerContactsField.GetValue(__instance);
if (__instance.InMode(8))
{
marbleControllerType.GetMethod("MoveStarting", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[] { dT });
__instance.SetVelocity(Vector3.zero);
contacts.Clear();
if (!NetworkManager.IsMultiplayer && __instance.IsServerObject())
{
Powerup[] array = ((GameProcess)marbleControllerType.GetField("LocalProcess", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance)).FindObjectsOfType<Powerup>();
for (int i = 0; i < array.Length; i++)
{
array[i].Restore();
}
}
}
bool flag = !MarbleManager.Rewinding && GamePlayManager.Get().PlayType != PlayType.Replay && !ConsoleGUI.IsActive;
if (__instance.InMode(32))
{
if (__instance.TrackingTarget != null)
{
Vector3 position = __instance.TrackingTarget.position;
if (position != Vector3.zero && contacts.Count > 0)
{
FieldInfo marbleControllerTrackingErrorSumField = marbleControllerType.GetField("TrackingErrorSum", BindingFlags.Instance | BindingFlags.NonPublic);
Vector3 trackingErrorSum = (Vector3)marbleControllerTrackingErrorSumField.GetValue(__instance);
Vector3 vector = position - __instance.transform.position;
Vector3 vector2 = vector * __instance.TrackingPID.x + trackingErrorSum * __instance.TrackingPID.y - __instance.GetVelocity() * __instance.TrackingPID.z;
move.d.x = vector2.x;
move.d.y = vector2.z;
trackingErrorSum += vector;
marbleControllerTrackingErrorSumField.SetValue(__instance, trackingErrorSum);
}
}
}
else if (flag && __instance.InMode(8))
{
move.trigger0 = false;
move.trigger1 = false;
move.trigger2 = false;
}
// PATCH STARTS HERE - don't normalize the input!
/*if (move.d.magnitude > 1f)
{
move.d.Normalize();
}*/
// PATCH ENDS HERE
Type marbleInputManagerType = miuuAsm.GetType("MarbleInputManager");
marbleInputManagerType.GetField("DebugMoveClamped", BindingFlags.Public | BindingFlags.Static).SetValue(null, move.d);
((HashSet<GameObject>)marbleControllerType.GetField("_ContactsThisTickList", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance)).Clear();
marbleControllerType.GetMethod("AdvancePhysics", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[] { move, dT });
if (NetworkManager.IsDedicated && !MarbleManager.Replaying)
{
__instance.transform.position = __instance.GetPosition();
__instance.transform.rotation = (Quaternion)marbleControllerType.GetField("qW", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance);
}
return false; // Skip original method
}
}
/*
* Reimplement this one without normalization as well
* aaaaaaaaaaaaaaa
*/
[HarmonyPatch(typeof(MarbleController), "ComputeMoveForces")]
internal class MarbleControllerComputeMoveForcesPatch
{
static bool Prefix(MarbleController __instance, ref bool __result, ref Vector3 aControl, ref Vector3 desiredOmega, GameMove move)
{
if (!Config.diagonalMovement)
return true; // Run original method
Assembly miuuAsm = typeof(MarbleController).Assembly;
Type marbleControllerType = miuuAsm.GetType("MarbleController");
aControl = Vector3.zero;
desiredOmega = Vector3.zero;
Vector3 vector = -__instance.GetGravityDir() * __instance.Radius;
Vector3 lhs = Vector3.Cross(__instance.GetAngularVelocity(), vector);
Vector3 sideDir = Vector3.zero;
Vector3 motionDir = Vector3.zero;
Vector3 upDir = Vector3.zero;
object[] inputParams = new object[] { sideDir, motionDir, upDir, move };
marbleControllerType.GetMethod("GetMarbleAxis", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, inputParams);
// Just in case?
sideDir = (Vector3)inputParams[0];
motionDir = (Vector3)inputParams[1];
upDir = (Vector3)inputParams[2];
float num = Vector3.Dot(lhs, motionDir);
float num2 = Vector3.Dot(lhs, sideDir);
// PATCH 1 STARTS HERE - don't do anything here. Note that this might reduce the input range on an analog stick
Vector2 vector2 = move.d;
/*Vector2 vector2 = move.d * 1f / 0.65f;
if (vector2.magnitude > 1f)
{
vector2.Normalize();
}*/
// PATCH 1 ENDS HERE
float maxRollVelocity = (float)marbleControllerType.GetField("MaxRollVelocity", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance);
float num3 = maxRollVelocity * vector2.y;
float num4 = maxRollVelocity * vector2.x;
float num5 = Math.Max(__instance.physMod.RollForceMult.x, __instance.physMod.RollForceMult.y);
if (vector2.magnitude > 0.01f)
{
TimeGraph.GraphLog("moveMag", vector2.magnitude);
if (num > num3 && num3 > 0.9f)
{
num3 = num;
}
else if (num < num3 && num3 < -0.9f)
{
num3 = num;
}
if (num2 > num4 && num4 > 0.9f)
{
num4 = num2;
}
else if (num2 < num4 && num4 < -0.9f)
{
num4 = num2;
}
Vector2 to = new Vector2(num2, num);
// PATCH 2 STARTS HERE - don't normalize
//Vector2 vector3 = new Vector2(num4, num3).normalized * Mathf.Max(maxRollVelocity * num5, to.magnitude);
Vector2 vector3 = new Vector2(num4, num3) * Mathf.Max(maxRollVelocity * num5, to.magnitude);
// PATCH 2 ENDS HERE
float num6 = Vector2.Angle(vector3, to);
float num7 = num6;
if (num7 >= 180f)
{
num7 = 179.99f;
}
if (num7 <= 0f)
{
num7 = 0f;
}
if (float.IsNaN(num7))
{
num7 = 0f;
}
float a = __instance.TurningCompensationFactor.Evaluate(0f);
float b = __instance.TurningCompensationFactor.Evaluate(num6);
float turningVelStartVelocity = (float)marbleControllerType.GetField("TurningVelStartVelocity", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance);
float num8 = Mathf.Lerp(a, b, (to.magnitude - turningVelStartVelocity * num5) / (maxRollVelocity - turningVelStartVelocity) * num5);
if (to.magnitude < turningVelStartVelocity * num5)
{
num8 = __instance.TurningCompensationFactor.Evaluate(0f);
}
// PATCH 3 STARTS HERE - don't normalize
//Vector2 vector4 = vector3.normalized * num8;
Vector2 vector4 = vector3 * num8;
// PATCH 3 ENDS HERE
vector4 = new Vector2(vector4.x * __instance.physMod.RollForceMult.y, vector4.y * __instance.physMod.RollForceMult.x);
vector3 = (vector3 + vector4) * vector2.magnitude;
num4 = vector3.x;
num3 = vector3.y;
desiredOmega = Vector3.Cross(vector, num3 * motionDir + num4 * sideDir) / Vector3.Dot(vector, vector);
aControl = desiredOmega - __instance.GetAngularVelocity();
float magnitude = aControl.magnitude;
float angularAcceleration = (float)marbleControllerType.GetField("AngularAcceleration", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance);
if (magnitude > angularAcceleration)
{
aControl *= angularAcceleration / magnitude;
}
__result = false;
return false; // Skip original method
}
__result = true;
return false; // Skip original method
}
}
/*
* Another one, awesome!!! A lot easier at least since we can do a Postfix and grab the correct value
*/
[HarmonyPatch(typeof(MarbleController), nameof(MarbleController.GetNextMove))]
internal class MarbleControllerGetNextMovePatch
{
static bool printed = false;
static void Postfix(MarbleController __instance, ref bool __result, ref GameMove move)
{
if (!Config.diagonalMovement)
return; // Don't do anything here
if (!__result)
return;
Assembly miuuAsm = typeof(MarbleController).Assembly;
//Type marbleControllerType = miuuAsm.GetType("MarbleController");
Type marbleInputManagerType = miuuAsm.GetType("MarbleInputManager");
move.d = (Vector2)marbleInputManagerType.GetField("DebugMoveScaled", BindingFlags.Public | BindingFlags.Static).GetValue(null);
marbleInputManagerType.GetField("DebugMoveEased", BindingFlags.Public | BindingFlags.Static).SetValue(null, move.d);
}
}
/*
* Remove speed cap. Very easy, just don't do it
*/
[HarmonyPatch(typeof(MarbleController), "EnforceVelocityCap")]
internal class MarbleControllerEnforceVelocityCapPatch
{
static bool Prefix()
{
if (!Config.uncapVelocity)
return true; // Run original method
return false; // Skip original method
}
}
}