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 ThreeChoiceChests v1.0.0
ThreeChoiceChests/ThreeChoiceChests.dll
Decompiled 10 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; 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.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using On.RoR2; 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("ExamplePlugin")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ExamplePlugin")] [assembly: AssemblyTitle("ExamplePlugin")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 ExamplePlugin { internal static class Log { private static ManualLogSource _logSource; internal static void Init(ManualLogSource logSource) { _logSource = logSource; } private static string Format(object data, string file, int line) { string fileName = Path.GetFileName(file); return $"[{fileName}:{line}] {data}"; } internal static void Debug(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0) { _logSource.LogDebug((object)Format(data, file, line)); } internal static void Error(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0) { _logSource.LogError((object)Format(data, file, line)); } internal static void Fatal(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0) { _logSource.LogFatal((object)Format(data, file, line)); } internal static void Info(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0) { _logSource.LogInfo((object)Format(data, file, line)); } internal static void Message(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0) { _logSource.LogMessage((object)Format(data, file, line)); } internal static void Warning(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0) { _logSource.LogWarning((object)Format(data, file, line)); } } } namespace ThreeChoiceChests { [BepInPlugin("com.local.threechoicechests", "ThreeChoiceChests", "1.0.0")] public class ThreeChoiceChestsPlugin : BaseUnityPlugin { [HarmonyPatch] private static class CreatePickupDropletPatch { private static MethodBase TargetMethod() { return typeof(PickupDropletController).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo method) { if (method.Name != "CreatePickupDroplet") { return false; } ParameterInfo[] parameters = method.GetParameters(); return parameters.Length == 3 && parameters[0].ParameterType == typeof(CreatePickupInfo) && parameters[1].ParameterType == typeof(Vector3) && parameters[2].ParameterType == typeof(Vector3); }); } private static bool Prefix(ref CreatePickupInfo __0, Vector3 __1, Vector3 __2) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) bool flag = TryCreateThreeChoicePicker(ref __0, __1); return !flag; } } [CompilerGenerated] private static class <>O { public static hook_OnInteractionBegin <0>__PurchaseInteraction_OnInteractionBegin; } public const string PluginGUID = "com.local.threechoicechests"; public const string PluginName = "ThreeChoiceChests"; public const string PluginVersion = "1.0.0"; private Harmony harmony; private static GameObject commandCubePrefab; private static readonly Queue<PendingChoice> pendingChoices = new Queue<PendingChoice>(); private static bool pickerActive; private static ThreeChoiceChestsPlugin instance; private void Awake() { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown instance = this; MarkChest("RoR2/Base/Chest1/Chest1.prefab", ThreeChoiceChestCategory.General); MarkChest("RoR2/Base/CategoryChest/CategoryChestDamage.prefab", ThreeChoiceChestCategory.Damage); MarkChest("RoR2/Base/CategoryChest/CategoryChestHealing.prefab", ThreeChoiceChestCategory.Healing); MarkChest("RoR2/Base/CategoryChest/CategoryChestUtility.prefab", ThreeChoiceChestCategory.Utility); MarkChest("RoR2/DLC1/CategoryChest2/CategoryChest2Damage Variant.prefab", ThreeChoiceChestCategory.Damage); MarkChest("RoR2/DLC1/CategoryChest2/CategoryChest2Healing Variant.prefab", ThreeChoiceChestCategory.Healing); MarkChest("RoR2/DLC1/CategoryChest2/CategoryChest2Utility Variant.prefab", ThreeChoiceChestCategory.Utility); MarkChest("RoR2/Base/Chest2/Chest2.prefab", ThreeChoiceChestCategory.General); MarkChest("RoR2/Base/GoldChest/GoldChest.prefab", ThreeChoiceChestCategory.General); MarkChest("RoR2/Base/Chest1StealthedVariant/Chest1StealthedVariant.prefab", ThreeChoiceChestCategory.General); MarkChest("RoR2/Base/EquipmentBarrel/EquipmentBarrel.prefab", ThreeChoiceChestCategory.General); commandCubePrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Command/CommandCube.prefab").WaitForCompletion(); if ((Object)(object)commandCubePrefab == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Could not load CommandCube prefab."); return; } object obj = <>O.<0>__PurchaseInteraction_OnInteractionBegin; if (obj == null) { hook_OnInteractionBegin val = PurchaseInteraction_OnInteractionBegin; <>O.<0>__PurchaseInteraction_OnInteractionBegin = val; obj = (object)val; } PurchaseInteraction.OnInteractionBegin += (hook_OnInteractionBegin)obj; harmony = new Harmony("com.local.threechoicechests"); harmony.PatchAll(typeof(CreatePickupDropletPatch)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ThreeChoiceChests 1.0.0 loaded."); } private void OnDestroy() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown object obj = <>O.<0>__PurchaseInteraction_OnInteractionBegin; if (obj == null) { hook_OnInteractionBegin val = PurchaseInteraction_OnInteractionBegin; <>O.<0>__PurchaseInteraction_OnInteractionBegin = val; obj = (object)val; } PurchaseInteraction.OnInteractionBegin -= (hook_OnInteractionBegin)obj; Harmony obj2 = harmony; if (obj2 != null) { obj2.UnpatchSelf(); } pendingChoices.Clear(); pickerActive = false; instance = null; } private void MarkChest(string address, ThreeChoiceChestCategory category) { //IL_0002: 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) GameObject val = Addressables.LoadAssetAsync<GameObject>((object)address).WaitForCompletion(); if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)("Could not load chest prefab: " + address)); return; } ThreeChoiceChestMarker threeChoiceChestMarker = val.GetComponent<ThreeChoiceChestMarker>(); if ((Object)(object)threeChoiceChestMarker == (Object)null) { threeChoiceChestMarker = val.AddComponent<ThreeChoiceChestMarker>(); } threeChoiceChestMarker.category = category; } private static void PurchaseInteraction_OnInteractionBegin(orig_OnInteractionBegin orig, PurchaseInteraction self, Interactor activator) { ThreeChoiceChestMarker component = ((Component)self).GetComponent<ThreeChoiceChestMarker>(); if ((Object)(object)component != (Object)null && self.CanBeAffordedByInteractor(activator)) { component.lastInteractor = activator; } orig.Invoke(self, activator); } private static bool TryCreateThreeChoicePicker(ref CreatePickupInfo pickupInfo, Vector3 position) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //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) if (!NetworkServer.active) { return false; } ChestBehavior chest = pickupInfo.chest; if ((Object)(object)chest == (Object)null) { return false; } ThreeChoiceChestMarker component = ((Component)chest).GetComponent<ThreeChoiceChestMarker>(); if ((Object)(object)component == (Object)null) { return false; } if ((Object)(object)component.lastInteractor == (Object)null) { return false; } UniquePickup pickup = ((CreatePickupInfo)(ref pickupInfo)).pickup; if (!((UniquePickup)(ref pickup)).isValid) { return false; } Option[] array = BuildThreeOptions(pickup, component.category); if (array == null || array.Length == 0) { return false; } Interactor lastInteractor = component.lastInteractor; component.lastInteractor = null; pendingChoices.Enqueue(new PendingChoice { firstPickup = pickup, options = array, activator = lastInteractor, position = position, rotation = pickupInfo.rotation }); if (!pickerActive) { OpenNextPendingChoice(); } return true; } private static void OpenNextPendingChoice() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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) if (!NetworkServer.active || pickerActive || pendingChoices.Count == 0) { return; } PendingChoice pendingChoice = pendingChoices.Dequeue(); if ((Object)(object)pendingChoice.activator == (Object)null) { OpenNextPendingChoice(); return; } GameObject pickerObject = Object.Instantiate<GameObject>(commandCubePrefab, pendingChoice.position, pendingChoice.rotation); HideCommandCubePrefab(pickerObject); PickupPickerController component = pickerObject.GetComponent<PickupPickerController>(); PickupIndexNetworker component2 = pickerObject.GetComponent<PickupIndexNetworker>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)component.networkUIPromptController == (Object)null) { Object.Destroy((Object)(object)pickerObject); OpenNextPendingChoice(); return; } component2.NetworkpickupState = pendingChoice.firstPickup; pickerActive = true; NetworkServer.Spawn(pickerObject); bool finished = false; component.networkUIPromptController.onDisplayEnd += delegate(NetworkUIPromptController controller, LocalUser localUser, CameraRigController cameraRigController) { if (!finished) { finished = true; controller.SetParticipantMaster((CharacterMaster)null); if (NetworkServer.active && (Object)(object)pickerObject != (Object)null) { NetworkServer.Destroy(pickerObject); } pickerActive = false; if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(OpenNextChoiceNextFrame()); } } }; component.SetOptionsServer(pendingChoice.options); if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(OpenPickerAfterSpawn(component, pendingChoice.activator)); } } private static IEnumerator OpenNextChoiceNextFrame() { yield return null; OpenNextPendingChoice(); } private static IEnumerator OpenPickerAfterSpawn(PickupPickerController picker, Interactor activator) { yield return (object)new WaitForSecondsRealtime(0.1f); if (!((Object)(object)picker == (Object)null) && !((Object)(object)activator == (Object)null)) { picker.OnInteractionBegin(activator); } } private static Option[] BuildThreeOptions(UniquePickup firstPickup, ThreeChoiceChestCategory category) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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) //IL_0008: 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_004d: Invalid comparison between Unknown and I4 //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) PickupIndex pickupIndex = firstPickup.pickupIndex; PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex); if (pickupDef == null || (Object)(object)Run.instance == (Object)null) { return MakeOptions(new List<UniquePickup> { firstPickup }); } List<PickupIndex> list = new List<PickupIndex>(); if ((int)pickupDef.equipmentIndex != -1) { AddMatchingPickups(Run.instance.availableEquipmentDropList, pickupDef, category, equipmentMode: true, list); } else { AddMatchingPickups(Run.instance.availableTier1DropList, pickupDef, category, equipmentMode: false, list); AddMatchingPickups(Run.instance.availableTier2DropList, pickupDef, category, equipmentMode: false, list); AddMatchingPickups(Run.instance.availableTier3DropList, pickupDef, category, equipmentMode: false, list); } List<UniquePickup> list2 = new List<UniquePickup>(); list2.Add(firstPickup); for (int num = list.Count - 1; num >= 0; num--) { if (list[num].value == pickupIndex.value) { list.RemoveAt(num); } } while (list2.Count < 3 && list.Count > 0) { int index = Random.Range(0, list.Count); PickupIndex val = list[index]; list.RemoveAt(index); list2.Add(new UniquePickup(val)); } return MakeOptions(list2); } private static void AddMatchingPickups(List<PickupIndex> source, PickupDef firstDef, ThreeChoiceChestCategory category, bool equipmentMode, List<PickupIndex> destination) { //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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Invalid comparison between Unknown and I4 //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) if (source == null) { return; } foreach (PickupIndex item in source) { PickupDef pickupDef = PickupCatalog.GetPickupDef(item); if (pickupDef == null) { continue; } if (equipmentMode) { if ((int)pickupDef.equipmentIndex == -1) { continue; } } else if ((int)pickupDef.itemIndex == -1 || pickupDef.itemTier != firstDef.itemTier || !MatchesCategory(pickupDef, category)) { continue; } bool flag = false; foreach (PickupIndex item2 in destination) { if (item2.value == item.value) { flag = true; break; } } if (!flag) { destination.Add(item); } } } private static bool MatchesCategory(PickupDef pickupDef, ThreeChoiceChestCategory category) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (category == ThreeChoiceChestCategory.General) { return true; } if ((int)pickupDef.itemIndex == -1) { return false; } ItemDef itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex); if ((Object)(object)itemDef == (Object)null) { return false; } return category switch { ThreeChoiceChestCategory.Damage => itemDef.ContainsTag((ItemTag)1), ThreeChoiceChestCategory.Healing => itemDef.ContainsTag((ItemTag)2), ThreeChoiceChestCategory.Utility => itemDef.ContainsTag((ItemTag)3), _ => true, }; } private static Option[] MakeOptions(List<UniquePickup> pickups) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) Option[] array = (Option[])(object)new Option[pickups.Count]; for (int i = 0; i < pickups.Count; i++) { array[i] = new Option { pickup = pickups[i], available = true }; } return array; } private static void HideCommandCubePrefab(GameObject prefab) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { val.enabled = false; } Light[] componentsInChildren2 = prefab.GetComponentsInChildren<Light>(true); Light[] array2 = componentsInChildren2; foreach (Light val2 in array2) { ((Behaviour)val2).enabled = false; } ParticleSystem[] componentsInChildren3 = prefab.GetComponentsInChildren<ParticleSystem>(true); ParticleSystem[] array3 = componentsInChildren3; foreach (ParticleSystem val3 in array3) { EmissionModule emission = val3.emission; ((EmissionModule)(ref emission)).enabled = false; val3.Stop(true, (ParticleSystemStopBehavior)0); } AudioSource[] componentsInChildren4 = prefab.GetComponentsInChildren<AudioSource>(true); AudioSource[] array4 = componentsInChildren4; foreach (AudioSource val4 in array4) { val4.playOnAwake = false; ((Behaviour)val4).enabled = false; } } } public class PendingChoice { public UniquePickup firstPickup; public Option[] options; public Interactor activator; public Vector3 position; public Quaternion rotation; } public enum ThreeChoiceChestCategory { General, Damage, Healing, Utility } public class ThreeChoiceChestMarker : MonoBehaviour { public ThreeChoiceChestCategory category; public Interactor lastInteractor; } }