Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of EgoPools v1.3.1
plugins/EgoPools.dll
Decompiled 4 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; } } }