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 ImmortalSnailFork v0.1.1
ImmortalSnail.dll
Decompiled 13 hours agousing System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using GameNetcodeStuff; using LethalLib.Modules; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ImmortalSnail")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Escape from an incredibly slow snail that instantly kills you upon contact.")] [assembly: AssemblyFileVersion("0.7.4.0")] [assembly: AssemblyInformationalVersion("0.7.4")] [assembly: AssemblyProduct("ImmortalSnail")] [assembly: AssemblyTitle("ImmortalSnail")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.7.4.0")] [module: UnverifiableCode] [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 ImmortalSnail { [BepInPlugin("dev.idjut.SnailFork", "ImmortalSnailFork", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string modGUID = "dev.idjut.SnailFork"; public const string modName = "ImmortalSnailFork"; public const string modVersion = "0.1.0"; public static AssetBundle bundle; public static ConfigEntry<float> configSize; public static ConfigEntry<float> configSpeed; public static ConfigEntry<int> configMaxSnails; public static ConfigEntry<int> configRarity; public static ConfigEntry<bool> configGoOutside; public static ConfigEntry<bool> configEnterShip; public static ConfigEntry<bool> configGary; public static ConfigEntry<bool> configCanExplode; public static ConfigEntry<bool> configExplosionKillOthers; public static ConfigEntry<bool> configShowTarget; public static ConfigEntry<bool> configKillAnyPlayer; private void Awake() { //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading a mod by swAAn\n\n _\n ,-\"\" \"\".\n ,' ____ `.\n ,' ,' `. `._\n (`. _..--.._ ,' ,' \\ \\\n (`-.\\ .-\"\" \"\"' / ( d _b\n (`._ `-\"\" ,._ ( `-( \\\n <_ ` ( <`< \\ `-._\\\n <`- (__< < :\n (__ (_<_< ;\n `~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"\n __,._\n / _ \\\n | 6 \\ \\ oo\n \\___/ .|__||\n __,..=\" ^ . , \" ,\\\n<.__________________/"); NetcodePatcher(); configSize = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Scale", 100f, "The size of the snail."); configSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Speed", 0.5f, "The speed of the snail."); configMaxSnails = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Max Snails", 4, "The maximum number of snails that can spawn in a round."); configRarity = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Rarity", 80, "Honestly not sure exactly how this works, but a higher \"Rarity\" will make the snail more likely to spawn."); configGoOutside = ((BaseUnityPlugin)this).Config.Bind<bool>("Pathing", "Can Go Outside", true, "If enabled, allows the snail to exit the factory and chase players outside."); configEnterShip = ((BaseUnityPlugin)this).Config.Bind<bool>("Pathing", "Can Enter Ship", true, "If enabled, allows the snail to target players that are in the ship room."); configGary = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "Gary Mode", false, "Snail is reskinned to look like Spongebob's faithful pet snail, Gary!"); configCanExplode = ((BaseUnityPlugin)this).Config.Bind<bool>("Explosions", "Can Explode", true, "Snail creates an explosion when killing player."); configExplosionKillOthers = ((BaseUnityPlugin)this).Config.Bind<bool>("Explosions", "Explosions Kill Other Players", false, "If enabled, snail explosion will kill other players in explosion radius."); configShowTarget = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show Target on Scan", true, "If enabled, shows the targeted player when scanned."); configKillAnyPlayer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Kill Any Player", false, "If enabled, the snail will kill ANY player it comes in contact with. The snail targeting system will work the same way."); string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); bundle = AssetBundle.LoadFromFile(Path.Combine(directoryName, "immortalsnail")); if ((Object)(object)bundle == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Failed to load asset bundle."); return; } EnemyType val = bundle.LoadAsset<EnemyType>("ImmortalSnail.EnemyType"); if ((Object)(object)val == (Object)null || (Object)(object)val.enemyPrefab == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Snail Failed to load properly."); return; } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Configuring Snail."); if (configGary.Value) { val.enemyPrefab = bundle.LoadAsset<GameObject>("gary_snail.prefab"); } val.enemyPrefab.AddComponent<SnailAI>(); ((EnemyAI)val.enemyPrefab.GetComponent<SnailAI>()).enemyType = val; val.enemyPrefab.GetComponentInChildren<EnemyAICollisionDetect>().mainScript = (EnemyAI)(object)val.enemyPrefab.GetComponent<SnailAI>(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Applying User-Defined Configuration Settings"); Transform transform = val.enemyPrefab.transform; transform.localScale *= configSize.Value / 100f; val.enemyPrefab.GetComponent<NavMeshAgent>().speed = configSpeed.Value; val.MaxCount = configMaxSnails.Value; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Registering Snail as Enemy"); LevelTypes val2 = (LevelTypes)(-1); SpawnType val3 = (SpawnType)0; TerminalNode val4 = ScriptableObject.CreateInstance<TerminalNode>(); val4.displayText = "The Immortal Snail\n\nDanger level: 50%\n\nThe following is a recitation of the events that transpired on [REDACTED] to the best of my memory. This is my experience with the entity and I swear to do right by the company and describe it as best I can. There were four of us out on a routine scrap-job, absolutely nothing was out of the ordinary before [REDACTED] spotted it. We laughed our asses off. Half the things in here will make you soil your hazmat suit on the spot, and then there's this thing, moving at, well you know. We had our fun, but ultimately moved on and forgot about the thing. Me and the boys went our separate ways and decided to rendezvous at the ship. Three of us returned, but [REDACTED] was missing. We all decided to go back in and investigate. The place was silent. We thought things might have taken a turn for the worse, so we decided to split up and either guide [REDACTED] back to ship, or at least recover his remains. As often happens, I found myself lost. Turning the corners of this elaborate labyrinth, I finally found what was left of [REDACTED]. It was unusual, I'd never seen a coworker left in such a state. Reality struck as I turned a corner and found another comrade waiting on the ground for me, and then another. I made the heartbreaking decision to leave my comrades behind. I was almost free, when I find staring at me from the front entrance the same snail I'd seen before. I saw red. I beat that thing as ruthlessly as I could (with my shovel), entirely imprinting my rage on its presumably fragile shell. I expected to find a small puddle where the snail once stood, but the it was unaffected. It moved towards me at the same agitating pace it did before. The aftermath is a blur. Sometimes I wonder if I even made it back to the ship at all.\n\n"; val4.clearPreviousText = true; val4.maxCharactersToType = 2000; val4.creatureName = "The Immortal Snail"; val4.creatureFileID = 1738; TerminalKeyword val5 = TerminalUtils.CreateTerminalKeyword("snail", false, (CompatibleNoun[])null, val4, (TerminalKeyword)null, false); NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab); Enemies.RegisterEnemy(val, configRarity.Value, val2, val3, val4, val5); } private static void NetcodePatcher() { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); Type[] array = types; foreach (Type type in array) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo in array2) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { methodInfo.Invoke(null, null); } } } } } internal class SnailAI : EnemyAI { private float timeAtLastUsingEntrance; private float timeOfLastExplosion; public override void Start() { base.enemyHP = 1; ((EnemyAI)this).Start(); RefreshTargetServerRpc(); } public override void OnCollideWithPlayer(Collider other) { PlayerControllerB component = ((Component)other).gameObject.GetComponent<PlayerControllerB>(); if ((Object)(object)component == (Object)null) { Debug.LogWarning((object)"Snail collided with a player, but player was null."); return; } ((EnemyAI)this).OnCollideWithPlayer(other); if ((Object.op_Implicit((Object)(object)base.targetPlayer) && component.playerClientId == base.targetPlayer.playerClientId) || Plugin.configKillAnyPlayer.Value) { KillPlayerServerRpc((int)component.playerClientId); } } public override void DoAIInterval() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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) if ((Object)(object)base.targetPlayer == (Object)null || base.targetPlayer.isPlayerDead || !base.targetPlayer.isPlayerControlled || (base.targetPlayer.isInHangarShipRoom && !Plugin.configEnterShip.Value) || (!base.targetPlayer.isInsideFactory && !Plugin.configGoOutside.Value)) { RefreshTargetServerRpc(); } if (base.movingTowardsTargetPlayer) { if (isInTargetPlayerArea()) { base.destination = RoundManager.Instance.GetNavMeshPosition(((Component)base.targetPlayer).transform.position, RoundManager.Instance.navHit, 2.7f, -1); } else { SetDestinationToOtherArea(); } base.agent.SetDestination(base.destination); base.agent.isStopped = false; } else { base.agent.isStopped = true; } } private void SetDestinationToOtherArea() { //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00c1: Unknown result type (might be due to invalid IL or missing references) Transform nearbyExitTransform = getNearbyExitTransform(); if (Object.op_Implicit((Object)(object)nearbyExitTransform) && Time.realtimeSinceStartup - timeAtLastUsingEntrance > 3f) { if (((NetworkBehaviour)this).IsOwner) { ((Behaviour)base.agent).enabled = false; ((Component)this).transform.position = nearbyExitTransform.position; ((Behaviour)base.agent).enabled = true; } else { ((Component)this).transform.position = nearbyExitTransform.position; } timeAtLastUsingEntrance = Time.realtimeSinceStartup; base.isOutside = !base.isOutside; base.destination = RoundManager.Instance.GetNavMeshPosition(((Component)base.targetPlayer).transform.position, RoundManager.Instance.navHit, 2.7f, -1); } else { base.destination = RoundManager.Instance.GetNavMeshPosition(getNearestExitTransform().position, RoundManager.Instance.navHit, 2.7f, -1); } } [ServerRpc(RequireOwnership = false)] public void RefreshTargetServerRpc() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; PlayerControllerB val = null; float num = float.MaxValue; for (int i = 0; i < allPlayerScripts.Length; i++) { if (!((Object)(object)allPlayerScripts[i] == (Object)null) && !allPlayerScripts[i].isPlayerDead && allPlayerScripts[i].isPlayerControlled && (!allPlayerScripts[i].isInHangarShipRoom || Plugin.configEnterShip.Value) && (allPlayerScripts[i].isInsideFactory || Plugin.configGoOutside.Value)) { float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)allPlayerScripts[i]).transform.position); if (num2 < num) { val = allPlayerScripts[i]; num = num2; } } } if ((Object)(object)val == (Object)null) { base.targetPlayer = null; base.movingTowardsTargetPlayer = false; RefreshTargetClientRpc(-1); return; } ((EnemyAI)this).SetMovingTowardsTargetPlayer(val); if (Plugin.configShowTarget.Value) { ((Component)this).gameObject.GetComponentInChildren<ScanNodeProperties>().subText = "Current Target : " + val.playerUsername; } RefreshTargetClientRpc((int)val.playerClientId); } [ClientRpc] public void RefreshTargetClientRpc(int playerId) { if (playerId == -1) { base.targetPlayer = null; base.movingTowardsTargetPlayer = false; return; } PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerId]; ((EnemyAI)this).SetMovingTowardsTargetPlayer(val); if (Plugin.configShowTarget.Value) { ((Component)this).gameObject.GetComponentInChildren<ScanNodeProperties>().subText = "Current Target: " + val.playerUsername; } } [ServerRpc(RequireOwnership = false)] public void KillPlayerServerRpc(int playerId) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (Plugin.configCanExplode.Value) { Explode(playerId, Plugin.configExplosionKillOthers.Value); } else { StartOfRound.Instance.allPlayerScripts[playerId].KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 0, default(Vector3), false); } KillPlayerClientRpc(playerId, Plugin.configCanExplode.Value, Plugin.configExplosionKillOthers.Value); } [ClientRpc] public void KillPlayerClientRpc(int playerId, bool explode, bool killOthers) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (explode) { Explode(playerId, killOthers); } else { StartOfRound.Instance.allPlayerScripts[playerId].KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 0, default(Vector3), false); } } private Transform getNearbyExitTransform() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) EntranceTeleport[] array = Object.FindObjectsOfType<EntranceTeleport>(false); EntranceTeleport[] array2 = array; foreach (EntranceTeleport val in array2) { if (!(Vector3.Distance(((Component)this).transform.position, val.entrancePoint.position) < 1f)) { continue; } EntranceTeleport[] array3 = array; foreach (EntranceTeleport val2 in array3) { if (val2.isEntranceToBuilding != val.isEntranceToBuilding && val2.entranceId == val.entranceId) { return val2.entrancePoint; } } } return null; } private Transform getNearestExitTransform() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) EntranceTeleport[] array = Object.FindObjectsOfType<EntranceTeleport>(false); Transform result = null; float num = float.MaxValue; EntranceTeleport[] array2 = array; foreach (EntranceTeleport val in array2) { float num2 = Vector3.Distance(((Component)this).transform.position, val.entrancePoint.position); if (num2 < num) { result = val.entrancePoint; num = num2; } } return result; } private bool isInTargetPlayerArea() { return (base.targetPlayer.isInsideFactory && !base.isOutside) || (!base.targetPlayer.isInsideFactory && base.isOutside); } private void Explode(int playerId, bool killOthers) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_0092: 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) if (!(Time.realtimeSinceStartup - timeOfLastExplosion <= 0.5f)) { if (killOthers) { Landmine.SpawnExplosion(((Component)this).transform.position, true, 5.7f, 6.4f, 50, 0f, (GameObject)null, false); } else { Landmine.SpawnExplosion(((Component)this).transform.position, true, 0f, 0f, 50, 0f, (GameObject)null, false); StartOfRound.Instance.allPlayerScripts[playerId].KillPlayer(GetBodyVelocity(playerId), true, (CauseOfDeath)3, 0, default(Vector3), false); } timeOfLastExplosion = Time.realtimeSinceStartup; } } private Vector3 GetBodyVelocity(int playerId) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)StartOfRound.Instance.allPlayerScripts[playerId].gameplayCamera).transform.position; position -= ((Component)this).transform.position; position *= 80f; return position / Vector3.Distance(((Component)StartOfRound.Instance.allPlayerScripts[playerId].gameplayCamera).transform.position, ((Component)this).transform.position); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "ImmortalSnail"; public const string PLUGIN_NAME = "ImmortalSnail"; public const string PLUGIN_VERSION = "0.7.4"; } }