using 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)
{
}
}
}