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 ShrineOfDisorder v1.1.7
ShrineOfDisorder.dll
Decompiled 3 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; 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 Microsoft.CodeAnalysis; using On.RoR2; using R2API.Utils; using RoR2; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; [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("ShrineOfDisorder")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.1.5.0")] [assembly: AssemblyInformationalVersion("1.1.5+c6bf74dff62d80f925ba9f9fcd1f6d7e5fa22526")] [assembly: AssemblyProduct("ShrineOfDisorder")] [assembly: AssemblyTitle("ShrineOfDisorder")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.5.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 ShrineOfDisorder { public enum ShrineBehavior { RandomizeEachStack, RandomizeEachItem, SwapOneInventory, SwapAllInventories } public class ShrineConfig { public ConfigEntry<bool> lunarItemsCfg; public ConfigEntry<bool> bossItemsCfg; public ConfigEntry<bool> voidItemsCfg; public ConfigEntry<bool> voidBossItemsCfg; public ConfigEntry<ShrineBehavior> shrineBehaviorCfg; public ConfigEntry<bool> preserveStackCountCfg; public ConfigEntry<bool> onlyObtainedItemsCfg; public ConfigEntry<bool> shrineOnAllMapsCfg; public ConfigEntry<float> shrineSpawnMultiplierCfg; public bool lunarItems => lunarItemsCfg.Value; public bool bossItems => bossItemsCfg.Value; public bool voidItems => voidItemsCfg.Value; public bool voidBossItems => voidBossItemsCfg.Value; public ShrineBehavior shrineBehavior => shrineBehaviorCfg.Value; public bool preserveStackCount => preserveStackCountCfg.Value; public bool onlyObtainedItems => onlyObtainedItemsCfg.Value; public bool shrineOnAllMaps => shrineOnAllMapsCfg.Value; public float shrineSpawnMultiplier => shrineSpawnMultiplierCfg.Value; public ShrineConfig(ConfigFile cfg) { lunarItemsCfg = cfg.Bind<bool>("Items", "LunarItems", false, "Allow the shrine to randomize lunar items."); voidItemsCfg = cfg.Bind<bool>("Items", "VoidItems", false, "Allow the shrine to randomize void items."); bossItemsCfg = cfg.Bind<bool>("Items", "BossItems", false, "Allow the shrine to randomize boss items."); voidBossItemsCfg = cfg.Bind<bool>("Items", "VoidBossItems", false, "Allow the shrine to randomize void items."); shrineBehaviorCfg = cfg.Bind<ShrineBehavior>("Behavior", "ShrineBehavior", ShrineBehavior.RandomizeEachStack, "The behavior of the shrine. The inventory swapping behavior is only enabled for games with 2 or more players. Otherwise, the default behavior will be used."); preserveStackCountCfg = cfg.Bind<bool>("Behavior", "PreserveStackCount", true, "Preserve the number of unique stacks when using the RandomizeEachStack behavior. If disabled, the same item can be randomly selected for multiple stacks, effectively merging them."); onlyObtainedItemsCfg = cfg.Bind<bool>("Behavior", "OnlyObtainedItems", false, "When determining which items to give the player, only pick from the list of items that they already have in their inventory."); shrineOnAllMapsCfg = cfg.Bind<bool>("Behavior", "ShrineOnAllMaps", true, "Allow the shrine to spawn on all maps."); shrineSpawnMultiplierCfg = cfg.Bind<float>("Behavior", "ShrineSpawnMultiplier", 1f, "A multiplier on the shrine's spawn weight."); } } internal static class Log { internal static ManualLogSource _logSource; internal static void Init(ManualLogSource logSource) { _logSource = logSource; } internal static void LogDebug(object data) { _logSource.LogDebug(data); } internal static void LogError(object data) { _logSource.LogError(data); } internal static void LogFatal(object data) { _logSource.LogFatal(data); } internal static void LogInfo(object data) { _logSource.LogInfo(data); } internal static void LogMessage(object data) { _logSource.LogMessage(data); } internal static void LogWarning(object data) { _logSource.LogWarning(data); } } public static class DccsExtensions { public static int FindCategoryIndexByName_WorkingVersion(this DirectorCardCategorySelection dccs, string categoryName) { for (int i = 0; i < dccs.categories.Length; i++) { if (dccs.categories[i].name == categoryName) { return i; } } return -1; } public static DirectorCard GetCard(this DirectorCardCategorySelection dccs, int categoryIndex, string cardName) { DirectorCard[] cards = dccs.categories[categoryIndex].cards; foreach (DirectorCard val in cards) { if (((Object)val.spawnCard).name.StartsWith(cardName)) { return val; } } return null; } public static bool HasCard(this DirectorCardCategorySelection dccs, int categoryIndex, string cardName) { return dccs.GetCard(categoryIndex, cardName) != null; } public static int GetWeight(this DirectorCardCategorySelection dccs, int categoryIndex, string cardName) { return dccs.GetCard(categoryIndex, cardName)?.selectionWeight ?? (-1); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("cbrl.ShrineOfDisorder", "ShrineOfDisorder", "1.0.0")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class ShrineOfDisorder : BaseUnityPlugin { public const string PluginGUID = "cbrl.ShrineOfDisorder"; public const string PluginAuthor = "cbrl"; public const string PluginName = "ShrineOfDisorder"; public const string PluginVersion = "1.0.0"; public ShrineConfig config; private HashSet<ItemTier> enabledTiers = new HashSet<ItemTier>(); private static Dictionary<ItemTier, List<ItemDef>> dropLists; private readonly string[] bannedStageNames = new string[4] { "bazaar", "artifactworld", "mysteryspace", "limbo" }; private readonly string[] searchWeights = new string[3] { "iscShrineBoss", "iscShrineBlood", "iscShrineCombat" }; private const int defaultShrineWeight = 3; public void Awake() { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown Log.Init(((BaseUnityPlugin)this).Logger); config = new ShrineConfig(((BaseUnityPlugin)this).Config); enabledTiers.Add((ItemTier)0); enabledTiers.Add((ItemTier)1); enabledTiers.Add((ItemTier)2); if (config.lunarItems) { enabledTiers.Add((ItemTier)3); } if (config.bossItems) { enabledTiers.Add((ItemTier)4); } if (config.voidBossItems) { enabledTiers.Add((ItemTier)9); } if (config.voidItems) { enabledTiers.Add((ItemTier)6); enabledTiers.Add((ItemTier)7); enabledTiers.Add((ItemTier)8); } Run.Start += new hook_Start(Run_Start); Inventory.ShrineRestackInventory += (hook_ShrineRestackInventory)delegate(orig_ShrineRestackInventory orig, Inventory self, Xoroshiro128Plus rng) { RestackBehavior(self, rng); }; if (config.shrineOnAllMaps) { SceneDirector.onGenerateInteractableCardSelection += SceneDirector_onGenerateInteractableCardSelection; } Log.LogInfo("Awake done."); } private void SceneDirector_onGenerateInteractableCardSelection(SceneDirector director, DirectorCardCategorySelection selection) { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) try { if (!NetworkServer.active || bannedStageNames.Contains(((Object)Stage.instance).name)) { return; } int index = selection.FindCategoryIndexByName_WorkingVersion("Shrines"); if (index >= 0 && !selection.HasCard(index, "iscShrineRestack")) { int num = searchWeights.Select((string search) => selection.GetWeight(index, search)).FirstOrDefault((int weight) => weight != -1); if (num == 0) { num = 3; } DirectorCard val = new DirectorCard { spawnCard = Addressables.LoadAssetAsync<SpawnCard>((object)"RoR2/Base/ShrineRestack/iscShrineRestack.asset").WaitForCompletion(), selectionWeight = (int)((float)num * config.shrineSpawnMultiplier) }; selection.AddCard(index, val); Log.LogInfo($"Added Shrine of Order card (iscShrineRestack) with weight: {val.selectionWeight}"); } else if (index < 0) { Log.LogWarning("Could not find 'Shrines' category in stage " + ((Object)Stage.instance).name + ". The Shrine of Order will not be added to this stage."); } Category[] categories = selection.categories; foreach (Category val2 in categories) { Log.LogDebug($"Category: '{val2.name}'. Weight: {val2.selectionWeight}"); foreach (DirectorCard item in val2.cards.Where((DirectorCard card) => card != null && (Object)(object)card.spawnCard != (Object)null)) { Log.LogDebug($" Card: {((Object)item.spawnCard).name} weight: {item.selectionWeight}"); } } } catch (Exception ex) { Log.LogError("Error in SceneDirector_onGenerateInteractableCardSelection: " + ex.Message); Log.LogError("Stack trace:\n" + ex.StackTrace); } } private void Run_Start(orig_Start orig, Run self) { //IL_01f6: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self); Dictionary<ItemTier, List<ItemDef>> dictionary = new Dictionary<ItemTier, List<ItemDef>>(); dictionary.Add((ItemTier)0, Run.instance.availableTier1DropList.ConvertAll(GetItemDef)); dictionary.Add((ItemTier)1, Run.instance.availableTier2DropList.ConvertAll(GetItemDef)); dictionary.Add((ItemTier)2, Run.instance.availableTier3DropList.ConvertAll(GetItemDef)); dictionary.Add((ItemTier)3, Run.instance.availableLunarItemDropList.ConvertAll(GetItemDef)); dictionary.Add((ItemTier)4, Run.instance.availableBossDropList.ConvertAll(GetItemDef)); dictionary.Add((ItemTier)6, Run.instance.availableVoidTier1DropList.ConvertAll(GetItemDef)); dictionary.Add((ItemTier)7, Run.instance.availableVoidTier2DropList.ConvertAll(GetItemDef)); dictionary.Add((ItemTier)8, Run.instance.availableVoidTier3DropList.ConvertAll(GetItemDef)); dictionary.Add((ItemTier)9, Run.instance.availableVoidBossDropList.ConvertAll(GetItemDef)); dropLists = dictionary; foreach (KeyValuePair<ItemTier, List<ItemDef>> dropList in dropLists) { Log.LogDebug(string.Format("{0} Drop List: {1}", dropList.Key, string.Join(", ", dropList.Value))); } } private void Update() { } private void RestackBehavior(Inventory self, Xoroshiro128Plus rng) { if (!NetworkServer.active) { return; } if (NetworkUser.readOnlyInstancesList.Count < 2) { ShrineBehavior shrineBehavior = config.shrineBehavior; ShrineBehavior shrineBehavior2 = shrineBehavior; if (shrineBehavior2 == ShrineBehavior.RandomizeEachItem) { RandomizeItems(self, rng); } else { RandomizeItemStacks(self, rng); } return; } switch (config.shrineBehavior) { case ShrineBehavior.RandomizeEachItem: RandomizeItems(self, rng); break; case ShrineBehavior.RandomizeEachStack: RandomizeItemStacks(self, rng); break; case ShrineBehavior.SwapOneInventory: SwapOneInventory(self, rng); break; case ShrineBehavior.SwapAllInventories: SwapAllInventories(rng); break; default: RandomizeItemStacks(self, rng); break; } } private static void ResetItems(Inventory inventory, List<ItemDef> items) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) foreach (ItemDef item in items) { inventory.ResetItemPermanent(item); inventory.itemAcquisitionOrder.Remove(item.itemIndex); } } private static Dictionary<ItemDef, int> GiveRandomItems(Inventory inventory, List<ItemDef> dropList, int count, Xoroshiro128Plus rng) { Dictionary<ItemDef, int> dictionary = new Dictionary<ItemDef, int>(); for (int i = 0; i < count; i++) { ItemDef val = rng.NextElementUniform<ItemDef>(dropList); inventory.GiveItemPermanent(val, 1); if (!dictionary.ContainsKey(val)) { dictionary[val] = 0; } dictionary[val]++; } return dictionary; } private static ItemDef GiveRandomStack(Inventory inventory, List<ItemDef> dropList, int count, Xoroshiro128Plus rng) { ItemDef val = rng.NextElementUniform<ItemDef>(dropList); inventory.GiveItemPermanent(val, count); return val; } private Dictionary<ItemTier, Dictionary<ItemDef, int>> GetItemCounts(Inventory inventory) { //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) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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) Dictionary<ItemTier, Dictionary<ItemDef, int>> dictionary = new Dictionary<ItemTier, Dictionary<ItemDef, int>>(); foreach (ItemTier key in dropLists.Keys) { foreach (ItemDef item in dropLists[key]) { int itemCountPermanent = inventory.GetItemCountPermanent(item.itemIndex); if (itemCountPermanent > 0) { if (!dictionary.ContainsKey(key)) { dictionary.Add(key, new Dictionary<ItemDef, int>()); } dictionary[key][item] = itemCountPermanent; } } } return dictionary; } private void RandomizeItems(Inventory self, Xoroshiro128Plus rng) { //IL_001a: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) Dictionary<ItemTier, Dictionary<ItemDef, int>> itemCounts = GetItemCounts(self); foreach (ItemTier enabledTier in enabledTiers) { ResetItems(self, dropLists[enabledTier]); } ((NetworkBehaviour)self).SetDirtyBit(8u); foreach (KeyValuePair<ItemTier, Dictionary<ItemDef, int>> item in itemCounts.Where((KeyValuePair<ItemTier, Dictionary<ItemDef, int>> pair) => enabledTiers.Contains(pair.Key))) { List<ItemDef> dropList = (config.onlyObtainedItems ? item.Value.Keys.ToList() : dropLists[item.Key]); int count = item.Value.Sum((KeyValuePair<ItemDef, int> pair) => pair.Value); GiveRandomItems(self, dropList, count, rng); } } private void RandomizeItemStacks(Inventory self, Xoroshiro128Plus rng) { //IL_001a: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) Dictionary<ItemTier, Dictionary<ItemDef, int>> itemCounts = GetItemCounts(self); foreach (ItemTier enabledTier in enabledTiers) { ResetItems(self, dropLists[enabledTier]); } ((NetworkBehaviour)self).SetDirtyBit(8u); foreach (KeyValuePair<ItemTier, Dictionary<ItemDef, int>> item2 in itemCounts.Where((KeyValuePair<ItemTier, Dictionary<ItemDef, int>> pair) => enabledTiers.Contains(pair.Key))) { ItemTier key = item2.Key; Dictionary<ItemDef, int> value = item2.Value; List<ItemDef> list = null; list = ((!config.preserveStackCount) ? (config.onlyObtainedItems ? value.Keys.ToList() : dropLists[key]) : new List<ItemDef>(config.onlyObtainedItems ? value.Keys.ToList() : dropLists[key])); foreach (KeyValuePair<ItemDef, int> item3 in value) { ItemDef item = GiveRandomStack(self, list, item3.Value, rng); if (config.preserveStackCount) { list.Remove(item); } } } } private void SwapOneInventory(Inventory self, Xoroshiro128Plus rng) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown List<Inventory> list = PlayerCharacterMasterController.instances.Select((PlayerCharacterMasterController user) => user.master.inventory).ToList(); Inventory val = new Inventory(); Inventory val2 = rng.NextElementUniform<Inventory>(list); val.CopyItemsFrom(self); self.CopyItemsFrom(val2); val2.CopyItemsFrom(val); } private void SwapAllInventories(Xoroshiro128Plus rng) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown List<Inventory> list = PlayerCharacterMasterController.instances.Select((PlayerCharacterMasterController user) => user.master.inventory).ToList(); Inventory val = new Inventory(); IOrderedEnumerable<Inventory> second = list.OrderBy((Inventory n) => rng.Next()); foreach (var (val2, val3) in list.Zip(second, (Inventory a, Inventory b) => (a, b))) { val.CopyItemsFrom(val2); val2.CopyItemsFrom(val3); val3.CopyItemsFrom(val); } } private static ItemDef GetItemDef(PickupIndex index) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return ItemCatalog.GetItemDef(PickupCatalog.GetPickupDef(index).itemIndex); } } }