Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BalanceTweaksForMe v1.0.1
BalanceTweaks.dll
Decompiled 19 hours agousing 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; } } }