Decompiled source of NoMovementPenalty v1.0.8

plugins/NoMovementPenalty.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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 BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("NoMovementPenalty")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("NoMovementPenalty")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("05078777-8b4c-43fd-98ec-887e0f886aae")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace NoMovementPenalty;

[BepInPlugin("posixone_NoMovementPenalty", "NoMovementPenalty", "1.0.8")]
public class Main : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Player), "UpdateModifiers")]
	public class EquippedArmorDoesntAffectMovementSpeedMod
	{
		public static void Prefix(ItemData ___m_rightItem, ItemData ___m_leftItem, ItemData ___m_helmetItem, ItemData ___m_chestItem, ItemData ___m_legItem, ItemData ___m_shoulderItem, ItemData ___m_utilityItem, ItemData ___m_trinketItem)
		{
			Neutralise(___m_rightItem, rightItemEnable, "right");
			Neutralise(___m_leftItem, leftItemEnable, "left");
			Neutralise(___m_helmetItem, helmetItemEnable, "helmet");
			Neutralise(___m_chestItem, chestItemEnable, "chest");
			Neutralise(___m_legItem, legItemEnable, "legs");
			Neutralise(___m_shoulderItem, shoulderItemEnable, "shoulder");
			Neutralise(___m_utilityItem, utilityItemEnable, "utility");
			Neutralise(___m_trinketItem, trinketItemEnable, "trinket");
		}
	}

	[HarmonyPatch(typeof(Player), "GetEquipmentMovementModifier")]
	public class ClampNegativeEquipmentMovementModifier
	{
		public static void Postfix(ref float __result)
		{
			if (!(__result >= 0f) && (!zeroPenaltyOnItem.Value || AllSlotsEnabled()))
			{
				__result = 0f;
			}
		}
	}

	[HarmonyPatch(typeof(Player), "GetRunSpeedFactor")]
	public class SpeedRacerRunSpeed
	{
		public static void Postfix(ref float __result)
		{
			if (SpeedRacer.Active)
			{
				__result *= 3f;
			}
		}
	}

	[HarmonyPatch(typeof(Terminal), "InitTerminal")]
	public class RegisterSpeedRacerCommand
	{
		public static void Postfix()
		{
			SpeedRacer.RegisterCommand();
		}
	}

	public const string MODNAME = "NoMovementPenalty";

	public const string AUTHOR = "posixone";

	public const string GUID = "posixone_NoMovementPenalty";

	public const string VERSION = "1.0.8";

	public static ConfigEntry<bool> modEnable;

	public static ConfigEntry<bool> zeroPenaltyOnItem;

	public static ConfigEntry<bool> rightItemEnable;

	public static ConfigEntry<bool> leftItemEnable;

	public static ConfigEntry<bool> helmetItemEnable;

	public static ConfigEntry<bool> chestItemEnable;

	public static ConfigEntry<bool> legItemEnable;

	public static ConfigEntry<bool> shoulderItemEnable;

	public static ConfigEntry<bool> utilityItemEnable;

	public static ConfigEntry<bool> trinketItemEnable;

	internal static ManualLogSource Log;

	private static readonly HashSet<string> s_logged = new HashSet<string>();

	private const float ZeroSentinel = 1E-18f;

	private void Awake()
	{
		//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_0036: Expected O, but got Unknown
		//IL_0036: Expected O, but got Unknown
		//IL_004b: 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_0066: Expected O, but got Unknown
		//IL_0066: Expected O, but got Unknown
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Expected O, but got Unknown
		//IL_0096: Expected O, but got Unknown
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Expected O, but got Unknown
		//IL_00c6: Expected O, but got Unknown
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Expected O, but got Unknown
		//IL_00f6: Expected O, but got Unknown
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Expected O, but got Unknown
		//IL_0126: Expected O, but got Unknown
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Expected O, but got Unknown
		//IL_0156: Expected O, but got Unknown
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Expected O, but got Unknown
		//IL_0186: Expected O, but got Unknown
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Expected O, but got Unknown
		//IL_01b6: Expected O, but got Unknown
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Expected O, but got Unknown
		//IL_01e6: Expected O, but got Unknown
		//IL_0245: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		modEnable = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("1-Global", "modEnable"), true, new ConfigDescription("Set this to true to enable and false to disable this mod.", (AcceptableValueBase)null, Array.Empty<object>()));
		zeroPenaltyOnItem = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("1-Global", "zeroPenaltyOnItem"), true, new ConfigDescription("True: zero the penalty on the equipped item itself, so its tooltip reads +0% and the per-slot toggles below apply. False: leave items untouched and only clamp the player's total, which is how v1.0.6/v1.0.7 behaved -- use this if Epic Loot or another mod reports odd movement values. The penalty is removed either way.", (AcceptableValueBase)null, Array.Empty<object>()));
		rightItemEnable = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("2-Toggles", "rightItemEnable"), true, new ConfigDescription("Set this to true to enable NoMovementPenalty for the equipped right-handed item.", (AcceptableValueBase)null, Array.Empty<object>()));
		leftItemEnable = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("2-Toggles", "leftItemEnable"), true, new ConfigDescription("Set this to true to enable NoMovementPenalty for the equipped left-handed item.", (AcceptableValueBase)null, Array.Empty<object>()));
		helmetItemEnable = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("2-Toggles", "helmetItemEnable"), true, new ConfigDescription("Set this to true to enable NoMovementPenalty for the equipped helmet item.", (AcceptableValueBase)null, Array.Empty<object>()));
		chestItemEnable = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("2-Toggles", "chestItemEnable"), true, new ConfigDescription("Set this to true to enable NoMovementPenalty for the equipped chest item.", (AcceptableValueBase)null, Array.Empty<object>()));
		legItemEnable = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("2-Toggles", "legItemEnable"), true, new ConfigDescription("Set this to true to enable NoMovementPenalty for the equipped leg item.", (AcceptableValueBase)null, Array.Empty<object>()));
		shoulderItemEnable = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("2-Toggles", "shoulderItemEnable"), true, new ConfigDescription("Set this to true to enable NoMovementPenalty for the equipped shoulder item.", (AcceptableValueBase)null, Array.Empty<object>()));
		utilityItemEnable = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("2-Toggles", "utilityItemEnable"), true, new ConfigDescription("Set this to true to enable NoMovementPenalty for the equipped utility item.", (AcceptableValueBase)null, Array.Empty<object>()));
		trinketItemEnable = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition("2-Toggles", "trinketItemEnable"), true, new ConfigDescription("Set this to true to enable NoMovementPenalty for the equipped trinket item.", (AcceptableValueBase)null, Array.Empty<object>()));
		if (!modEnable.Value)
		{
			Log.LogInfo((object)"modEnable=false, not patching.");
			return;
		}
		if (!VerifyTargets())
		{
			Log.LogError((object)"Aborting patch: the game no longer matches what this mod expects. The mod is loaded but will have NO effect.");
			return;
		}
		if (!zeroPenaltyOnItem.Value && !AllSlotsEnabled())
		{
			Log.LogWarning((object)"zeroPenaltyOnItem=false ignores the per-slot toggles -- in that mode the penalty is removed for every slot. Set zeroPenaltyOnItem=true for per-slot control.");
		}
		new Harmony("posixone_NoMovementPenalty").PatchAll(Assembly.GetExecutingAssembly());
		Log.LogInfo((object)"v1.0.8 patched Player.UpdateModifiers, Player.GetEquipmentMovementModifier, Player.GetRunSpeedFactor, Terminal.InitTerminal.");
	}

	private void Update()
	{
		SpeedRacer.Tick();
	}

	private static bool VerifyTargets()
	{
		bool result = true;
		if (AccessTools.Method(typeof(Player), "UpdateModifiers", (Type[])null, (Type[])null) == null)
		{
			Log.LogError((object)"Player.UpdateModifiers() not found.");
			result = false;
		}
		if (AccessTools.Method(typeof(Player), "GetEquipmentMovementModifier", (Type[])null, (Type[])null) == null)
		{
			Log.LogError((object)"Player.GetEquipmentMovementModifier() not found.");
			result = false;
		}
		if (AccessTools.Method(typeof(Player), "GetRunSpeedFactor", (Type[])null, (Type[])null) == null)
		{
			Log.LogError((object)"Player.GetRunSpeedFactor() not found.");
			result = false;
		}
		if (AccessTools.Method(typeof(Terminal), "InitTerminal", (Type[])null, (Type[])null) == null)
		{
			Log.LogError((object)"Terminal.InitTerminal() not found.");
			result = false;
		}
		string[] array = new string[8] { "m_rightItem", "m_leftItem", "m_helmetItem", "m_chestItem", "m_legItem", "m_shoulderItem", "m_utilityItem", "m_trinketItem" };
		foreach (string text in array)
		{
			if (AccessTools.Field(typeof(Player), text) == null)
			{
				Log.LogError((object)("Equipment slot field '" + text + "' not found on Player/Humanoid."));
				result = false;
			}
		}
		if (AccessTools.Field(typeof(SharedData), "m_movementModifier") == null)
		{
			Log.LogError((object)"ItemDrop.ItemData.SharedData.m_movementModifier not found.");
			result = false;
		}
		return result;
	}

	internal static bool AllSlotsEnabled()
	{
		if (rightItemEnable.Value && leftItemEnable.Value && helmetItemEnable.Value && chestItemEnable.Value && legItemEnable.Value && shoulderItemEnable.Value && utilityItemEnable.Value)
		{
			return trinketItemEnable.Value;
		}
		return false;
	}

	internal static void Neutralise(ItemData item, ConfigEntry<bool> toggle, string slot)
	{
		if (!zeroPenaltyOnItem.Value || item == null || !toggle.Value)
		{
			return;
		}
		SharedData shared = item.m_shared;
		if (shared != null && !(shared.m_movementModifier >= 0f))
		{
			float movementModifier = shared.m_movementModifier;
			shared.m_movementModifier = 1E-18f;
			string text = shared.m_name ?? "<unnamed>";
			if (s_logged.Add(slot + ":" + text))
			{
				Log.LogInfo((object)("neutralised " + slot + " '" + text + "' (" + movementModifier.ToString("0.###") + " -> 0)"));
			}
		}
	}
}
internal static class SpeedRacer
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static ConsoleEvent <>9__8_0;

		internal void <RegisterCommand>b__8_0(ConsoleEventArgs args)
		{
			Toggle();
			args.Context.AddString(Active ? "<color=#3CFF5A>GO SPEED RACER GO --- run speed +200%</color>" : "<color=#3CFF5A>speed racer off</color>");
		}
	}

	internal const string Command = "gospeedracer";

	internal const float Multiplier = 3f;

	private static GameObject s_aura;

	private static Player s_auraOwner;

	internal static bool Active { get; private set; }

	internal static void RegisterCommand()
	{
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Expected O, but got Unknown
		ConstructorInfo constructorInfo = null;
		ConstructorInfo[] constructors = typeof(ConsoleCommand).GetConstructors();
		foreach (ConstructorInfo constructorInfo2 in constructors)
		{
			ParameterInfo[] parameters = constructorInfo2.GetParameters();
			if (parameters.Length >= 3 && parameters[0].ParameterType == typeof(string) && parameters[1].ParameterType == typeof(string) && parameters[2].ParameterType == typeof(ConsoleEvent))
			{
				constructorInfo = constructorInfo2;
				break;
			}
		}
		if (constructorInfo == null)
		{
			Main.Log.LogWarning((object)"could not resolve a Terminal.ConsoleCommand constructor; 'gospeedracer' not registered.");
			return;
		}
		object obj = <>c.<>9__8_0;
		if (obj == null)
		{
			ConsoleEvent val = delegate(ConsoleEventArgs args)
			{
				Toggle();
				args.Context.AddString(Active ? "<color=#3CFF5A>GO SPEED RACER GO --- run speed +200%</color>" : "<color=#3CFF5A>speed racer off</color>");
			};
			<>c.<>9__8_0 = val;
			obj = (object)val;
		}
		ConsoleEvent val2 = (ConsoleEvent)obj;
		ParameterInfo[] parameters2 = constructorInfo.GetParameters();
		object[] array = new object[parameters2.Length];
		for (int num = 0; num < parameters2.Length; num++)
		{
			array[num] = (parameters2[num].HasDefaultValue ? parameters2[num].DefaultValue : null);
			if (parameters2[num].Name == "isSecret")
			{
				array[num] = true;
			}
			if (parameters2[num].Name == "isCheat")
			{
				array[num] = false;
			}
		}
		array[0] = "gospeedracer";
		array[1] = "";
		array[2] = val2;
		constructorInfo.Invoke(array);
		Main.Log.LogInfo((object)"registered console command 'gospeedracer'.");
	}

	internal static void Toggle()
	{
		Active = !Active;
		Main.Log.LogInfo((object)("gospeedracer -> " + (Active ? ("ON (run x" + 3f + ")") : "OFF")));
		if (!Active)
		{
			DestroyAura();
		}
	}

	internal static void Tick()
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Expected O, but got Unknown
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		if (!Active || (Object)(object)Player.m_localPlayer == (Object)null)
		{
			if ((Object)(object)s_aura != (Object)null)
			{
				DestroyAura();
			}
			return;
		}
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)s_aura != (Object)null) || !((Object)(object)s_auraOwner == (Object)(object)localPlayer))
		{
			DestroyAura();
			s_aura = new GameObject("NMP_SpeedRacerAura");
			s_aura.transform.SetParent(((Component)localPlayer).transform, false);
			s_aura.transform.localPosition = new Vector3(0f, 0.25f, 0f);
			s_aura.AddComponent<SpeedRacerAura>();
			s_auraOwner = localPlayer;
		}
	}

	private static void DestroyAura()
	{
		if ((Object)(object)s_aura != (Object)null)
		{
			Object.Destroy((Object)(object)s_aura);
		}
		s_aura = null;
		s_auraOwner = null;
	}
}
internal class SpeedRacerAura : MonoBehaviour
{
	private const float BaseIntensity = 1.4f;

	private const float PulseDepth = 0.35f;

	private const float PulseSpeed = 2.2f;

	private Light m_light;

	private float m_phase;

	private void Awake()
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		m_light = ((Component)this).gameObject.AddComponent<Light>();
		m_light.type = (LightType)2;
		m_light.color = new Color(0.24f, 1f, 0.35f);
		m_light.range = 3f;
		m_light.intensity = 1.4f;
		m_light.shadows = (LightShadows)0;
	}

	private void Update()
	{
		if (!((Object)(object)m_light == (Object)null))
		{
			m_phase += Time.deltaTime * 2.2f;
			m_light.intensity = 1.4f + Mathf.Sin(m_phase) * 0.35f;
		}
	}
}