using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("WeeWeeShotgunTweaks")] [assembly: AssemblyDescription("Lethal Company shotgun and friendly-fire tweaks")] [assembly: AssemblyCompany("WeeWee")] [assembly: AssemblyProduct("WeeWeeShotgunTweaks")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyVersion("1.0.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 WeeWeeShotgunTweaks { [BepInPlugin("LilWeeWee.WeeWeeShotgunTweaks", "Wee Wee Shotgun Tweaks", "1.0.1")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "LilWeeWee.WeeWeeShotgunTweaks"; public const string PluginName = "Wee Wee Shotgun Tweaks"; public const string PluginVersion = "1.0.1"; internal static ModConfig Settings { get; private set; } private void Awake() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) Settings = new ModConfig(((BaseUnityPlugin)this).Config); new Harmony("LilWeeWee.WeeWeeShotgunTweaks").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Wee Wee Shotgun Tweaks 1.0.1 loaded."); } } internal sealed class ModConfig { internal ConfigEntry InfiniteShotgunAmmo { get; } internal ConfigEntry DisableShotgunMisfire { get; } internal ConfigEntry DisableIncomingFriendlyFire { get; } internal ConfigEntry DisableOutgoingFriendlyFire { get; } internal ConfigEntry ShotgunDamage { get; } internal ConfigEntry ShovelDamage { get; } internal ModConfig(ConfigFile config) { InfiniteShotgunAmmo = config.Bind("Shotgun", "InfiniteShotgunAmmo", true, "Prevents player-held shotguns from consuming shells."); DisableShotgunMisfire = config.Bind("Shotgun", "DisableShotgunMisfire", true, "Prevents dropped player shotguns from firing by themselves."); ShotgunDamage = config.Bind("Shotgun", "ShotgunDamage", -1, "Custom shotgun damage. -1 keeps the game's normal damage value."); DisableIncomingFriendlyFire = config.Bind("Friendly Fire", "DisableIncomingFriendlyFire", true, "Blocks damage dealt to you by another player."); DisableOutgoingFriendlyFire = config.Bind("Friendly Fire", "DisableOutgoingFriendlyFire", true, "Blocks your weapon damage against other players."); ShovelDamage = config.Bind("Shovel", "ShovelDamage", 2, "Damage force used by shovels and signs. Vanilla is normally 1."); } } internal static class Helpers { internal static PlayerControllerB LocalPlayer { get { if (!((Object)(object)GameNetworkManager.Instance != (Object)null)) { return null; } return GameNetworkManager.Instance.localPlayerController; } } internal static bool IsWeaponCause(CauseOfDeath cause) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)cause != 1) { return (int)cause == 7; } return true; } } [HarmonyPatch(typeof(ShotgunItem), "ShootGun")] internal static class ShotgunShootPatch { [HarmonyPrefix] private static bool PreventDroppedMisfire(ShotgunItem __instance) { if (!Plugin.Settings.DisableShotgunMisfire.Value) { return true; } if (!((GrabbableObject)__instance).isHeld) { return ((GrabbableObject)__instance).isHeldByEnemy; } return true; } internal static bool PreCheckFriendly(ShotgunItem shotgun) { if (!Plugin.Settings.DisableOutgoingFriendlyFire.Value) { return false; } return !((GrabbableObject)shotgun).isHeldByEnemy; } internal static int GetShotgunDamage(int originalDamage) { int value = Plugin.Settings.ShotgunDamage.Value; if (value >= 0) { return value; } return originalDamage; } [HarmonyTranspiler] private static IEnumerable ShootGunTranspiler(IEnumerable instructions) { bool injectedFriendlyFireCheck = false; foreach (CodeInstruction instruction in instructions) { if (!injectedFriendlyFireCheck && instruction.opcode == OpCodes.Stloc_0) { yield return instruction; yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ShotgunShootPatch), "PreCheckFriendly", (Type[])null, (Type[])null)); yield return new CodeInstruction(OpCodes.Stloc_0, (object)null); injectedFriendlyFireCheck = true; } else if (instruction.opcode == OpCodes.Ldc_I4_5) { yield return instruction; yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ShotgunShootPatch), "GetShotgunDamage", (Type[])null, (Type[])null)); } else { yield return instruction; } } } } [HarmonyPatch(typeof(ShotgunItem), "Update")] internal static class ShotgunUpdatePatch { [HarmonyPostfix] private static void UpdatePostfix(ShotgunItem __instance, ref float ___misfireTimer, ref bool ___hasHitGroundWithSafetyOff, ref int ___shellsLoaded) { if (!((Object)(object)__instance == (Object)null) && !((GrabbableObject)__instance).isHeldByEnemy) { if (Plugin.Settings.DisableShotgunMisfire.Value) { ___misfireTimer = 30f; ___hasHitGroundWithSafetyOff = false; } if (Plugin.Settings.InfiniteShotgunAmmo.Value && ___shellsLoaded < 2) { ___shellsLoaded = 2; } } } } [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")] internal static class PlayerDamagePatch { [HarmonyPrefix] private static bool DamagePlayerPrefix(PlayerControllerB __instance, CauseOfDeath causeOfDeath, bool callRPC) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (!Helpers.IsWeaponCause(causeOfDeath)) { return true; } PlayerControllerB localPlayer = Helpers.LocalPlayer; if ((Object)(object)localPlayer == (Object)null) { return true; } if ((Object)(object)__instance == (Object)(object)localPlayer && Plugin.Settings.DisableIncomingFriendlyFire.Value) { return false; } if ((Object)(object)__instance != (Object)(object)localPlayer && callRPC && Plugin.Settings.DisableOutgoingFriendlyFire.Value) { return false; } return true; } } [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayerFromOtherClientClientRpc")] internal static class IncomingNetworkDamagePatch { [HarmonyPrefix] private static bool IncomingPrefix(PlayerControllerB __instance) { PlayerControllerB localPlayer = Helpers.LocalPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)__instance != (Object)(object)localPlayer)) { return !Plugin.Settings.DisableIncomingFriendlyFire.Value; } return true; } } [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayerFromOtherClientServerRpc")] internal static class OutgoingNetworkDamagePatch { [HarmonyPrefix] private static bool OutgoingPrefix(int playerWhoHit) { PlayerControllerB localPlayer = Helpers.LocalPlayer; if ((Object)(object)localPlayer == (Object)null || !Plugin.Settings.DisableOutgoingFriendlyFire.Value) { return true; } return playerWhoHit != (int)localPlayer.playerClientId; } } [HarmonyPatch(typeof(Shovel), "HitShovel")] internal static class ShovelPatch { [HarmonyPrefix] private static void HitShovelPrefix(ref int ___shovelHitForce) { int value = Plugin.Settings.ShovelDamage.Value; if (value >= 0) { ___shovelHitForce = value; } } } }