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 ConfigurableTrials v0.5.0
plugins/ShandoVK-ConfigurableTrials/ConfigurableTrialsPlugin.dll
Decompiled 4 days agousing System; 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.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HG; using Microsoft.CodeAnalysis; using On.RoR2; using RiskOfOptions; using RiskOfOptions.Options; using RoR2; using RoR2.ExpansionManagement; using UnityEngine; 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("ConfigurableTrialsPlugin")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ConfigurableTrialsPlugin")] [assembly: AssemblyTitle("ConfigurableTrialsPlugin")] [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 ConfigurableTrialPlugin { [BepInPlugin("ShandoIsSad.ConfigurableTrials", "ConfigurableTrials", "0.5.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ConfigurableTrials : BaseUnityPlugin { public const string PluginGUID = "ShandoIsSad.ConfigurableTrials"; public const string PluginAuthor = "ShandoVK"; public const string PluginName = "ConfigurableTrials"; public const string PluginVersion = "0.5.0"; private static readonly FieldInfo trialSelectionField = typeof(DLC4TrialSelector).GetField("_trialSelection", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly MethodInfo canAddTrialMethod = typeof(DLC4TrialSelector).GetMethod("CanAddTrial", BindingFlags.Instance | BindingFlags.NonPublic); private static DLC4TrialSelector activeTrialSelector; public static ConfigEntry<float> startingTimer; public static ConfigEntry<float> timeAddedStage; public static ConfigEntry<float> timeAddedLoop; public static ConfigEntry<bool> moreUmbra; private static readonly Dictionary<string, ConfigEntry<bool>> trialVariantToggle = new Dictionary<string, ConfigEntry<bool>>(); private static readonly Dictionary<string, (string section, (string id, string name)[] variants)> SceneVariants = new Dictionary<string, (string, (string, string)[])> { { "sad1", ("Winnowing of Predation", new(string, string)[3] { ("MakingMoneyAndDollars", "Trial of Infernal Greed"), ("BreakTheTargets", "Trial of Broken Glass"), ("OpenTheChests", "Trial of the Scavenger's Dream") }) }, { "soul1", ("Winnowing of Mortality", new(string, string)[3] { ("SpeedRunVariant_A", "Trial of the Agile"), ("SpeedRunVariant_B", "Trial of the Fleet-Footed"), ("SpeedRunVariant_C", "Trial of the Conduit") }) }, { "surv2", ("Winnowing of Survival", new(string, string)[3] { ("UmbraVariant", "Trial of the Lesser Echoes"), ("ProcCityVariant", "Trial of Casualty"), ("MonstersOffMapVariant", "Trial of the Abyss") }) } }; private static readonly HashSet<string> umbraSurvivorBL = new HashSet<string> { "ToolbotMonsterMasterVariant", "TreebotMonsterMaster", "HereticMonsterMaster", "VoidSurvivorMonsterMaster", "FalseSonMonsterMaster", "AcolyteMonsterMaster" }; private static readonly (string name, int count)[] umbraItems = new(string, int)[13] { ("SecondarySkillMagazine", 1), ("ArmorReductionOnHit", 1), ("AlienHead", 2), ("HealWhileSafe", 6), ("Phasing", 1), ("AutoCastEquipment", 5), ("Medkit", 1), ("Seed", 5), ("Feather", 10), ("EquipmentMagazine", 1), ("ArmorPlate", 3), ("Syringe", 1), ("Mushroom", 10) }; private static readonly (string name, float weight, string dlc, bool loopOnly)[] umbraEquipment = new(string, float, string, bool)[13] { ("TeamWarCry", 1f, null, false), ("Jetpack", 1f, null, false), ("VendingMachine", 1f, "DLC1", false), ("PassiveHealing", 1f, null, false), ("QuestVolatileBattery", 0.01f, null, false), ("EliteFireEquipment", 0.5f, null, false), ("EliteIceEquipment", 0.5f, null, false), ("EliteLightningEquipment", 0.25f, null, false), ("EliteEarthEquipment", 0.25f, "DLC1", false), ("ElitePoisonEquipment", 0.1f, null, true), ("EliteHauntedEquipment", 0.05f, null, true), ("EliteBeadEquipment", 0.1f, "DLC2", true), ("EliteCollectiveEquipment", 0.05f, "DLC3", true) }; public void Awake() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Expected O, but got Unknown //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Expected O, but got Unknown //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Expected O, but got Unknown //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Expected O, but got Unknown //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Expected O, but got Unknown //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Expected O, but got Unknown //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Expected O, but got Unknown Log.Init(((BaseUnityPlugin)this).Logger); startingTimer = ((BaseUnityPlugin)this).Config.Bind<float>("Timer", "Initial time limit for trials", 210f, new ConfigDescription("Starting timer for N’kuhana Trials, in seconds. Vanilla is 210s (3:30)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2592000f), Array.Empty<object>())); timeAddedStage = ((BaseUnityPlugin)this).Config.Bind<float>("Timer", "Time added per stage cleared", 0f, new ConfigDescription("For each stage you clear, the timer increases by this value. Set it to 0 to disable", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 86400f), Array.Empty<object>())); timeAddedLoop = ((BaseUnityPlugin)this).Config.Bind<float>("Timer", "Time added per loop finished", 0f, new ConfigDescription("For each time you loop, the timer increases by this value. Set it to 0 to disable", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 86400f), Array.Empty<object>())); foreach (var value in SceneVariants.Values) { (string, string)[] item = value.variants; for (int i = 0; i < item.Length; i++) { var (text, text2) = item[i]; trialVariantToggle[text] = ((BaseUnityPlugin)this).Config.Bind<bool>(value.section, text, true, "Allows the '" + text2 + "' to appear"); } } moreUmbra = ((BaseUnityPlugin)this).Config.Bind<bool>("WTF was that", "More varied umbra spawns", false, "When enabled, more survivors, items, and equipment will be added to the Trial of the Lesser Echoes. May make the trial noticeably harder"); if (RiskOfOptionsCompat.Enabled) { RiskOfOptionsCompat.AddFloatField(startingTimer); RiskOfOptionsCompat.AddFloatField(timeAddedStage); RiskOfOptionsCompat.AddFloatField(timeAddedLoop); foreach (ConfigEntry<bool> value2 in trialVariantToggle.Values) { RiskOfOptionsCompat.AddCheckbox(value2); } RiskOfOptionsCompat.AddCheckbox(moreUmbra); } Run.AdvanceStage += new hook_AdvanceStage(Run_AdvanceStage); DirectorCore.TrySpawnObject += new hook_TrySpawnObject(DirectorCore_TrySpawnObject); TrialVariantEventRelay.IsAvailableServer += new hook_IsAvailableServer(TrialVariantEventRelay_IsAvailableServer); DLC4TrialSelector.Awake += new hook_Awake(DLC4TrialSelector_Awake); DLC4TrialSelector.CanAddTrial += new hook_CanAddTrial(DLC4TrialSelector_CanAddTrial); DLC4TrialSelector.RemoveTrialFromSelectionServer += new hook_RemoveTrialFromSelectionServer(DLC4TrialSelector_RemoveTrialFromSelectionServer); DLC4TrialSelector.RemoveTrialSceneFromCollectionServer += new hook_RemoveTrialSceneFromCollectionServer(DLC4TrialSelector_RemoveTrialSceneFromCollectionServer); } private void DLC4TrialSelector_Awake(orig_Awake orig, DLC4TrialSelector self) { orig.Invoke(self); activeTrialSelector = self; if (NetworkServer.active) { self.SetRemainingTrialTimeServer(startingTimer.Value); } } private void Run_AdvanceStage(orig_AdvanceStage orig, Run self, SceneDef nextScene) { int stageClearCount = self.stageClearCount; int loopClearCount = self.loopClearCount; orig.Invoke(self, nextScene); if (!NetworkServer.active || !Object.op_Implicit((Object)(object)activeTrialSelector)) { return; } float num = 0f; if (self.stageClearCount > stageClearCount) { num += timeAddedStage.Value; } if (self.loopClearCount > loopClearCount) { num += timeAddedLoop.Value; } if (!(num <= 0f)) { float remainingTrialTimeServer = activeTrialSelector.GetRemainingTrialTimeServer(); if (!(remainingTrialTimeServer <= 0f)) { activeTrialSelector.SetRemainingTrialTimeServer(remainingTrialTimeServer + num); } } } private static bool IsVariantEnabled(string customName) { ConfigEntry<bool> value; return !trialVariantToggle.TryGetValue(customName, out value) || value.Value; } private bool DLC4TrialSelector_CanAddTrial(orig_CanAddTrial orig, DLC4TrialSelector self, SceneDef sceneDef) { if (!orig.Invoke(self, sceneDef)) { return false; } if (SceneVariants.TryGetValue(sceneDef.cachedName, out (string, (string, string)[]) value)) { return value.Item2.Any(((string id, string name) v) => IsVariantEnabled(v.id)); } return true; } private bool TrialVariantEventRelay_IsAvailableServer(orig_IsAvailableServer orig, TrialVariantEventRelay self) { return orig.Invoke(self) && IsVariantEnabled(self.customName); } private void DLC4TrialSelector_RemoveTrialFromSelectionServer(orig_RemoveTrialFromSelectionServer orig, DLC4TrialSelector self, SceneDef trialScene) { orig.Invoke(self, trialScene); if (NetworkServer.active && !self.IsAnyTrialAvailableServer((SceneDef)null)) { WeightedSelection<SceneDef> val = (WeightedSelection<SceneDef>)trialSelectionField.GetValue(self); Func<SceneDef, bool> func = (Func<SceneDef, bool>)Delegate.CreateDelegate(typeof(Func<SceneDef, bool>), self, canAddTrialMethod); self.trialsSceneCollection.AddToWeightedSelection(val, func); } } private void DLC4TrialSelector_RemoveTrialSceneFromCollectionServer(orig_RemoveTrialSceneFromCollectionServer orig, DLC4TrialSelector self, TrialController trialController) { orig.Invoke(self, trialController); if (!NetworkServer.active || !Object.op_Implicit((Object)(object)Run.instance)) { return; } TrialVariantEventRelay[] trialVariants = trialController.trialVariants; foreach (TrialVariantEventRelay val in trialVariants) { if (val.exhaustOnSuccess) { Run.instance.ResetEventFlag(val.customName + "_Exhausted"); } } } private static bool DLCRequired(string name) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_001b: Unknown result type (might be due to invalid IL or missing references) if (name == null) { return true; } Enumerator<ExpansionDef> enumerator = ExpansionCatalog.expansionDefs.GetEnumerator(); try { while (enumerator.MoveNext()) { ExpansionDef current = enumerator.Current; if (((Object)current).name == name && Run.instance.IsExpansionEnabled(current)) { return true; } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } return false; } private static bool IsMasterAllowed(CharacterMaster master) { if (!Object.op_Implicit((Object)(object)master) || !Object.op_Implicit((Object)(object)master.bodyPrefab)) { return false; } if (umbraSurvivorBL.Contains(((Object)master).name)) { return false; } if (!Object.op_Implicit((Object)(object)SurvivorCatalog.FindSurvivorDefFromBody(master.bodyPrefab))) { return false; } return IsExpansionRequirementMet(((Component)master).gameObject) && IsExpansionRequirementMet(master.bodyPrefab); } private static bool IsExpansionRequirementMet(GameObject obj) { ExpansionRequirementComponent component = obj.GetComponent<ExpansionRequirementComponent>(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.requiredExpansion)) { return true; } return Run.instance.IsExpansionEnabled(component.requiredExpansion); } private static void scaleUmbra(CharacterBody body) { if (Object.op_Implicit((Object)(object)body)) { body.levelMaxHealth *= 0.8f; body.baseDamage *= 0.5f; body.levelDamage *= 0.1f; body.statsDirty = true; } } private static GameObject pickUmbraSurvivor() { List<CharacterMaster> list = MasterCatalog.allMasters.Where(IsMasterAllowed).ToList(); return (list.Count == 0) ? null : ((Component)list[Random.Range(0, list.Count)]).gameObject; } private static (string name, int count) pickUmbraItems() { return umbraItems[Random.Range(0, umbraItems.Length)]; } private static string pickUmbraEquipment() { bool looped = Run.instance.loopClearCount > 0; List<(string, float, string, bool)> list = umbraEquipment.Where(((string name, float weight, string dlc, bool loopOnly) e) => (!e.loopOnly || looped) && DLCRequired(e.dlc)).ToList(); if (list.Count == 0) { return null; } float num = Random.value * list.Sum<(string, float, string, bool)>(((string name, float weight, string dlc, bool loopOnly) e) => e.weight); foreach (var item in list) { if ((num -= item.Item2) <= 0f) { return item.Item1; } } return list[list.Count - 1].Item1; } private GameObject DirectorCore_TrySpawnObject(orig_TrySpawnObject orig, DirectorCore self, DirectorSpawnRequest request) { //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) SpawnCard obj = request?.spawnCard; CharacterSpawnCard val = (CharacterSpawnCard)(object)((obj is CharacterSpawnCard) ? obj : null); SceneDef val2 = (Object.op_Implicit((Object)(object)SceneInfo.instance) ? SceneInfo.instance.sceneDef : null); if (!moreUmbra.Value || !NetworkServer.active || !Object.op_Implicit((Object)(object)Run.instance) || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2) || val2.cachedName != "surv2" || !((Object)val).name.StartsWith("cscCommandoUmbraMaster")) { return orig.Invoke(self, request); } GameObject val3 = pickUmbraSurvivor(); if (!Object.op_Implicit((Object)(object)val3)) { return orig.Invoke(self, request); } string equipment = pickUmbraEquipment(); (string, int) tuple = pickUmbraItems(); string itemName = tuple.Item1; int itemCount = tuple.Item2; CharacterSpawnCard val4 = Object.Instantiate<CharacterSpawnCard>(val); ((Object)val4).name = ((Object)val).name; ((SpawnCard)val4).prefab = val3; CharacterBody component = val3.GetComponent<CharacterMaster>().bodyPrefab.GetComponent<CharacterBody>(); if (Object.op_Implicit((Object)(object)component)) { ((SpawnCard)val4).hullSize = component.hullClassification; } Action<SpawnResult> originalCallback = request.onSpawnedServer; request.spawnCard = (SpawnCard)(object)val4; request.onSpawnedServer = delegate(SpawnResult result) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_007b: Invalid comparison between Unknown and I4 //IL_0097: Unknown result type (might be due to invalid IL or missing references) originalCallback?.Invoke(result); CharacterMaster val5 = (Object.op_Implicit((Object)(object)result.spawnedInstance) ? result.spawnedInstance.GetComponent<CharacterMaster>() : null); if (Object.op_Implicit((Object)(object)val5)) { if (equipment != null && Object.op_Implicit((Object)(object)val5.inventory)) { val5.inventory.GiveEquipmentString(equipment); } ItemIndex val6 = ItemCatalog.FindItemIndex(itemName); if ((int)val6 != -1 && Object.op_Implicit((Object)(object)val5.inventory)) { val5.inventory.GiveItemPermanent(val6, itemCount); } CharacterBody body = val5.GetBody(); scaleUmbra(body); } }; try { return orig.Invoke(self, request); } finally { request.spawnCard = (SpawnCard)(object)val; request.onSpawnedServer = originalCallback; Object.Destroy((Object)(object)val4); } } } public static class RiskOfOptionsCompat { private static bool? _enabled; public static bool Enabled { get { bool valueOrDefault = _enabled == true; bool result; if (!_enabled.HasValue) { valueOrDefault = Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); _enabled = valueOrDefault; result = valueOrDefault; } else { result = valueOrDefault; } return result; } } [MethodImpl(MethodImplOptions.NoInlining)] public static void AddCheckbox(ConfigEntry<bool> entry) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(entry)); } [MethodImpl(MethodImplOptions.NoInlining)] public static void AddFloatField(ConfigEntry<float> entry) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(entry)); } } 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)); } } }