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 HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [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("REPO_Shop_Items_in_Level")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.7.21.0")] [assembly: AssemblyInformationalVersion("1.7.21+dcb58465e4081c92a79e034f149783b3cd72f762")] [assembly: AssemblyProduct("Shop Items spawn in Level")] [assembly: AssemblyTitle("REPO_Shop_Items_in_Level")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.7.21.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 REPO_Shop_Items_in_Level { public class UsedVolumeTracker : MonoBehaviour { } public class SpawnedItemTracker : MonoBehaviour { } [BepInPlugin("REPO_Shop_Items_in_Level", "Shop Items spawn in Level", "1.7.21")] [BepInProcess("REPO.exe")] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(EnemyParent), "Despawn")] private class DespawnPatch { private static int GetEnemySpawnValuableCurrent(EnemyParent enemyParent) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown Enemy val = (Enemy)(AccessTools.Field(typeof(EnemyParent), "Enemy")?.GetValue(enemyParent)); if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)("Failed to access Enemy from EnemyParent " + ((Object)enemyParent).name + ".")); return 0; } EnemyHealth val2 = (EnemyHealth)(AccessTools.Field(typeof(Enemy), "Health")?.GetValue(val)); if ((Object)(object)val2 == (Object)null) { Logger.LogWarning((object)("Failed to access Health from Enemy " + ((Object)enemyParent).name + ".")); return 0; } FieldInfo fieldInfo = AccessTools.Field(typeof(EnemyHealth), "spawnValuableCurrent"); if (fieldInfo == null) { Logger.LogWarning((object)("Field spawnValuableCurrent not found in EnemyHealth for enemy " + ((Object)enemyParent).name + ".")); return 0; } return (int)fieldInfo.GetValue(val2); } private static void Prefix(EnemyParent __instance, out int __state) { __state = GetEnemySpawnValuableCurrent(__instance); } private static void Postfix(EnemyParent __instance, int __state) { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.IsMasterClientOrSingleplayer() || !SpawnHealthPacksFromEnemies.Value || GetEnemySpawnValuableCurrent(__instance) <= __state) { return; } Logger.LogInfo((object)("Enemy " + ((Object)__instance).name + " spawned a valuable!")); Item item; if (Random.Range(0f, 100f) >= HealthPackDropChance.Value) { Logger.LogInfo((object)$"Health pack spawn roll failed (chance: {HealthPackDropChance.Value}%)"); } else if (GetRandomItemOfType((itemType)8, out item)) { Enemy val = (Enemy)(AccessTools.Field(typeof(EnemyParent), "Enemy")?.GetValue(__instance)); Transform val2 = val.CustomValuableSpawnTransform; if (!Object.op_Implicit((Object)(object)val2)) { val2 = val.CenterTransform; } Vector3 position = val2.position + new Vector3(0f, 1f, 0f); Quaternion identity = Quaternion.identity; SpawnItem(item, position, identity); } } } [HarmonyPatch] private class ValuableDirector_Spawn_Patch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(ValuableDirector), "Spawn", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(ValuableDirector), "SpawnValuable", (Type[])null, (Type[])null); } [HarmonyPrefix] private static void Prefix(object[] __args) { ValuableVolume val = __args.OfType().FirstOrDefault(); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.AddComponent(); } } } internal static ManualLogSource Logger; internal static ConfigEntry SpawnUpgradeItems; internal static ConfigEntry MapHideUpgradeItems; internal static ConfigEntry UpgradeItemSpawnChance; internal static ConfigEntry UseShopPriceForUpgradeItems; internal static ConfigEntry SpawnDroneItems; internal static ConfigEntry MapHideDroneItems; internal static ConfigEntry DroneItemSpawnChance; internal static ConfigEntry UseShopPriceForDroneItems; internal static ConfigEntry SpawnHealthPacksFromEnemies; internal static ConfigEntry HealthPackDropChance; internal static List> DisallowedItems; private Harmony harmony; public static Plugin Instance { get; private set; } private void Awake() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Expected O, but got Unknown //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Expected O, but got Unknown //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Expected O, but got Unknown //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Expected O, but got Unknown //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; Logger.LogInfo((object)"Plugin REPO_Shop_Items_in_Level is loaded!"); harmony = new Harmony("REPO_Shop_Items_in_Level"); harmony.PatchAll(typeof(Plugin)); harmony.PatchAll(typeof(DespawnPatch)); Logger.LogInfo((object)"Harmony patches applied!"); SpawnUpgradeItems = ((BaseUnityPlugin)this).Config.Bind("UpgradeItems", "SpawnUpgradeItems", true, new ConfigDescription("Whether upgrade items can spawn in levels", (AcceptableValueBase)null, Array.Empty())); MapHideUpgradeItems = ((BaseUnityPlugin)this).Config.Bind("UpgradeItems", "MapHideShopUpgradeItems", true, new ConfigDescription("(Client) Whether upgrade items are hidden on the map", (AcceptableValueBase)null, Array.Empty())); UpgradeItemSpawnChance = ((BaseUnityPlugin)this).Config.Bind("UpgradeItems", "UpgradeItemSpawnChance", 2.5f, new ConfigDescription("% chance for an upgrade item to spawn", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); UseShopPriceForUpgradeItems = ((BaseUnityPlugin)this).Config.Bind("UpgradeItems", "UseShopPriceForItemSelection", true, new ConfigDescription("If ON: Cheaper upgrade items appear more often. If OFF: All upgrade items have equal chance.", (AcceptableValueBase)null, Array.Empty())); SpawnDroneItems = ((BaseUnityPlugin)this).Config.Bind("DroneItems", "SpawnDroneItems", true, new ConfigDescription("Whether drone items can spawn in levels", (AcceptableValueBase)null, Array.Empty())); MapHideDroneItems = ((BaseUnityPlugin)this).Config.Bind("DroneItems", "MapHideDroneItems", true, new ConfigDescription("(Client) Whether drone items are hidden on the map", (AcceptableValueBase)null, Array.Empty())); DroneItemSpawnChance = ((BaseUnityPlugin)this).Config.Bind("DroneItems", "DroneItemsSpawnChance", 0.95f, new ConfigDescription("% chance for a drone item to spawn", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); UseShopPriceForDroneItems = ((BaseUnityPlugin)this).Config.Bind("DroneItems", "UseShopPriceForItemSelection", true, new ConfigDescription("If ON: Cheaper drone items appear more often. If OFF: All drone items have equal chance.", (AcceptableValueBase)null, Array.Empty())); SpawnHealthPacksFromEnemies = ((BaseUnityPlugin)this).Config.Bind("HealthPacks", "SpawnHealthPacksFromEnemies", true, new ConfigDescription("Whether health packs can spawn when enemies die", (AcceptableValueBase)null, Array.Empty())); HealthPackDropChance = ((BaseUnityPlugin)this).Config.Bind("HealthPacks", "HealthPackDropChance", 100f, new ConfigDescription("% chance for a health pack to spawn when an enemy dies", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); } [HarmonyPatch(typeof(MainMenuOpen), "Awake")] [HarmonyPostfix] public static void MainMenuOpen_Awake_Postfix(StatsManager __instance) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Invalid comparison between Unknown and I4 //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown if (DisallowedItems != null) { return; } Logger.LogInfo((object)"Initializing disallowed items list"); DisallowedItems = new List>(); foreach (Item value in StatsManager.instance.itemDictionary.Values) { itemType itemType = value.itemType; itemType val = itemType; ConfigEntry val2; if ((int)val != 0) { if ((int)val != 3) { continue; } val2 = ((BaseUnityPlugin)Instance).Config.Bind("AllowedItems Upgrades", ((Object)value).name, true, new ConfigDescription("Whether this upgrade item can spawn in levels", (AcceptableValueBase)null, Array.Empty())); } else { val2 = ((BaseUnityPlugin)Instance).Config.Bind("AllowedItems Drones", ((Object)value).name, true, new ConfigDescription("Whether this drone item can spawn in levels", (AcceptableValueBase)null, Array.Empty())); } if (!val2.Value) { DisallowedItems.Add(val2); } } } private static bool GetRandomItemOfType(itemType itemType, out Item item) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Invalid comparison between Unknown and I4 //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Invalid comparison between Unknown and I4 //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) item = null; List list = (from i in StatsManager.instance.itemDictionary.Values where i.itemType == itemType where (Object)(object)i.value != (Object)null && i.value.valueMin > 0f where !DisallowedItems.Any((ConfigEntry cfg) => ((ConfigEntryBase)cfg).Definition.Key == ((Object)i).name && !cfg.Value) select i).ToList(); if (list.Count == 0) { Logger.LogWarning((object)$"GetRandomItemOfType: No valid items found for type {itemType} after filtering."); return false; } bool flag = false; itemType val = itemType; itemType val2 = val; if ((int)val2 != 0) { if ((int)val2 != 3) { if ((int)val2 == 8) { flag = true; } } else { flag = UseShopPriceForUpgradeItems.Value; } } else { flag = UseShopPriceForDroneItems.Value; } if (flag) { float num = list.Sum((Item i) => 1f / i.value.valueMin); if (num <= 0f || float.IsNaN(num) || float.IsInfinity(num)) { Logger.LogWarning((object)($"GetRandomItemOfType: Invalid total weight {num} for type {itemType}. " + "This may indicate an issue with item values or weights.")); return false; } float num2 = Random.Range(0f, num); foreach (Item item2 in list) { float num3 = 1f / item2.value.valueMin; num2 -= num3; if (num2 <= 0f) { item = item2; break; } } if ((Object)(object)item == (Object)null) { Logger.LogWarning((object)($"GetRandomItemOfType: Weighted selection loop for type {itemType} completed unexpectedly " + "without selecting an item. This may indicate a precision issue.")); return false; } float num4 = 1f / item.value.valueMin / num * 100f; Logger.LogInfo((object)$"Selecting {((Object)item).name} at a chance of {num4:F2}% compared to others of type {itemType} (based on shop price)"); } else { int index = Random.Range(0, list.Count); item = list[index]; Logger.LogInfo((object)$"Selecting {((Object)item).name} at a chance of {100f / (float)list.Count:F2}% compared to others of type {itemType} (equal chance)"); } return true; } private static bool HasValuablePropSwitch(ValuableVolume volume) { return (Object)(object)((Component)((Component)volume).transform).GetComponentInParent() != (Object)null; } private static bool ShouldSpawnItem(ValuableVolume volume, out itemType? itemType, out bool hasSwitch) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 itemType = null; hasSwitch = HasValuablePropSwitch(volume); if (hasSwitch) { return false; } Type volumeType = volume.VolumeType; Type val = volumeType; if ((int)val != 0) { if ((int)val == 1) { if (!SpawnDroneItems.Value) { return false; } itemType = (itemType)0; return Random.Range(0f, 100f) <= DroneItemSpawnChance.Value; } return false; } if (!SpawnUpgradeItems.Value) { return false; } itemType = (itemType)3; return Random.Range(0f, 100f) <= UpgradeItemSpawnChance.Value; } private static GameObject SpawnItem(Item item, Vector3 position, Quaternion rotation) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) GameObject val = ((!SemiFunc.IsMultiplayer()) ? Object.Instantiate(item.prefab.Prefab, position, rotation) : PhotonNetwork.Instantiate("Items/" + ((Object)item).name, position, rotation, (byte)0, (object[])null)); val.AddComponent(); return val; } private static bool RandomItemSpawn(ValuableVolume volume) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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) if (!ShouldSpawnItem(volume, out var itemType, out var _)) { return false; } if (!itemType.HasValue) { return false; } if (!GetRandomItemOfType(itemType.Value, out var item)) { return false; } SpawnItem(item, ((Component)volume).transform.position, ((Component)volume).transform.rotation); return true; } [HarmonyPatch(typeof(ValuableDirector), "VolumesAndSwitchSetup")] [HarmonyPostfix] public static void ValuableDirector_VolumesAndSwitchSetup_Postfix(ValuableDirector __instance) { if (!SemiFunc.RunIsLevel()) { return; } IEnumerable enumerable = from volume in Object.FindObjectsOfType(false).ToList() where (Object)(object)((Component)volume).gameObject.GetComponent() == (Object)null where !HasValuablePropSwitch(volume) select volume; Logger.LogInfo((object)$"Found {enumerable.Count()} potential volumes to spawn items in"); Logger.LogInfo((object)$"Upgrade item spawn chance: {UpgradeItemSpawnChance.Value}% on {enumerable.Where((ValuableVolume volume) => (int)volume.VolumeType == 0).Count()} tiny volumes"); Logger.LogInfo((object)$"Drone item spawn chance: {DroneItemSpawnChance.Value}% on {enumerable.Where((ValuableVolume volume) => (int)volume.VolumeType == 1).Count()} small volumes"); int num = 0; foreach (ValuableVolume item in enumerable) { if (RandomItemSpawn(item)) { num++; } } Logger.LogInfo((object)$"Spawned {num} items in total"); } [HarmonyPatch(typeof(Map), "AddCustom")] [HarmonyPostfix] public static void Map_AddCustom_Postfix(MapCustom mapCustom) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 ItemAttributes val = default(ItemAttributes); if (!SemiFunc.RunIsLevel() || !((Component)mapCustom).gameObject.TryGetComponent(ref val)) { return; } itemType itemType = val.item.itemType; itemType val2 = itemType; if ((int)val2 != 0) { if ((int)val2 != 3 || !MapHideUpgradeItems.Value) { return; } } else if (!MapHideDroneItems.Value) { return; } ((Component)mapCustom.mapCustomEntity).gameObject.SetActive(false); } [HarmonyPatch(typeof(ExtractionPoint), "DestroyAllPhysObjectsInHaulList")] [HarmonyPostfix] public static void ExtractionPoint_DestroyAllPhysObjectsInHaulList_Postfix(ExtractionPoint __instance) { if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } List list = (from tracker in Object.FindObjectsOfType(false) select ((Component)tracker).gameObject).ToList(); foreach (GameObject item in list) { RoomVolumeCheck component = item.GetComponent(); if (!((Object)(object)component == (Object)null) && component.CurrentRooms.Any((RoomVolume room) => room.Extraction)) { ItemAttributes component2 = item.GetComponent(); Logger.LogInfo((object)("Adding item " + component2.itemAssetName + " to purchased items")); StatsManager.instance.ItemPurchase(component2.itemAssetName); Logger.LogInfo((object)("Destroying spawned item " + ((Object)item).name + " in extraction point " + ((Object)__instance).name)); item.GetComponent().DestroyPhysGrabObject(); } } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "REPO_Shop_Items_in_Level"; public const string PLUGIN_NAME = "Shop Items spawn in Level"; public const string PLUGIN_VERSION = "1.7.21"; } }