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 EgoPools v1.3.1
plugins/EgoPools.dll
Decompiled 9 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using RoR2; using RoR2.UI; using UnityEngine; using UnityEngine.Networking; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("EgoPools")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("EgoPools")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("ad0dfd7e-da05-41fe-9133-6134e468d380")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace EgoPools; [BepInPlugin("com.yourname.egopools", "Ego Pools", "1.3.1")] public class EgoPoolPlugin : BaseUnityPlugin { private sealed class PoolObjectiveTracker : ObjectiveTracker { private string cached; protected override string GenerateString() { if (cached == null) { cached = "☼ A Cleansing Pool has manifested this stage. ☼"; } return cached; } protected override bool IsDirty() { return false; } } [CompilerGenerated] private sealed class <DelayedPoolMessage>d__18 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public int stageIndex; private float <waited>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedPoolMessage>d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <waited>5__2 = 0f; <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; case 1: <>1__state = -1; <waited>5__2 += 0.5f; break; case 2: <>1__state = -1; <waited>5__2 += 0.5f; if ((Object)(object)Run.instance == (Object)null || Run.instance.stageClearCount != stageIndex) { return false; } break; } if (<waited>5__2 < 12f) { bool flag = false; foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances) { object obj; if (instance == null) { obj = null; } else { CharacterMaster master = instance.master; obj = ((master != null) ? master.GetBody() : null); } CharacterBody val = (CharacterBody)obj; if (Object.op_Implicit((Object)(object)val) && val.HasBuff(Buffs.HiddenInvincibility)) { flag = true; break; } } if (flag) { <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 2; return true; } } if ((Object)(object)Run.instance == (Object)null || Run.instance.stageClearCount != stageIndex) { return false; } if (!AnyPoolExists()) { return false; } Chat.AddMessage("<color=#00ffff><size=20>✦ A Cleansing Pool has manifested this stage. ✦</size></color>"); 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 int lastHandledStage = -1; private static bool poolSpawnedThisStage = false; private static EgoPoolPlugin Instance; private static ConfigEntry<float> SpawnChance; private static ConfigEntry<int> MinLunarsRequired; private static ConfigEntry<bool> DisableNaturalPools; private static ConfigEntry<int> MaxForcedPerStage; private static ConfigEntry<int> MinStageNumber; private static ConfigEntry<bool> AlwaysShowMessage; public void Awake() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown Instance = this; SpawnChance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SpawnChance", 1f, new ConfigDescription("Chance (0.0–1.0) for the mod to spawn a Cleansing Pool when conditions are met.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); MinLunarsRequired = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MinLunarsRequired", 0, new ConfigDescription("Total lunar items required across all players before the mod will spawn pools.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), Array.Empty<object>())); DisableNaturalPools = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisableNaturalPools", false, "If true, remove naturally spawned Cleansing Pools so only the mod controls spawns."); MaxForcedPerStage = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxForcedPerStage", 1, new ConfigDescription("Maximum number of pools the mod will try to spawn per stage.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 5), Array.Empty<object>())); MinStageNumber = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MinStageNumber", 1, new ConfigDescription("Do not spawn pools before this stage number (1 = first stage).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>())); AlwaysShowMessage = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AlwaysShowMessage", false, "If true, the chat message will display whenever a pool exists this stage, even without Egocentrism."); ObjectivePanelController.collectObjectiveSources += OnCollectObjectiveSources; SceneDirector.onPostPopulateSceneServer += OnPostPopulateScene; } private void OnDestroy() { ObjectivePanelController.collectObjectiveSources -= OnCollectObjectiveSources; SceneDirector.onPostPopulateSceneServer -= OnPostPopulateScene; if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private static void OnCollectObjectiveSources(CharacterMaster master, List<ObjectiveSourceDescriptor> dest) { //IL_0014: 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) if (poolSpawnedThisStage && !((Object)(object)master == (Object)null)) { dest.Add(new ObjectiveSourceDescriptor { master = master, objectiveType = typeof(PoolObjectiveTracker), source = null }); } } private static bool AnyPlayerHasEgocentrism() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances) { object obj; if (instance == null) { obj = null; } else { CharacterMaster master = instance.master; obj = ((master != null) ? master.inventory : null); } Inventory val = (Inventory)obj; if ((Object)(object)val == (Object)null) { continue; } try { if (val.GetItemCount(Items.LunarSun.itemIndex) > 0) { return true; } } catch { } } return false; } private static int TotalLunarCountAcrossPlayers() { int num = 0; foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances) { object obj; if (instance == null) { obj = null; } else { CharacterMaster master = instance.master; obj = ((master != null) ? master.inventory : null); } Inventory val = (Inventory)obj; if (!((Object)(object)val == (Object)null)) { num += val.GetTotalItemCountOfTier((ItemTier)3); } } return num; } private static bool AnyPoolExists() { return Object.FindObjectsOfType<PurchaseInteraction>().Any((PurchaseInteraction pi) => Object.op_Implicit((Object)(object)pi) && ((Object)pi).name.IndexOf("ShrineCleanse", StringComparison.OrdinalIgnoreCase) >= 0); } private static int RemoveAllPools() { int num = 0; PurchaseInteraction[] array = Object.FindObjectsOfType<PurchaseInteraction>(); foreach (PurchaseInteraction val in array) { if (Object.op_Implicit((Object)(object)val) && ((Object)val).name.IndexOf("ShrineCleanse", StringComparison.OrdinalIgnoreCase) >= 0) { Object.Destroy((Object)(object)((Component)((Component)val).transform.root).gameObject); num++; } } return num; } private static void OnPostPopulateScene(SceneDirector dir) { //IL_001f: 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) if (!NetworkServer.active || (Object)(object)Run.instance == (Object)null || (Object)(object)dir == (Object)null) { return; } Scene activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name.Equals("bazaar", StringComparison.OrdinalIgnoreCase)) { return; } int stageClearCount = Run.instance.stageClearCount; int num = stageClearCount + 1; if (stageClearCount == lastHandledStage) { return; } lastHandledStage = stageClearCount; poolSpawnedThisStage = false; bool flag = AnyPlayerHasEgocentrism(); int num2 = TotalLunarCountAcrossPlayers(); if (DisableNaturalPools.Value) { RemoveAllPools(); } else if (AnyPoolExists()) { if ((flag || AlwaysShowMessage.Value) && (Object)(object)Instance != (Object)null) { ((MonoBehaviour)Instance).StartCoroutine(DelayedPoolMessage(stageClearCount)); } return; } if (!flag || num < Mathf.Max(1, MinStageNumber.Value) || num2 < Mathf.Max(0, MinLunarsRequired.Value)) { return; } int num3 = Mathf.Max(0, MaxForcedPerStage.Value); float num4 = Mathf.Clamp01(SpawnChance.Value); int num5 = 0; for (int i = 0; i < num3; i++) { if ((!(num4 < 1f) || !(Random.value > num4)) && TrySpawnOneVanillaPool()) { num5++; } } if (num5 > 0) { poolSpawnedThisStage = true; if ((Object)(object)Instance != (Object)null) { ((MonoBehaviour)Instance).StartCoroutine(DelayedPoolMessage(stageClearCount)); } } } [IteratorStateMachine(typeof(<DelayedPoolMessage>d__18))] private static IEnumerator DelayedPoolMessage(int stageIndex) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedPoolMessage>d__18(0) { stageIndex = stageIndex }; } private static bool TrySpawnOneVanillaPool() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) //IL_0032: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown try { InteractableSpawnCard val = Resources.Load<InteractableSpawnCard>("SpawnCards/InteractableSpawnCard/iscShrineCleanse"); if (!Object.op_Implicit((Object)(object)val)) { Debug.LogWarning((object)"[Ego Pools] Could not load iscShrineCleanse."); return false; } DirectorPlacementRule val2 = new DirectorPlacementRule { placementMode = (PlacementMode)4 }; Xoroshiro128Plus val3 = new Xoroshiro128Plus(((Object)(object)Run.instance != (Object)null) ? Run.instance.seed : ((ulong)DateTime.UtcNow.Ticks)); DirectorSpawnRequest val4 = new DirectorSpawnRequest((SpawnCard)(object)val, val2, val3); if (!Object.op_Implicit((Object)(object)DirectorCore.instance.TrySpawnObject(val4))) { Debug.LogWarning((object)"[Ego Pools] TrySpawnObject returned null."); return false; } return true; } catch (Exception arg) { Debug.LogWarning((object)$"[Ego Pools] Spawn error: {arg}"); return false; } } }