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