Decompiled source of BalanceTweaksForMe v1.0.1

BalanceTweaks.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("BalanceTweaksForMe")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("BalanceTweaks")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("BalanceTweaksForMe")]
[assembly: AssemblyTitle("BalanceTweaksForMe")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("1.0.1.0")]
namespace BalanceTweaksPlugin
{
	[BepInPlugin("BalanceTweaksForMe", "BalanceTweaksForMe", "1.0.1")]
	public class BalanceTweaksPlugin : BaseUnityPlugin
	{
		public static ConfigEntry<bool> CreateNetworkPrefab;

		public static ConfigEntry<bool> ShotgunConductive;

		public static ConfigEntry<bool> ShotgunEnemyDamage;

		public static ConfigEntry<bool> BeltBagShotgunAmmo;

		public static ConfigEntry<bool> AmmoWeight;

		public static ConfigEntry<bool> ShotgunWeight;

		public static ConfigEntry<bool> ShovelWeight;

		public static ConfigEntry<bool> KnifeWeight;

		public static ConfigEntry<bool> EnableShovelNarrowHitbox;

		public static ConfigEntry<bool> EnableShovelTriggerHit;

		public static ConfigEntry<bool> EnableShovelLinecastBlock;

		public static ConfigEntry<bool> EnableKnifeTriggerHit;

		public static ConfigEntry<bool> EnableKnifeLinecastBlock;

		public const string PLUGIN_GUID = "BalanceTweaksForMe";

		public const string PLUGIN_NAME = "BalanceTweaksForMe";

		public const string PLUGIN_VERSION = "1.0.1";

		public const string PLUGIN_VERSION_FULL = "1.0.1.0";

		private Harmony harmony = new Harmony("BalanceTweaksForMe");

		public static ManualLogSource logger;

		public static BalanceTweaksPlugin Instance;

		private void Awake()
		{
			Instance = this;
			logger = ((BaseUnityPlugin)this).Logger;
			CreateNetworkPrefab = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "CreateNetworkPrefab", false, "");
			ShotgunConductive = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShotgunConductive", true, "");
			ShotgunEnemyDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShotgunEnemyDamage", true, "");
			BeltBagShotgunAmmo = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "BeltBagShotgunAmmo", true, "");
			AmmoWeight = ((BaseUnityPlugin)this).Config.Bind<bool>("Balance", "AmmoWeight", false, "");
			ShotgunWeight = ((BaseUnityPlugin)this).Config.Bind<bool>("Balance", "ShotgunWeight", true, "");
			ShovelWeight = ((BaseUnityPlugin)this).Config.Bind<bool>("Balance", "ShovelWeight", true, "");
			KnifeWeight = ((BaseUnityPlugin)this).Config.Bind<bool>("Balance", "KnifeWeight", true, "");
			EnableShovelNarrowHitbox = ((BaseUnityPlugin)this).Config.Bind<bool>("HitDetection", "EnableShovelNarrowHitbox", true, "");
			EnableShovelTriggerHit = ((BaseUnityPlugin)this).Config.Bind<bool>("HitDetection", "EnableShovelTriggerHit", true, "");
			EnableShovelLinecastBlock = ((BaseUnityPlugin)this).Config.Bind<bool>("HitDetection", "EnableShovelLinecastBlock", true, "");
			EnableKnifeTriggerHit = ((BaseUnityPlugin)this).Config.Bind<bool>("HitDetection", "EnableKnifeTriggerHit", true, "");
			EnableKnifeLinecastBlock = ((BaseUnityPlugin)this).Config.Bind<bool>("HitDetection", "EnableKnifeLinecastBlock", true, "");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"BalanceTweaksForMe is loaded!");
		}
	}
}
namespace BalanceTweaksPlugin.Patches
{
	[HarmonyPatch(typeof(StartOfRound), "Start")]
	internal static class AmmoWeightPatch
	{
		[HarmonyPostfix]
		private static void ModifyAmmoWeight()
		{
			if (!BalanceTweaksPlugin.AmmoWeight.Value)
			{
				return;
			}
			foreach (Item items in StartOfRound.Instance.allItemsList.itemsList)
			{
				if (items.itemName == "Ammo")
				{
					items.weight = 1f;
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(BeltBagItem), "TryAddObjectToBagServerRpc")]
	internal static class BeltBagShotgunAmmoPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(BeltBagItem __instance, NetworkObjectReference netObjectRef, int playerWhoAdded)
		{
			if (!((NetworkBehaviour)__instance).IsHost)
			{
				return true;
			}
			if (!BalanceTweaksPlugin.BeltBagShotgunAmmo.Value)
			{
				return true;
			}
			NetworkObject val = default(NetworkObject);
			if (((NetworkObjectReference)(ref netObjectRef)).TryGet(ref val, (NetworkManager)null) && ((Component)val).GetComponent<GrabbableObject>() is GunAmmo)
			{
				__instance.CancelAddObjectToBagClientRpc(playerWhoAdded);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(KnifeItem), "HitKnife")]
	internal static class KnifeAttackPatch
	{
		private const int QueryTriggerIgnore = 1;

		private const int QueryTriggerUseGlobal = 0;

		private const sbyte QueryTriggerIgnore_SByte = 1;

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				CodeInstruction val = list[i];
				if (BalanceTweaksPlugin.EnableKnifeLinecastBlock.Value && i + 1 < list.Count && list[i + 1].opcode == OpCodes.Call && list[i + 1].operand is MethodInfo { Name: "Linecast", IsStatic: not false })
				{
					if (val.opcode == OpCodes.Ldc_I4_1)
					{
						val.opcode = OpCodes.Ldc_I4_0;
						val.operand = null;
					}
					else if (val.opcode == OpCodes.Ldc_I4_S && val.operand is sbyte b && b == 1)
					{
						val.operand = (sbyte)0;
					}
					else if (val.opcode == OpCodes.Ldc_I4 && val.operand is int num && num == 1)
					{
						val.operand = 0;
					}
				}
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(KnifeItem), "HitKnife")]
	internal static class KnifeTriggerPatch
	{
		private static readonly MethodInfo IsTriggerGetter = AccessTools.PropertyGetter(typeof(Collider), "isTrigger");

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			if (!BalanceTweaksPlugin.EnableKnifeTriggerHit.Value)
			{
				return instructions;
			}
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (!(list[i].opcode == OpCodes.Callvirt) || !(list[i].operand is MethodInfo methodInfo) || !(methodInfo == IsTriggerGetter))
				{
					continue;
				}
				list[i].opcode = OpCodes.Pop;
				list[i].operand = null;
				for (int j = i + 1; j < list.Count; j++)
				{
					if (list[j].opcode == OpCodes.Brtrue || list[j].opcode == OpCodes.Brtrue_S)
					{
						list[j].opcode = OpCodes.Nop;
						list[j].operand = null;
						break;
					}
				}
				break;
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "Start")]
	internal static class KnifeWeightPatch
	{
		[HarmonyPostfix]
		private static void ModifyKnifeWeight()
		{
			if (!BalanceTweaksPlugin.KnifeWeight.Value)
			{
				return;
			}
			foreach (Item items in StartOfRound.Instance.allItemsList.itemsList)
			{
				if (items.itemName == "Kitchen knife")
				{
					items.weight = 1.05f;
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(NetworkManager), "SetSingleton")]
	internal static class NetworkPrefabPatch
	{
		private static void Postfix()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!BalanceTweaksPlugin.CreateNetworkPrefab.Value || (Object)(object)NetworkManager.Singleton == (Object)null || NetworkManager.Singleton.PrefabHandler == null)
			{
				return;
			}
			GameObject val = new GameObject("BalanceTweaksForMe Prefab");
			((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x3D);
			Object.DontDestroyOnLoad((Object)(object)val);
			NetworkObject obj = val.AddComponent<NetworkObject>();
			try
			{
				FieldInfo field = typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.NonPublic);
				if (field != null)
				{
					uint hashCode = (uint)"BalanceTweaksForMe".GetHashCode();
					field.SetValue(obj, hashCode);
				}
			}
			catch
			{
			}
			NetworkManager.Singleton.PrefabHandler.AddNetworkPrefab(val);
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "Start")]
	internal static class ShotgunConductivePatch
	{
		[HarmonyPostfix]
		private static void MakeShotgunConductive()
		{
			if (!BalanceTweaksPlugin.ShotgunConductive.Value || !((NetworkBehaviour)StartOfRound.Instance).IsHost)
			{
				return;
			}
			foreach (Item items in StartOfRound.Instance.allItemsList.itemsList)
			{
				if (items.itemName == "Shotgun")
				{
					items.isConductiveMetal = true;
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(ShotgunItem), "ShootGun")]
	internal static class ShotgunEnemyDamagePatch
	{
		private const float OriginalRangeThreshold = 3.7f;

		private const int OriginalDamageClose = 5;

		private const int OriginalDamageMedium = 3;

		private const int OriginalDamageFar = 2;

		private const int DamageClose = 4;

		private const int DamageMedium = 3;

		private const int DamageFar = 2;

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			int remainingMatches = 0;
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Ldc_R4 && Mathf.Approximately((float)instruction.operand, 3.7f))
				{
					remainingMatches = 3;
				}
				if (remainingMatches > 0)
				{
					if (instruction.opcode == OpCodes.Ldc_I4_5)
					{
						instruction.opcode = OpCodes.Ldc_I4;
						instruction.operand = 4;
						remainingMatches--;
					}
					else if (instruction.opcode == OpCodes.Ldc_I4_3)
					{
						instruction.opcode = OpCodes.Ldc_I4;
						instruction.operand = 3;
						remainingMatches--;
					}
					else if (instruction.opcode == OpCodes.Ldc_I4_2)
					{
						instruction.opcode = OpCodes.Ldc_I4;
						instruction.operand = 2;
						remainingMatches--;
					}
					else if (instruction.opcode == OpCodes.Ldc_I4 && instruction.operand is int num && (num == 5 || num == 3 || num == 2))
					{
						instruction.operand = num switch
						{
							3 => 3, 
							5 => 4, 
							_ => 2, 
						};
						remainingMatches--;
					}
				}
				yield return instruction;
			}
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "HitEnemyServerRpc")]
	internal static class ShotgunEnemyDamageSyncPatch
	{
		private static readonly int[] OriginalDamage = new int[3] { 5, 3, 2 };

		private static readonly int[] ModdedDamage = new int[3] { 4, 3, 2 };

		[HarmonyPrefix]
		private static void SyncShotgunDamage(ref int force, int playerWhoHit)
		{
			if (!((NetworkBehaviour)StartOfRound.Instance).IsHost || playerWhoHit < 0 || playerWhoHit >= StartOfRound.Instance.allPlayerScripts.Length)
			{
				return;
			}
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerWhoHit];
			if ((Object)(object)val == (Object)null || !(val.currentlyHeldObjectServer is ShotgunItem))
			{
				return;
			}
			int[] array = (BalanceTweaksPlugin.ShotgunEnemyDamage.Value ? OriginalDamage : ModdedDamage);
			int[] array2 = (BalanceTweaksPlugin.ShotgunEnemyDamage.Value ? ModdedDamage : OriginalDamage);
			for (int i = 0; i < array.Length; i++)
			{
				if (force == array[i])
				{
					force = array2[i];
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "Start")]
	internal static class ShotgunWeightPatch
	{
		[HarmonyPostfix]
		private static void ModifyShotgunWeight()
		{
			if (!BalanceTweaksPlugin.ShotgunWeight.Value)
			{
				return;
			}
			foreach (Item items in StartOfRound.Instance.allItemsList.itemsList)
			{
				if (items.itemName == "Shotgun")
				{
					items.weight = 1.2f;
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Shovel), "HitShovel")]
	internal static class ShovelAttackPatch
	{
		private const float OriginalSphereCastRadius = 0.8f;

		private const float SphereCastRadius = 0.75f;

		private const float OriginalSphereCastDistance = 1.5f;

		private const float SphereCastDistance = 1.5f;

		private const float FloatComparisonEpsilon = 0.0001f;

		private const int QueryTriggerIgnore = 1;

		private const int QueryTriggerUseGlobal = 0;

		private const sbyte QueryTriggerIgnore_SByte = 1;

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				CodeInstruction val = list[i];
				if (BalanceTweaksPlugin.EnableShovelNarrowHitbox.Value && val.opcode == OpCodes.Ldc_R4 && val.operand is float num)
				{
					if (Math.Abs(num - 0.8f) < 0.0001f)
					{
						val.operand = 0.75f;
					}
					else if (Math.Abs(num - 1.5f) < 0.0001f)
					{
						val.operand = 1.5f;
					}
				}
				if (BalanceTweaksPlugin.EnableShovelLinecastBlock.Value && i + 1 < list.Count && list[i + 1].opcode == OpCodes.Call && list[i + 1].operand is MethodInfo { Name: "Linecast", IsStatic: not false })
				{
					if (val.opcode == OpCodes.Ldc_I4_1)
					{
						val.opcode = OpCodes.Ldc_I4_0;
						val.operand = null;
					}
					else if (val.opcode == OpCodes.Ldc_I4_S && val.operand is sbyte b && b == 1)
					{
						val.operand = (sbyte)0;
					}
					else if (val.opcode == OpCodes.Ldc_I4 && val.operand is int num2 && num2 == 1)
					{
						val.operand = 0;
					}
				}
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(Shovel), "HitShovel")]
	internal static class ShovelTriggerPatch
	{
		private static readonly MethodInfo IsTriggerGetter = AccessTools.PropertyGetter(typeof(Collider), "isTrigger");

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			if (!BalanceTweaksPlugin.EnableShovelTriggerHit.Value)
			{
				return instructions;
			}
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (!(list[i].opcode == OpCodes.Callvirt) || !(list[i].operand is MethodInfo methodInfo) || !(methodInfo == IsTriggerGetter))
				{
					continue;
				}
				list[i].opcode = OpCodes.Pop;
				list[i].operand = null;
				for (int j = i + 1; j < list.Count; j++)
				{
					if (list[j].opcode == OpCodes.Brtrue || list[j].opcode == OpCodes.Brtrue_S)
					{
						list[j].opcode = OpCodes.Nop;
						list[j].operand = null;
						break;
					}
				}
				break;
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "Start")]
	internal static class ShovelWeightPatch
	{
		[HarmonyPostfix]
		private static void ModifyShovelWeight()
		{
			if (!BalanceTweaksPlugin.ShovelWeight.Value)
			{
				return;
			}
			foreach (Item items in StartOfRound.Instance.allItemsList.itemsList)
			{
				if (items.itemName == "Shovel")
				{
					items.weight = 1.18f;
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")]
	internal static class BlockScrollSwitchPatch
	{
		private const float KnifeCooldownTime = 0.43f;

		private static readonly FieldInfo knifeCooldownField = AccessTools.Field(typeof(KnifeItem), "timeAtLastDamageDealt");

		[HarmonyPrefix]
		private static bool Prefix(PlayerControllerB __instance)
		{
			GrabbableObject currentlyHeldObjectServer = __instance.currentlyHeldObjectServer;
			Shovel val = (Shovel)(object)((currentlyHeldObjectServer is Shovel) ? currentlyHeldObjectServer : null);
			if ((Object)(object)val != (Object)null && val.reelingUp)
			{
				return false;
			}
			GrabbableObject currentlyHeldObjectServer2 = __instance.currentlyHeldObjectServer;
			KnifeItem val2 = (KnifeItem)(object)((currentlyHeldObjectServer2 is KnifeItem) ? currentlyHeldObjectServer2 : null);
			if ((Object)(object)val2 != (Object)null && Time.realtimeSinceStartup - (float)knifeCooldownField.GetValue(val2) < 0.43f)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "UseUtilitySlot_performed")]
	internal static class BlockUtilitySlotSwitchPatch
	{
		private const float KnifeCooldownTime = 0.43f;

		private static readonly FieldInfo knifeCooldownField = AccessTools.Field(typeof(KnifeItem), "timeAtLastDamageDealt");

		[HarmonyPrefix]
		private static bool Prefix(PlayerControllerB __instance)
		{
			GrabbableObject currentlyHeldObjectServer = __instance.currentlyHeldObjectServer;
			Shovel val = (Shovel)(object)((currentlyHeldObjectServer is Shovel) ? currentlyHeldObjectServer : null);
			if ((Object)(object)val != (Object)null && val.reelingUp)
			{
				return false;
			}
			GrabbableObject currentlyHeldObjectServer2 = __instance.currentlyHeldObjectServer;
			KnifeItem val2 = (KnifeItem)(object)((currentlyHeldObjectServer2 is KnifeItem) ? currentlyHeldObjectServer2 : null);
			if ((Object)(object)val2 != (Object)null && Time.realtimeSinceStartup - (float)knifeCooldownField.GetValue(val2) < 0.43f)
			{
				return false;
			}
			return true;
		}
	}
}