using System; using System.Collections; 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 HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [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("Omniscye")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.0.0.0")] [assembly: AssemblyInformationalVersion("2.0.0+7caf00520587bc4705fdf22c05a4ce546279ff19")] [assembly: AssemblyProduct("EmpressShopAPI")] [assembly: AssemblyTitle("EmpressShopAPI")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 Empress_ShopLoaderAPI { [BepInPlugin("com.Empress.ShopAPI", "Empress Shop Loader API", "2.0.0")] public class ShopLoaderPlugin : BaseUnityPlugin { internal class ShopEntry { public GameObject Prefab; public string ResourcePath; public ConfigEntry EnabledConfig; public Level Level; } internal static ShopLoaderPlugin Instance = null; internal static List RegisteredShops = new List(); internal static ConfigEntry IncludeVanillaShop = null; internal static List VanillaShopLevels = new List(); internal static bool VanillaShopLevelsCaptured; private void Awake() { Instance = this; IncludeVanillaShop = ((BaseUnityPlugin)this).Config.Bind("General", "IncludeVanillaShop", true, "Allow the base game shop to be selected."); IncludeVanillaShop.SettingChanged += delegate { ApplyShopLevelsToGame(); }; Harmony.CreateAndPatchAll(typeof(LevelGeneratorPatch), (string)null); Harmony.CreateAndPatchAll(typeof(RunManagerPatch), (string)null); } internal static void ApplyShopLevelsToGame() { RunManager instance = RunManager.instance; if (instance?.levelShop == null) { return; } CaptureVanillaShopLevels(instance); Level template = VanillaShopLevels.FirstOrDefault(); foreach (Level vanillaShopLevel in VanillaShopLevels) { if (IncludeVanillaShop.Value) { if (!instance.levelShop.Contains(vanillaShopLevel)) { instance.levelShop.Add(vanillaShopLevel); } } else { instance.levelShop.Remove(vanillaShopLevel); } } foreach (ShopEntry registeredShop in RegisteredShops) { EnsureShopLevel(registeredShop, template); if (registeredShop.EnabledConfig.Value) { if (!instance.levelShop.Contains(registeredShop.Level)) { instance.levelShop.Add(registeredShop.Level); } } else { instance.levelShop.Remove(registeredShop.Level); } } } internal static ShopEntry GetShopForLevel(Level level) { Level level2 = level; return RegisteredShops.FirstOrDefault((ShopEntry shop) => (Object)(object)shop.Level == (Object)(object)level2); } private static void CaptureVanillaShopLevels(RunManager rm) { if (!VanillaShopLevelsCaptured) { VanillaShopLevels = rm.levelShop.Where((Level level) => (Object)(object)level != (Object)null && GetShopForLevel(level) == null).ToList(); VanillaShopLevelsCaptured = true; } } private static void EnsureShopLevel(ShopEntry shop, Level template) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)shop.Level == (Object)null) { string text = CreateDisplayName(shop.ResourcePath); shop.Level = ScriptableObject.CreateInstance(); ((Object)shop.Level).name = "Level - " + text; shop.Level.NarrativeName = text; shop.Level.ModuleAmount = 1; shop.Level.PassageMaxAmount = 0; shop.Level.HasEnemies = false; shop.Level.ConnectObject = new PrefabRef(); shop.Level.BlockObject = new PrefabRef(); shop.Level.StartRooms = new List(); shop.Level.ModulesNormal1 = new List(); shop.Level.ModulesPassage1 = new List(); shop.Level.ModulesDeadEnd1 = new List(); shop.Level.ModulesExtraction1 = new List(); shop.Level.ModulesNormal2 = new List(); shop.Level.ModulesPassage2 = new List(); shop.Level.ModulesDeadEnd2 = new List(); shop.Level.ModulesExtraction2 = new List(); shop.Level.ModulesNormal3 = new List(); shop.Level.ModulesPassage3 = new List(); shop.Level.ModulesDeadEnd3 = new List(); shop.Level.ModulesExtraction3 = new List(); shop.Level.ModulesSpecialAmount = 0; shop.Level.ModulesSpecial = new List(); shop.Level.ValuablePresets = new List(); shop.Level.AmbiencePresets = new List(); } if (!((Object)(object)template == (Object)null)) { CopyLoadingGraphic(template, shop.Level, "LoadingGraphic01"); CopyLoadingGraphic(template, shop.Level, "LoadingGraphic02"); CopyLoadingGraphic(template, shop.Level, "LoadingGraphic03"); shop.Level.MusicPreset = template.MusicPreset; shop.Level.ConstantMusicPreset = template.ConstantMusicPreset; shop.Level.ValuablePresets = new List(template.ValuablePresets); shop.Level.AmbiencePresets = new List(template.AmbiencePresets); shop.Level.FogColor = template.FogColor; shop.Level.FogStartDistance = template.FogStartDistance; shop.Level.FogEndDistance = template.FogEndDistance; shop.Level.AmbientColor = template.AmbientColor; shop.Level.AmbientColorAdaptation = template.AmbientColorAdaptation; shop.Level.ColorTemperature = template.ColorTemperature; shop.Level.ColorFilter = template.ColorFilter; shop.Level.BloomIntensity = template.BloomIntensity; shop.Level.BloomThreshold = template.BloomThreshold; shop.Level.LensDistortionIntensity = template.LensDistortionIntensity; shop.Level.VignetteColor = template.VignetteColor; shop.Level.VignetteIntensity = template.VignetteIntensity; shop.Level.VignetteSmoothness = template.VignetteSmoothness; } } private static void CopyLoadingGraphic(Level source, Level target, string fieldName) { FieldInfo fieldInfo = AccessTools.Field(typeof(Level), fieldName); if (!(fieldInfo == null)) { object value = fieldInfo.GetValue(source); if (value != null) { fieldInfo.SetValue(target, value); } } } private static string CreateDisplayName(string resourcePath) { string text = resourcePath.Split('/').LastOrDefault() ?? resourcePath; text = text.Replace('_', ' ').Replace('-', ' ').Replace('.', ' '); List list = new List(); for (int i = 0; i < text.Length; i++) { char c = text[i]; if (i > 0 && char.IsUpper(c) && !char.IsWhiteSpace(text[i - 1]) && !char.IsUpper(text[i - 1])) { list.Add(' '); } list.Add(c); } return new string(list.ToArray()).Trim(); } } public static class ShopAPI { public static void RegisterShop(GameObject shopPrefab, string uniqueResourcePath) { string uniqueResourcePath2 = uniqueResourcePath; if (!((Object)(object)shopPrefab == (Object)null) && !((Object)(object)ShopLoaderPlugin.Instance == (Object)null)) { Object.DontDestroyOnLoad((Object)(object)shopPrefab); ((Object)shopPrefab).hideFlags = (HideFlags)32; ConfigEntry val = ((BaseUnityPlugin)ShopLoaderPlugin.Instance).Config.Bind("Registered Shops", uniqueResourcePath2, true, "Enable the " + uniqueResourcePath2 + " shop."); val.SettingChanged += delegate { ShopLoaderPlugin.ApplyShopLevelsToGame(); }; ShopLoaderPlugin.ShopEntry shopEntry = ShopLoaderPlugin.RegisteredShops.FirstOrDefault((ShopLoaderPlugin.ShopEntry shop) => shop.ResourcePath == uniqueResourcePath2); if (shopEntry != null) { shopEntry.Prefab = shopPrefab; shopEntry.EnabledConfig = val; ShopLoaderPlugin.ApplyShopLevelsToGame(); } else { ShopLoaderPlugin.RegisteredShops.Add(new ShopLoaderPlugin.ShopEntry { Prefab = shopPrefab, ResourcePath = uniqueResourcePath2, EnabledConfig = val }); ShopLoaderPlugin.ApplyShopLevelsToGame(); } } } } [HarmonyPatch(typeof(RunManager), "Awake")] public static class RunManagerPatch { private static void Postfix() { ShopLoaderPlugin.ApplyShopLevelsToGame(); } } [HarmonyPatch(typeof(LevelGenerator), "Start")] public static class LevelGeneratorPatch { private static readonly FieldRef ModuleRotationsRef = AccessTools.FieldRefAccess("ModuleRotations"); private static readonly FieldRef PrefabNameRef = AccessTools.FieldRefAccess("prefabName"); private static readonly FieldRef ResourcePathRef = AccessTools.FieldRefAccess("resourcePath"); private static readonly FieldInfo SingleplayerPoolField = AccessTools.Field(typeof(RunManager), "singleplayerPool"); private static readonly FieldInfo MultiplayerPoolField = AccessTools.Field(typeof(RunManager), "multiplayerPool"); private static readonly FieldInfo ResourceCacheField = AccessTools.Field(typeof(MultiplayerPool), "ResourceCache"); private static void Postfix(LevelGenerator __instance) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (!SemiFunc.RunIsShop()) { return; } RunManager instance = RunManager.instance; Level levelCurrent = instance.levelCurrent; if (!((Object)(object)levelCurrent == (Object)null)) { ShopLoaderPlugin.ShopEntry shopForLevel = ShopLoaderPlugin.GetShopForLevel(levelCurrent); if (shopForLevel != null && shopForLevel.EnabledConfig.Value) { AddToPool(SingleplayerPoolField?.GetValue(instance), shopForLevel.ResourcePath, shopForLevel.Prefab); AddToPool(ResourceCacheField?.GetValue(MultiplayerPoolField?.GetValue(instance)), shopForLevel.ResourcePath, shopForLevel.Prefab); ModuleRotationsRef.Invoke(__instance) = (Vector3[])(object)new Vector3[1] { Vector3.zero }; PrefabRef val = new PrefabRef(); PrefabNameRef.Invoke(val) = ((Object)shopForLevel.Prefab).name; ResourcePathRef.Invoke(val) = shopForLevel.ResourcePath; levelCurrent.ModuleAmount = 1; levelCurrent.PassageMaxAmount = 0; levelCurrent.ModulesSpecialAmount = 0; levelCurrent.StartRooms.Clear(); levelCurrent.StartRooms.Add(val); levelCurrent.ModulesNormal1.Clear(); levelCurrent.ModulesNormal2.Clear(); levelCurrent.ModulesNormal3.Clear(); levelCurrent.ModulesPassage1.Clear(); levelCurrent.ModulesPassage2.Clear(); levelCurrent.ModulesPassage3.Clear(); levelCurrent.ModulesDeadEnd1.Clear(); levelCurrent.ModulesDeadEnd2.Clear(); levelCurrent.ModulesDeadEnd3.Clear(); levelCurrent.ModulesExtraction1.Clear(); levelCurrent.ModulesExtraction2.Clear(); levelCurrent.ModulesExtraction3.Clear(); levelCurrent.ModulesSpecial.Clear(); } } } private static void AddToPool(object? poolObject, string resourcePath, GameObject prefab) { if (poolObject is IDictionary dictionary && !dictionary.Contains(resourcePath)) { dictionary.Add(resourcePath, prefab); } } } }