Decompiled source of MovementPlus v2.0.0
plugins/MovementPlus/MovementPlus.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using MovementPlus.NewAbility; using Reptile; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("MovementPlus")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("MovementPlus")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("aa66f97d-0b0a-40a8-a961-64081a320b66")] [assembly: AssemblyFileVersion("2.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 MovementPlus { public class MyConfig { public class ConfigRailGoon { public ConfigEntry<bool> Enabled = config.Bind<bool>(category, "Rail Goon Enabled", true, "Trigered by landing on a rail corner."); public ConfigEntry<float> Amount = config.Bind<float>(category, "Rail Goon Amount", 15f, "Amount of speed added when triggering a rail goon."); public ConfigEntry<float> Cap = config.Bind<float>(category, "Rail Goon Cap", -1f, "Maximum amount of speed that can be added when triggering a rail goon."); public ConfigRailGoon(ConfigFile config, string category) { } } public class ConfigRailFrameboost { public ConfigEntry<bool> Enabled = config.Bind<bool>(category, "Rail Frameboost Enabled", true, "Trigered by jumping shortly after landing on a rail."); public ConfigEntry<float> Amount = config.Bind<float>(category, "Rail Frameboost Amount", 5f, "Amount of speed added when triggering a rail frameboost."); public ConfigEntry<float> Grace = config.Bind<float>(category, "Rail Frameboost Grace", 0.1f, "Amount of time for a rail frameboost."); public ConfigEntry<float> Cap = config.Bind<float>(category, "Rail Frameboost Cap", -1f, "Maximum speed that can be obtained from rail frameboosts."); public ConfigRailFrameboost(ConfigFile config, string category) { } } public class ConfigWallFrameboost { public ConfigEntry<bool> Enabled = config.Bind<bool>(category, "Wall Frameboost Enabled", true, "Trigered by jumping after landing on a wallride."); public ConfigEntry<bool> RunoffEnabled = config.Bind<bool>(category, "Wall Frameboost Runoff Enabled", false, "Trigered by running off a wallride"); public ConfigEntry<float> Amount = config.Bind<float>(category, "Wall Frameboost Amount", 5f, "Amount of speed added when triggering a wallride frameboost."); public ConfigEntry<float> Grace = config.Bind<float>(category, "Wall Frameboost Grace", 0.1f, "Amount of time for a wallride frameboost."); public ConfigEntry<float> Cap = config.Bind<float>(category, "Wall Frameboost Cap", -1f, "Maximum speed that can be obtained from wallride frameboosts."); public ConfigWallFrameboost(ConfigFile config, string category) { } } public class ConfigWallGeneral { public ConfigEntry<float> wallTotalSpeedCap = config.Bind<float>(category, "Wall Total Speed Cap", -1f, "Maximum amount of speed that can be added when landing on a wallride."); public ConfigWallGeneral(ConfigFile config, string category) { } } public class ConfigSuperTrickJump { public ConfigEntry<bool> Enabled = config.Bind<bool>(category, "Super Trick Jump Enabled", true, "On foot trick jump height increases with forward speed."); public ConfigEntry<float> Amount = config.Bind<float>(category, "Super Trick Jump Amount", 0.2f, "Amount of height gained with forward speed."); public ConfigEntry<float> Cap = config.Bind<float>(category, "Super Trick Jump Cap", 30f, "Maximum height gained from a super trick jump."); public ConfigEntry<float> Threshold = config.Bind<float>(category, "Super Trick Jump Threshold", 21f, "Minimum Speed required to add any jump height."); public ConfigSuperTrickJump(ConfigFile config, string category) { } } public class ConfigPerfectManual { public ConfigEntry<bool> Enabled = config.Bind<bool>(category, "Perfect Manual Enabled", true, "Pressing manual just before landing."); public ConfigEntry<float> Amount = config.Bind<float>(category, "Perfect Manual Amount", 5f, "Amount of speed added when performing a perfect manual."); public ConfigEntry<float> Grace = config.Bind<float>(category, "Perfect Manual Grace", 0.1f, "Amount of time for a perfect manual."); public ConfigEntry<float> Cap = config.Bind<float>(category, "Perfect Manual Cap", 45f, "Maximum speed that can be obtained from perfect manuals."); public ConfigPerfectManual(ConfigFile config, string category) { } } public class ConfigSuperSlide { public ConfigEntry<bool> Enabled = config.Bind<bool>(category, "Super Slide Enabled", true, "Carpet sliding changes."); public ConfigEntry<float> Speed = config.Bind<float>(category, "Super Slide Base Speed", 35f, "Base speed of the super slide, this speed is reached very quickly."); public ConfigEntry<float> Amount = config.Bind<float>(category, "Super Slide Amount", 0.1f, "Amount of speed added while super sliding."); public ConfigEntry<float> Cap = config.Bind<float>(category, "Super Slide Cap", 55f, "Maximum speed that can be obtained from super sliding."); public ConfigSuperSlide(ConfigFile config, string category) { } } public class ConfigFastFall { public ConfigEntry<bool> Enabled = config.Bind<bool>(category, "Fast Fall Enabled", true, "Pressing manual while falling."); public ConfigEntry<float> Amount = config.Bind<float>(category, "Fast Fall Amount", -13f, "Amount of speed added when triggering a fast fall."); public ConfigFastFall(ConfigFile config, string category) { } } public class ConfigVertGeneral { public ConfigEntry<bool> Enabled = config.Bind<bool>(category, "Vert Change Enabled", true, "Vert ramp speed is adjusted to your total speed."); public ConfigEntry<bool> JumpEnabled = config.Bind<bool>(category, "Vert Jump Change Enabled", true, "Jump height from vert ramps scales with your speed."); public ConfigEntry<float> JumpStrength = config.Bind<float>(category, "Vert Jump Strength", 0.4f, "Multiplier applied to your total speed to calculate vert jump height."); public ConfigEntry<float> JumpCap = config.Bind<float>(category, "Vert Jump Cap", 75f, "Maximum jump height from vert ramps."); public ConfigEntry<float> ExitSpeed = config.Bind<float>(category, "Vert Bonus Bottom Exit Speed", 7f, "Bonus speed added when exiting a vert ramp."); public ConfigEntry<float> ExitSpeedCap = config.Bind<float>(category, "Vert Bonus Bottom Exit Speed Cap", 75f, "Maximum speed that can be obtained from exiting a vert ramp."); public ConfigVertGeneral(ConfigFile config, string category) { } } public class ConfigBoostGeneral { public ConfigEntry<bool> StartEnabled = config.Bind<bool>(category, "Boost Start Change Enabled", true, "Bonus speed when using a boost outside of a grind or wallride."); public ConfigEntry<float> StartAmount = config.Bind<float>(category, "Boost Start Amount", 2f, "Amount of speed added when starting a boost."); public ConfigEntry<float> StartCap = config.Bind<float>(category, "Boost Start Cap", 60f, "Maximum speed that can be obtained from starting a boost."); public ConfigEntry<float> RailAmount = config.Bind<float>(category, "Boost On Rail Speed Over Time", 4f, "Amount of speed added over time while boosting on a rail."); public ConfigEntry<float> WallAmount = config.Bind<float>(category, "Boost On Wallride Speed Over Time", 15f, "Amount of speed added over time while boosting on a wallride."); public ConfigEntry<float> RailCap = config.Bind<float>(category, "Boost Rail Cap", 55f, "Maximum amount of speed that can be obtained from boosting while on a rail."); public ConfigEntry<float> WallCap = config.Bind<float>(category, "Boost Wallride Cap", 70f, "Maximum amount of speed that can be obtained from boosting while on a wallride."); public ConfigEntry<bool> TotalSpeedEnabled = config.Bind<bool>(category, "Total Speed Change Enabled", true, "Boost speed scales with total speed."); public ConfigEntry<float> TotalSpeedCap = config.Bind<float>(category, "Total Speed Change Cap", -1f, "Maximum amount of speed obtainable from the total speed boost change."); public ConfigBoostGeneral(ConfigFile config, string category) { } } public class ConfigRailGeneral { public ConfigEntry<float> HardAmount = config.Bind<float>(category, "Rail Hard Corner Amount", 3f, "Amount of speed per hard corner."); public ConfigEntry<float> HardCap = config.Bind<float>(category, "Rail Hard Corner Cap", 45f, "Maximum amount of speed that can be obtained from rail hard corners."); public ConfigEntry<float> Decc = config.Bind<float>(category, "Rail Deceleration", 1f, "Deceleration while grinding."); public ConfigRailGeneral(ConfigFile config, string category) { } } public class ConfigRailSlope { public ConfigEntry<bool> Enabled = config.Bind<bool>(category, "Rail Slope Change Enabled", true, "Jumping while on an upwards sloped rail gives a larger jump and a downwards slope gives bonus speed."); public ConfigEntry<float> SlopeJumpAmount = config.Bind<float>(category, "Rail Slope Jump Height Amount", 4f, "Bonus height amount for sloped rail jump. This is affected by your speed and the slope of the rail."); public ConfigEntry<float> SlopeSpeedAmount = config.Bind<float>(category, "Rail Slope Jump Speed Amount", 6f, "Bonus speed amount for sloped rail jump. This is affected by your speed and the slope of the rail."); public ConfigEntry<float> SlopeJumpMax = config.Bind<float>(category, "Rail Slope Jump Height Max", 20f, "Maximum jump height you can gain from a sloped rail jump."); public ConfigEntry<float> SlopeSpeedCap = config.Bind<float>(category, "Rail Slope Jump Speed Cap", -1f, "Maximum Speed you can gain from a sloped rail jump."); public ConfigEntry<float> SlopeJumpMin = config.Bind<float>(category, "Rail Slope Jump Height Minimum", -7f, "Minimum jump height from a sloped rail jump."); public ConfigEntry<float> SlopeSpeedMin = config.Bind<float>(category, "Rail Slope Jump Speed Minimum", -10f, "Minimum speed from a sloped rail jump."); public ConfigEntry<float> SlopeSpeedMax = config.Bind<float>(category, "Rail Slope Jump Speed Max", 7f, "Maximum speed gained from a single sloped rail jump."); public ConfigRailSlope(ConfigFile config, string category) { } } public class ConfigComboGeneral { public ConfigEntry<bool> BoostEnabled = config.Bind<bool>(category, "Combo During Boost Enabled", true, "Allows you to maintain combo while boosting."); public ConfigEntry<bool> NoAbilityEnabled = config.Bind<bool>(category, "Combo No Ability Enabled", true, "Forces combo meter when touching the ground even without a manual."); public ConfigEntry<float> BoostTimeout = config.Bind<float>(category, "Combo Boost Timer", 0.5f, "How fast the combo timer ticks while boosting."); public ConfigEntry<float> BoostJumpAmount = config.Bind<float>(category, "Combo Boost Jump", 0.1f, "Amount of the combo timer is removed when jumping while boosting."); public ConfigEntry<float> NoAbilityTimeout = config.Bind<float>(category, "Combo No Ability Timer", 5f, "How fast the combo timer ticks down while not manualing."); public ConfigComboGeneral(ConfigFile config, string category) { } } public class ConfigLedgeClimbGeneral { public ConfigEntry<bool> Enabled = config.Bind<bool>(category, "Ledge Climb Cancel Enabled", true, "Allows you to cancel the ledge climb animation with a jump."); public ConfigEntry<float> Amount = config.Bind<float>(category, "Ledge Climb Cancel Amount", 15f, "Amount of speed added when you cancel a ledge climb."); public ConfigEntry<float> Cap = config.Bind<float>(category, "Ledge Climb Cancel Cap", -1f, "Maximum amount of speed that can be added when canceling a ledge climb."); public ConfigLedgeClimbGeneral(ConfigFile config, string category) { } } public class ConfigButtslap { public ConfigEntry<bool> Enabled = config.Bind<bool>(category, "Buttslap Enabled", true, "Allows a jump during a ground trick animation while in the air."); public ConfigEntry<bool> MultiEnabled = config.Bind<bool>(category, "Buttslap Multi Enabled", true, "Allows multiple jumps during a buttslap."); public ConfigEntry<float> Amount = config.Bind<float>(category, "Buttslap Amount", 2f, "Forward speed added when performing a buttslap."); public ConfigEntry<float> ComboAmount = config.Bind<float>(category, "Buttslap Combo Amount", -0.1f, "Amount of combo meter added when performing a buttslap."); public ConfigEntry<float> Cap = config.Bind<float>(category, "Buttslap Cap", -1f, "Maximum amount of speed that can be added when performing a buttslap."); public ConfigEntry<float> JumpAmount = config.Bind<float>(category, "Buttslap Jump Amount", 5f, "Jump height per buttslap."); public ConfigEntry<float> Timer = config.Bind<float>(category, "Buttslap Multi Time", 0.3f, "Amount of time after the initial buttslap to perform multiple."); public ConfigButtslap(ConfigFile config, string category) { } } public class ConfigMisc { public ConfigEntry<float> groundTrickDecc = config.Bind<float>(category, "Ground Trick Deceleration", 1f, "Deceleration while performing a ground trick."); public ConfigEntry<bool> collisionChangeEnabled = config.Bind<bool>(category, "Collision Change Enabled", true, "Changes the collision fixing almost all instances of clipping through objects."); public ConfigEntry<float> speedLimit = config.Bind<float>(category, "Speed Limit", -1f, "Soft speed limit, if moving faster than this speed your speed will be reduced over time."); public ConfigEntry<float> speedLimitAmount = config.Bind<float>(category, "Speed Limit Penalty Amount", 5f, "Amount of speed to remove over time while above the speed limit."); public ConfigEntry<float> maxFallSpeed = config.Bind<float>(category, "Max Fall Speed", 40f, "Maximum speed you're allowed to fall."); public ConfigEntry<float> airDashStrength = config.Bind<float>(category, "Air Dash Strength", 0.3f, "How much speed you lose when changing direction with the air dash."); public ConfigEntry<float> averageSpeedTimer = config.Bind<float>(category, "Average Speed Timer", 0.4f, "Many mechanics use your average speed over a period of time this is that period of time, a lower time will be more responsive but less forgiving and might feel less smooth."); public ConfigMisc(ConfigFile config, string category) { } } public ConfigRailGoon RailGoon = new ConfigRailGoon(config, "Rail Goon"); public ConfigRailFrameboost RailFrameboost = new ConfigRailFrameboost(config, "Rail Frameboost"); public ConfigWallFrameboost WallFrameboost = new ConfigWallFrameboost(config, "Wall Frameboost"); public ConfigWallGeneral WallGeneral = new ConfigWallGeneral(config, "Wall General"); public ConfigSuperTrickJump SuperTrickJump = new ConfigSuperTrickJump(config, "Super Trick Jump"); public ConfigPerfectManual PerfectManual = new ConfigPerfectManual(config, "Perfect Manual"); public ConfigSuperSlide SuperSlide = new ConfigSuperSlide(config, "Super Slide"); public ConfigFastFall FastFall = new ConfigFastFall(config, "Fast Fall"); public ConfigVertGeneral VertGeneral = new ConfigVertGeneral(config, "Vert General"); public ConfigBoostGeneral BoostGeneral = new ConfigBoostGeneral(config, "Boost General"); public ConfigRailGeneral RailGeneral = new ConfigRailGeneral(config, "Rail General"); public ConfigRailSlope RailSlope = new ConfigRailSlope(config, "Rail Slope"); public ConfigComboGeneral ComboGeneral = new ConfigComboGeneral(config, "Combo General"); public ConfigLedgeClimbGeneral LedgeClimbGeneral = new ConfigLedgeClimbGeneral(config, "Ledge Climb General"); public ConfigButtslap Buttslap = new ConfigButtslap(config, "Buttslap"); public ConfigMisc Misc = new ConfigMisc(config, "Misc"); public MyConfig(ConfigFile config) { } } [BepInPlugin("com.yuril.MovementPlus", "MovementPlus", "2.0.0")] public class MovementPlusPlugin : BaseUnityPlugin { private const string MyGUID = "com.yuril.MovementPlus"; private const string PluginName = "MovementPlus"; private const string VersionString = "2.0.0"; private Harmony harmony; public static Player player; public static MyConfig ConfigSettings; public static bool canFastFall; public static float defaultBoostSpeed; public static float defaultVertMaxSpeed; public static float defaultVertTopJumpSpeed; public static float defaultJumpSpeed; public static float savedLastSpeed; public static float noAbilitySpeed; public static float timeInAir; public static Queue<float> forwardSpeeds; public static Queue<float> totalSpeeds; public static Queue<Vector3> forwardDirs; public static float averageSpeedTimer; public static float averageForwardTimer; public static bool hasGooned; public static bool railGoonAppllied; public static bool jumpedFromRail; public static float jumpedFromRailTimer; private bool slideBoost; private float slideTimer; private bool slideTimerStarted; private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown harmony = new Harmony("com.yuril.MovementPlus"); PatchAllInNamespace(harmony, "MovementPlus.Patches"); ConfigSettings = new MyConfig(((BaseUnityPlugin)this).Config); forwardSpeeds = new Queue<float>(); totalSpeeds = new Queue<float>(); forwardDirs = new Queue<Vector3>(); averageSpeedTimer = 0f; ((BaseUnityPlugin)this).Logger.LogInfo((object)"MovementPlus has been loaded!"); } private void FixedUpdate() { if ((Object)(object)player != (Object)null) { FastFall(); VertChanges(); BoostChanges(); SaveSpeed(); TimeInAir(); LogSpeed(ConfigSettings.Misc.averageSpeedTimer.Value); LogForward(0.032f); JustJumpedFromRail(); SpeedLimit(); if (ConfigSettings.PerfectManual.Enabled.Value) { PerfectManual(); } } } public static void PatchAllInNamespace(Harmony harmony, string namespaceName) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); IEnumerable<Type> enumerable = from t in executingAssembly.GetTypes() where t.Namespace == namespaceName select t; foreach (Type item in enumerable) { harmony.PatchAll(item); } } private void PerfectManual() { if (!player.IsGrounded()) { slideBoost = false; } if (player.slideButtonNew) { slideTimer = 0f; slideTimerStarted = true; } if (slideTimerStarted) { slideTimer += Time.deltaTime; if (player.IsGrounded() && player.timeGrounded <= ConfigSettings.PerfectManual.Grace.Value && !slideBoost) { DoPerfectManual(); } if (slideTimer >= ConfigSettings.PerfectManual.Grace.Value) { slideTimerStarted = false; } } } private void DoPerfectManual() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) player.SetForwardSpeed(LosslessClamp(AverageForwardSpeed(), ConfigSettings.PerfectManual.Amount.Value, ConfigSettings.PerfectManual.Cap.Value)); slideBoost = true; player.CreateHighJumpDustEffect(player.tf.up); player.DoTrick((TrickType)4, "Perfect Manual", 1); } private void FastFall() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (player.slideButtonNew && !player.TreatPlayerAsSortaGrounded() && player.motor.velocity.y <= 0f && canFastFall && ConfigSettings.FastFall.Enabled.Value) { player.motor.SetVelocityYOneTime(Mathf.Min(player.motor.velocity.y + ConfigSettings.FastFall.Amount.Value, ConfigSettings.FastFall.Amount.Value)); player.ringParticles.Emit(1); player.AudioManager.PlaySfxGameplay((SfxCollectionID)20, (AudioClipID)19, player.playerOneShotAudioSource, 0f); canFastFall = false; } if (player.TreatPlayerAsSortaGrounded()) { canFastFall = true; } } private void BoostChanges() { if (hasGooned) { ApplyRailGoon(); } else if (player.ability != player.wallrunAbility && player.ability != player.grindAbility && player.ability != player.boostAbility) { player.normalBoostSpeed = Mathf.Max(defaultBoostSpeed, AverageForwardSpeed()); } } private void ApplyRailGoon() { if (!railGoonAppllied && ConfigSettings.RailGoon.Enabled.Value) { player.grindAbility.speed = LosslessClamp(Mathf.Max(AverageForwardSpeed(), defaultBoostSpeed), ConfigSettings.RailGoon.Amount.Value, ConfigSettings.RailGoon.Cap.Value); railGoonAppllied = true; } } private void HandleGrindAbility() { player.normalBoostSpeed = LosslessClamp(player.normalBoostSpeed, ConfigSettings.BoostGeneral.RailAmount.Value * Core.dt, ConfigSettings.BoostGeneral.RailCap.Value); } private void VertChanges() { if (player.ability != player.vertAbility) { HandleVertAbility(); } } private void HandleVertAbility() { if (ConfigSettings.VertGeneral.Enabled.Value) { UpdateVertBottomExitSpeed(); } if (ConfigSettings.VertGeneral.JumpEnabled.Value) { UpdateVertTopJumpSpeed(); } } private void UpdateVertBottomExitSpeed() { float num = Mathf.Max(player.GetTotalSpeed(), AverageTotalSpeed()); float num2 = num + ConfigSettings.VertGeneral.ExitSpeed.Value; num2 = Mathf.Min(num2, ConfigSettings.VertGeneral.ExitSpeedCap.Value); player.vertMaxSpeed = Mathf.Max(defaultVertMaxSpeed, player.GetTotalSpeed()); player.vertBottomExitSpeed = num2; } private void UpdateVertTopJumpSpeed() { float num = Mathf.Max(player.GetTotalSpeed(), AverageTotalSpeed()); float num2 = Mathf.Max(defaultVertTopJumpSpeed, num * ConfigSettings.VertGeneral.JumpStrength.Value); num2 = Mathf.Min(ConfigSettings.VertGeneral.JumpCap.Value, num2); player.vertTopJumpSpeed = num2; } private void JustJumpedFromRail() { if (jumpedFromRail) { player.SetForwardSpeed(Mathf.Max(AverageForwardSpeed(), player.GetForwardSpeed())); jumpedFromRailTimer -= Core.dt; } if (jumpedFromRailTimer <= 0f) { jumpedFromRail = false; } } private void SpeedLimit() { if (player.GetForwardSpeed() >= ConfigSettings.Misc.speedLimit.Value && player.ability != player.grindAbility && player.ability != player.wallrunAbility && ConfigSettings.Misc.speedLimit.Value > 0f) { float forwardSpeed = player.GetForwardSpeed() - ConfigSettings.Misc.speedLimitAmount.Value * Core.dt; player.SetForwardSpeed(forwardSpeed); } } private void LogSpeed(float time) { forwardSpeeds.Enqueue(player.GetForwardSpeed()); totalSpeeds.Enqueue(player.GetTotalSpeed()); if (averageSpeedTimer >= time) { forwardSpeeds.Dequeue(); totalSpeeds.Dequeue(); } else { averageSpeedTimer += Core.dt; } } public static float AverageForwardSpeed() { float num = 0f; foreach (float forwardSpeed in forwardSpeeds) { num += forwardSpeed; } return num / (float)forwardSpeeds.Count; } public static float AverageTotalSpeed() { float num = 0f; foreach (float totalSpeed in totalSpeeds) { num += totalSpeed; } return num / (float)totalSpeeds.Count; } private void LogForward(float time) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) forwardDirs.Enqueue(player.tf.forward); if (averageForwardTimer >= time) { forwardDirs.Dequeue(); } else { averageForwardTimer += Core.dt; } } public static Vector3 AverageForwardDir() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_001b: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0048: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.zero; foreach (Vector3 forwardDir in forwardDirs) { val += forwardDir; } return val / (float)forwardDirs.Count; } private void SaveSpeed() { noAbilitySpeed = ((player.ability == player.grindAbility || player.ability == player.handplantAbility) ? Mathf.Max(noAbilitySpeed, player.grindAbility.speed) : player.GetForwardSpeed()); } private void TimeInAir() { timeInAir = (player.TreatPlayerAsSortaGrounded() ? 0f : (timeInAir + Core.dt)); } public static float Remap(float val, float in1, float in2, float out1, float out2) { return out1 + (val - in1) * (out2 - out1) / (in2 - in1); } public static float TableCurve(float a, float b, float c, float x) { return (a + b) * x / (b + x) + c; } public static float LosslessClamp(float input, float toAdd, float cap) { float num = input; float num2 = num + toAdd; if (cap < 0f) { return num2; } num = Mathf.Min(num2, cap); return Mathf.Max(num, input); } } } namespace MovementPlus.Patches { internal static class BoostAbilityPatch { private static readonly MyConfig ConfigSettings = MovementPlusPlugin.ConfigSettings; private static float defaultBoostSpeed; [HarmonyPatch(typeof(BoostAbility), "Init")] [HarmonyPostfix] private static void BoostAbility_Init_Postfix(BoostAbility __instance) { if (!((Ability)__instance).p.isAI) { ((Ability)__instance).decc = 0f; defaultBoostSpeed = ((Ability)__instance).p.normalBoostSpeed; } } [HarmonyPatch(typeof(BoostAbility), "FixedUpdateAbility")] [HarmonyPostfix] private static void BoostAbility_FixedUpdateAbility_Postfix(BoostAbility __instance) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) if (((Ability)__instance).p.IsGrounded() && ((Ability)__instance).p.IsComboing() && ConfigSettings.ComboGeneral.BoostEnabled.Value) { ((Ability)__instance).p.DoComboTimeOut(Core.dt / 2f * ConfigSettings.ComboGeneral.BoostTimeout.Value); } if (ConfigSettings.BoostGeneral.StartEnabled.Value && (int)__instance.state == 0) { float num = ((((Ability)__instance).p.ability == ((Ability)__instance).p.grindAbility) ? MovementPlusPlugin.AverageForwardSpeed() : MovementPlusPlugin.AverageTotalSpeed()); float input = Mathf.Max(defaultBoostSpeed, num); float normalBoostSpeed = MovementPlusPlugin.LosslessClamp(input, ConfigSettings.BoostGeneral.StartAmount.Value, ConfigSettings.BoostGeneral.StartCap.Value); ((Ability)__instance).p.normalBoostSpeed = normalBoostSpeed; } else if (ConfigSettings.BoostGeneral.TotalSpeedEnabled.Value) { float normalBoostSpeed2 = MovementPlusPlugin.LosslessClamp(MovementPlusPlugin.AverageForwardSpeed(), MovementPlusPlugin.AverageTotalSpeed() - MovementPlusPlugin.AverageForwardSpeed(), ConfigSettings.BoostGeneral.TotalSpeedCap.Value); ((Ability)__instance).p.normalBoostSpeed = normalBoostSpeed2; } } [HarmonyPatch(typeof(BoostAbility), "OnJump")] [HarmonyPrefix] private static void BoostAbility_OnJump_PreFix(BoostAbility __instance) { if (((Ability)__instance).p.IsComboing()) { ((Ability)__instance).p.DoComboTimeOut(ConfigSettings.ComboGeneral.BoostJumpAmount.Value); } } } internal static class GrindAbilityPatch { private static readonly MyConfig ConfigSettings = MovementPlusPlugin.ConfigSettings; [HarmonyPatch(typeof(GrindAbility), "Init")] [HarmonyPrefix] private static void GrindAbility_Init_Prefix(GrindAbility __instance) { __instance.grindDeccAboveNormal = ConfigSettings.RailGeneral.Decc.Value; } [HarmonyPatch(typeof(GrindAbility), "OnStartAbility")] [HarmonyPrefix] private static void GrindAbility_OnStartAbility_Prefix(GrindAbility __instance) { __instance.trickTimer = 0f; } [HarmonyPatch(typeof(GrindAbility), "UpdateSpeed")] [HarmonyPrefix] private static bool GrindAbility_UpdateSpeed_Prefix(GrindAbility __instance) { if (((Ability)__instance).p.abilityTimer <= 0.025f && !((Ability)__instance).p.isJumping) { float num = MovementPlusPlugin.AverageForwardSpeed(); num = Mathf.Max(num, __instance.speedTarget); ((Ability)__instance).p.normalBoostSpeed = num; __instance.speed = Mathf.Max(num, __instance.speedTarget); } if (__instance.speed < __instance.speedTarget) { __instance.speed = Mathf.Min(__instance.speedTarget, __instance.speed + __instance.grindAcc * Core.dt); } else if (__instance.speed > __instance.speedTarget) { __instance.speed = Mathf.Max(__instance.speedTarget, __instance.speed - ((__instance.speed >= ((Ability)__instance).p.stats.grindSpeed) ? __instance.grindDeccAboveNormal : __instance.grindDeccBelowNormal) * Core.dt); } if (((Ability)__instance).p.boosting) { float input = Mathf.Max(MovementPlusPlugin.AverageForwardSpeed(), __instance.speed); __instance.speed = MovementPlusPlugin.LosslessClamp(input, ConfigSettings.BoostGeneral.RailAmount.Value * Core.dt, ConfigSettings.BoostGeneral.RailCap.Value); } if (__instance.softCornerBoost) { __instance.speedTarget = Mathf.Max(MovementPlusPlugin.AverageForwardSpeed(), ((Ability)__instance).p.GetForwardSpeed()); if (__instance.timeSinceLastNode > 1f) { __instance.softCornerBoost = false; } } else { if (((Ability)__instance).p.AirBraking() && !((Ability)__instance).p.isAI) { __instance.braking = true; __instance.speedTarget = ((Ability)__instance).p.stats.grindSpeed * 0.35f; } __instance.braking = false; __instance.speedTarget = ((Ability)__instance).p.stats.grindSpeed; } return false; } [HarmonyPatch(typeof(GrindAbility), "FixedUpdateAbility")] [HarmonyPrefix] private static bool GrindAbility_FixedUpdateAbility_Prefix(GrindAbility __instance) { //IL_0011: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_0583: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_0556: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) //IL_055d: Unknown result type (might be due to invalid IL or missing references) //IL_0675: Unknown result type (might be due to invalid IL or missing references) //IL_067a: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0730: Unknown result type (might be due to invalid IL or missing references) //IL_0732: Unknown result type (might be due to invalid IL or missing references) //IL_0737: Unknown result type (might be due to invalid IL or missing references) //IL_073b: Unknown result type (might be due to invalid IL or missing references) //IL_0741: Unknown result type (might be due to invalid IL or missing references) //IL_0746: Unknown result type (might be due to invalid IL or missing references) //IL_0711: Unknown result type (might be due to invalid IL or missing references) //IL_0713: Unknown result type (might be due to invalid IL or missing references) //IL_0718: Unknown result type (might be due to invalid IL or missing references) //IL_071b: Unknown result type (might be due to invalid IL or missing references) //IL_071d: Unknown result type (might be due to invalid IL or missing references) //IL_0692: Unknown result type (might be due to invalid IL or missing references) //IL_0694: Unknown result type (might be due to invalid IL or missing references) //IL_0699: Unknown result type (might be due to invalid IL or missing references) //IL_069d: Unknown result type (might be due to invalid IL or missing references) //IL_06a2: Unknown result type (might be due to invalid IL or missing references) //IL_06a4: Unknown result type (might be due to invalid IL or missing references) //IL_06a7: Unknown result type (might be due to invalid IL or missing references) //IL_06b1: Unknown result type (might be due to invalid IL or missing references) //IL_06b6: Unknown result type (might be due to invalid IL or missing references) //IL_05c4: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Invalid comparison between Unknown and I4 //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_06c7: Unknown result type (might be due to invalid IL or missing references) //IL_06c9: Unknown result type (might be due to invalid IL or missing references) //IL_06d0: Unknown result type (might be due to invalid IL or missing references) //IL_06d5: Unknown result type (might be due to invalid IL or missing references) //IL_06c1: Unknown result type (might be due to invalid IL or missing references) //IL_06c3: Unknown result type (might be due to invalid IL or missing references) //IL_05e2: Unknown result type (might be due to invalid IL or missing references) //IL_05e7: Unknown result type (might be due to invalid IL or missing references) //IL_05eb: Unknown result type (might be due to invalid IL or missing references) //IL_05f0: Unknown result type (might be due to invalid IL or missing references) //IL_05f8: Unknown result type (might be due to invalid IL or missing references) //IL_05fa: Unknown result type (might be due to invalid IL or missing references) //IL_05ff: Unknown result type (might be due to invalid IL or missing references) //IL_0603: Unknown result type (might be due to invalid IL or missing references) //IL_0608: Unknown result type (might be due to invalid IL or missing references) //IL_060a: Unknown result type (might be due to invalid IL or missing references) //IL_060c: Unknown result type (might be due to invalid IL or missing references) //IL_0613: Unknown result type (might be due to invalid IL or missing references) //IL_0618: Unknown result type (might be due to invalid IL or missing references) //IL_0491: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_077a: Unknown result type (might be due to invalid IL or missing references) //IL_0787: Unknown result type (might be due to invalid IL or missing references) //IL_078c: Unknown result type (might be due to invalid IL or missing references) //IL_0796: Unknown result type (might be due to invalid IL or missing references) //IL_079b: Unknown result type (might be due to invalid IL or missing references) //IL_07a6: Unknown result type (might be due to invalid IL or missing references) //IL_075d: Unknown result type (might be due to invalid IL or missing references) //IL_0760: Unknown result type (might be due to invalid IL or missing references) //IL_0765: Unknown result type (might be due to invalid IL or missing references) //IL_076a: Unknown result type (might be due to invalid IL or missing references) //IL_0772: Unknown result type (might be due to invalid IL or missing references) //IL_0626: Unknown result type (might be due to invalid IL or missing references) //IL_0628: Unknown result type (might be due to invalid IL or missing references) //IL_0638: Unknown result type (might be due to invalid IL or missing references) //IL_063d: Unknown result type (might be due to invalid IL or missing references) //IL_0620: Unknown result type (might be due to invalid IL or missing references) //IL_0622: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_07d7: Unknown result type (might be due to invalid IL or missing references) //IL_07dc: Unknown result type (might be due to invalid IL or missing references) //IL_06ec: Unknown result type (might be due to invalid IL or missing references) //IL_06f2: Unknown result type (might be due to invalid IL or missing references) //IL_0640: Unknown result type (might be due to invalid IL or missing references) //IL_0642: Unknown result type (might be due to invalid IL or missing references) //IL_04d0: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04c1: Unknown result type (might be due to invalid IL or missing references) //IL_065f: Unknown result type (might be due to invalid IL or missing references) //IL_0665: Unknown result type (might be due to invalid IL or missing references) //IL_0501: Unknown result type (might be due to invalid IL or missing references) //IL_04f0: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_0517: Unknown result type (might be due to invalid IL or missing references) //IL_0519: Unknown result type (might be due to invalid IL or missing references) //IL_051e: Unknown result type (might be due to invalid IL or missing references) //IL_0529: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) float absoluteLinePos = __instance.grindLine.GetAbsoluteLinePos(((Ability)__instance).p.tf.position, ((Ability)__instance).p.dir); if (((Ability)__instance).p.abilityTimer >= 0.1f) { MovementPlusPlugin.hasGooned = false; } if (absoluteLinePos <= 1.5f && ((Ability)__instance).p.boosting && ((Ability)__instance).p.abilityTimer <= 0.1f && !MovementPlusPlugin.hasGooned) { MovementPlusPlugin.hasGooned = true; } if (__instance.inRetour) { if (((Ability)__instance).p.GetAnimTime() < 1f) { return false; } __instance.EndRetour(); } int curAnim = ((Ability)__instance).p.curAnim; bool flag = false; int num = 3; for (int i = 0; i < num; i++) { flag |= curAnim == __instance.grindTrickHoldHashes[i] || curAnim == __instance.grindBoostTrickHoldHashes[i]; } __instance.timeSinceLastNode += Core.dt; ((Ability)__instance).p.SetDustEmission(0); __instance.UpdateSpeed(); __instance.UpdateTricks(); Vector3 position = ((Ability)__instance).p.tf.position; Vector3 val = ((Ability)__instance).p.tf.forward; Vector3 right = ((Ability)__instance).p.tf.right; if (!__instance.justFollowNodes) { __instance.nextNode = __instance.grindLine.GetNextNode(val); } position = __instance.grindLine.SnapPosToLine(position); Vector3 val2 = position; Vector3 val3 = __instance.nextNode - position; position = val2 + ((Vector3)(ref val3)).normalized * __instance.speed * Core.dt; __instance.posOnLine = (__instance.justFollowNodes ? __instance.grindLine.GetRelativePosOnLine(position, __instance.nextNode) : __instance.grindLine.GetRelativePosOnLine(position, val)); float num2 = (__instance.justFollowNodes ? __instance.grindLine.GetAbsoluteLinePos(position, __instance.nextNode) : __instance.grindLine.GetAbsoluteLinePos(position, val)); if (__instance.posOnLine >= 1f) { __instance.timeSinceLastNode = 0f; float num3 = __instance.posOnLine * __instance.grindLine.Length() - __instance.grindLine.Length(); if (__instance.nextNode.IsEndpoint) { if (__instance.nextNode.retour) { __instance.StartRetour(); return false; } if (__instance.grindLine.isPole) { if (Mathf.Abs(Vector3.Dot(val, Vector3.up)) > 0f) { ((Ability)__instance).p.handplantAbility.SetToPole(__instance.nextNode.position); return false; } __instance.JumpOut(true); return false; } if (Mathf.Abs(Vector3.Dot(((Ability)__instance).p.tf.up, Vector3.up)) < 0.35f || __instance.grindLine.alwaysFlipBack) { __instance.JumpOut(true); return false; } ((Ability)__instance).p.motor.SetPositionTeleport(position + Vector3.up * ((Ability)__instance).p.motor.GetCapsule().height * Mathf.Clamp(((Ability)__instance).p.tf.up.y, -1f, 0f)); __instance.normal = Vector3.up; Vector3 val4 = ((Ability)__instance).p.FlattenRotationHard(); ((Ability)__instance).p.SetVelocity(val4 * __instance.speed); if (((Ability)__instance).p.boosting) { ((Ability)__instance).p.ActivateAbility((Ability)(object)((Ability)__instance).p.boostAbility); ((Ability)__instance).p.boostAbility.StartFromRunOffGrindOrWallrun(); return false; } ((Ability)__instance).p.StopCurrentAbility(); ((Ability)__instance).p.FlattenRotationHard(); return false; } GrindLine val5 = (__instance.justFollowNodes ? __instance.grindLine.GetNextLine(val, __instance.nextNode) : __instance.grindLine.GetNextLine(val, (GrindNode)null)); val3 = val5.GetOtherNode(__instance.nextNode) - __instance.nextNode; Vector3 normalized = ((Vector3)(ref val3)).normalized; __instance.RewardTilting(right, normalized); val = normalized; position = __instance.nextNode.position + num3 * normalized; if (__instance.grindLine.sfxCollection != val5.sfxCollection && (int)val5.sfxCollection != -1) { ((Ability)__instance).p.AudioManager.PlaySfxGameplayLooping(val5.sfxCollection, (AudioClipID)11, ((Ability)__instance).p.playerGrindLoopAudioSource, 0f, 0f); } __instance.grindLine = val5; __instance.nextNode = (__instance.justFollowNodes ? __instance.grindLine.GetOtherNode(__instance.nextNode) : __instance.grindLine.GetNextNode(normalized)); __instance.posOnLine = (__instance.justFollowNodes ? __instance.grindLine.GetRelativePosOnLine(position, __instance.nextNode) : __instance.grindLine.GetRelativePosOnLine(position, normalized)); num2 = (__instance.justFollowNodes ? __instance.grindLine.GetAbsoluteLinePos(position, __instance.nextNode) : __instance.grindLine.GetAbsoluteLinePos(position, val)); __instance.normal = __instance.grindLine.GetNormalAtPos(position); ((Ability)__instance).p.SetRotation(normalized, __instance.normal); } __instance.UpdateBoostpack(); __instance.UpdateTilting(); if (!__instance.grindLine.isPole) { __instance.normal = __instance.grindLine.GetNormalAtPos(position); } float num4 = __instance.grindLine.Length(); float num5 = Mathf.Min(num4 * 0.5f, 1.5f); Vector3 val6 = Vector3.forward; if (!__instance.nextNode.IsEndpoint && num2 >= num4 - num5) { val3 = (__instance.justFollowNodes ? __instance.grindLine.GetNextLine(val, __instance.nextNode) : __instance.grindLine.GetNextLine(val, (GrindNode)null)).GetOtherNode(__instance.nextNode) - __instance.nextNode; Vector3 normalized2 = ((Vector3)(ref val3)).normalized; val3 = __instance.nextNode - position; Vector3 normalized3 = ((Vector3)(ref val3)).normalized; Vector3 val7 = Vector3.Slerp(normalized3, normalized2, 0.5f); val6 = ((!(num2 >= num4)) ? Vector3.Slerp(normalized3, val7, 1f - (num4 - num2) / num5) : val7); __instance.preGrindDir = normalized3; if (!((Ability)__instance).p.smoothRotation) { ((Ability)__instance).p.SetRotation(((Vector3)(ref val6)).normalized, __instance.normal); } } else if (__instance.preGrindDir != Vector3.zero && num2 <= num5) { val3 = __instance.nextNode - position; Vector3 normalized4 = ((Vector3)(ref val3)).normalized; Vector3 val8 = Vector3.Slerp(normalized4, __instance.preGrindDir, 0.5f); val6 = ((!(num2 <= 0f)) ? Vector3.Slerp(val8, normalized4, num2 / num5) : val8); if (!((Ability)__instance).p.smoothRotation) { ((Ability)__instance).p.SetRotation(((Vector3)(ref val6)).normalized, __instance.normal); } } else if (((Ability)__instance).p.smoothRotation) { val6 = (__instance.preGrindDir = __instance.nextNode - position); } else { Player p = ((Ability)__instance).p; val3 = __instance.nextNode - position; p.SetRotHard(Quaternion.LookRotation(((Vector3)(ref val3)).normalized, __instance.normal)); } if (((Ability)__instance).p.smoothRotation) { Quaternion rotation = Quaternion.LookRotation(val6, __instance.normal); ((Ability)__instance).p.SetRotation(rotation); } ((Ability)__instance).customVelocity = (position - ((Ability)__instance).p.tf.position) * 60f; ((Ability)__instance).p.lastElevationForSlideBoost = position.y; if (((Ability)__instance).p.jumpButtonNew || ((Ability)__instance).p.isAI) { float num6 = Vector3.Dot(((Ability)__instance).p.tf.up, Vector3.up); __instance.JumpOut(__instance.grindLine.isPole || (num6 > -0.25f && num6 < 0.35f)); return false; } ((Ability)__instance).p.SetVisualRotLocalZ(__instance.grindTilt.x * -30f); return false; } [HarmonyPatch(typeof(GrindAbility), "JumpOut")] [HarmonyPrefix] private static bool GrindAbility_JumpOut_Prefix(bool flipOut, GrindAbility __instance) { //IL_002d: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: 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_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_04e9: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Unknown result type (might be due to invalid IL or missing references) //IL_04f3: Unknown result type (might be due to invalid IL or missing references) //IL_04f7: Unknown result type (might be due to invalid IL or missing references) //IL_04fc: Unknown result type (might be due to invalid IL or missing references) float num = ((Ability)__instance).customVelocity.y / ((Vector3)(ref ((Ability)__instance).customVelocity)).magnitude; num = (float)Math.Round(num, 2); float num2 = Vector3.Dot(((Ability)__instance).p.tf.up, Vector3.up); ((Ability)__instance).p.AudioManager.PlayVoice(ref ((Ability)__instance).p.currentVoicePriority, ((Ability)__instance).p.character, (AudioClipID)489, ((Ability)__instance).p.playerGameplayVoicesAudioSource, (VoicePriority)0); ((Ability)__instance).p.timeSinceLastJump = 0f; ((Ability)__instance).p.isJumping = true; ((Ability)__instance).p.jumpConsumed = true; ((Ability)__instance).p.jumpRequested = false; ((Ability)__instance).p.jumpedThisFrame = true; ((Ability)__instance).p.maintainSpeedJump = false; ((Ability)__instance).p.lastElevationForSlideBoost = float.PositiveInfinity; Vector3 up = ((Ability)__instance).p.tf.up; ((Ability)__instance).p.DoJumpEffects(up); Transform tf = ((Ability)__instance).p.tf; tf.position += Vector3.up * ((Ability)__instance).p.motor.GetCapsule().height * Mathf.Clamp(((Ability)__instance).p.tf.up.y, -1f, 0f); if (flipOut) { Vector3 val = Vector3.ProjectOnPlane(up, Vector3.up); Vector3 normalized = ((Vector3)(ref val)).normalized; ((Ability)__instance).p.SetRotHard(Quaternion.LookRotation(normalized)); float num3 = ((Ability)__instance).p.jumpSpeed * 0.35f; float num4 = ((((Ability)__instance).p.abilityTimer <= ConfigSettings.RailFrameboost.Grace.Value) ? MovementPlusPlugin.noAbilitySpeed : ((Ability)__instance).p.maxMoveSpeed); ((Ability)__instance).p.SetVelocity(num3 * Vector3.up + normalized * num4); ((Ability)__instance).p.ActivateAbility((Ability)(object)((Ability)__instance).p.flipOutJumpAbility); } else { ((Ability)__instance).p.PlayAnim(__instance.jumpHash, false, false, -1f); Vector3 val2 = ((Ability)__instance).p.FlattenRotationHard(); float num5 = 1f + Mathf.Clamp01(0f) * 0.5f; if (!__instance.lastPath.upwardsGrindJumpAllowed || !__instance.grindLine.upwardsGrindJump) { num5 = 1f; } float num6 = ((Ability)__instance).p.jumpSpeed + ((Ability)__instance).p.bonusJumpSpeedGrind; float num7 = ((Vector3.Dot(up, Vector3.up) > -0.1f) ? (num6 * num5) : ((0f - ((Ability)__instance).p.jumpSpeed) * 0.5f)); float num8 = Mathf.Min(__instance.speed, ((Ability)__instance).p.boostSpeed); if (num2 >= 0.35f && !flipOut && ConfigSettings.RailSlope.Enabled.Value) { float num9 = num * ConfigSettings.RailSlope.SlopeJumpAmount.Value; float num10 = num * (0f - ConfigSettings.RailSlope.SlopeSpeedAmount.Value); num9 *= MovementPlusPlugin.AverageTotalSpeed() / 10f; num10 *= MovementPlusPlugin.AverageTotalSpeed() / 10f; num10 = Mathf.Clamp(num10, ConfigSettings.RailSlope.SlopeSpeedMin.Value, ConfigSettings.RailSlope.SlopeSpeedMax.Value); num9 = Mathf.Clamp(num9, ConfigSettings.RailSlope.SlopeJumpMin.Value, num9); num7 = Mathf.Clamp(num7 + num9, ConfigSettings.RailSlope.SlopeJumpMin.Value, ConfigSettings.RailSlope.SlopeJumpMax.Value); num8 = ((num10 > 0f) ? MovementPlusPlugin.LosslessClamp(num8, num10, ConfigSettings.RailSlope.SlopeSpeedCap.Value) : (num8 + num10)); } if (((Ability)__instance).p.boosting) { ((Ability)__instance).p.ActivateAbility((Ability)(object)((Ability)__instance).p.boostAbility); ((Ability)__instance).p.boostAbility.StartFromJumpGrindOrWallrun(); } else if (((Ability)__instance).p.slideButtonHeld) { num7 *= ((Ability)__instance).p.abilityShorthopFactor; ((Ability)__instance).p.StopCurrentAbility(); ((Ability)__instance).p.maintainSpeedJump = true; } else { ((Ability)__instance).p.StopCurrentAbility(); } if (((Ability)__instance).p.abilityTimer <= ConfigSettings.RailFrameboost.Grace.Value && ConfigSettings.RailFrameboost.Enabled.Value) { float num11 = MovementPlusPlugin.LosslessClamp(num8, ConfigSettings.RailFrameboost.Amount.Value, ConfigSettings.RailFrameboost.Cap.Value); num8 = num11; ((Ability)__instance).p.DoTrick((TrickType)2, "Frameboost", 0); } ((Ability)__instance).p.SetVelocity(num7 * Vector3.up + val2 * num8); } ((Ability)__instance).p.ForceUnground(true); MovementPlusPlugin.jumpedFromRail = true; MovementPlusPlugin.jumpedFromRailTimer = 0.025f; return false; } [HarmonyPatch(typeof(GrindAbility), "RewardTilting")] [HarmonyPrefix] private static bool GrindAbility_RewardTilting_Prefix(Vector3 rightDir, Vector3 nextLineDir, GrindAbility __instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0048: 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_0074: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Invalid comparison between Unknown and I4 //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Invalid comparison between Unknown and I4 //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) rightDir = Vector3.Cross(((Component)__instance.nextNode).transform.up, __instance.preGrindDir); if (!__instance.grindLine.cornerBoost) { return false; } Vector3 val = rightDir; Vector3 val2 = Vector3.ProjectOnPlane(nextLineDir, Vector3.up); float num = Vector3.Dot(val, ((Vector3)(ref val2)).normalized); Side val3 = (Side)(-1); if (__instance.grindTiltBuffer.x < -0.25f) { val3 = (Side)6; } else if (__instance.grindTiltBuffer.x > 0.25f) { val3 = (Side)2; } Side val4 = (Side)(-1); if (num < -0.02f) { val4 = (Side)6; } else if (num > 0.02f) { val4 = (Side)2; } if ((int)val4 != -1) { __instance.softCornerBoost = false; } bool flag = Mathf.Abs(num) > 0.1f; if ((int)val3 != -1 && val3 == val4) { if (flag && __instance.lastPath.hardCornerBoostsAllowed) { ((Ability)__instance).p.StartScreenShake((ScreenShakeType)0, 0.2f, false); ((Ability)__instance).p.AudioManager.PlaySfxGameplay((SfxCollectionID)20, (AudioClipID)19, ((Ability)__instance).p.playerOneShotAudioSource, 0f); ((Ability)__instance).p.ringParticles.Emit(1); float speed = MovementPlusPlugin.LosslessClamp(__instance.speed, ConfigSettings.RailGeneral.HardAmount.Value, ConfigSettings.RailGeneral.HardCap.Value); __instance.speed = speed; ((Ability)__instance).p.HardCornerGrindLine(__instance.nextNode); return false; } if (__instance.lastPath.softCornerBoostsAllowed) { __instance.softCornerBoost = true; ((Ability)__instance).p.DoTrick((TrickType)22, "Corner", 0); } } return false; } [HarmonyPatch(typeof(GrindAbility), "OnStopAbility")] [HarmonyPostfix] private static void GrindAbility_OnStopAbility_Postfix() { MovementPlusPlugin.hasGooned = false; MovementPlusPlugin.railGoonAppllied = false; } } internal static class GroundTrickAbilityPatch { private static readonly MyConfig ConfigSettings = MovementPlusPlugin.ConfigSettings; [HarmonyPatch(typeof(GroundTrickAbility), "OnStartAbility")] [HarmonyPostfix] private static void GroundTrickAbility_OnStartAbility_Postfix(GroundTrickAbility __instance) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) ((Ability)__instance).decc = ConfigSettings.Misc.groundTrickDecc.Value; if ((int)((Ability)__instance).p.moveStyle == 0) { ((Ability)__instance).allowNormalJump = false; } else { ((Ability)__instance).allowNormalJump = true; } } [HarmonyPatch(typeof(GroundTrickAbility), "FixedUpdateAbility")] [HarmonyPrefix] private static void GroundTrickAbility_FixedUpdateAbility_Prefix(GroundTrickAbility __instance) { if (!((Ability)__instance).p.TreatPlayerAsSortaGrounded() && ((Ability)__instance).p.jumpButtonNew) { _ = ConfigSettings.Buttslap.Enabled.Value; } } } internal static class AirDashAbilityPatch { private static readonly MyConfig ConfigSettings = MovementPlusPlugin.ConfigSettings; [HarmonyPatch(typeof(AirDashAbility), "OnStartAbility")] [HarmonyPrefix] private static bool AirDashAbility_onStartAbility_Prefix(AirDashAbility __instance) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) if ((int)((Ability)__instance).p.moveStyle == 4) { ((Ability)__instance).p.ActivateAbility((Ability)(object)((Ability)__instance).p.airTrickAbility); Vector3 velocity = ((Ability)__instance).p.GetVelocity(); velocity.y = 5f; ((Ability)__instance).p.SetVelocity(velocity); return false; } ((Ability)__instance).p.ringParticles.Emit(1); __instance.airDashSpeed = __instance.airDashStartSpeed; Vector3 val = ((Ability)__instance).p.moveInput; if (((Vector3)(ref val)).sqrMagnitude == 0f) { val = (__instance.dirIfNoSteer.HasValue ? __instance.dirIfNoSteer.Value : ((Ability)__instance).p.dir); } Vector3 val2 = Vector3.ProjectOnPlane(val, Vector3.up); val = ((Vector3)(ref val2)).normalized; if (((Ability)__instance).p.smoothRotation) { ((Ability)__instance).p.SetRotHard(val); } else { ((Ability)__instance).p.SetRotation(val); } ((Ability)__instance).p.OrientVisualInstantReset(); val2 = ((Ability)__instance).p.GetFlatVelocity(); if (((Vector3)(ref val2)).magnitude > __instance.airDashStartSpeed) { Vector3 val3 = val; val2 = ((Ability)__instance).p.GetFlatVelocity(); float val4 = Vector3.Dot(val3, ((Vector3)(ref val2)).normalized); val4 = MovementPlusPlugin.Remap(val4, -1f, 1f, ConfigSettings.Misc.airDashStrength.Value, 1f); if (val4 < 0f) { val4 = 0f; } float airDashStartSpeed = __instance.airDashStartSpeed; val2 = ((Ability)__instance).p.GetFlatVelocity(); __instance.airDashSpeed = airDashStartSpeed + (((Vector3)(ref val2)).magnitude - __instance.airDashStartSpeed) * val4; } ((Ability)__instance).p.SetVelocity(new Vector3(val.x * __instance.airDashSpeed, Mathf.Max(__instance.airDashInitialUpSpeed, ((Ability)__instance).p.GetVelocity().y), val.z * __instance.airDashSpeed)); ((Ability)__instance).targetSpeed = __instance.airDashSpeed; __instance.haveAirDash = false; ((Ability)__instance).p.PlayAnim(__instance.airDashHash, true, false, -1f); Core.Instance.AudioManager.PlaySfxGameplay((SfxCollectionID)20, (AudioClipID)4, ((Ability)__instance).p.playerOneShotAudioSource, 0f); ((Ability)__instance).p.wallrunAbility.cooldownTimer = 0f; ((Ability)__instance).p.wallrunAbility.wallrunLine = null; return false; } } internal static class HandplantAbilityPatch { private static readonly MyConfig ConfigSettings = MovementPlusPlugin.ConfigSettings; [HarmonyPatch(typeof(HandplantAbility), "FixedUpdateAbility")] [HarmonyPrefix] private static bool HandplantAbility_FixedUpdateAbility_Prefix(HandplantAbility __instance) { //IL_0052: 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_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) if (((Ability)__instance).p.abilityTimer < 0.35f) { ((Ability)__instance).p.hitbox.SetActive(true); } else { ((Ability)__instance).p.hitbox.SetActive(false); } if (__instance.screwPoleMode) { float num = 0f; if (((Component)((Ability)__instance).p).transform.position.y + Mathf.Epsilon < __instance.screwPole.maxPoint.position.y) { int num2 = 6; float num3 = 1f; if (((Ability)__instance).p.AnyTrickInput()) { if ((double)__instance.screwSpinTimer < 0.25) { __instance.screwSpinTimer = 0.5f; } if (__instance.screwFastSpinTimer > 0f) { __instance.screwFastPressCount++; num = ((__instance.screwFastPressCount > num2) ? num3 : 0f); } else { __instance.screwFastPressCount = 0; } __instance.screwFastSpinTimer = 0.25f; } else if (__instance.screwFastSpinTimer > 0f) { __instance.screwFastSpinTimer -= Core.dt; num = Mathf.Lerp(0f, num3, (float)Convert.ToInt32(__instance.screwFastPressCount > num2) * __instance.screwFastSpinTimer * 4f); } } float num4; if (__instance.screwSpinTimer > 0f) { __instance.screwSpinTimer -= Core.dt; num4 = Mathf.Min(((Ability)__instance).customVelocity.y + __instance.screwAcc * Core.dt, __instance.maxScrewSpeed + num); } else { num4 = Mathf.Max(((Ability)__instance).customVelocity.y - __instance.screwDecc * Core.dt, 0f); } if (((Component)((Ability)__instance).p).transform.position.y + Mathf.Epsilon < __instance.screwPole.maxPoint.position.y) { ((Ability)__instance).customVelocity.y = num4; __instance.screwPole.Move(num4); ((Ability)__instance).p.rotLean = Mathf.Min(num4, __instance.screwSpinTimer * 2f); } else { if (((Ability)__instance).customVelocity.y != 0f) { __instance.screwPole.StopPlayingSound(); ((Ability)__instance).p.AudioManager.PlaySfxGameplay(((Ability)__instance).p.moveStyle, (AudioClipID)490, ((Ability)__instance).p.playerOneShotAudioSource, 0f); } ((Ability)__instance).customVelocity.y = 0f; ((Ability)__instance).p.rotLean = __instance.screwSpinTimer * 2f; } } if (((Ability)__instance).p.jumpButtonNew || ((Ability)__instance).p.isAI) { float num5 = ((Ability)__instance).p.maxMoveSpeed; if (__instance.screwPoleMode) { num5 = ((Ability)__instance).p.maxMoveSpeed / 2f; } Vector3 val; if (((Ability)__instance).p.isAI) { ((Ability)__instance).p.AI.HandplantJump(); if ((Object)(object)((Ability)__instance).p.AI.nextWaypoint != (Object)null) { val = ((Ability)__instance).p.AI.dirToWaypoint; val.y = 0f; val = ((Vector3)(ref val)).normalized; ((Ability)__instance).p.SetRotHard(Vector3.ProjectOnPlane(val, Vector3.up)); val *= num5; } else { val = ((Ability)__instance).p.dir * num5; } } else { val = ((Ability)__instance).p.cam.realTf.forward; val.y = 0f; val = ((Vector3)(ref val)).normalized; ((Ability)__instance).p.SetRotHard(Vector3.ProjectOnPlane(val, Vector3.up)); val *= num5; } ((Ability)__instance).p.AudioManager.PlayVoice(ref ((Ability)__instance).p.currentVoicePriority, ((Ability)__instance).p.character, (AudioClipID)489, ((Ability)__instance).p.playerGameplayVoicesAudioSource, (VoicePriority)0); val.y = ((Ability)__instance).p.jumpSpeed + ((Ability)__instance).p.bonusJumpSpeedHandplantJump; ((Ability)__instance).p.SetVelocity(val); ((Ability)__instance).p.CreateHighJumpDustEffect(Vector3.up); ((Ability)__instance).p.PlayAnim(Animator.StringToHash("jump"), false, false, -1f); if (((Ability)__instance).p.abilityTimer <= 0.12f + ConfigSettings.RailFrameboost.Grace.Value) { ((Ability)__instance).p.SetForwardSpeed(Mathf.Max(MovementPlusPlugin.noAbilitySpeed, ((Ability)__instance).p.GetForwardSpeed())); } ((Ability)__instance).p.StopCurrentAbility(); } return false; } } internal static class SlideAbilityPatch { private static readonly MyConfig ConfigSettings = MovementPlusPlugin.ConfigSettings; [HarmonyPatch(typeof(SlideAbility), "FixedUpdateAbility")] [HarmonyPostfix] private static void SlideAbility_FixedUpdateAbility_Postfix(SlideAbility __instance) { float num = Mathf.Max(ConfigSettings.SuperSlide.Speed.Value, ((Ability)__instance).p.GetForwardSpeed()); if (ConfigSettings.SuperSlide.Enabled.Value) { num = MovementPlusPlugin.LosslessClamp(num, ConfigSettings.SuperSlide.Amount.Value, ConfigSettings.SuperSlide.Cap.Value); } __instance.superSpeed = num; __instance.slopeSlideSpeed = num; } } internal static class LedgeClimbAbilityPatch { private static readonly MyConfig ConfigSettings = MovementPlusPlugin.ConfigSettings; private static float savedSpeed; [HarmonyPatch(typeof(LedgeClimbAbility), "OnStartAbility")] [HarmonyPrefix] private static void LedgeClimbAbility_OnStartAbility_Prefix() { savedSpeed = MovementPlusPlugin.AverageTotalSpeed(); } [HarmonyPatch(typeof(LedgeClimbAbility), "FixedUpdateAbility")] [HarmonyPrefix] private static void LedgeClimbAbility_FixedUpdateAbility_Prefix(LedgeClimbAbility __instance) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (((Ability)__instance).p.jumpButtonNew && ConfigSettings.LedgeClimbGeneral.Enabled.Value) { float num = MovementPlusPlugin.LosslessClamp(savedSpeed, ConfigSettings.LedgeClimbGeneral.Amount.Value, ConfigSettings.LedgeClimbGeneral.Cap.Value); ((Ability)__instance).p.SetVelocity(((Ability)__instance).p.dir * num); ((Ability)__instance).p.ringParticles.Emit(1); ((Ability)__instance).p.AudioManager.PlaySfxGameplay((SfxCollectionID)20, (AudioClipID)19, ((Ability)__instance).p.playerOneShotAudioSource, 0f); ((Ability)__instance).p.Jump(); ((Ability)__instance).p.StopCurrentAbility(); } } } internal static class SpecialAirAbilityPatch { private static readonly MyConfig ConfigSettings = MovementPlusPlugin.ConfigSettings; [HarmonyPatch(typeof(SpecialAirAbility), "OnStartAbility")] [HarmonyPrefix] private static void SpecialAirAbility_OnStartAbility_Prefix(SpecialAirAbility __instance) { if (ConfigSettings.SuperTrickJump.Enabled.Value) { float num = Mathf.Max(((Ability)__instance).p.GetForwardSpeed() - ConfigSettings.SuperTrickJump.Threshold.Value, 0f); __instance.jumpSpeed = MovementPlusPlugin.LosslessClamp(__instance.jumpSpeed, num * ConfigSettings.SuperTrickJump.Amount.Value, ConfigSettings.SuperTrickJump.Cap.Value); __instance.duration = 0.3f; } } [HarmonyPatch(typeof(SpecialAirAbility), "OnStopAbility")] [HarmonyPostfix] private static void SpecialAirAbility_OnStopAbility_Prefix(SpecialAirAbility __instance) { __instance.jumpSpeed = MovementPlusPlugin.defaultJumpSpeed; } } internal static class PlayerPatch { private static readonly MyConfig ConfigSettings = MovementPlusPlugin.ConfigSettings; public static ButtslapAbility buttslapAbility; private static bool tooFast; [HarmonyPatch(typeof(Player), "Init")] [HarmonyPostfix] private static void Player_Init_Postfix(Player __instance) { if (!((Object)(object)MovementPlusPlugin.player == (Object)null) || __instance.isAI) { return; } MovementPlusPlugin.player = __instance; MovementPlusPlugin.defaultBoostSpeed = __instance.normalBoostSpeed; MovementPlusPlugin.defaultVertMaxSpeed = __instance.vertMaxSpeed; MovementPlusPlugin.defaultVertTopJumpSpeed = __instance.vertTopJumpSpeed; MovementPlusPlugin.defaultJumpSpeed = __instance.specialAirAbility.jumpSpeed; __instance.motor.maxFallSpeed = ConfigSettings.Misc.maxFallSpeed.Value; __instance.wallrunAbility.lastSpeed = MovementPlusPlugin.savedLastSpeed; __instance.vertBottomExitSpeedThreshold = 0f; buttslapAbility = new ButtslapAbility(__instance); if (ConfigSettings.Misc.collisionChangeEnabled.Value) { Rigidbody[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Rigidbody>(); Rigidbody[] array = componentsInChildren; foreach (Rigidbody val in array) { val.collisionDetectionMode = (CollisionDetectionMode)2; } } } [HarmonyPatch(typeof(Player), "FixedUpdatePlayer")] [HarmonyPostfix] private static void Player_FixedUpdatePlayer_Postfix(Player __instance) { if (MovementPlusPlugin.timeInAir >= 1.5f) { tooFast = true; } else { tooFast = false; } buttslapAbility.Activation(); } [HarmonyPatch(typeof(Player), "Jump")] [HarmonyPrefix] private static bool Player_Jump_Prefix(Player __instance) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) __instance.audioManager.PlayVoice(ref __instance.currentVoicePriority, __instance.character, (AudioClipID)489, __instance.playerGameplayVoicesAudioSource, (VoicePriority)0); __instance.PlayAnim(__instance.jumpHash, false, false, -1f); float num = 1f; if ((int)__instance.targetMovement == 0 && __instance.IsGrounded() && ((Component)__instance.motor.groundCollider).gameObject.layer != 23) { Vector3 val = Vector3.ProjectOnPlane(__instance.motor.groundNormal, Vector3.up); if (Vector3.Dot(((Vector3)(ref val)).normalized, __instance.dir) < -0.5f) { num = 1f + Mathf.Min(__instance.motor.groundAngle / 90f, 0.3f); } } __instance.ForceUnground(true); float num2 = 0f; if (__instance.timeSinceGrinding <= __instance.JumpPostGroundingGraceTime) { num2 = __instance.bonusJumpSpeedGrind; } else if (__instance.timeSinceWallrunning <= __instance.JumpPostGroundingGraceTime) { num2 = __instance.bonusJumpSpeedWallrun; } float num3 = __instance.jumpSpeed * num + num2; if (num2 != 0f && __instance.slideButtonHeld) { num3 *= __instance.abilityShorthopFactor; __instance.maintainSpeedJump = true; } else { __instance.maintainSpeedJump = false; } if (Object.op_Implicit((Object)(object)__instance.onLauncher)) { if (!((Object)((Component)__instance.onLauncher.parent).gameObject).name.Contains("Super")) { __instance.motor.SetVelocityYOneTime(__instance.jumpSpeedLauncher); } else { __instance.motor.SetVelocityYOneTime(__instance.jumpSpeedLauncher * 1.4f); } if ((int)__instance.targetMovement == 0 && Vector3.Dot(__instance.dir, TransformExtentions.back(__instance.onLauncher)) > 0.7f && !((Object)((Component)__instance.onLauncher.parent).gameObject).name.Contains("flat")) { __instance.SetForwardSpeed(__instance.GetForwardSpeed() + 5f); } __instance.audioManager.PlaySfxGameplay((SfxCollectionID)20, (AudioClipID)114, __instance.playerOneShotAudioSource, 0f); __instance.DoHighJumpEffects(__instance.motor.groundNormalVisual * -1f); } else { __instance.DoJumpEffects(__instance.motor.groundNormalVisual * -1f); __instance.motor.SetVelocityYOneTime(num3); __instance.isJumping = true; } __instance.jumpRequested = false; __instance.jumpConsumed = true; __instance.jumpedThisFrame = true; __instance.timeSinceLastJump = 0f; if (__instance.ability != null) { __instance.ability.OnJump(); if (__instance.ability != null && Object.op_Implicit((Object)(object)__instance.onLauncher) && __instance.ability.autoAirTrickFromLauncher) { __instance.ActivateAbility((Ability)(object)__instance.airTrickAbility); return false; } } else if (Object.op_Implicit((Object)(object)__instance.onLauncher)) { __instance.ActivateAbility((Ability)(object)__instance.airTrickAbility); } return false; } [HarmonyPatch(typeof(Player), "OnLanded")] [HarmonyPrefix] private static bool Player_OnLanded_Prefix(Player __instance) { //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) __instance.OrientVisualInstant(); if ((Object)(object)__instance.motor.groundRigidbody != (Object)null) { Car component = ((Component)__instance.motor.groundRigidbody).GetComponent<Car>(); if ((Object)(object)component != (Object)null) { component.PlayerLandsOn(); } } if (__instance.ability == null) { if (__instance.GetForwardSpeed() <= __instance.minMoveSpeed + 1f) { __instance.PlayAnim(__instance.landHash, false, false, -1f); } else { __instance.PlayAnim(__instance.landRunHash, false, false, -1f); } if (tooFast && (int)__instance.moveStyle == 0) { __instance.SetSpeedFlat(__instance.maxMoveSpeed); } if (__instance.slideButtonHeld && !((Ability)__instance.slideAbility).locked) { __instance.ActivateAbility((Ability)(object)__instance.slideAbility); } else if (!ConfigSettings.ComboGeneral.NoAbilityEnabled.Value) { __instance.LandCombo(); } } else if (__instance.ability == __instance.boostAbility && !ConfigSettings.ComboGeneral.BoostEnabled.Value) { __instance.LandCombo(); } __instance.audioManager.PlaySfxGameplay(__instance.moveStyle, (AudioClipID)255, __instance.playerOneShotAudioSource, 0f); __instance.CreateCircleDustEffect(__instance.motor.groundNormalVisual * -1f); return false; } [HarmonyPatch(typeof(Player), "FixedUpdateAbilities")] [HarmonyPrefix] private static bool Player_FixedUpdateAbilities_Prefix(Player __instance) { if (__instance.hitpause > 0f) { __instance.hitpause -= Core.dt; if (__instance.hitpause <= 0f) { __instance.StopHitpause(); return false; } } else { bool flag = __instance.IsGrounded(); __instance.abilityTimer += Core.dt; if (flag) { __instance.RegainAirMobility(); } __instance.grindAbility.PassiveUpdate(); if (__instance.isAI) { __instance.pseudoGraffitiAbility.PassiveUpdate(); } __instance.wallrunAbility.PassiveUpdate(); __instance.handplantAbility.PassiveUpdate(); if (__instance.ability == null) { if (!__instance.IsBusyWithSequence()) { for (int i = 0; i < __instance.abilities.Count; i++) { if (__instance.abilities[i].CheckActivation()) { return false; } } } if (flag && __instance.inWalkZone) { if (__instance.usingEquippedMovestyle) { __instance.ActivateAbility((Ability)(object)__instance.switchMoveStyleAbility); } } else if (__instance.switchStyleButtonNew && !__instance.switchToEquippedMovestyleLocked && !flag) { __instance.SwitchToEquippedMovestyle(!__instance.usingEquippedMovestyle, true, true, true); } } else { __instance.ability.FixedUpdateAbility(); } if (__instance.ability == null && flag) { if (!__instance.IsBusyWithSequence() && !__instance.motor.wasGrounded && __instance.slideButtonHeld && !((Ability)__instance.slideAbility).locked) { __instance.ActivateAbility((Ability)(object)__instance.slideAbility); return false; } if (__instance.IsComboing() && ConfigSettings.ComboGeneral.NoAbilityEnabled.Value && !__instance.boosting) { float num = Mathf.Min(__instance.GetForwardSpeed() / __instance.boostSpeed, 0.95f); __instance.DoComboTimeOut(Mathf.Max(Core.dt * (1f - num), Core.dt / 2f) * ConfigSettings.ComboGeneral.NoAbilityTimeout.Value); } else { __instance.LandCombo(); } } } return false; } } internal static class WallrunLineAbilityPatch { private static readonly MyConfig ConfigSettings = MovementPlusPlugin.ConfigSettings; private static float defaultMoveSpeed; private static float savedSpeed; [HarmonyPatch(typeof(WallrunLineAbility), "Init")] [HarmonyPostfix] private static void WallrunLineAbility_Init_Postfix(WallrunLineAbility __instance) { __instance.minDurationBeforeJump = 0f; __instance.wallrunDecc = 0f; defaultMoveSpeed = __instance.wallRunMoveSpeed; } [HarmonyPatch(typeof(WallrunLineAbility), "RunOff")] [HarmonyPrefix] private static bool WallrunLineAbility_RunOff_Prefix(WallrunLineAbility __instance, Vector3 direction) { //IL_011e: 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_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: 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_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_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_00b3: Unknown result type (might be due to invalid IL or missing references) Vector3 velocity; if (((Ability)__instance).p.abilityTimer <= ConfigSettings.WallFrameboost.Grace.Value) { if (ConfigSettings.WallFrameboost.Enabled.Value && ConfigSettings.WallFrameboost.RunoffEnabled.Value) { float num = MovementPlusPlugin.LosslessClamp(Mathf.Max(__instance.lastSpeed, ((Vector3)(ref ((Ability)__instance).customVelocity)).magnitude), ConfigSettings.WallFrameboost.Amount.Value, ConfigSettings.WallFrameboost.Cap.Value); velocity = direction * num + __instance.wallrunFaceNormal * 1f; ((Ability)__instance).p.DoTrick((TrickType)10, "Frameboost", 0); } else { velocity = direction * Mathf.Max(__instance.lastSpeed, ((Vector3)(ref ((Ability)__instance).customVelocity)).magnitude) + __instance.wallrunFaceNormal * 1f; } __instance.lastSpeed = Mathf.Max(savedSpeed, __instance.lastSpeed); savedSpeed = __instance.lastSpeed; } else { velocity = direction * Mathf.Max(new float[3] { __instance.lastSpeed, ((Vector3)(ref ((Ability)__instance).customVelocity)).magnitude, 13f }) + __instance.wallrunFaceNormal * 1f; savedSpeed = __instance.lastSpeed; } ((Ability)__instance).p.SetVelocity(velocity); ((Ability)__instance).p.SetRotHard(Quaternion.LookRotation(((Vector3)(ref velocity)).normalized)); ((Ability)__instance).p.FlattenRotationHard(); if (((Ability)__instance).p.boosting) { ((Ability)__instance).p.ActivateAbility((Ability)(object)((Ability)__instance).p.boostAbility); ((Ability)__instance).p.boostAbility.StartFromRunOffGrindOrWallrun(); return false; } ((Ability)__instance).p.StopCurrentAbility(); ((Ability)__instance).p.PlayAnim(__instance.fallHash, false, false, -1f); return false; } [HarmonyPatch(typeof(WallrunLineAbility), "FixedUpdateAbility")] [HarmonyPrefix] private static bool WallrunLineAbility_FixedUpdateAbility_Prefix(WallrunLineAbility __instance) { //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: 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) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) __instance.UpdateBoostpack(); __instance.scoreTimer += Core.dt; if (((Ability)__instance).p.abilityTimer <= 0.025f && !((Ability)__instance).p.isJumping) { float num = MovementPlusPlugin.LosslessClamp(MovementPlusPlugin.AverageForwardSpeed(), MovementPlusPlugin.AverageTotalSpeed() - MovementPlusPlugin.AverageForwardSpeed(), ConfigSettings.WallGeneral.wallTotalSpeedCap.Value); __instance.speed = Mathf.Max(num, __instance.wallRunMoveSpeed); } if (__instance.scoreTimer > 0.7f) { __instance.scoreTimer = 0f; ((Ability)__instance).p.DoTrick((TrickType)10, __instance.trickName, 0); } if (__instance.speed > __instance.wallRunMoveSpeed) { __instance.speed = Mathf.Max(__instance.wallRunMoveSpeed, __instance.speed - __instance.wallrunDecc * Core.dt); } if (((Ability)__instance).p.boosting) { __instance.speed = MovementPlusPlugin.LosslessClamp(__instance.speed, ConfigSettings.BoostGeneral.WallAmount.Value * Core.dt, ConfigSettings.BoostGeneral.WallCap.Value); } __instance.journey += __instance.speed / __instance.nodeToNodeLength * Core.dt; __instance.wallrunPos = Vector3.LerpUnclamped(__instance.prevNode.position, __instance.nextNode.position, __instance.journey); Vector3 val = __instance.nextNode.position - __instance.prevNode.position; __instance.dirToNextNode = ((Vector3)(ref val)).normalized; __instance.wallrunFaceNormal = ((Component)__instance.wallrunLine).transform.forward; float num2 = (0f - ((Ability)__instance).p.motor.GetCapsule().height) * 1f; if (__instance.wallrunHeight > num2) { if (__instance.wallRunUpDownSpeed > 0f) { __instance.wallRunUpDownSpeed = Mathf.Max(__instance.wallRunUpDownSpeed - __instance.wallRunUpDownDecc * Core.dt, 0f); } else if (__instance.wallRunUpDownSpeed < 0f) { __instance.wallRunUpDownSpeed = Mathf.Min(__instance.wallRunUpDownSpeed + __instance.wallRunUpDownDecc * Core.dt, 0f); } } else { __instance.wallRunUpDownSpeed = __instance.wallRunUpDownMaxSpeed; } __instance.wallrunHeight += __instance.wallRunUpDownSpeed * Core.dt; Vector3 val2 = __instance.wallrunPos + __instance.wallrunHeight * Vector3.up + __instance.wallrunFaceNormal * ((Ability)__instance).p.motor.GetCapsule().radius; ((Ability)__instance).customVelocity = (val2 - ((Ability)__instance).p.tf.position) / Core.dt; __instance.lastSpeed = ((Vector3)(ref ((Ability)__instance).customVelocity)).magnitude; ((Ability)__instance).p.lastElevationForSlideBoost = val2.y; val = Vector3.RotateTowards(((Ability)__instance).p.dir, __instance.dirToNextNode, __instance.rotSpeed * Core.dt, 1000f); Vector3 normalized = ((Vector3)(ref val)).normalized; if (((Ability)__instance).p.smoothRotation) { ((Ability)__instance).p.SetRotation(normalized); } else { ((Ability)__instance).p.SetRotHard(normalized); } if (((Ability)__instance).p.jumpButtonNew && (((Ability)__instance).p.abilityTimer > __instance.minDurationBeforeJump || ((Ability)__instance).p.isAI)) { __instance.Jump(); } else if (__instance.journey > 1f) { __instance.AtEndOfWallrunLine(); } ((Ability)__instance).p.SetVisualRotLocal0(); MovementPlusPlugin.savedLastSpeed = __instance.lastSpeed; if (((Ability)__instance).p.abilityTimer > ConfigSettings.WallFrameboost.Grace.Value && ConfigSettings.WallFrameboost.Enabled.Value) { savedSpeed = __instance.lastSpeed; } return false; } [HarmonyPatch(typeof(WallrunLineAbility), "Jump")] [HarmonyPostfix] private static void WallrunLineAbility_Jump_Postfix(WallrunLineAbility __instance) { if (((Ability)__instance).p.abilityTimer <= ConfigSettings.WallFrameboost.Grace.Value && ConfigSettings.WallFrameboost.Enabled.Value) { float forwardSpeed = MovementPlusPlugin.LosslessClamp(Mathf.Max(MovementPlusPlugin.AverageForwardSpeed(), ((Ability)__instance).p.GetForwardSpeed()), ConfigSettings.WallFrameboost.Amount.Value, ConfigSettings.WallFrameboost.Cap.Value); __instance.lastSpeed += ConfigSettings.WallFrameboost.Amount.Value; ((Ability)__instance).p.SetForwardSpeed(forwardSpeed); ((Ability)__instance).p.DoTrick((TrickType)10, "Frameboost", 0); __instance.lastSpeed = Mathf.Max(savedSpeed, __instance.lastSpeed); savedSpeed = __instance.lastSpeed; } } [HarmonyPatch(typeof(WallrunLineAbility), "OnStopAbility")] [HarmonyPostfix] private static void WallrunLineAbility_OnStopAbility_Postfix(WallrunLineAbility __instance) { __instance.cooldownTimer = 0.2f; } } } namespace MovementPlus.NewAbility { public class ButtslapAbility : Ability { private static readonly MyConfig ConfigSettings = MovementPlusPlugin.ConfigSettings; private float buttslapTimer; public ButtslapAbility(Player player) : base(player) { } public override void Init() { base.allowNormalJump = false; base.normalRotation = true; buttslapTimer = 0f; } public void Activation() { if (!base.p.motor.isGrounded && base.p.jumpButtonNew && ConfigSettings.Buttslap.Enabled.Value && base.p.ability == base.p.groundTrickAbility && !base.p.isJumping) { base.p.ActivateAbility((Ability)(object)this); } } public override void OnStartAbility() { if (!ConfigSettings.Buttslap.Multi