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 NoFriendlyFire v1.0.0
plugins/NoFriendlyFire.dll
Decompiled 4 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("NOFRIENDLYFIRE")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("NOFRIENDLYFIRE")] [assembly: AssemblyTitle("NOFRIENDLYFIRE")] [assembly: AssemblyVersion("1.0.0.0")] [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 NoFriendlyFire { [BepInPlugin("PxntxrezStudio.NoFriendlyFire", "No Friendly Fire", "1.0.0")] public class NoFriendlyFirePlugin : BaseUnityPlugin { public const string PLUGIN_GUID = "PxntxrezStudio.NoFriendlyFire"; public const string PLUGIN_NAME = "No Friendly Fire"; public const string PLUGIN_VERSION = "1.0.0"; public static NoFriendlyFirePlugin Instance; public static ConfigEntry<bool> DisableFriendlyFire; public static ConfigEntry<bool> AllowGunBulletDamage; public static ConfigEntry<bool> AllowCartCannonDamage; public static ConfigEntry<bool> AllowCartLaserDamage; public static ConfigEntry<bool> AllowWeaponExplosiveDamage; public static ConfigEntry<bool> AllowMeleeDamage; public static ConfigEntry<bool> AllowMeleePhysicsDamage; public static ConfigEntry<bool> AllowThrownObjectDamage; public static ConfigEntry<bool> AllowThrownObjectPhysicsDamage; public static ConfigEntry<bool> AllowSelfDamageFromOwnObjects; public static ConfigEntry<bool> AllowExplosiveValuableDamage; public static ConfigEntry<bool> AllowGrenadeDamage; public static ConfigEntry<bool> AllowMineDamage; public static ConfigEntry<bool> AllowExplosivePhysicsDamage; public static ConfigEntry<bool> EnableInLevel; public static ConfigEntry<bool> EnableInShop; public static ConfigEntry<bool> EnableInLobby; public static ConfigEntry<bool> EnableInArena; public static ConfigEntry<bool> EnableLogging; private static FieldInfo lastPlayerGrabbingField; private static FieldInfo playerNameField; public static HashSet<GameObject> ExplosiveValuableExplosions = new HashSet<GameObject>(); private void Awake() { //IL_02eb: Unknown result type (might be due to invalid IL or missing references) Instance = this; DisableFriendlyFire = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "DisableFriendlyFire", true, "Master switch - disable friendly fire completely"); AllowGunBulletDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Guns & Weapons", "AllowGunBulletDamage", false, "Allow bullets from guns to damage players"); AllowCartCannonDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Guns & Weapons", "AllowCartCannonDamage", false, "Allow cart cannon to damage players"); AllowCartLaserDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Guns & Weapons", "AllowCartLaserDamage", false, "Allow cart laser to damage players"); AllowWeaponExplosiveDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Guns & Weapons", "AllowWeaponExplosiveDamage", false, "Allow explosive damage from weapons (ducks, etc)"); AllowMeleeDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Melee Weapons", "AllowMeleeDamage", false, "Allow melee weapons to damage players"); AllowMeleePhysicsDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Melee Weapons", "AllowMeleePhysicsDamage", false, "Allow physics damage from swinging melee weapons"); AllowThrownObjectDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Thrown Objects", "AllowThrownObjectDamage", false, "Allow direct damage from thrown objects"); AllowThrownObjectPhysicsDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Thrown Objects", "AllowThrownObjectPhysicsDamage", false, "Allow physics collision damage from thrown objects"); AllowSelfDamageFromOwnObjects = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Thrown Objects", "AllowSelfDamageFromOwnObjects", true, "Allow players to damage themselves with their own thrown objects"); AllowExplosiveValuableDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("5. Explosives", "AllowExplosiveValuableDamage", true, "Allow explosive valuables to damage players"); AllowGrenadeDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("5. Explosives", "AllowGrenadeDamage", false, "Allow grenades to damage players"); AllowMineDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("5. Explosives", "AllowMineDamage", false, "Allow mines to damage players"); AllowExplosivePhysicsDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("5. Explosives", "AllowExplosivePhysicsDamage", true, "Allow physics damage from explosions (knockback/impact)"); EnableInLevel = ((BaseUnityPlugin)this).Config.Bind<bool>("6. Game Modes", "EnableInLevel", true, "Enable no friendly fire in levels"); EnableInShop = ((BaseUnityPlugin)this).Config.Bind<bool>("6. Game Modes", "EnableInShop", true, "Enable no friendly fire in shop"); EnableInLobby = ((BaseUnityPlugin)this).Config.Bind<bool>("6. Game Modes", "EnableInLobby", true, "Enable no friendly fire in lobby"); EnableInArena = ((BaseUnityPlugin)this).Config.Bind<bool>("6. Game Modes", "EnableInArena", false, "Enable no friendly fire in arena"); EnableLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("7. Debug", "EnableLogging", false, "Enable detailed logging"); lastPlayerGrabbingField = typeof(PhysGrabObject).GetField("lastPlayerGrabbing", BindingFlags.Instance | BindingFlags.NonPublic); playerNameField = typeof(PlayerAvatar).GetField("playerName", BindingFlags.Instance | BindingFlags.NonPublic); if (lastPlayerGrabbingField == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Failed to find 'lastPlayerGrabbing' field!"); } if (playerNameField == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Failed to find 'playerName' field!"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin No Friendly Fire v1.0.0 loaded!"); new Harmony("PxntxrezStudio.NoFriendlyFire").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"All patches applied!"); } public static bool IsEnabledInCurrentMode() { if (SemiFunc.RunIsLevel() && EnableInLevel.Value) { return true; } if (SemiFunc.RunIsShop() && EnableInShop.Value) { return true; } if (SemiFunc.RunIsLobby() && EnableInLobby.Value) { return true; } if (SemiFunc.RunIsArena() && EnableInArena.Value) { return true; } return false; } public static void Log(string message) { if (EnableLogging.Value) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[NFF] " + message)); } } public static PlayerAvatar GetLastPlayerGrabbing(PhysGrabObject physObj) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if (lastPlayerGrabbingField == null) { return null; } return (PlayerAvatar)lastPlayerGrabbingField.GetValue(physObj); } public static string GetPlayerName(PlayerAvatar player) { if (playerNameField == null || (Object)(object)player == (Object)null) { return "Unknown"; } return (string)playerNameField.GetValue(player); } } public class ExplosiveValuableMarker : MonoBehaviour { public ValuableObject sourceValuable; } public class GrenadeExplosionMarker : MonoBehaviour { public ItemGrenade sourceGrenade; } public class MineExplosionMarker : MonoBehaviour { public ItemMine sourceMine; } public class PlayerWeaponBulletMarker : MonoBehaviour { public bool isFromPlayerWeapon = true; } [HarmonyPatch(typeof(ParticleScriptExplosion), "Spawn")] public class ParticleScriptExplosion_Spawn_Patch { [CompilerGenerated] private sealed class <CleanupExplosionMarker>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float delay; public GameObject explosion; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CleanupExplosionMarker>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(delay); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)explosion != (Object)null) { NoFriendlyFirePlugin.ExplosiveValuableExplosions.Remove(explosion); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static void Postfix(ParticleScriptExplosion __instance, ParticlePrefabExplosion __result) { if ((Object)(object)__result == (Object)null) { return; } ValuableObject componentInParent = ((Component)__instance).GetComponentInParent<ValuableObject>(); if ((Object)(object)componentInParent != (Object)null) { ((Component)__result).gameObject.AddComponent<ExplosiveValuableMarker>().sourceValuable = componentInParent; NoFriendlyFirePlugin.ExplosiveValuableExplosions.Add(((Component)__result).gameObject); NoFriendlyFirePlugin.Log("Marked explosion from valuable: " + ((Object)((Component)componentInParent).gameObject).name); ((MonoBehaviour)__instance).StartCoroutine(CleanupExplosionMarker(((Component)__result).gameObject, 10f)); return; } ItemGrenade componentInParent2 = ((Component)__instance).GetComponentInParent<ItemGrenade>(); if ((Object)(object)componentInParent2 != (Object)null) { ((Component)__result).gameObject.AddComponent<GrenadeExplosionMarker>().sourceGrenade = componentInParent2; NoFriendlyFirePlugin.Log("Marked explosion from grenade: " + ((Object)((Component)componentInParent2).gameObject).name); return; } ItemMine componentInParent3 = ((Component)__instance).GetComponentInParent<ItemMine>(); if ((Object)(object)componentInParent3 != (Object)null) { ((Component)__result).gameObject.AddComponent<MineExplosionMarker>().sourceMine = componentInParent3; NoFriendlyFirePlugin.Log("Marked explosion from mine: " + ((Object)((Component)componentInParent3).gameObject).name); return; } PhysGrabObject componentInParent4 = ((Component)__instance).GetComponentInParent<PhysGrabObject>(); if ((Object)(object)componentInParent4 != (Object)null) { PlayerAvatar lastPlayerGrabbing = NoFriendlyFirePlugin.GetLastPlayerGrabbing(componentInParent4); if (componentInParent4.playerGrabbing.Count > 0 || (Object)(object)lastPlayerGrabbing != (Object)null) { ((Component)__result).gameObject.AddComponent<PlayerWeaponBulletMarker>(); NoFriendlyFirePlugin.Log("Marked explosion from player-thrown object: " + ((Object)((Component)componentInParent4).gameObject).name); } } } [IteratorStateMachine(typeof(<CleanupExplosionMarker>d__1))] private static IEnumerator CleanupExplosionMarker(GameObject explosion, float delay) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CleanupExplosionMarker>d__1(0) { explosion = explosion, delay = delay }; } } [HarmonyPatch(typeof(ItemGunBullet), "ActivateAll")] public class ItemGunBullet_ActivateAll_Patch { private static void Postfix(ItemGunBullet __instance) { if ((Object)(object)((Component)__instance).gameObject.GetComponent<PlayerWeaponBulletMarker>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<PlayerWeaponBulletMarker>(); NoFriendlyFirePlugin.Log("Marked bullet from weapon"); } } } [HarmonyPatch(typeof(HurtCollider), "PlayerHurt")] public class HurtCollider_PlayerHurt_Patch { private static bool Prefix(HurtCollider __instance, PlayerAvatar _player) { if (!NoFriendlyFirePlugin.IsEnabledInCurrentMode()) { NoFriendlyFirePlugin.Log("Mod disabled in current game mode - allowing all damage"); return true; } if (!NoFriendlyFirePlugin.DisableFriendlyFire.Value) { NoFriendlyFirePlugin.Log("Friendly fire enabled - allowing all damage"); return true; } if ((Object)(object)__instance.enemyHost != (Object)null) { NoFriendlyFirePlugin.Log("Enemy damage - allowed"); return true; } if ((Object)(object)((Component)__instance).GetComponentInParent<PlayerWeaponBulletMarker>() != (Object)null) { if (NoFriendlyFirePlugin.AllowGunBulletDamage.Value) { NoFriendlyFirePlugin.Log("Gun bullet damage - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Gun bullet damage - blocked by config"); return false; } if ((Object)(object)((Component)__instance).GetComponentInParent<ExplosiveValuableMarker>() != (Object)null) { if (NoFriendlyFirePlugin.AllowExplosiveValuableDamage.Value) { NoFriendlyFirePlugin.Log("Explosive valuable damage - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Explosive valuable damage - blocked by config"); return false; } if ((Object)(object)((Component)__instance).GetComponentInParent<GrenadeExplosionMarker>() != (Object)null) { if (NoFriendlyFirePlugin.AllowGrenadeDamage.Value) { NoFriendlyFirePlugin.Log("Grenade damage - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Grenade damage - blocked by config"); return false; } if ((Object)(object)((Component)__instance).GetComponentInParent<MineExplosionMarker>() != (Object)null) { if (NoFriendlyFirePlugin.AllowMineDamage.Value) { NoFriendlyFirePlugin.Log("Mine damage - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Mine damage - blocked by config"); return false; } if ((Object)(object)((Component)__instance).GetComponentInParent<ItemGun>() != (Object)null) { if (NoFriendlyFirePlugin.AllowWeaponExplosiveDamage.Value) { NoFriendlyFirePlugin.Log("Weapon explosive damage - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Weapon explosive damage - blocked by config"); return false; } if ((Object)(object)((Component)__instance).GetComponentInParent<ItemCartCannon>() != (Object)null) { if (NoFriendlyFirePlugin.AllowCartCannonDamage.Value) { NoFriendlyFirePlugin.Log("Cart cannon damage - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Cart cannon damage - blocked by config"); return false; } if ((Object)(object)((Component)__instance).GetComponentInParent<ItemCartLaser>() != (Object)null) { if (NoFriendlyFirePlugin.AllowCartLaserDamage.Value) { NoFriendlyFirePlugin.Log("Cart laser damage - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Cart laser damage - blocked by config"); return false; } if ((Object)(object)((Component)__instance).GetComponentInParent<ItemMelee>() != (Object)null) { if (NoFriendlyFirePlugin.AllowMeleeDamage.Value) { NoFriendlyFirePlugin.Log("Melee damage - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Melee damage - blocked by config"); return false; } PhysGrabObject component = ((Component)__instance).GetComponent<PhysGrabObject>(); if ((Object)(object)component != (Object)null) { PlayerAvatar lastPlayerGrabbing = NoFriendlyFirePlugin.GetLastPlayerGrabbing(component); if (component.playerGrabbing.Count > 0) { if (NoFriendlyFirePlugin.AllowThrownObjectDamage.Value) { NoFriendlyFirePlugin.Log("Held object damage - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Held object damage - blocked by config"); return false; } if ((Object)(object)lastPlayerGrabbing != (Object)null) { if ((Object)(object)lastPlayerGrabbing == (Object)(object)_player) { if (NoFriendlyFirePlugin.AllowSelfDamageFromOwnObjects.Value) { string playerName = NoFriendlyFirePlugin.GetPlayerName(_player); NoFriendlyFirePlugin.Log("Player " + playerName + " hit themselves - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Self damage from own object - blocked by config"); return false; } if (NoFriendlyFirePlugin.AllowThrownObjectDamage.Value) { string playerName2 = NoFriendlyFirePlugin.GetPlayerName(lastPlayerGrabbing); string playerName3 = NoFriendlyFirePlugin.GetPlayerName(_player); NoFriendlyFirePlugin.Log("Thrown object by " + playerName2 + " hit " + playerName3 + " - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Thrown object damage - blocked by config"); return false; } NoFriendlyFirePlugin.Log("Environmental object damage (never touched by players) - allowed"); return true; } NoFriendlyFirePlugin.Log("Environmental damage (pits, traps, etc) - allowed"); return true; } } [HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "OnCollisionStay")] public class PhysGrabObjectImpactDetector_OnCollisionStay_Patch { private static bool Prefix(PhysGrabObjectImpactDetector __instance, Collision collision) { if (!NoFriendlyFirePlugin.IsEnabledInCurrentMode()) { return true; } if (!NoFriendlyFirePlugin.DisableFriendlyFire.Value) { return true; } if (!((Component)collision.transform).CompareTag("Player") && !((Object)(object)((Component)collision.transform).GetComponent<PlayerTumble>() != (Object)null)) { return true; } if (__instance.isEnemy) { NoFriendlyFirePlugin.Log("Enemy physics collision - allowed"); return true; } if ((Object)(object)((Component)__instance).GetComponentInParent<PlayerWeaponBulletMarker>() != (Object)null) { if (NoFriendlyFirePlugin.AllowGunBulletDamage.Value) { NoFriendlyFirePlugin.Log("Gun bullet physics damage - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Gun bullet physics damage - blocked by config"); return false; } if ((Object)(object)((Component)__instance).GetComponentInParent<ExplosiveValuableMarker>() != (Object)null) { if (NoFriendlyFirePlugin.AllowExplosivePhysicsDamage.Value) { NoFriendlyFirePlugin.Log("Explosive physics damage - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Explosive physics damage - blocked by config"); return false; } if ((Object)(object)((Component)__instance).GetComponentInParent<GrenadeExplosionMarker>() != (Object)null) { if (NoFriendlyFirePlugin.AllowExplosivePhysicsDamage.Value) { NoFriendlyFirePlugin.Log("Grenade physics damage - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Grenade physics damage - blocked by config"); return false; } if ((Object)(object)((Component)__instance).GetComponentInParent<MineExplosionMarker>() != (Object)null) { if (NoFriendlyFirePlugin.AllowExplosivePhysicsDamage.Value) { NoFriendlyFirePlugin.Log("Mine physics damage - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Mine physics damage - blocked by config"); return false; } if ((Object)(object)((Component)__instance).GetComponentInParent<ItemMelee>() != (Object)null) { if (NoFriendlyFirePlugin.AllowMeleePhysicsDamage.Value) { NoFriendlyFirePlugin.Log("Melee physics damage - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Melee physics damage - blocked by config"); return false; } PhysGrabObject component = ((Component)__instance).GetComponent<PhysGrabObject>(); if ((Object)(object)component != (Object)null) { PlayerAvatar lastPlayerGrabbing = NoFriendlyFirePlugin.GetLastPlayerGrabbing(component); if (component.playerGrabbing.Count > 0) { if (NoFriendlyFirePlugin.AllowThrownObjectPhysicsDamage.Value) { NoFriendlyFirePlugin.Log("Physics: Held object collision - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Physics: Held object collision - blocked by config"); return false; } if ((Object)(object)lastPlayerGrabbing != (Object)null) { PlayerAvatar val = null; PlayerTumble component2 = ((Component)collision.transform).GetComponent<PlayerTumble>(); if ((Object)(object)component2 != (Object)null) { val = component2.playerAvatar; } else { val = ((Component)collision.transform).GetComponentInParent<PlayerAvatar>(); if ((Object)(object)val == (Object)null) { PlayerController componentInParent = ((Component)collision.transform).GetComponentInParent<PlayerController>(); if ((Object)(object)componentInParent != (Object)null) { val = componentInParent.playerAvatarScript; } } } if ((Object)(object)val != (Object)null) { if ((Object)(object)lastPlayerGrabbing == (Object)(object)val) { if (NoFriendlyFirePlugin.AllowSelfDamageFromOwnObjects.Value) { NoFriendlyFirePlugin.Log("Physics: Player hit themselves - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Physics: Self damage blocked by config"); return false; } if (NoFriendlyFirePlugin.AllowThrownObjectPhysicsDamage.Value) { NoFriendlyFirePlugin.Log("Physics: Thrown object collision - allowed by config"); return true; } NoFriendlyFirePlugin.Log("Physics: Thrown object collision - blocked by config"); return false; } } NoFriendlyFirePlugin.Log("Physics: Environmental object collision - allowed"); return true; } NoFriendlyFirePlugin.Log("Generic physics damage - allowed (environmental)"); return true; } } }