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 TripleProjectiles v1.0.0
TripleProjectiles.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 System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [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("TripleProjectiles")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+24662fadeff5955ed4ca55468e1621967bbb8e1a")] [assembly: AssemblyProduct("TripleProjectiles")] [assembly: AssemblyTitle("TripleProjectiles")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.0.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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; } } } [BepInPlugin("com.adwamogus.tripleprojectiles", "Triple Projectiles", "1.0.0")] public class TripleProjectilesPlugin : BaseUnityPlugin { [CompilerGenerated] private sealed class <CloneProjectile>d__13 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public GameObject gameObject; public string sourceMethod; private ProjectileCloneMarker <marker>5__1; private List<ProjectileCloneMarker> <projectileClones>5__2; private float <currentAngle>5__3; private float <angleStepSize>5__4; private Rigidbody2D <originalRB>5__5; private int <i>5__6; private GameObject <newObject>5__7; private ProjectileCloneMarker <newMarker>5__8; private string[] <>s__9; private int <>s__10; private string <keyword>5__11; private Vector2 <originalVelocity>5__12; private int <i>5__13; private ProjectileCloneMarker <clone>5__14; private Rigidbody2D <rb>5__15; private float <angle>5__16; private Vector2 <newVel>5__17; private float <baseAngle>5__18; private int <i>5__19; private ProjectileCloneMarker <clone>5__20; private float <angle>5__21; private Exception <ex>5__22; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CloneProjectile>d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <marker>5__1 = null; <projectileClones>5__2 = null; <originalRB>5__5 = null; <newObject>5__7 = null; <newMarker>5__8 = null; <>s__9 = null; <keyword>5__11 = null; <clone>5__14 = null; <rb>5__15 = null; <clone>5__20 = null; <ex>5__22 = null; <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.05f); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)gameObject == (Object)null) { Log("[" + sourceMethod + "] object is null"); return false; } if ((Object)(object)gameObject.GetComponent<ProjectileCloneMarker>() != (Object)null || Multiplier.Value <= 1) { return false; } Log("[" + sourceMethod + "] Cloning " + ((Object)gameObject).name); try { <marker>5__1 = gameObject.AddComponent<ProjectileCloneMarker>(); <marker>5__1.isOriginal = true; <projectileClones>5__2 = new List<ProjectileCloneMarker>(); <projectileClones>5__2.Add(<marker>5__1); <i>5__6 = 0; while (<i>5__6 < Multiplier.Value - 1) { <newObject>5__7 = Object.Instantiate<GameObject>(((Component)<marker>5__1).gameObject, ((Component)<marker>5__1).transform.position, ((Component)<marker>5__1).transform.rotation, ((Component)<marker>5__1).transform.parent); <newMarker>5__8 = <newObject>5__7.GetComponent<ProjectileCloneMarker>(); if ((Object)(object)<newMarker>5__8 == (Object)null) { <newMarker>5__8 = <newObject>5__7.AddComponent<ProjectileCloneMarker>(); } <newMarker>5__8.isOriginal = false; <projectileClones>5__2.Add(<newMarker>5__8); <newObject>5__7 = null; <newMarker>5__8 = null; <i>5__6++; } <>s__9 = TPBlacklist.RigidbodyIgnore; for (<>s__10 = 0; <>s__10 < <>s__9.Length; <>s__10++) { <keyword>5__11 = <>s__9[<>s__10]; if (((Object)gameObject).name.Contains(<keyword>5__11)) { return false; } <keyword>5__11 = null; } <>s__9 = null; <currentAngle>5__3 = -(MaxSpread.Value / 2); <angleStepSize>5__4 = MaxSpread.Value / (Multiplier.Value - 1); <originalRB>5__5 = ((Component)<marker>5__1).GetComponent<Rigidbody2D>(); if ((Object)(object)<originalRB>5__5 != (Object)null) { <originalVelocity>5__12 = <originalRB>5__5.linearVelocity; <i>5__13 = 0; while (<i>5__13 < <projectileClones>5__2.Count) { <clone>5__14 = <projectileClones>5__2[<i>5__13]; <rb>5__15 = ((Component)<clone>5__14).GetComponent<Rigidbody2D>(); if (!((Object)(object)<rb>5__15 == (Object)null)) { <angle>5__16 = <currentAngle>5__3 + <angleStepSize>5__4 * (float)<i>5__13; <newVel>5__17 = Rotate(<originalVelocity>5__12, <angle>5__16); <rb>5__15.linearVelocity = <newVel>5__17; ((Component)<clone>5__14).transform.rotation = Quaternion.Euler(0f, 0f, Mathf.Atan2(<newVel>5__17.y, <newVel>5__17.x) * 57.29578f); <clone>5__14 = null; <rb>5__15 = null; } <i>5__13++; } } else if (!OnlyClonePhysicsProjectiles.Value) { Quaternion rotation = ((Component)<marker>5__1).transform.rotation; <baseAngle>5__18 = ((Quaternion)(ref rotation)).eulerAngles.z; <i>5__19 = 0; while (<i>5__19 < <projectileClones>5__2.Count) { <clone>5__20 = <projectileClones>5__2[<i>5__19]; <angle>5__21 = <currentAngle>5__3 + <angleStepSize>5__4 * (float)<i>5__19; ((Component)<clone>5__20).transform.rotation = Quaternion.Euler(0f, 0f, <baseAngle>5__18 + <angle>5__21); <clone>5__20 = null; <i>5__19++; } } <marker>5__1 = null; <projectileClones>5__2 = null; <originalRB>5__5 = null; } catch (Exception ex) { <ex>5__22 = ex; Log(<ex>5__22.ToString()); } 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(); } } public static string Name = "Triple Projectiles"; public static ConfigEntry<int> Multiplier; public static ConfigEntry<int> MaxSpread; public static ConfigEntry<bool> debugLog; public static ConfigEntry<bool> debugLogDestroy; public static ConfigEntry<bool> EnablePlayerProjectiles; public static ConfigEntry<bool> OnlyClonePhysicsProjectiles; private static ManualLogSource logger; private static List<string> blacklisted = new List<string>(); private void Awake() { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Plugin " + Name + " has loaded!")); logger = ((BaseUnityPlugin)this).Logger; Multiplier = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Multiplier", 3, "Projectile * Multiplier = the amount of projectiles spawned"); MaxSpread = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxSpread", 60, "Spreads the clones in MaxSpread degrees"); EnablePlayerProjectiles = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnablePlayerProjectiles", false, "Enables player projectiles (tools)"); OnlyClonePhysicsProjectiles = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "OnlyClonePhysicsProjectiles", false, "Disables cloning of static objects like flame walls or tentacles in the lost lace fight."); debugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLog", false, "For development"); debugLogDestroy = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "debugLogDestroy", false, "For development"); Harmony.CreateAndPatchAll(typeof(TripleProjectilesPlugin), (string)null); } public static void Log(string msg) { bool flag = true; if (logger != null) { logger.LogInfo((object)msg); return; } logger = Logger.CreateLogSource(Name); logger.LogInfo((object)msg); } [HarmonyPostfix] [HarmonyPatch(typeof(ObjectPool), "Spawn", new Type[] { typeof(GameObject), typeof(Transform), typeof(Vector3), typeof(Quaternion) })] private static void SpawnPostfix(GameObject __result) { try { FilterObject(__result, "ObjectPool.Spawn"); } catch (Exception ex) { Log(ex.ToString()); } } private static void FilterObject(GameObject __result, string sourceMethod) { string[] generalBlacklist = TPBlacklist.GeneralBlacklist; foreach (string text in generalBlacklist) { if (((Object)__result).name.Contains(text)) { if (debugLog.Value && !blacklisted.Contains(((Object)__result).name)) { blacklisted.Add(((Object)__result).name); Log("[GeneralBlacklist] " + ((Object)__result).name + " was blacklisted by keyword " + text); } return; } } if (!EnablePlayerProjectiles.Value) { string[] playerBlacklist = TPBlacklist.PlayerBlacklist; foreach (string text2 in playerBlacklist) { if (((Object)__result).name.Contains(text2)) { if (debugLog.Value && !blacklisted.Contains(((Object)__result).name)) { blacklisted.Add(((Object)__result).name); Log("[PlayerBlacklist] " + ((Object)__result).name + " was blacklisted by keyword " + text2); } return; } } } ((MonoBehaviour)CoroutineRunner.Instance).StartCoroutine(CloneProjectile(__result, sourceMethod)); } [IteratorStateMachine(typeof(<CloneProjectile>d__13))] private static IEnumerator CloneProjectile(GameObject gameObject, string sourceMethod) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CloneProjectile>d__13(0) { gameObject = gameObject, sourceMethod = sourceMethod }; } private static Vector2 Rotate(Vector2 v, float degrees) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) //IL_0030: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) float num = degrees * (MathF.PI / 180f); float num2 = Mathf.Sin(num); float num3 = Mathf.Cos(num); return new Vector2(v.x * num3 - v.y * num2, v.x * num2 + v.y * num3); } private static void LogAllComponents(GameObject gameObject) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown Log("--- Components on " + ((Object)gameObject).name + " ---"); Component[] components = gameObject.GetComponents<Component>(); Component[] array = components; foreach (Component val in array) { if ((Object)(object)val != (Object)null) { Log(((object)val).GetType().Name); } else { Log("Missing (null) Component found!"); } } foreach (Transform item in gameObject.transform) { Transform val2 = item; Log("[" + ((Object)gameObject).name + "] has child: " + ((Object)((Component)val2).gameObject).name); components = ((Component)val2).GetComponents<Component>(); Log("--- Components on " + ((Object)val2).name + " ---"); Component[] array2 = components; foreach (Component val3 in array2) { if ((Object)(object)val3 != (Object)null) { Log(((object)val3).GetType().Name); } else { Log("Missing (null) Component found!"); } } } } } public class ProjectileCloneMarker : MonoBehaviour { public bool isOriginal = false; private void OnDisable() { if (isOriginal) { if (TripleProjectilesPlugin.debugLogDestroy.Value) { TripleProjectilesPlugin.Log("[Original] Destroying Component"); } Object.Destroy((Object)(object)this); } else { if (TripleProjectilesPlugin.debugLogDestroy.Value) { TripleProjectilesPlugin.Log("[Clone] Destroying GameObject"); } Object.Destroy((Object)(object)((Component)this).gameObject); } } } public class CoroutineRunner : MonoBehaviour { private static CoroutineRunner? _instance; public static CoroutineRunner Instance { get { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("TPCoroutineRunner"); _instance = val.AddComponent<CoroutineRunner>(); Object.DontDestroyOnLoad((Object)(object)val); } return _instance; } } } public static class TPBlacklist { public static readonly string[] GeneralBlacklist = new string[42] { "Audio", "Effect", "thread_spines", "Silk_Recharge_glow", "Silk Chunk", "hornet", "Spatter White", "Splash", "Dripper White", "Prompt", "Impact", "Strike Nail", "Geo Get", "blood", "Pt", "Threaded Corpse Steam", "Shell Shard", "Hit Particles", "standard_health_hit", "Block Hit v2", "Geo", "Dust Land Small R", "White Flash", "HP Up Particles", "dive_in", "Hit Flash Black", "Wanderer_Precision_strike", "double health hit", "Hornet", "Conch Projectile", "first_weaver_tele_flash", "Thread Sphere Slash", "Block Hit Dull", "water_maggot_follow", "hero_maggoted_effect", "Block Hit Silent", "hunter_combo_damage_effect", "Boss Death Antic", "Boss Death Explosion", "cog_dancer_parry_flash", "Hit Lines Generic", "Collectable Get Msg" }; public static readonly string[] PlayerBlacklist = new string[6] { "Drill Down Black Rock Hit", "Clockwork Hatchling", "Weaver Bomb", "Tool", "Hero Wisp Fireball", "Revenge Crystal Hornet" }; public static readonly string[] RigidbodyIgnore = new string[0]; } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } }