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.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ShrineOfDisorder")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.5.0")]
[assembly: AssemblyInformationalVersion("1.1.5+6262c21f4e90eac30b9c107451b935ba9cef7043")]
[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_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Expected O, but got Unknown
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: 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_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: 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)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Expected O, but got Unknown
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 card 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;
for (int i = 0; i < categories.Length; i++)
{
Category cat = categories[i];
string arg = string.Join("\n ", cat.cards.Select((DirectorCard card) => $"{cat.name}.{((Object)card.spawnCard).name} weight: {card.selectionWeight}"));
Log.LogDebug($"{cat.name} weight: {cat.selectionWeight}\n {arg}");
}
}
private void Run_Start(orig_Start orig, Run self)
{
//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
orig.Invoke(self);
dropLists = new Dictionary<ItemTier, List<ItemDef>>
{
{
(ItemTier)0,
Run.instance.availableTier1DropList.ConvertAll(GetItemDef)
},
{
(ItemTier)1,
Run.instance.availableTier2DropList.ConvertAll(GetItemDef)
},
{
(ItemTier)2,
Run.instance.availableTier3DropList.ConvertAll(GetItemDef)
},
{
(ItemTier)3,
Run.instance.availableLunarItemDropList.ConvertAll(GetItemDef)
},
{
(ItemTier)4,
Run.instance.availableBossDropList.ConvertAll(GetItemDef)
},
{
(ItemTier)6,
Run.instance.availableVoidTier1DropList.ConvertAll(GetItemDef)
},
{
(ItemTier)7,
Run.instance.availableVoidTier2DropList.ConvertAll(GetItemDef)
},
{
(ItemTier)8,
Run.instance.availableVoidTier3DropList.ConvertAll(GetItemDef)
},
{
(ItemTier)9,
Run.instance.availableVoidBossDropList.ConvertAll(GetItemDef)
}
};
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)
{
if (config.shrineBehavior == 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_001f: Unknown result type (might be due to invalid IL or missing references)
foreach (ItemDef item in items)
{
inventory.ResetItem(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.GiveItem(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.GiveItem(val, count);
return val;
}
private Dictionary<ItemTier, Dictionary<ItemDef, int>> GetItemCounts(Inventory inventory)
{
//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_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: 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 itemCount = inventory.GetItemCount(item.itemIndex);
if (itemCount > 0)
{
if (!dictionary.ContainsKey(key))
{
dictionary.Add(key, new Dictionary<ItemDef, int>());
}
dictionary[key][item] = itemCount;
}
}
}
return dictionary;
}
private void RandomizeItems(Inventory self, Xoroshiro128Plus rng)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: 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_0085: 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_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: 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_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: 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_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: 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_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: 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_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
return ItemCatalog.GetItemDef(PickupCatalog.GetPickupDef(index).itemIndex);
}
}
}