using 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.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using GlobalEnums; using GlobalSettings; using HarmonyLib; using HutongGames.PlayMaker; using HutongGames.PlayMaker.Actions; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Silksong.DataManager; using Silksong.ModMenu.Elements; using Silksong.ModMenu.Models; using Silksong.ModMenu.Plugin; using Silksong.ModMenu.Screens; using Smol_Randomizer.Randomizers; using Smol_Randomizer.Settings; using UnityEngine; using UnityEngine.SceneManagement; [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("Ashilstraza")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Randomizer for Miscellanious Smol Things")] [assembly: AssemblyFileVersion("0.1.1.0")] [assembly: AssemblyInformationalVersion("0.1.1+5f70d32d08c8a1e4d5f0e8fee639c8795e271cb8")] [assembly: AssemblyProduct("Smol_Randomizer")] [assembly: AssemblyTitle("Smol_Randomizer")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Ashilstraza/Smol_Randomizer")] [assembly: AssemblyVersion("0.1.1.0")] [module: RefSafetyRules(11)] namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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; } } } internal sealed class ConfigurationManagerAttributes { public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput); public bool? ShowRangeAsPercent; public Action CustomDrawer; public CustomHotkeyDrawerFunc CustomHotkeyDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public Func ObjToStr; public Func StrToObj; } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Embedded] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Embedded] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace Microsoft.CodeAnalysis { [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace Smol_Randomizer { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("ashilstraza.randomizer.cute", "Smol Randomizer", "0.1.0")] public class CuteRandoCore : BaseUnityPlugin, IModMenuInterface, IModMenuCustomMenu, IRawSaveDataMod { public const string GUID = "ashilstraza.randomizer.cute"; public const string MODNAME = "Smol Randomizer"; public const string VERSION = "0.1.0"; private bool updateActiveLimitRegions; private bool updateOnFirstSceneFrame; private static readonly HashSet allRandomizers = new HashSet(); private static readonly HashSet allRandomizerActions = new HashSet(); internal static bool testing = false; internal static bool randomize = true; internal static readonly Harmony harmony = new Harmony("ashilstraza.randomizer.cute"); internal static SettingMenu cuteRandomizerSettingWindow; internal static Random noSeedRNG = new Random(); private static readonly Dictionary> activeLimitRegions = new Dictionary>(); private static readonly Dictionary> activeOnSceneLoad = new Dictionary>(); private static readonly Dictionary activeGameStartup = new Dictionary(); private static readonly Dictionary activeGameShutdown = new Dictionary(); private static readonly Dictionary activeOnFirstSceneFrame = new Dictionary(); private static readonly Dictionary randomizerDescriptions = new Dictionary(); public static readonly string[] bossFilter = new string[10] { "Lace", "Phantom", "Silk Boss", "Bone Beast", "Trobbio", "Shakra", "Mapper", "Forebrother", "Garmond", "SG_head" }; public static string DataLocation { get; private set; } = ""; public bool HasSaveData => Smol_Randomizer.Settings.Settings.SaveData != null; private void Awake() { DataLocation = ((BaseUnityPlugin)this).Info.Location.TrimEnd("\\\\Smol_Randomizer.dll".ToCharArray()) + "\\Smol_Randomizer"; Smol_Randomizer.Settings.Settings.Init(((BaseUnityPlugin)this).Config); _ = Enemy_Currency_Rando.Instance; _ = World_Currency_Drop_Rando.Instance; _ = Enemy_Health_Rando.Instance; _ = Enemy_Damage_Rando.Instance; _ = Hero_Damage_Rando.Instance; _ = Enemy_Size_Rando.Instance; } private void Start() { SceneManager.sceneLoaded += OnSceneLoaded; foreach (KeyValuePair item in activeGameStartup) { item.Value(); } } private void Update() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)GameManager.SilentInstance == (Object)null || !randomize || (((Object)(object)GameManager.instance.sm != (Object)null) ? new SceneType?(GameManager.instance.sm.sceneType) : ((SceneType?)null)) != (SceneType?)0) { return; } if (updateActiveLimitRegions) { foreach (ICurrencyLimitRegion item in (HashSet)Traverse.Create().Field("_activeRegions").GetValue()) { foreach (KeyValuePair> activeLimitRegion in activeLimitRegions) { activeLimitRegion.Value(item); } } updateActiveLimitRegions = false; } if (!updateOnFirstSceneFrame) { return; } foreach (KeyValuePair item2 in activeOnFirstSceneFrame) { item2.Value(); } updateOnFirstSceneFrame = false; } internal static void UpdateSettings(object sender, EventArgs args) { //IL_0011: 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) randomize = Smol_Randomizer.Settings.Settings.EnableRandomizer; if (!randomize) { SmolRandomizerMenuBuilder.Enabled = SmolRandomizerMenuBuilder.LightGray; SmolRandomizerMenuBuilder.Disabled = SmolRandomizerMenuBuilder.LightGray; } else { SettingMenu.ChangeColors(Smol_Randomizer.Settings.Settings.EnabledRandomizerColors); } SettingMenu.thisSettingMenu?.UpdateAllSubMenuColors(); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //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) if (!randomize) { return; } foreach (KeyValuePair> item in activeOnSceneLoad) { item.Value(scene, mode); } updateOnFirstSceneFrame = true; updateActiveLimitRegions = true; } private void OnApplicationQuit() { foreach (KeyValuePair item in activeGameShutdown) { item.Value(); } } public AbstractMenuScreen BuildCustomMenu() { cuteRandomizerSettingWindow = new SettingMenu(LocalizedText.op_Implicit("Smol Randomizer")); return (AbstractMenuScreen)(object)cuteRandomizerSettingWindow; } public static string GetRandoDescription(string randoName) { randomizerDescriptions.TryGetValue(randoName, out string value); return value; } internal static void AddRandoDescription(string randoName, string randoDescription) { randomizerDescriptions.Add(randoName, randoDescription); } public void WriteSaveData(Stream saveFile) { RandoPerSaveData.Saving(); string value = JsonConvert.SerializeObject((object)Smol_Randomizer.Settings.Settings.SaveData, (Formatting)1); using StreamWriter streamWriter = new StreamWriter(saveFile); try { streamWriter.Write(value); } catch (Exception ex) { Console.Error.WriteLine("[Smol Randomizer] Exception encountered, unable to write per-save data for current save slot.\n" + ex.Message); } } public void ReadSaveData(Stream? saveFile) { if (saveFile == null) { Smol_Randomizer.Settings.Settings.SaveData = new RandoPerSaveData(); return; } using StreamReader streamReader = new StreamReader(saveFile); try { Smol_Randomizer.Settings.Settings.SaveData = JsonConvert.DeserializeObject(streamReader.ReadToEnd()) ?? new RandoPerSaveData(); } catch (Exception ex) { Console.Error.WriteLineAsync("[Smol Randomizer] Exception encountered, unable to load per-save data for current save slot.\n" + ex.Message); } } internal static void ImportJsonFile(string fileName, out string importTarget) { if (!File.Exists(DataLocation + "\\\\" + fileName + ".json")) { importTarget = ""; return; } try { importTarget = File.ReadAllText(DataLocation + "\\\\" + fileName + ".json"); } catch (Exception ex) { Console.Error.WriteLine("Exception encountered, unable to import " + fileName + ".\n" + ex.Message); importTarget = ""; } } internal static void ExportJsonFile(string fileName, object exportTarget) { string contents = JsonConvert.SerializeObject(exportTarget, (Formatting)1); try { File.WriteAllText(DataLocation + "\\\\" + fileName + ".json", contents); } catch (Exception ex) { Console.Error.WriteLine("Exception encountered, unable to export " + fileName + ".\n" + ex.Message); } } public static bool RegisterRandomizer(Randomizer_Info randomizer) { if (randomizer == null) { throw new ArgumentNullException("randomizer", "Unable to register null as a randomizer."); } if (randomizer.Name == null) { throw new ArgumentException("Randomizer has a null name."); } if (randomizer.Method == null) { throw new ArgumentException("Randomizer has a null action."); } foreach (Randomizer_Info allRandomizerAction in allRandomizerActions) { if (randomizer.Name == allRandomizerAction.Name) { Console.Error.WriteLine("[Smol Randomizer] Unable to register randomizer action: There already is a randomizer with the same name."); } else if (randomizer.Method == allRandomizerAction.Method) { Console.Error.WriteLine("[Smol Randomizer] Unable to register randomizer action: Duplicate action."); } } if (!allRandomizerActions.Add(randomizer)) { return false; } if (allRandomizers.Add(randomizer.Name)) { Console.WriteLine("[Smol Randomizer] Registering randomizer: " + randomizer.Name + "."); } switch (randomizer.RandomizerType) { case RandomizerEventType.ActiveLimitRegion: activeLimitRegions.Add(randomizer.Name, (Action)DelegateHelper(typeof(Action), randomizer.Method, randomizer.Object)); break; case RandomizerEventType.OnSceneLoad: activeOnSceneLoad.Add(randomizer.Name, (Action)DelegateHelper(typeof(Action), randomizer.Method, randomizer.Object)); break; case RandomizerEventType.OnFirstSceneFrame: activeOnFirstSceneFrame.Add(randomizer.Name, (Action)DelegateHelper(typeof(Action), randomizer.Method, randomizer.Object)); break; case RandomizerEventType.GameStartup: activeGameStartup.Add(randomizer.Name, (Action)DelegateHelper(typeof(Action), randomizer.Method, randomizer.Object)); break; case RandomizerEventType.GameShutdown: activeGameShutdown.Add(randomizer.Name, (Action)DelegateHelper(typeof(Action), randomizer.Method, randomizer.Object)); break; default: Console.Error.WriteLine("Unimplemented entryType"); allRandomizerActions.Remove(randomizer); return false; case RandomizerEventType.ActiveEnemy: case RandomizerEventType.ActiveHeroDamager: break; } return true; static Delegate DelegateHelper(Type type, MethodInfo methodInfo, object? firstArgument = null) { if (firstArgument != null) { return Delegate.CreateDelegate(type, firstArgument, methodInfo); } return Delegate.CreateDelegate(type, methodInfo); } } public static bool UnregisterRandomizer(Randomizer_Info randomizer) { if (randomizer == null) { throw new ArgumentNullException("randomizer", "Not able to unregister a null randomizer."); } if (randomizer.Name == null) { throw new ArgumentException("Not able to unregister a randomizer with a null name."); } if (!allRandomizerActions.Remove(randomizer)) { return false; } Console.WriteLine(string.Format("[{0}] Unregistering randomizer event: {1} from {2}.", "Smol Randomizer", randomizer.RandomizerType, randomizer.Name)); switch (randomizer.RandomizerType) { case RandomizerEventType.ActiveLimitRegion: activeLimitRegions.Remove(randomizer.Name); break; case RandomizerEventType.OnSceneLoad: activeOnSceneLoad.Remove(randomizer.Name); break; case RandomizerEventType.OnFirstSceneFrame: activeOnFirstSceneFrame.Remove(randomizer.Name); break; case RandomizerEventType.GameStartup: activeGameStartup.Remove(randomizer.Name); break; case RandomizerEventType.GameShutdown: activeGameShutdown.Remove(randomizer.Name); break; default: Console.Error.WriteLine("Unimplemented entryType"); return false; case RandomizerEventType.ActiveEnemy: case RandomizerEventType.ActiveHeroDamager: break; } if (allRandomizerActions.FirstOrDefault((Randomizer_Info x) => x.Name == randomizer.Name) == null) { allRandomizers.Remove(randomizer.Name); } return true; } public static Traverse TraverseHelper(object type, string field) { return Traverse.Create(type).Field(field); } public static float RandoHelper((float min, float max) tuple, int seed = int.MinValue) { return RandoHelper(tuple.min, tuple.max, seed); } public static int RandoHelper((int min, int max) tuple, int seed = int.MinValue) { return RandoHelper(tuple.min, tuple.max, seed); } public static float RandoHelper(float min, float max, int seed = int.MinValue) { if (seed > int.MinValue) { Random.InitState(seed); return Random.Range(min, max); } return (float)(noSeedRNG.NextDouble() * (double)(max - min) + (double)min); } public static int RandoHelper(int min, int max, int seed = int.MinValue) { checked { if (seed > int.MinValue) { Random.InitState(seed); return Random.Range(min, max + 1); } return noSeedRNG.Next(min, max + 1); } } public static int GetNewSaveSeed() { return Random.Range(-2147483647, int.MaxValue); } public static int RNGSeed(string modifier) { int num = Smol_Randomizer.Settings.Settings.SaveData.SaveSeed; byte[] bytes = Encoding.Unicode.GetBytes(modifier); foreach (byte b in bytes) { num = checked(num + b); } return num; } public static bool IsBoss(HealthManager thing) { if ((Object)(object)thing == (Object)null || ((Component)thing).GetComponent() is EnemyDeathEffectsNoEffect) { return false; } string[] array = bossFilter; foreach (string value in array) { if (((Object)thing).name.Contains(value)) { return true; } } PlayMakerFSM[] components = ((Component)thing).GetComponents(); for (int i = 0; i < components.Length; i++) { FsmState[] fsmStates = components[i].FsmStates; foreach (FsmState obj in fsmStates) { if (obj != null && obj.Actions.Any((FsmStateAction action) => action is DisplayBossTitle)) { return true; } } } return false; } } public enum RandomizerEventType : byte { ActiveEnemy, ActiveLimitRegion, OnSceneLoad, OnFirstSceneFrame, GameStartup, GameShutdown, ActiveHeroDamager } public class Randomizer_Info(string name, RandomizerEventType randomizerType, MethodInfo method, object? o = null) { public string Name => name; public RandomizerEventType RandomizerType => randomizerType; public MethodInfo Method => method; public object? Object => o; } } namespace Smol_Randomizer.Settings { public class FloatRange { private float min; private float max; public float Min { get { return min; } set { int num = value.CompareTo(max); if (num > 0) { throw new ArgumentException($"{value} is greater than the maximum value ({max})"); } min = value; } } public float Max { get { return max; } set { int num = value.CompareTo(min); if (num < 0) { throw new ArgumentException($"{value} is less than the minimum value ({min})"); } max = value; } } private float Both { get { if (min != max) { return max / min; } return min; } set { min = value; max = value; } } public (float min, float max) AsTuple() { return (min: min, max: max); } public FloatRange(float min, float max) { if (min.CompareTo(max) <= 0) { this.min = min; this.max = max; return; } throw new ArgumentException($"{min} is greater than the maximum value ({max})"); } public static implicit operator float(FloatRange fr) { return fr.Both; } public static explicit operator FloatRange(float f) { return new FloatRange(f, f); } public bool ContainsValue(float value) { if (value.CompareTo(min) >= 0) { return value.CompareTo(max) <= 0; } return false; } public override string ToString() { return $"[{min} - {max}]"; } public static FloatRange Parse(string s) { string[] array = s.Split(new char[4] { '[', ' ', '-', ']' }, StringSplitOptions.RemoveEmptyEntries); return new FloatRange(float.Parse(array[0]), float.Parse(array[1])); } public static FloatRange Parse(string s1, string s2) { float num = float.Parse(s1); float num2 = float.Parse(s2); return new FloatRange(num, num2); } public override bool Equals(object obj) { if (obj is FloatRange floatRange && floatRange.Min == Min && floatRange.Max == Max) { return true; } return false; } public override int GetHashCode() { return HashCode.Combine(min, max); } } public class AcceptableRangeforFloatRange(float minValue, float maxValue) : AcceptableValueBase(typeof(FloatRange)) { public float MinValue { get; } = minValue; public float MaxValue { get; } = maxValue; public override object Clamp(object value) { if (value.GetType() == typeof(FloatRange)) { FloatRange floatRange = (FloatRange)value; if (MinValue.CompareTo(floatRange.Min) > 0) { floatRange.Min = MinValue; } if (MaxValue.CompareTo(floatRange.Max) < 0) { floatRange.Max = MaxValue; } return floatRange; } if (value.GetType() == typeof(float)) { float value2 = (float)value; if (MinValue.CompareTo(value2) > 0) { return MinValue; } if (MaxValue.CompareTo(value2) < 0) { return MaxValue; } return value; } throw new ArgumentException("Unable to clamp an object that is not an IntRange or int"); } public override bool IsValid(object value) { if (value.GetType() == typeof(FloatRange)) { FloatRange floatRange = (FloatRange)value; if (MinValue.CompareTo(floatRange.Min) <= 0) { return MaxValue.CompareTo(floatRange.Max) >= 0; } } else if (value.GetType() == typeof(float)) { float value2 = (float)value; if (MinValue.CompareTo(value2) <= 0) { return MaxValue.CompareTo(value2) >= 0; } } return false; } public override string ToDescriptionString() { return $"# Acceptable value range: From {MinValue} to {MaxValue}"; } } public class IntRange { private int min; private int max; public int Min { get { return min; } set { int num = value.CompareTo(max); if (num > 0) { throw new ArgumentException($"{value} is greater than the maximum value ({max})"); } min = value; } } public int Max { get { return max; } set { int num = value.CompareTo(min); if (num < 0) { throw new ArgumentException($"{value} is less than the minimum value ({min})"); } max = value; } } private int Both { get { if (min != max) { return max / min; } return min; } set { min = value; max = value; } } public (int min, int max) AsTuple() { return (min: min, max: max); } public IntRange(int min, int max) { if (min.CompareTo(max) <= 0) { this.min = min; this.max = max; return; } throw new ArgumentException($"{min} is greater than the maximum value ({max})"); } public static implicit operator int(IntRange ir) { return ir.Both; } public static explicit operator IntRange(int i) { return new IntRange(i, i); } public bool ContainsValue(int value) { if (value.CompareTo(min) >= 0) { return value.CompareTo(max) <= 0; } return false; } public override string ToString() { return $"[{min} - {max}]"; } public static IntRange Parse(string s) { string[] array = s.Split(new char[4] { '[', ' ', '-', ']' }, StringSplitOptions.RemoveEmptyEntries); return new IntRange(int.Parse(array[0]), int.Parse(array[1])); } public static IntRange Parse(string s1, string s2) { int num = int.Parse(s1); int num2 = int.Parse(s2); return new IntRange(num, num2); } public override bool Equals(object obj) { if (obj is IntRange intRange && intRange.Min == Min && intRange.Max == Max) { return true; } return false; } public override int GetHashCode() { return HashCode.Combine(min, max); } } public class AcceptableRangeforIntRange(int minValue, int maxValue) : AcceptableValueBase(typeof(IntRange)) { public int MinValue { get; } = minValue; public int MaxValue { get; } = maxValue; public override object Clamp(object value) { if (value.GetType() == typeof(IntRange)) { IntRange intRange = (IntRange)value; if (MinValue.CompareTo(intRange.Min) > 0) { intRange.Min = MinValue; } if (MaxValue.CompareTo(intRange.Max) < 0) { intRange.Max = MaxValue; } return intRange; } if (value.GetType() == typeof(int)) { int value2 = (int)value; if (MinValue.CompareTo(value2) > 0) { return MinValue; } if (MaxValue.CompareTo(value2) < 0) { return MaxValue; } return value; } throw new ArgumentException("Unable to clamp an object that is not an IntRange or int"); } public override bool IsValid(object value) { if (value.GetType() == typeof(IntRange)) { IntRange intRange = (IntRange)value; if (MinValue.CompareTo(intRange.Min) <= 0) { return MaxValue.CompareTo(intRange.Max) >= 0; } } else if (value.GetType() == typeof(int)) { int value2 = (int)value; if (MinValue.CompareTo(value2) <= 0) { return MaxValue.CompareTo(value2) >= 0; } } return false; } public override string ToDescriptionString() { return $"# Acceptable value range: From {MinValue} to {MaxValue}"; } } internal class SettingMenu : SmolRandomizerMenuBuilder { private readonly HashSet randoMenuButtons = new HashSet(); private static readonly Dictionary preInitSetting = new Dictionary(); internal static SettingMenu thisSettingMenu; private static readonly HashSet randoResetButtons = new HashSet(); public static event Action OnResetClicked; internal SettingMenu(LocalizedText title) : base(title) { ((ScrollingMenuScreen)this).Content.VerticalSpacing = 60f; GenerateMainPage(); thisSettingMenu = this; UpdateAllSubMenuColors(); } private void GenerateMainPage() { ConfigFile configFile = Settings.ConfigFile; Dictionary> dictionary = new Dictionary>(); foreach (KeyValuePair item in configFile) { if (!dictionary.TryGetValue(item.Key.Section, out var value)) { dictionary[item.Key.Section] = new Dictionary { { item.Key.Key, item.Value } }; } else { value.Add(item.Key.Key, item.Value); } } foreach (KeyValuePair> item2 in dictionary) { if (item2.Value.Count == 1) { KeyValuePair keyValuePair = item2.Value.First(); Label(item2.Key, (FontSizes)1); ElementBuilder(keyValuePair.Value); continue; } SmolRandomizerMenuBuilder screenBuilder = (SmolRandomizerMenuBuilder)(object)SmolRandomizerMenuBuilder.BuildPagedSubMenu(item2); Additional_Elements(ref screenBuilder, item2); randoMenuButtons.Add(SubMenuButton((AbstractMenuScreen)(object)screenBuilder, CuteRandoCore.GetRandoDescription(item2.Key), (FontSizes)1)); if (!(item2.Key == "Main Settings")) { continue; } TextButton saveInfo = SubMenuButton((AbstractMenuScreen)(object)SaveInfoScreen(), "Information for the current save.", (FontSizes)1); ((MenuElement)saveInfo).OnVisibilityChanged += delegate(bool visible) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (visible) { ((MenuElement)saveInfo).SetMainColor(Settings.Loaded ? Color.white : Color.gray); } }; randoMenuButtons.Add(saveInfo); } } private static void Additional_Elements(ref SmolRandomizerMenuBuilder screenBuilder, KeyValuePair> settingGroup) { string key = settingGroup.Key; Dictionary settings = settingGroup.Value; if (!key.Equals("Main Settings")) { screenBuilder.Button("Defaults", delegate { foreach (ConfigEntryBase value in settings.Values) { value.BoxedValue = value.DefaultValue; } }, "Resets the settings to their default values.", (FontSizes)1); screenBuilder.BlankSpace(); return; } screenBuilder.Button("Reset All Settings to Their Defaults", delegate { try { foreach (KeyValuePair item in Settings.ConfigFile) { if (item.Key.Section != "Main Settings") { item.Value.BoxedValue = item.Value.DefaultValue; } } } catch (Exception ex) { Console.Error.WriteLineAsync("[Smol Randomizer] Exception encountered when resetting all settings.\n" + ex.Message); } }, "Resets the settings for all the randomizers to their default settings.", (FontSizes)1); screenBuilder.BlankSpace(); } private static void ResetAllSavedData() { try { HashSet hashSet = new HashSet(); foreach (KeyValuePair item in Settings.ConfigFile) { string section = item.Key.Section; if (!hashSet.Contains(item.Key.Section)) { SettingMenu.OnResetClicked?.Invoke(section); hashSet.Add(section); } } } catch (Exception ex) { Console.Error.WriteLineAsync("[Smol Randomizer] Exception encountered when resetting all saved values.\n" + ex.Message); } } private static SmolRandomizerMenuBuilder SaveInfoScreen() { SmolRandomizerMenuBuilder smolRandomizerMenuBuilder = new SmolRandomizerMenuBuilder(LocalizedText.op_Implicit("Current Save Information")); TextLabel seedLabel = smolRandomizerMenuBuilder.Label(SeedText(), (FontSizes)1); ((MenuElement)seedLabel).OnVisibilityChanged += delegate(bool visible) { //IL_002d: 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) if (visible) { seedLabel.Text.text = SeedText(); ((MenuElement)seedLabel).SetMainColor(Settings.Loaded ? Color.white : Color.gray); } }; TextInput seedInput = SeedInput("Set Seed", "Sets the seed to the entered value.", seedLabel); TextButton seedButton = smolRandomizerMenuBuilder.Button("Reroll Seed", delegate { if (Settings.Loaded) { Settings.SaveData.RerollSeed(); seedLabel.Text.text = SeedText(); ((SelectableValueElement)(object)seedInput).Model.SetValue(Settings.SaveData.SaveSeed); } }, "", (FontSizes)1); ((MenuElement)seedButton).OnVisibilityChanged += delegate(bool visible) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (visible) { ((MenuElement)seedButton).SetMainColor(Settings.Loaded ? Color.white : Color.gray); } }; ((ScrollingMenuScreen)smolRandomizerMenuBuilder).Add((MenuElement)(object)seedInput); return smolRandomizerMenuBuilder; static TextInput SeedInput(string label, string description, TextLabel val2) { ParserTextModel val = TextModels.ForIntegers(); TextInput intInput = new TextInput(LocalizedText.op_Implicit(label), (ITextModel)(object)val, LocalizedText.op_Implicit(description)) { Value = (Settings.Loaded ? Settings.SaveData.SaveSeed : 0) }; ((SelectableValueElement)(object)intInput).OnValueChanged += delegate(int value) { if (Settings.Loaded) { Settings.SaveData.SetSeed(value); val2.Text.text = SeedText(); ResetAllSavedData(); } }; ((MenuElement)intInput).OnVisibilityChanged += delegate(bool visible) { //IL_0037: 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) if (visible) { ((SelectableValueElement)(object)intInput).Value = (Settings.Loaded ? Settings.SaveData.SaveSeed : 0); ((MenuElement)intInput).SetMainColor(Settings.Loaded ? Color.white : Color.gray); } }; return intInput; } static string SeedText() { if (!Settings.Loaded) { return "No Save Loaded"; } return "Seed: " + Settings.SaveData.SaveSeed; } } internal static void OnRandomizerEnable(object sender, EventArgs args) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) UpdateSubMenuColor(((SettingChangedEventArgs)args).ChangedSetting); } internal static void UpdateSubMenuColor(ConfigEntryBase entry) { bool flag; switch (entry.BoxedValue.ToString().ToLower()) { case "none": case "disabled": case "false": flag = true; break; default: flag = false; break; } bool flag2 = flag; preInitSetting[entry.Definition.Section] = flag2; if (thisSettingMenu != null) { thisSettingMenu?.UpdateSubMenuColor(entry.Definition.Section, flag2); } } internal void UpdateAllSubMenuColors() { foreach (KeyValuePair item in preInitSetting) { UpdateSubMenuColor(item.Key, item.Value); } } private void UpdateSubMenuColor(string entry, bool enabled) { //IL_003f: 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) foreach (TextButton randoMenuButton in randoMenuButtons) { if (randoMenuButton.ButtonText.text.TrimEnd() == entry) { if (enabled) { ((MenuElement)randoMenuButton).SetMainColor(SmolRandomizerMenuBuilder.Disabled); } else { ((MenuElement)randoMenuButton).SetMainColor(SmolRandomizerMenuBuilder.Enabled); } } } } internal static void OnEnabledRandomizerColorChanged(object sender, EventArgs args) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ChangeColors((RandomizerColors)((SettingChangedEventArgs)args).ChangedSetting.BoxedValue); } internal static void ChangeColors(RandomizerColors newColor) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0051: Unknown result type (might be due to invalid IL or missing references) if (CuteRandoCore.randomize) { switch (newColor) { case RandomizerColors.GreenRed: SmolRandomizerMenuBuilder.Enabled = Color.green; SmolRandomizerMenuBuilder.Disabled = Color.red; break; case RandomizerColors.BlueYellow: SmolRandomizerMenuBuilder.Enabled = SmolRandomizerMenuBuilder.EBlue; SmolRandomizerMenuBuilder.Disabled = SmolRandomizerMenuBuilder.DYellow; break; case RandomizerColors.PurpleOrange: SmolRandomizerMenuBuilder.Enabled = SmolRandomizerMenuBuilder.EPurple; SmolRandomizerMenuBuilder.Disabled = SmolRandomizerMenuBuilder.DOrange; break; default: throw new NotImplementedException(); } } else { SmolRandomizerMenuBuilder.Enabled = SmolRandomizerMenuBuilder.LightGray; SmolRandomizerMenuBuilder.Disabled = SmolRandomizerMenuBuilder.LightGray; } thisSettingMenu?.UpdateAllSubMenuColors(); } } public static class Settings { public enum RangeType { Percent, Value } internal static ConfigEntry enableRandomizer; public static readonly bool defaultEnableRandomizer = true; private static ConfigEntry enabledRandomizerColors; public static readonly RandomizerColors defaultEnabledRandomizerColors = RandomizerColors.GreenRed; public static readonly int maxSliderPercent = 300; public static readonly int maxSliderValue = 100; private static readonly TypeConverter FloatRangeConverter = new TypeConverter { ConvertToString = (object obj, Type type) => obj.ToString(), ConvertToObject = (string str, Type type) => FloatRange.Parse(str) }; private static readonly TypeConverter IntRangeConverter = new TypeConverter { ConvertToString = (object obj, Type type) => obj.ToString(), ConvertToObject = (string str, Type type) => IntRange.Parse(str) }; private static RandoPerSaveData saveData; private static bool loaded = false; internal static bool loading = false; public static bool EnableRandomizer { get { return enableRandomizer.Value; } internal set { enableRandomizer.Value = value; } } public static RandomizerColors EnabledRandomizerColors { get { return enabledRandomizerColors.Value; } internal set { enabledRandomizerColors.Value = value; } } public static ConfigFile ConfigFile { get; private set; } public static RandoPerSaveData SaveData { get { if (saveData == null) { if (saveData == null) { saveData = new RandoPerSaveData(); } RandoPerSaveData.Saving(); } return saveData; } set { saveData = value; saveData.Load(); } } public static bool Loaded { get { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (loading) { if ((int)GameManager.instance.sm.sceneType == 0) { loaded = true; } else { loaded = false; } loading = false; } return loaded; } } public static void Init(ConfigFile config) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown ConfigFile = config; TomlTypeConverter.AddConverter(typeof(FloatRange), FloatRangeConverter); TomlTypeConverter.AddConverter(typeof(IntRange), IntRangeConverter); enableRandomizer = config.Bind("Main Settings", "Enable Randomizer", defaultEnableRandomizer, new ConfigDescription("Enable Randomization.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); enabledRandomizerColors = config.Bind("Main Settings", "Enabled/Disabled Colors", defaultEnabledRandomizerColors, new ConfigDescription("Changes the colors of the enabled/disabled randomizers.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); enableRandomizer.SettingChanged += CuteRandoCore.UpdateSettings; enabledRandomizerColors.SettingChanged += SettingMenu.OnEnabledRandomizerColorChanged; SettingMenu.ChangeColors(EnabledRandomizerColors); } public static void RangeDrawer(ConfigEntryBase entry) { Type settingType = entry.SettingType; if (settingType == typeof(FloatRange)) { FloatRange obj = (FloatRange)entry.BoxedValue; string min = (obj.Min * 100f).ToString(); string max = (obj.Max * 100f).ToString(); TextRange(ref min, ref max, RangeType.Percent, entry.Description.AcceptableValues); try { entry.BoxedValue = new FloatRange(float.Parse(min) / 100f, float.Parse(max) / 100f); return; } catch (ArgumentException ex) { Console.Error.WriteLine(ex.Message); return; } } if (settingType == typeof(IntRange)) { IntRange obj2 = (IntRange)entry.BoxedValue; string min2 = obj2.Min.ToString(); string max2 = obj2.Max.ToString(); TextRange(ref min2, ref max2, RangeType.Value, entry.Description.AcceptableValues); try { entry.BoxedValue = checked(new IntRange((int)Math.Round(float.Parse(min2)), (int)Math.Round(float.Parse(max2)))); return; } catch (ArgumentException ex2) { Console.Error.WriteLine(ex2.Message); return; } } Console.Error.WriteLine("Unimplimented entryType"); } private static void TextRange(ref string min, ref string max, RangeType rangeType, AcceptableValueBase? acceptableRange = null) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Expected O, but got Unknown int num = 0; int num2 = (rangeType.Equals(RangeType.Percent) ? maxSliderPercent : maxSliderValue); checked { if (acceptableRange is AcceptableRangeforIntRange acceptableRangeforIntRange) { num = acceptableRangeforIntRange.MinValue; num2 = acceptableRangeforIntRange.MaxValue; } else if (acceptableRange is AcceptableRangeforFloatRange acceptableRangeforFloatRange) { num = (int)acceptableRangeforFloatRange.MinValue; num2 = (int)acceptableRangeforFloatRange.MaxValue; } VerticalScope val = new VerticalScope(GUIStyle.op_Implicit("box"), Array.Empty()); try { HorizontalScope val2 = new HorizontalScope(GUIStyle.op_Implicit("box"), Array.Empty()); try { GUILayout.Label("Minimum " + (rangeType.Equals(RangeType.Percent) ? "Percent" : "Value"), Array.Empty()); min = GUILayout.TextField(min, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) }); min = GUILayout.HorizontalSlider((float)Math.Round(float.Parse(min)), (float)num, (float)Math.Round(float.Parse(max)), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }).ToString(); } finally { ((IDisposable)val2)?.Dispose(); } HorizontalScope val3 = new HorizontalScope(GUIStyle.op_Implicit("box"), Array.Empty()); try { GUILayout.Label("Maximum " + (rangeType.Equals(RangeType.Percent) ? "Percent" : "Value"), Array.Empty()); max = GUILayout.TextField(max, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) }); max = GUILayout.HorizontalSlider((float)Math.Round(float.Parse(max)), (float)Math.Round(float.Parse(min)), (float)num2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }).ToString(); } finally { ((IDisposable)val3)?.Dispose(); } } finally { ((IDisposable)val)?.Dispose(); } } } } public class RandoPerSaveData { [JsonProperty] private int saveSeed = int.MinValue; [JsonIgnore] public int SaveSeed { get { if (saveSeed == int.MinValue) { saveSeed = CuteRandoCore.GetNewSaveSeed(); } return saveSeed; } } internal static event Action OnSettingsLoaded; internal static event Action OnSettingsSaved; internal void Load() { Settings.loading = true; } internal static void Saving() { RandoPerSaveData.OnSettingsSaved?.Invoke(); } internal void RerollSeed() { saveSeed = CuteRandoCore.GetNewSaveSeed(); } internal void SetSeed(int seed) { saveSeed = seed; } } public enum RandomizeByRangeTypes { Disabled, Percent, Value } internal enum RandomizeByFlatAmount { Disabled, Shift, Range } public enum RandomizerConsistencyA { None, Scene, EnemyType } public enum RandomizerConsistencyB { None, Scene, PerSave } [Flags] public enum RandomizerEnemyTypeFlags { None = 0, Enemy = 1, Boss = 2, Both = 3 } public enum RandomizerColors { GreenRed, BlueYellow, PurpleOrange } public class SmolRandomizerMenuBuilder : ScrollingMenuScreen { public const float VSPACE_TIGHT = 60f; public static Color LightGray => new Color(0.75f, 0.75f, 0.75f); public static Color EBlue => RGBInttoColor(12, 123, 220); public static Color DYellow => RGBInttoColor(255, 194, 10); public static Color EPurple => RGBInttoColor(151, 93, 255); public static Color DOrange => RGBInttoColor(230, 97, 0); public static Color Enabled { get; internal set; } public static Color Disabled { get; internal set; } public SmolRandomizerMenuBuilder(LocalizedText title) : base(title) { } private static Color RGBInttoColor(int r, int g, int b, int a = 255) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) return new Color((float)clamp(r) / 255f, (float)clamp(g) / 255f, (float)clamp(b) / 255f, (float)clamp(a) / 255f); static int clamp(int val) { if (val > 255) { val = 255; } if (val < 0) { val = 0; } return val; } } public TextLabel BlankSpace() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown TextLabel val = new TextLabel(LocalizedText.op_Implicit("")); ((ScrollingMenuScreen)this).Add((MenuElement)(object)val); return val; } public TextLabel Label(string label, FontSizes fontSize = (FontSizes)1) { //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) return Label(label, Color.white, fontSize); } public TextLabel Label(string label, Color color, FontSizes fontSize = (FontSizes)1) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //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) TextLabel val = new TextLabel(LocalizedText.op_Implicit(label)); ((MenuElement)val).SetFontSizes(fontSize); ((MenuElement)val).SetMainColor(color); val.Text.horizontalOverflow = (HorizontalWrapMode)1; ((ScrollingMenuScreen)this).Add((MenuElement)(object)val); return val; } public TextButton Button(string label, Action onClick, string description = "", FontSizes fontSize = (FontSizes)1) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0013: Unknown result type (might be due to invalid IL or missing references) TextButton val = new TextButton(LocalizedText.op_Implicit(label), LocalizedText.op_Implicit(description)); ((MenuElement)val).SetFontSizes(fontSize); val.OnSubmit = (Action)Delegate.Combine(val.OnSubmit, onClick); val.DescriptionText.horizontalOverflow = (HorizontalWrapMode)1; ((ScrollingMenuScreen)this).Add((MenuElement)(object)val); return val; } public TextButton SubMenuButton(AbstractMenuScreen subMenu, string description = "", FontSizes fontSize = (FontSizes)1) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0008: Unknown result type (might be due to invalid IL or missing references) TextButton val = new TextButton(subMenu); ((MenuElement)val).SetFontSizes(fontSize); LocalizedTextExtensions[val.DescriptionText] = LocalizedText.op_Implicit(description); val.DescriptionText.horizontalOverflow = (HorizontalWrapMode)1; ((ScrollingMenuScreen)this).Add((MenuElement)(object)val); BlankSpace(); return val; } public ChoiceElement ToggleElement(string label, ConfigEntryBase configEntry, string description = "", FontSizes fontSizes = (FontSizes)1) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) ChoiceElement val = new ChoiceElement(LocalizedText.op_Implicit(label), (IChoiceModel)(object)ChoiceModels.ForBool(), LocalizedText.op_Implicit(description)); ConfigEntryFactoryExtensions.SynchronizeRawWith((BaseSelectableValueElement)(object)val, configEntry); ((MenuElement)val).SetFontSizes(fontSizes); val.DescriptionText.horizontalOverflow = (HorizontalWrapMode)1; ((ScrollingMenuScreen)this).Add((MenuElement)(object)val); return val; } public object? EnumList(ConfigEntryBase configEntry, FontSizes fontSizes = (FontSizes)1) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) MenuElement val = default(MenuElement); if (!ConfigEntryFactory.GenerateEnumChoiceElement(configEntry, ref val) || val == null) { string text = "Failed Generation"; if (val == null) { text = "Null Element"; } Label("(" + text + ")" + ConfigEntryFactoryExtensions.LabelName(configEntry), Color.magenta, (FontSizes)1); return null; } val.SetFontSizes(fontSizes); ((ChoiceElement)(object)val).DescriptionText.horizontalOverflow = (HorizontalWrapMode)1; ((ScrollingMenuScreen)this).Add(val); return val; } public SliderElement[] SliderRangeFloat(string label, ConfigEntryBase configEntry, string description = "") { //IL_0018: Unknown result type (might be due to invalid IL or missing references) Label(label, (FontSizes)1); if (description != "") { Label(description, LightGray, (FontSizes)0).Text.horizontalOverflow = (HorizontalWrapMode)1; } float item; float item2; float num; float num2; if (!(configEntry.Description.AcceptableValues is AcceptableRangeforFloatRange acceptableRangeforFloatRange)) { Tuple.Create(0f, (float)Settings.maxSliderPercent).Deconstruct(out item, out item2); num = item; num2 = item2; } else { Tuple.Create(acceptableRangeforFloatRange.MinValue * 100f, acceptableRangeforFloatRange.MaxValue * 100f).Deconstruct(out item2, out item); num = item2; num2 = item; } int num3 = checked((int)Math.Round(num2 - num + 1f)); LinearFloatSliderModel val = SliderModels.ForFloats(num, num2, num3); ((SliderModel)(object)val).DisplayFn = SliderCuteExtensions.AsPercent; LinearFloatSliderModel val2 = SliderModels.ForFloats(num, num2, num3); ((SliderModel)(object)val2).DisplayFn = SliderCuteExtensions.AsPercent; SliderElement val3 = new SliderElement(LocalizedText.op_Implicit("Minimum Percent"), (SliderModel)(object)val); ((MenuElement)val3).SetFontSizes((FontSizes)0); ((SelectableValueElement)(object)val3).SynchronizeWithFloatRangeMin(configEntry); val3.ValueText.horizontalOverflow = (HorizontalWrapMode)1; ((ScrollingMenuScreen)this).Add((MenuElement)(object)val3); SliderElement val4 = new SliderElement(LocalizedText.op_Implicit("Maximum Percent"), (SliderModel)(object)val2); ((MenuElement)val4).SetFontSizes((FontSizes)0); ((SelectableValueElement)(object)val4).SynchronizeWithFloatRangeMax(configEntry); val4.ValueText.horizontalOverflow = (HorizontalWrapMode)1; ((ScrollingMenuScreen)this).Add((MenuElement)(object)val4); return new SliderElement[2] { val3, val4 }; } public SliderElement[] SliderRangeInt(string label, ConfigEntryBase configEntry, string description = "") { //IL_0018: Unknown result type (might be due to invalid IL or missing references) Label(label, (FontSizes)1); if (description != "") { Label(description, LightGray, (FontSizes)0).Text.horizontalOverflow = (HorizontalWrapMode)1; } int item; int item2; int num; int num2; if (!(configEntry.Description.AcceptableValues is AcceptableRangeforIntRange acceptableRangeforIntRange)) { Tuple.Create(0, Settings.maxSliderPercent).Deconstruct(out item, out item2); num = item; num2 = item2; } else { Tuple.Create(acceptableRangeforIntRange.MinValue, acceptableRangeforIntRange.MaxValue).Deconstruct(out item2, out item); num = item2; num2 = item; } IntSliderModel val = SliderModels.ForInts(num, num2); IntSliderModel val2 = SliderModels.ForInts(num, num2); SliderElement val3 = new SliderElement(LocalizedText.op_Implicit("Minimum Value"), (SliderModel)(object)val); ((MenuElement)val3).SetFontSizes((FontSizes)0); ((SelectableValueElement)(object)val3).SynchronizeWithIntRangeMin(configEntry); val3.ValueText.horizontalOverflow = (HorizontalWrapMode)1; ((ScrollingMenuScreen)this).Add((MenuElement)(object)val3); SliderElement val4 = new SliderElement(LocalizedText.op_Implicit("Maximum Value"), (SliderModel)(object)val2); ((MenuElement)val4).SetFontSizes((FontSizes)0); ((SelectableValueElement)(object)val4).SynchronizeWithIntRangeMax(configEntry); val4.ValueText.horizontalOverflow = (HorizontalWrapMode)1; ((ScrollingMenuScreen)this).Add((MenuElement)(object)val4); return new SliderElement[2] { val3, val4 }; } public TextInput IntInput(string label, ConfigEntryBase configEntry, string description = "") { ParserTextModel val = ((configEntry.Description.AcceptableValues is AcceptableValueRange val2) ? TextModels.ForIntegers(val2.MinValue, val2.MaxValue) : TextModels.ForIntegers()); TextInput val3 = new TextInput(LocalizedText.op_Implicit(label), (ITextModel)(object)val, LocalizedText.op_Implicit(description)); ConfigEntryFactoryExtensions.SynchronizeRawWith((BaseSelectableValueElement)(object)val3, configEntry); ((SelectableValueElement)(object)val3).Model.SetValue((int)configEntry.BoxedValue); val3.DescriptionText.horizontalOverflow = (HorizontalWrapMode)1; ((ScrollingMenuScreen)this).Add((MenuElement)(object)val3); return val3; } public SliderElement IntSlider(string label, ConfigEntryBase configEntry, string description = "") { //IL_0087: Unknown result type (might be due to invalid IL or missing references) int num; int num2; if (configEntry.Description.AcceptableValues is AcceptableValueRange range) { (num, num2) = SliderCuteExtensions.RangeAsTuple(range); } else { int maxSliderValue = Settings.maxSliderValue; num2 = maxSliderValue; num = 0; } IntSliderModel val = SliderModels.ForInts(num, num2); SliderElement val2 = new SliderElement(LocalizedText.op_Implicit(label), (SliderModel)(object)val); ConfigEntryFactoryExtensions.SynchronizeRawWith((BaseSelectableValueElement)(object)val2, configEntry); ((SelectableValueElement)(object)val2).Model.SetValue((int)configEntry.BoxedValue); ((ScrollingMenuScreen)this).Add((MenuElement)(object)val2); if (description != "") { Label(description, LightGray, (FontSizes)0).Text.horizontalOverflow = (HorizontalWrapMode)1; } return val2; } public static ScrollingMenuScreen BuildPagedSubMenu(KeyValuePair> settingGroup) { string key = settingGroup.Key; Dictionary value = settingGroup.Value; SmolRandomizerMenuBuilder smolRandomizerMenuBuilder = new SmolRandomizerMenuBuilder(LocalizedText.op_Implicit(key)); ((ScrollingMenuScreen)smolRandomizerMenuBuilder).Content.VerticalSpacing = 60f; foreach (ConfigEntryBase value2 in value.Values) { smolRandomizerMenuBuilder.ElementBuilder(value2); } return (ScrollingMenuScreen)(object)smolRandomizerMenuBuilder; } public void ElementBuilder(ConfigEntryBase entry) { //IL_0153: Unknown result type (might be due to invalid IL or missing references) switch (entry.SettingType.IsEnum ? "Enum" : entry.SettingType.Name) { case "Boolean": ToggleElement(ConfigEntryFactoryExtensions.LabelName(entry), entry, entry.Description.Description, (FontSizes)1); if (entry.Description.Description != "") { BlankSpace(); } break; case "Int32": IntSlider(ConfigEntryFactoryExtensions.LabelName(entry), entry, entry.Description.Description); if (entry.Description.Description != "") { BlankSpace(); } break; case "FloatRange": SliderRangeFloat(ConfigEntryFactoryExtensions.LabelName(entry), entry, entry.Description.Description); break; case "IntRange": SliderRangeInt(ConfigEntryFactoryExtensions.LabelName(entry), entry, entry.Description.Description); break; case "Enum": EnumList(entry, (FontSizes)1); if (entry.Description.Description != "") { BlankSpace(); } break; default: Label("(Unimplemented)" + ConfigEntryFactoryExtensions.LabelName(entry), Color.magenta, (FontSizes)1); break; } } } public static class SliderCuteExtensions { public static LocalizedText AsPercent(int _, float item) { return LocalizedText.op_Implicit($"{item:0.###}%"); } public static (int min, int max) RangeAsTuple(AcceptableValueRange range) { return (min: range.MinValue, max: range.MaxValue); } public static void SynchronizeWithFloatRangeMin(this SelectableValueElement element, ConfigEntryBase entry) { ConfigEntry configEntry = (entry as ConfigEntry) ?? throw new ArgumentException("Parameter entry was not a FloatRange"); IValueModel model = element.Model; model.SetValue(configEntry.Value.Min * 100f); model.OnValueChanged += delegate(float value) { value /= 100f; if (value > configEntry.Value.Max) { value = configEntry.Value.Max; model.SetValue(value * 100f); } ((ConfigEntryBase)configEntry).BoxedValue = new FloatRange(value, configEntry.Value.Max); }; ((MenuElement)element).OnVisibilityChanged += delegate(bool visible) { if (visible) { model.SetValue(configEntry.Value.Min * 100f); } }; configEntry.SettingChanged += handler; ((MenuDisposable)element).OnDispose += delegate { configEntry.SettingChanged -= handler; }; void handler(object _, EventArgs args) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) model.SetValue(((FloatRange)((SettingChangedEventArgs)args).ChangedSetting.BoxedValue).Min * 100f); } } public static void SynchronizeWithFloatRangeMax(this SelectableValueElement element, ConfigEntryBase entry) { ConfigEntry configEntry = (entry as ConfigEntry) ?? throw new ArgumentException("Parameter entry was not a FloatRange"); IValueModel model = element.Model; model.SetValue(configEntry.Value.Max * 100f); model.OnValueChanged += delegate(float value) { value /= 100f; if (value < configEntry.Value.Min) { value = configEntry.Value.Min; model.SetValue(value * 100f); } ((ConfigEntryBase)configEntry).BoxedValue = new FloatRange(configEntry.Value.Min, value); }; ((MenuElement)element).OnVisibilityChanged += delegate(bool visible) { if (visible) { model.SetValue(configEntry.Value.Max * 100f); } }; configEntry.SettingChanged += handler; ((MenuDisposable)element).OnDispose += delegate { configEntry.SettingChanged -= handler; }; void handler(object _, EventArgs args) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) model.SetValue(((FloatRange)((SettingChangedEventArgs)args).ChangedSetting.BoxedValue).Max * 100f); } } public static void SynchronizeWithIntRangeMin(this SelectableValueElement element, ConfigEntryBase entry) { ConfigEntry configEntry = (entry as ConfigEntry) ?? throw new ArgumentException("Parameter entry was not an IntRange"); IValueModel model = element.Model; model.SetValue(configEntry.Value.Min); model.OnValueChanged += delegate(int value) { if (value > configEntry.Value.Max) { value = configEntry.Value.Max; model.SetValue(value); } ((ConfigEntryBase)configEntry).BoxedValue = new IntRange(value, configEntry.Value.Max); }; ((MenuElement)element).OnVisibilityChanged += delegate(bool visible) { if (visible) { model.SetValue(configEntry.Value.Min); } }; configEntry.SettingChanged += handler; ((MenuDisposable)element).OnDispose += delegate { configEntry.SettingChanged -= handler; }; void handler(object _, EventArgs args) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) model.SetValue(((IntRange)((SettingChangedEventArgs)args).ChangedSetting.BoxedValue).Min); } } public static void SynchronizeWithIntRangeMax(this SelectableValueElement element, ConfigEntryBase entry) { ConfigEntry configEntry = (entry as ConfigEntry) ?? throw new ArgumentException("Parameter entry was not an IntRange"); IValueModel model = element.Model; model.SetValue(configEntry.Value.Max); model.OnValueChanged += delegate(int value) { if (value < configEntry.Value.Min) { value = configEntry.Value.Min; model.SetValue(value); } ((ConfigEntryBase)configEntry).BoxedValue = new IntRange(configEntry.Value.Min, value); }; ((MenuElement)element).OnVisibilityChanged += delegate(bool visible) { if (visible) { model.SetValue(configEntry.Value.Max); } }; configEntry.SettingChanged += handler; ((MenuDisposable)element).OnDispose += delegate { configEntry.SettingChanged -= handler; }; void handler(object _, EventArgs args) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) model.SetValue(((IntRange)((SettingChangedEventArgs)args).ChangedSetting.BoxedValue).Max); } } } } namespace Smol_Randomizer.Randomizers { internal class Enemy_Currency_Rando : Rando_Base { private static readonly Lazy instance = new Lazy(() => new Enemy_Currency_Rando()); private readonly HashSet currentEnemyHealthManagers = new HashSet(); private readonly Dictionary enemyGeoSets = new Dictionary(); private readonly Dictionary> sceneGeoSets = new Dictionary>(); private readonly Dictionary enemyShards = new Dictionary(); private readonly Dictionary> sceneShards = new Dictionary>(); internal static int smallGeoValue = 0; internal static int mediumGeoValue = 0; internal static int largeGeoValue = 0; private Randomizer_Info eventActiveEnemy; private Randomizer_Info eventOnFirstSceneFrame; private ConfigEntry randomizerConsistency; public readonly RandomizerConsistencyA defaultRandomizerConsistency; private ConfigEntry rosaryRandomizerType; public readonly RandomizeByRangeTypes defaultRosaryRandomizerType; private ConfigEntry rosaryPercentDropRange; public readonly FloatRange defaultRosaryPercentDropRange = new FloatRange(0.5f, 2f); private ConfigEntry rosaryValueDropRange; public readonly IntRange defaultRosaryValueDropRange = new IntRange(0, 15); private ConfigEntry shardRandomizerType; public readonly RandomizeByRangeTypes defaultShardRandomizerType; private ConfigEntry shardPercentDropRange; public readonly FloatRange defaultShardPercentDropRange = new FloatRange(0.5f, 2f); private ConfigEntry shardValueDropRange; public readonly IntRange defaultShardValueDropRange = new IntRange(0, 15); private RandomizeByRangeTypes currentRosarySetting; private RandomizeByRangeTypes currentShardSetting; public static Enemy_Currency_Rando Instance => instance.Value; public RandomizerConsistencyA RandomizerConsistency { get { return randomizerConsistency.Value; } internal set { randomizerConsistency.Value = value; } } public RandomizeByRangeTypes RosaryRandomizerType { get { return rosaryRandomizerType.Value; } internal set { rosaryRandomizerType.Value = value; } } public FloatRange RosaryPercentDropRange { get { return rosaryPercentDropRange.Value; } internal set { rosaryPercentDropRange.Value = value; } } public IntRange RosaryValueDropRange { get { return rosaryValueDropRange.Value; } internal set { rosaryValueDropRange.Value = value; } } public RandomizeByRangeTypes ShardRandomizerType { get { return shardRandomizerType.Value; } internal set { shardRandomizerType.Value = value; } } public FloatRange ShardPercentDropRange { get { return shardPercentDropRange.Value; } internal set { shardPercentDropRange.Value = value; } } public IntRange ShardValueDropRange { get { return shardValueDropRange.Value; } internal set { shardValueDropRange.Value = value; } } private Enemy_Currency_Rando() { InitRandomizer(); } private protected override void InitRandomizer() { RandomizerName = "Enemy Currency Randomizer"; RandomizerDescription = "Randomizes the quantity of Rosaries and Shards dropped by enemies."; if (CuteRandoCore.RegisterRandomizer(new Randomizer_Info(RandomizerName, RandomizerEventType.GameStartup, AccessTools.Method(typeof(Enemy_Currency_Rando), "GameStartup", (Type[])null, (Type[])null), this))) { eventActiveEnemy = new Randomizer_Info(RandomizerName, RandomizerEventType.ActiveEnemy, AccessTools.Method(typeof(Enemy_Currency_Rando), "SetCurrency", (Type[])null, (Type[])null), this); eventOnFirstSceneFrame = new Randomizer_Info(RandomizerName, RandomizerEventType.OnFirstSceneFrame, AccessTools.Method(typeof(Enemy_Currency_Rando), "OnFirstSceneFrame", (Type[])null, (Type[])null), this); smallGeoValue = ((IntReference)Gameplay.SmallGeoValue).Value; mediumGeoValue = ((IntReference)Gameplay.MediumGeoValue).Value; largeGeoValue = ((IntReference)Gameplay.LargeGeoValue).Value; base.InitRandomizer(); } } private protected override void Register() { CuteRandoCore.RegisterRandomizer(eventActiveEnemy); CuteRandoCore.RegisterRandomizer(eventOnFirstSceneFrame); } private protected override void Unregister() { CuteRandoCore.UnregisterRandomizer(eventActiveEnemy); CuteRandoCore.UnregisterRandomizer(eventOnFirstSceneFrame); } private void GameStartup() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown CuteRandoCore.harmony.Patch((MethodBase)AccessTools.Method(typeof(HealthManager), "OnEnable", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Enemy_Currency_Rando), "HealthManagerOnEnablePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private void OnFirstSceneFrame() { currentEnemyHealthManagers.RemoveWhere((HealthManager x) => (Object)(object)x == (Object)null); } private static void HealthManagerOnEnablePostfix(ref HealthManager __instance, ref int ___smallGeoDrops, ref int ___mediumGeoDrops, ref int ___largeGeoDrops, ref int ___shellShardDrops) { if (Instance.coreEnableRandomization && Instance.currentEnemyHealthManagers.Add(__instance)) { Instance.SetCurrency(__instance, ref ___smallGeoDrops, ref ___mediumGeoDrops, ref ___largeGeoDrops, ref ___shellShardDrops); } } private void SetCurrency(HealthManager thing, ref int smallGeoDrops, ref int mediumGeoDrops, ref int largeGeoDrops, ref int shellShardDrops) { if (!((Object)(object)thing == (Object)null)) { if (RosaryRandomizerType != RandomizeByRangeTypes.Disabled) { RandomizeGeo(thing, out RandomizedGeoSet geoSet); smallGeoDrops = geoSet.SmallGeo; mediumGeoDrops = geoSet.MediumGeo; largeGeoDrops = geoSet.LargeGeo; } if (ShardRandomizerType != RandomizeByRangeTypes.Disabled) { RandomizeShards(thing, ref shellShardDrops); } } } private void RandomizeShards(HealthManager thing, ref int shellShardDrops) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Scene scene = ((Component)thing).gameObject.scene; string name = ((Scene)(ref scene)).name; string text = ((Object)thing).name; int num = checked(text.IndexOf('(') - 1); if (num > 0) { text = text.Substring(0, num); } int value2; switch (RandomizerConsistency) { case RandomizerConsistencyA.EnemyType: if (!enemyShards.TryGetValue(text, out value2)) { value2 = GetRandoTypeShards(shellShardDrops, CuteRandoCore.RNGSeed(text)); enemyShards[text] = value2; } shellShardDrops = value2; break; case RandomizerConsistencyA.Scene: { if (!sceneShards.TryGetValue(name, out Dictionary value)) { value2 = GetRandoTypeShards(shellShardDrops, CuteRandoCore.RNGSeed(text + name)); sceneShards[name] = new Dictionary { { text, value2 } }; } else if (!value.TryGetValue(text, out value2)) { value2 = (value[text] = GetRandoTypeShards(shellShardDrops, CuteRandoCore.RNGSeed(text + name))); } shellShardDrops = value2; break; } case RandomizerConsistencyA.None: shellShardDrops = GetRandoTypeShards(shellShardDrops); break; default: throw new NotImplementedException(); } int GetRandoTypeShards(int num3, int seed = int.MinValue) { int result = 0; if (ShardRandomizerType == RandomizeByRangeTypes.Percent) { result = checked((int)Math.Round(CuteRandoCore.RandoHelper(ShardPercentDropRange.AsTuple(), seed) * (float)num3)); } else if (ShardRandomizerType == RandomizeByRangeTypes.Value) { result = CuteRandoCore.RandoHelper(ShardValueDropRange.AsTuple(), seed); } return result; } } private void RandomizeGeo(HealthManager thing, out RandomizedGeoSet geoSet) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) string text = ((Object)thing).name; int num = checked(text.IndexOf('(') - 1); if (num > 0) { text = text.Substring(0, num); } switch (RandomizerConsistency) { case RandomizerConsistencyA.EnemyType: if (!enemyGeoSets.TryGetValue(text, out geoSet)) { geoSet = GetRandoTypeGeo(thing, CuteRandoCore.RNGSeed(text)); enemyGeoSets[text] = geoSet; } break; case RandomizerConsistencyA.Scene: { Scene scene = ((Component)thing).gameObject.scene; string name = ((Scene)(ref scene)).name; if (!sceneGeoSets.TryGetValue(name, out Dictionary value)) { geoSet = GetRandoTypeGeo(thing, CuteRandoCore.RNGSeed(text + name)); sceneGeoSets[name] = new Dictionary { { text, geoSet } }; } else if (!value.TryGetValue(text, out geoSet)) { geoSet = GetRandoTypeGeo(thing, CuteRandoCore.RNGSeed(text + name)); value[text] = geoSet; } break; } case RandomizerConsistencyA.None: geoSet = GetRandoTypeGeo(thing); break; default: throw new NotImplementedException(); } RandomizedGeoSet GetRandoTypeGeo(HealthManager thing2, int seed = int.MinValue) { RandomizedGeoSet randomizedGeoSet = new RandomizedGeoSet(thing2); if (RosaryRandomizerType == RandomizeByRangeTypes.Percent) { randomizedGeoSet.MultiplyGeo(CuteRandoCore.RandoHelper(RosaryPercentDropRange.AsTuple(), seed)); } else if (RosaryRandomizerType == RandomizeByRangeTypes.Value) { randomizedGeoSet.SetGeoQuantity(CuteRandoCore.RandoHelper(RosaryValueDropRange.AsTuple(), seed)); } return randomizedGeoSet; } } private protected override void ResetAllLists() { currentEnemyHealthManagers.Clear(); enemyGeoSets.Clear(); enemyShards.Clear(); sceneGeoSets.Clear(); sceneShards.Clear(); } private protected override void InitSettings() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Expected O, but got Unknown //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Expected O, but got Unknown ConfigFile configFile = Smol_Randomizer.Settings.Settings.ConfigFile; randomizerConsistency = configFile.Bind(RandomizerName, "Currency Consistancy", defaultRandomizerConsistency, new ConfigDescription("Setting for if the drops should be consistent per enemy or room.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 6 } })); rosaryRandomizerType = configFile.Bind(RandomizerName, "Rosary Quantity", defaultRosaryRandomizerType, new ConfigDescription("Randomize rosary quantities dropped from enemies.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 5 } })); rosaryPercentDropRange = configFile.Bind(RandomizerName, "Rosary Percent Drop Range", defaultRosaryPercentDropRange, new ConfigDescription("Randomize the rosary drops as a percentage.", (AcceptableValueBase)(object)new AcceptableRangeforFloatRange(0f, 3f), new object[1] { new ConfigurationManagerAttributes { Order = 4, CustomDrawer = Smol_Randomizer.Settings.Settings.RangeDrawer } })); rosaryValueDropRange = configFile.Bind(RandomizerName, "Rosary Value Drop Range", defaultRosaryValueDropRange, new ConfigDescription("Randomize the rosary drops as a flat amount.", (AcceptableValueBase)(object)new AcceptableRangeforIntRange(0, 100), new object[1] { new ConfigurationManagerAttributes { Order = 3, CustomDrawer = Smol_Randomizer.Settings.Settings.RangeDrawer } })); shardRandomizerType = configFile.Bind(RandomizerName, "Shard Quantity", defaultShardRandomizerType, new ConfigDescription("Randomize shard quantities dropped from enemies.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); shardPercentDropRange = configFile.Bind(RandomizerName, "Shard Percent Drop Range", defaultShardPercentDropRange, new ConfigDescription("Randomize the shard drops as a percentage.", (AcceptableValueBase)(object)new AcceptableRangeforFloatRange(0f, 3f), new object[1] { new ConfigurationManagerAttributes { Order = 1, CustomDrawer = Smol_Randomizer.Settings.Settings.RangeDrawer } })); shardValueDropRange = configFile.Bind(RandomizerName, "Shard Value Drop Range", defaultShardValueDropRange, new ConfigDescription("Randomize the shard drops as a flat amount.", (AcceptableValueBase)(object)new AcceptableRangeforIntRange(0, 50), new object[1] { new ConfigurationManagerAttributes { Order = 0, CustomDrawer = Smol_Randomizer.Settings.Settings.RangeDrawer } })); currentRosarySetting = rosaryRandomizerType.Value; currentShardSetting = shardRandomizerType.Value; rosaryRandomizerType.SettingChanged += OnRosarySettingsUpdated; rosaryPercentDropRange.SettingChanged += OnRosarySettingsUpdated; rosaryValueDropRange.SettingChanged += OnRosarySettingsUpdated; shardRandomizerType.SettingChanged += OnShardSettingsUpdated; shardPercentDropRange.SettingChanged += OnShardSettingsUpdated; shardValueDropRange.SettingChanged += OnShardSettingsUpdated; if (rosaryRandomizerType.Value.Equals(RandomizeByRangeTypes.Disabled) && shardRandomizerType.Value.Equals(RandomizeByRangeTypes.Disabled)) { SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)rosaryRandomizerType); } else if (!rosaryRandomizerType.Value.Equals(RandomizeByRangeTypes.Disabled)) { SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)rosaryRandomizerType); } else { SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)shardRandomizerType); } } private protected override void OnSettingsUpdated(object sender, EventArgs args) { } private void OnRosarySettingsUpdated(object sender, EventArgs args) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (((SettingChangedEventArgs)args).ChangedSetting.BoxedValue is RandomizeByRangeTypes randomizeByRangeTypes && !randomizeByRangeTypes.Equals(currentRosarySetting)) { if (currentShardSetting.Equals(RandomizeByRangeTypes.Disabled)) { if (randomizeByRangeTypes.Equals(RandomizeByRangeTypes.Disabled) && !currentRosarySetting.Equals(RandomizeByRangeTypes.Disabled)) { Unregister(); SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)rosaryRandomizerType); } if (currentRosarySetting.Equals(RandomizeByRangeTypes.Disabled) && !randomizeByRangeTypes.Equals(RandomizeByRangeTypes.Disabled)) { Register(); SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)rosaryRandomizerType); } } currentRosarySetting = randomizeByRangeTypes; } enemyGeoSets.Clear(); sceneGeoSets.Clear(); } private void OnShardSettingsUpdated(object sender, EventArgs args) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (((SettingChangedEventArgs)args).ChangedSetting.BoxedValue is RandomizeByRangeTypes randomizeByRangeTypes && !randomizeByRangeTypes.Equals(currentShardSetting)) { if (currentRosarySetting.Equals(RandomizeByRangeTypes.Disabled)) { if (randomizeByRangeTypes.Equals(RandomizeByRangeTypes.Disabled) && !currentShardSetting.Equals(RandomizeByRangeTypes.Disabled)) { Unregister(); SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)shardRandomizerType); } if (currentShardSetting.Equals(RandomizeByRangeTypes.Disabled) && !randomizeByRangeTypes.Equals(RandomizeByRangeTypes.Disabled)) { Register(); SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)shardRandomizerType); } } currentShardSetting = randomizeByRangeTypes; } enemyShards.Clear(); sceneShards.Clear(); } } internal record RandomizedGeoSet { public int SmallGeo { get; private set; } public int MediumGeo { get; private set; } public int LargeGeo { get; private set; } [JsonConstructor] public RandomizedGeoSet(int SmallGeo = 0, int MediumGeo = 0, int LargeGeo = 0) { this.SmallGeo = SmallGeo; this.MediumGeo = MediumGeo; this.LargeGeo = LargeGeo; } public RandomizedGeoSet(HealthManager thing) : this((int)CuteRandoCore.TraverseHelper(thing, "smallGeoDrops").GetValue(), (int)CuteRandoCore.TraverseHelper(thing, "mediumGeoDrops").GetValue(), (int)CuteRandoCore.TraverseHelper(thing, "largeGeoDrops").GetValue()) { } public void MultiplyGeo(float multiplier) { checked { SmallGeo = (int)Math.Round((float)SmallGeo * multiplier); MediumGeo = (int)Math.Round((float)MediumGeo * multiplier); LargeGeo = (int)Math.Round((float)LargeGeo * multiplier); } } public void SetGeoQuantity(int quantity) { LargeGeo = quantity / Enemy_Currency_Rando.largeGeoValue; MediumGeo = quantity % Enemy_Currency_Rando.largeGeoValue / Enemy_Currency_Rando.mediumGeoValue; SmallGeo = quantity % Enemy_Currency_Rando.largeGeoValue % Enemy_Currency_Rando.mediumGeoValue / Enemy_Currency_Rando.smallGeoValue; } } internal class Enemy_Damage_Rando : Rando_Base { private static readonly Lazy instance = new Lazy(() => new Enemy_Damage_Rando()); private readonly Dictionary enemyDamageNumbers = new Dictionary(); private readonly Dictionary> sceneDamageNumbers = new Dictionary>(); private readonly HashSet currentHeroDamagers = new HashSet(); private Randomizer_Info eventActiveHeroDamager; private Randomizer_Info eventOnFirstSceneFrame; private ConfigEntry randomizerConsistency; public readonly RandomizerConsistencyA defaultRandomizerConsistency; private ConfigEntry damageModifierType; public readonly RandomizeByFlatAmount defaultDamageModifierType; private ConfigEntry damageShift; public readonly int defaultDamageShift = 1; private ConfigEntry damageRange; public readonly IntRange defaultDamageRange = new IntRange(0, 3); private ConfigEntry enemyDamageMinimum; public readonly bool defaultEnemyDamageMinimum; private ConfigEntry enemyAttackConsistancy; public readonly bool defaultEnemyAttackConsistancy = true; private RandomizeByFlatAmount currentDamageModifierType; public static Enemy_Damage_Rando Instance => instance.Value; public RandomizerConsistencyA RandomizerConsistency { get { return randomizerConsistency.Value; } internal set { randomizerConsistency.Value = value; } } public RandomizeByFlatAmount DamageModifierType { get { return damageModifierType.Value; } internal set { damageModifierType.Value = value; } } public int DamageShift { get { return damageShift.Value; } internal set { damageShift.Value = value; } } public IntRange DamageRange { get { return damageRange.Value; } internal set { damageRange.Value = value; } } public bool EnemyDamageMinimum { get { return enemyDamageMinimum.Value; } internal set { enemyDamageMinimum.Value = value; } } public bool EnemyAttackConsistancy { get { return enemyAttackConsistancy.Value; } internal set { enemyAttackConsistancy.Value = value; } } private Enemy_Damage_Rando() { InitRandomizer(); } private protected override void InitRandomizer() { RandomizerName = "Enemy Damage Randomizer"; RandomizerDescription = "Randomizes the damage delt to Hornet by enemies and bosses."; if (CuteRandoCore.RegisterRandomizer(new Randomizer_Info(RandomizerName, RandomizerEventType.GameStartup, AccessTools.Method(typeof(Enemy_Damage_Rando), "GameStartup", (Type[])null, (Type[])null), this))) { eventActiveHeroDamager = new Randomizer_Info(RandomizerName, RandomizerEventType.ActiveHeroDamager, AccessTools.Method(typeof(Enemy_Damage_Rando), "SetDamage", (Type[])null, (Type[])null), this); eventOnFirstSceneFrame = new Randomizer_Info(RandomizerName, RandomizerEventType.OnFirstSceneFrame, AccessTools.Method(typeof(Enemy_Damage_Rando), "OnFirstSceneFrame", (Type[])null, (Type[])null), this); base.InitRandomizer(); } } private protected override void Register() { CuteRandoCore.RegisterRandomizer(eventActiveHeroDamager); CuteRandoCore.RegisterRandomizer(eventOnFirstSceneFrame); } private protected override void Unregister() { CuteRandoCore.UnregisterRandomizer(eventActiveHeroDamager); CuteRandoCore.UnregisterRandomizer(eventOnFirstSceneFrame); } private void GameStartup() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown CuteRandoCore.harmony.Patch((MethodBase)AccessTools.Method(typeof(DamageHero), "OnEnable", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Enemy_Damage_Rando), "DamageHeroOnEnablePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private void OnFirstSceneFrame() { CleanCurrentHeroDamagers(); } private static void DamageHeroOnEnablePostfix(ref DamageHero __instance, ref HealthManager ___healthManager) { if (Instance.coreEnableRandomization && Instance.DamageModifierType != RandomizeByFlatAmount.Disabled && Instance.currentHeroDamagers.Add(__instance)) { Instance.SetDamage(__instance, ___healthManager); } } private void SetDamage(DamageHero damager, HealthManager enemyHealthManager) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)damager == (Object)null || (int)damager.hazardType != 1) { return; } Scene scene = ((Component)damager).gameObject.scene; string name = ((Scene)(ref scene)).name; int value = damager.damageDealt; string text = ((Object)damager).name; int num = text.IndexOf('('); if (num > 0) { text = text.Substring(0, num).TrimEnd(' '); } checked { if (EnemyAttackConsistancy && (Object)(object)enemyHealthManager != (Object)null) { string text2 = ((Object)enemyHealthManager).name; num = text2.IndexOf('('); if (num > 0) { text2 = text2.Substring(0, num).TrimEnd(' '); } if (text != text2 && char.IsDigit(text, text.Length - 1)) { do { text = text.Substring(0, text.Length - 1); } while (char.IsDigit(text, text.Length - 1)); if (text.LastIndexOf(' ') == text.Length - 1) { text = text.Substring(0, text.Length - 1); } } } switch (RandomizerConsistency) { case RandomizerConsistencyA.EnemyType: if (!enemyDamageNumbers.TryGetValue(text, out value)) { DamageSetter(ref value, CuteRandoCore.RNGSeed(text)); enemyDamageNumbers[text] = value; } damager.damageDealt = value; break; case RandomizerConsistencyA.Scene: { if (!sceneDamageNumbers.TryGetValue(name, out Dictionary value2)) { DamageSetter(ref value, CuteRandoCore.RNGSeed(text + name)); sceneDamageNumbers[name] = new Dictionary { { text, value } }; } else if (!value2.TryGetValue(text, out value)) { DamageSetter(ref value, CuteRandoCore.RNGSeed(text + name)); value2[text] = value; } damager.damageDealt = value; break; } case RandomizerConsistencyA.None: DamageSetter(ref damager.damageDealt); break; default: throw new NotImplementedException(); } } void DamageSetter(ref int damage, int seed = int.MinValue) { checked { if (DamageModifierType == RandomizeByFlatAmount.Shift) { damage += CuteRandoCore.RandoHelper(DamageShift * -1, DamageShift, seed); } else if (DamageModifierType == RandomizeByFlatAmount.Range) { damage = CuteRandoCore.RandoHelper(DamageRange.AsTuple(), seed); } if (damage <= 0 && EnemyDamageMinimum) { damage = 1; } else if (damage < 0) { damage = 0; } } } } private void CleanCurrentHeroDamagers() { currentHeroDamagers.RemoveWhere((DamageHero x) => (Object)(object)x == (Object)null); } private protected override void ResetAllLists() { currentHeroDamagers.Clear(); enemyDamageNumbers.Clear(); sceneDamageNumbers.Clear(); } private protected override void InitSettings() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Expected O, but got Unknown ConfigFile configFile = Smol_Randomizer.Settings.Settings.ConfigFile; damageModifierType = configFile.Bind(RandomizerName, "Enemy Damage Modifier Type", defaultDamageModifierType, new ConfigDescription("Damage modifier type. Shift adjusts by a random amount. Range randomizes within a range.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 5 } })); randomizerConsistency = configFile.Bind(RandomizerName, "Damage Consistancy", defaultRandomizerConsistency, new ConfigDescription("Setting for if the enemy damage should be consistent per enemy type or room.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 4 } })); damageShift = configFile.Bind(RandomizerName, "Damage Shift", defaultDamageShift, new ConfigDescription("Set damage shift amount. Acceptable values range from 0 to 10.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 10), new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); damageRange = configFile.Bind(RandomizerName, "Damage Range", defaultDamageRange, new ConfigDescription("Set damage range.", (AcceptableValueBase)(object)new AcceptableRangeforIntRange(0, 10), new object[1] { new ConfigurationManagerAttributes { Order = 2, CustomDrawer = Smol_Randomizer.Settings.Settings.RangeDrawer } })); enemyDamageMinimum = configFile.Bind(RandomizerName, "Enemy Damage Minimum", defaultEnemyDamageMinimum, new ConfigDescription("Enforces a minimum damage for enemies to be 1. Overrides set values.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); enemyAttackConsistancy = configFile.Bind(RandomizerName, "Enemy Attack Consistancy", defaultEnemyAttackConsistancy, new ConfigDescription("Makes each part of an attack do the same damage.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 0 } })); currentDamageModifierType = damageModifierType.Value; damageModifierType.SettingChanged += OnSettingsUpdated; damageShift.SettingChanged += OnSettingsUpdated; damageRange.SettingChanged += OnSettingsUpdated; enemyAttackConsistancy.SettingChanged += OnSettingsUpdated; damageModifierType.SettingChanged += SettingMenu.OnRandomizerEnable; SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)damageModifierType); } private protected override void OnSettingsUpdated(object sender, EventArgs args) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (((SettingChangedEventArgs)args).ChangedSetting.BoxedValue is RandomizeByFlatAmount randomizeByFlatAmount && !randomizeByFlatAmount.Equals(currentDamageModifierType)) { if (randomizeByFlatAmount.Equals(RandomizeByFlatAmount.Disabled) && !currentDamageModifierType.Equals(RandomizeByFlatAmount.Disabled)) { Unregister(); } if (currentDamageModifierType.Equals(RandomizeByFlatAmount.Disabled) && !randomizeByFlatAmount.Equals(RandomizeByFlatAmount.Disabled)) { Register(); } currentDamageModifierType = randomizeByFlatAmount; } ResetAllLists(); } } internal class Enemy_Health_Rando : Rando_Base { private static readonly Lazy instance = new Lazy(() => new Enemy_Health_Rando()); private readonly Dictionary enemyHealthNumbers = new Dictionary(); private readonly Dictionary> sceneHealthNumbers = new Dictionary>(); private readonly HashSet currentEnemyHealthManagers = new HashSet(); private Randomizer_Info eventActiveEnemy; private Randomizer_Info eventOnFirstSceneFrame; private ConfigEntry randomizerConsistency; public readonly RandomizerConsistencyA defaultRandomizerConsistency; private ConfigEntry enemyHealthRandomizerSetting; public readonly RandomizerEnemyTypeFlags defaultEnemyHealthRandomizerSetting; private ConfigEntry enemyHealthPercentRange; public readonly FloatRange defaultEnemyHealthPercentRange = new FloatRange(0.25f, 3f); private ConfigEntry bossHealthPercentRange; public readonly FloatRange defaultBossHealthPercentRange = new FloatRange(0.75f, 1.25f); private RandomizerEnemyTypeFlags currentHealthRandomizerSetting; public static Enemy_Health_Rando Instance => instance.Value; public RandomizerConsistencyA RandomizerConsistency { get { return randomizerConsistency.Value; } internal set { randomizerConsistency.Value = value; } } public RandomizerEnemyTypeFlags EnemyHealthRandomizerSetting { get { return enemyHealthRandomizerSetting.Value; } internal set { enemyHealthRandomizerSetting.Value = value; } } public FloatRange EnemyHealthPercentRange { get { return enemyHealthPercentRange.Value; } internal set { enemyHealthPercentRange.Value = value; } } public FloatRange BossHealthPercentRange { get { return bossHealthPercentRange.Value; } internal set { bossHealthPercentRange.Value = value; } } private Enemy_Health_Rando() { InitRandomizer(); } private protected override void InitRandomizer() { RandomizerName = "Enemy Health Randomizer"; RandomizerDescription = "Randomizes the health of enemies and bosses."; if (CuteRandoCore.RegisterRandomizer(new Randomizer_Info(RandomizerName, RandomizerEventType.GameStartup, AccessTools.Method(typeof(Enemy_Health_Rando), "GameStartup", (Type[])null, (Type[])null), this))) { eventActiveEnemy = new Randomizer_Info(RandomizerName, RandomizerEventType.ActiveEnemy, AccessTools.Method(typeof(Enemy_Health_Rando), "SetHealth", (Type[])null, (Type[])null), this); eventOnFirstSceneFrame = new Randomizer_Info(RandomizerName, RandomizerEventType.OnFirstSceneFrame, AccessTools.Method(typeof(Enemy_Health_Rando), "OnFirstSceneFrame", (Type[])null, (Type[])null), this); base.InitRandomizer(); } } private protected override void Register() { CuteRandoCore.RegisterRandomizer(eventActiveEnemy); CuteRandoCore.RegisterRandomizer(eventOnFirstSceneFrame); } private protected override void Unregister() { CuteRandoCore.UnregisterRandomizer(eventActiveEnemy); CuteRandoCore.UnregisterRandomizer(eventOnFirstSceneFrame); } private void GameStartup() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown CuteRandoCore.harmony.Patch((MethodBase)AccessTools.Method(typeof(HealthManager), "OnEnable", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Enemy_Health_Rando), "HealthManagerOnEnablePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private void OnFirstSceneFrame() { CleanCurrentHealthManagerList(); } internal static void HealthManagerOnEnablePostfix(ref HealthManager __instance, ref int ___initHp, ref int ___hp) { if (Instance.coreEnableRandomization && Instance.EnemyHealthRandomizerSetting != RandomizerEnemyTypeFlags.None && Instance.currentEnemyHealthManagers.Add(__instance)) { Instance.SetHealth(__instance, ref ___initHp, ref ___hp); } } private void SetHealth(HealthManager thing, ref int initHp, ref int hp) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)thing == (Object)null) { return; } bool flag = CuteRandoCore.IsBoss(thing); if (flag && !EnemyHealthRandomizerSetting.HasFlag(RandomizerEnemyTypeFlags.Boss)) { return; } Scene scene = ((Component)thing).gameObject.scene; string name = ((Scene)(ref scene)).name; string text = ((Object)thing).name; int num = checked(text.IndexOf('(') - 1); if (num > 0) { text = text.Substring(0, num); } int value2; switch (RandomizerConsistency) { case RandomizerConsistencyA.EnemyType: if (enemyHealthNumbers.TryGetValue(text, out value2)) { hp = (initHp = value2); } else { enemyHealthNumbers.Add(text, RandomizeHp(flag, ref initHp, ref hp, CuteRandoCore.RNGSeed(text))); } break; case RandomizerConsistencyA.Scene: { if (sceneHealthNumbers.TryGetValue(name, out Dictionary value)) { if (value.TryGetValue(text, out value2)) { hp = (initHp = value2); } else { value[text] = RandomizeHp(flag, ref initHp, ref hp, CuteRandoCore.RNGSeed(text + name)); } } else { sceneHealthNumbers[name] = new Dictionary { { text, RandomizeHp(flag, ref initHp, ref hp, CuteRandoCore.RNGSeed(text + name)) } }; } break; } case RandomizerConsistencyA.None: RandomizeHp(flag, ref initHp, ref hp); break; default: throw new NotImplementedException(); } int RandomizeHp(bool boss, ref int reference, ref int reference2, int seed = int.MinValue) { float num2 = CuteRandoCore.RandoHelper(boss ? BossHealthPercentRange.AsTuple() : EnemyHealthPercentRange.AsTuple(), seed); checked { int num3; if (reference <= 0) { num3 = (int)Math.Round((float)reference2 * num2); reference2 = (reference = num3); } else { num3 = (int)Math.Round((float)reference * num2); reference2 = (reference = num3); } return num3; } } } private void CleanCurrentHealthManagerList() { currentEnemyHealthManagers.RemoveWhere((HealthManager x) => (Object)(object)x == (Object)null); } private protected override void ResetAllLists() { currentEnemyHealthManagers.Clear(); enemyHealthNumbers.Clear(); sceneHealthNumbers.Clear(); } private protected override void InitSettings() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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 //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Expected O, but got Unknown ConfigFile configFile = Smol_Randomizer.Settings.Settings.ConfigFile; enemyHealthRandomizerSetting = configFile.Bind(RandomizerName, "Randomize Health", defaultEnemyHealthRandomizerSetting, new ConfigDescription("Allow randomization of enemy and/or boss health.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); randomizerConsistency = configFile.Bind(RandomizerName, "Health Consistency", defaultRandomizerConsistency, new ConfigDescription("Setting for if the enemy health should be consistent per enemy type or room.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); enemyHealthPercentRange = configFile.Bind(RandomizerName, "Enemy Health Range", defaultEnemyHealthPercentRange, new ConfigDescription("Randomize regular enemy health.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1, CustomDrawer = Smol_Randomizer.Settings.Settings.RangeDrawer } })); bossHealthPercentRange = configFile.Bind(RandomizerName, "Boss Health Range", defaultBossHealthPercentRange, new ConfigDescription("Randomize boss health.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 0, CustomDrawer = Smol_Randomizer.Settings.Settings.RangeDrawer } })); currentHealthRandomizerSetting = enemyHealthRandomizerSetting.Value; enemyHealthRandomizerSetting.SettingChanged += OnSettingsUpdated; enemyHealthPercentRange.SettingChanged += OnSettingsUpdated; bossHealthPercentRange.SettingChanged += OnSettingsUpdated; enemyHealthRandomizerSetting.SettingChanged += SettingMenu.OnRandomizerEnable; SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)enemyHealthRandomizerSetting); } private protected override void OnSettingsUpdated(object sender, EventArgs args) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (((SettingChangedEventArgs)args).ChangedSetting.BoxedValue is RandomizerEnemyTypeFlags randomizerEnemyTypeFlags && !randomizerEnemyTypeFlags.Equals(currentHealthRandomizerSetting)) { if (randomizerEnemyTypeFlags.Equals(RandomizerEnemyTypeFlags.None) && !currentHealthRandomizerSetting.Equals(RandomizerEnemyTypeFlags.None)) { Unregister(); } if (currentHealthRandomizerSetting.Equals(RandomizerEnemyTypeFlags.None) && !randomizerEnemyTypeFlags.Equals(RandomizerEnemyTypeFlags.None)) { Register(); } currentHealthRandomizerSetting = randomizerEnemyTypeFlags; } ResetAllLists(); } } internal sealed class Enemy_Size_Rando : Rando_Base { private static readonly Lazy instance = new Lazy(() => new Enemy_Size_Rando()); private readonly Dictionary enemySizes = new Dictionary(); private readonly Dictionary> sceneEnemySizes = new Dictionary>(); private readonly HashSet currentEnemyHealthManagers = new HashSet(); private Randomizer_Info eventActiveEnemy; private Randomizer_Info eventOnFirstSceneFrame; private ConfigEntry randomizerConsistency; public readonly RandomizerConsistencyA defaultRandomizerConsistency; private ConfigEntry enemySizeRandomizerSetting; public readonly RandomizerEnemyTypeFlags defaultEnemySizeRandomizerSetting; private ConfigEntry enemySizePercentRange; public readonly FloatRange defaultEnemySizePercentRange = new FloatRange(0.35f, 1.6f); private ConfigEntry bossSizePercentRange; public readonly FloatRange defaultBossSizePercentRange = new FloatRange(0.85f, 1.25f); private RandomizerEnemyTypeFlags currentSizeRandomizerSetting; public static Enemy_Size_Rando Instance => instance.Value; public RandomizerConsistencyA RandomizerConsistency { get { return randomizerConsistency.Value; } internal set { randomizerConsistency.Value = value; } } public RandomizerEnemyTypeFlags EnemySizeRandomizerSetting { get { return enemySizeRandomizerSetting.Value; } internal set { enemySizeRandomizerSetting.Value = value; } } public FloatRange EnemySizePercentRange { get { return enemySizePercentRange.Value; } internal set { enemySizePercentRange.Value = value; } } public FloatRange BossSizePercentRange { get { return bossSizePercentRange.Value; } internal set { bossSizePercentRange.Value = value; } } private Enemy_Size_Rando() { InitRandomizer(); } private protected override void InitRandomizer() { RandomizerName = "Enemy Size Randomizer"; RandomizerDescription = "Randomizes the sizes of enemies and bosses."; if (CuteRandoCore.RegisterRandomizer(new Randomizer_Info(RandomizerName, RandomizerEventType.GameStartup, AccessTools.Method(typeof(Enemy_Size_Rando), "GameStartup", (Type[])null, (Type[])null), this))) { eventActiveEnemy = new Randomizer_Info(RandomizerName, RandomizerEventType.ActiveEnemy, AccessTools.Method(typeof(Enemy_Size_Rando), "SetSize", (Type[])null, (Type[])null), this); eventOnFirstSceneFrame = new Randomizer_Info(RandomizerName, RandomizerEventType.OnFirstSceneFrame, AccessTools.Method(typeof(Enemy_Size_Rando), "OnFirstSceneFrame", (Type[])null, (Type[])null), this); base.InitRandomizer(); } } private protected override void Register() { CuteRandoCore.RegisterRandomizer(eventActiveEnemy); CuteRandoCore.RegisterRandomizer(eventOnFirstSceneFrame); } private protected override void Unregister() { CuteRandoCore.UnregisterRandomizer(eventActiveEnemy); CuteRandoCore.UnregisterRandomizer(eventOnFirstSceneFrame); } private void GameStartup() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown CuteRandoCore.harmony.Patch((MethodBase)AccessTools.Method(typeof(HealthManager), "OnEnable", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Enemy_Size_Rando), "HealthManagerOnEnablePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); CuteRandoCore.harmony.Patch((MethodBase)AccessTools.Method(typeof(SetScale), "DoSetScale", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Enemy_Size_Rando), "SetScaleDoSetScalePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private void OnFirstSceneFrame() { CleanCurrentHealthManagerList(); } private static void HealthManagerOnEnablePostfix(ref HealthManager __instance) { if (Instance.coreEnableRandomization && Instance.EnemySizeRandomizerSetting != RandomizerEnemyTypeFlags.None && Instance.currentEnemyHealthManagers.Add(__instance)) { Instance.SetSize(__instance); } } private static bool SetScaleDoSetScalePrefix(ref SetScale __instance) { float value = __instance.x.Value; if (value != -1f && value != 1f) { return true; } if ((Object)(object)((FsmStateAction)__instance).Owner != (Object)null && Instance.currentEnemyHealthManagers.Contains(((FsmStateAction)__instance).Owner.GetComponent())) { __instance.x = FsmFloat.op_Implicit(Extensions.GetScaleX(((FsmStateAction)__instance).Owner.transform)); } return true; } private void SetSize(HealthManager thing) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)thing == (Object)null || (Object)(object)((Component)thing).transform == (Object)null) { return; } bool flag = CuteRandoCore.IsBoss(thing); if (flag && !EnemySizeRandomizerSetting.HasFlag(RandomizerEnemyTypeFlags.Boss)) { return; } Scene scene = ((Component)thing).gameObject.scene; string name = ((Scene)(ref scene)).name; Walker component = ((Component)thing).gameObject.GetComponent(); Transform transform = ((Component)thing).transform; string text = ((Object)thing).name; int num = checked(text.IndexOf('(') - 1); if (num > 0) { text = text.Substring(0, num); } float value2; switch (RandomizerConsistency) { case RandomizerConsistencyA.EnemyType: if (enemySizes.TryGetValue(text, out value2)) { ApplySize(transform, value2, component); } else { enemySizes.Add(text, RandomizeSize(flag, transform, component, CuteRandoCore.RNGSeed(text))); } break; case RandomizerConsistencyA.Scene: { if (sceneEnemySizes.TryGetValue(name, out Dictionary value)) { if (value.TryGetValue(text, out value2)) { ApplySize(transform, value2, component); } else { value[text] = RandomizeSize(flag, transform, component, CuteRandoCore.RNGSeed(text + name)); } } else { sceneEnemySizes[name] = new Dictionary { { text, RandomizeSize(flag, transform, component, CuteRandoCore.RNGSeed(text + name)) } }; } break; } case RandomizerConsistencyA.None: RandomizeSize(flag, transform, component); break; default: throw new NotImplementedException(); } static void ApplySize(Transform val, float multiplier, Walker walker) { //IL_0002: 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_003e: Unknown result type (might be due to invalid IL or missing references) val.localScale *= multiplier; if ((Object)(object)walker != (Object)null) { Traverse obj = CuteRandoCore.TraverseHelper(walker, "rightScale"); int num2 = ((!((float)obj.GetValue() < 0f)) ? 1 : (-1)); obj.SetValue((object)(Math.Abs(val.localScale.x) * (float)num2)); } } float RandomizeSize(bool boss, Transform transform2, Walker walker, int seed = int.MinValue) { float num2 = CuteRandoCore.RandoHelper(boss ? BossSizePercentRange.AsTuple() : EnemySizePercentRange.AsTuple(), seed); ApplySize(transform2, num2, walker); return num2; } } private void CleanCurrentHealthManagerList() { currentEnemyHealthManagers.RemoveWhere((HealthManager x) => (Object)(object)x == (Object)null); } private protected override void ResetAllLists() { currentEnemyHealthManagers.Clear(); enemySizes.Clear(); sceneEnemySizes.Clear(); } private protected override void InitSettings() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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 //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Expected O, but got Unknown ConfigFile configFile = Smol_Randomizer.Settings.Settings.ConfigFile; enemySizeRandomizerSetting = configFile.Bind(RandomizerName, "Randomize Size", defaultEnemySizeRandomizerSetting, new ConfigDescription("Allow randomization of enemy and/or boss size.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); randomizerConsistency = configFile.Bind(RandomizerName, "Size Consistency", defaultRandomizerConsistency, new ConfigDescription("Setting for if the enemy size should be consistent per enemy type or room.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); enemySizePercentRange = configFile.Bind(RandomizerName, "Enemy Size Range", defaultEnemySizePercentRange, new ConfigDescription("Randomize regular enemy size.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1, CustomDrawer = Smol_Randomizer.Settings.Settings.RangeDrawer } })); bossSizePercentRange = configFile.Bind(RandomizerName, "Boss Size Range", defaultBossSizePercentRange, new ConfigDescription("Randomize boss size.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 0, CustomDrawer = Smol_Randomizer.Settings.Settings.RangeDrawer } })); currentSizeRandomizerSetting = enemySizeRandomizerSetting.Value; enemySizeRandomizerSetting.SettingChanged += OnSettingsUpdated; enemySizePercentRange.SettingChanged += OnSettingsUpdated; bossSizePercentRange.SettingChanged += OnSettingsUpdated; enemySizeRandomizerSetting.SettingChanged += SettingMenu.OnRandomizerEnable; SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)enemySizeRandomizerSetting); } private protected override void OnSettingsUpdated(object sender, EventArgs args) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (((SettingChangedEventArgs)args).ChangedSetting.BoxedValue is RandomizerEnemyTypeFlags randomizerEnemyTypeFlags && !randomizerEnemyTypeFlags.Equals(currentSizeRandomizerSetting)) { if (randomizerEnemyTypeFlags.Equals(RandomizerEnemyTypeFlags.None) && !currentSizeRandomizerSetting.Equals(RandomizerEnemyTypeFlags.None)) { CuteRandoCore.UnregisterRandomizer(eventActiveEnemy); CuteRandoCore.UnregisterRandomizer(eventOnFirstSceneFrame); } if (currentSizeRandomizerSetting.Equals(RandomizerEnemyTypeFlags.None) && !randomizerEnemyTypeFlags.Equals(RandomizerEnemyTypeFlags.None)) { CuteRandoCore.RegisterRandomizer(eventActiveEnemy); CuteRandoCore.RegisterRandomizer(eventOnFirstSceneFrame); } currentSizeRandomizerSetting = randomizerEnemyTypeFlags; } ResetAllLists(); } } internal class Hero_Damage_Rando : Rando_Base { private static readonly Lazy instance = new Lazy(() => new Hero_Damage_Rando()); public int saveNailDamageOffset = int.MinValue; public Dictionary nailUpgradeDamages = new Dictionary(); private ConfigEntry consistancySetting; public readonly PlayerNailDamageConsistancy defaultConsistancySetting; private ConfigEntry playerNailDamageRando; public readonly bool defaultPlayerNailDamageRando; private ConfigEntry playerNailDamageMinimum; public readonly bool defaultPlayerNailDamageMinimum = true; private ConfigEntry playerNailDamageShift; public readonly int defaultPlayerNailDamageShift = 3; public static Hero_Damage_Rando Instance => instance.Value; public PlayerNailDamageConsistancy ConsistancySetting { get { return consistancySetting.Value; } internal set { consistancySetting.Value = value; } } public bool PlayerNailDamageRando { get { return playerNailDamageRando.Value; } internal set { playerNailDamageRando.Value = value; } } public bool PlayerNailDamageMinimum { get { return playerNailDamageMinimum.Value; } internal set { playerNailDamageMinimum.Value = value; } } public int PlayerNailDamageShift { get { return playerNailDamageShift.Value; } internal set { playerNailDamageShift.Value = value; } } private Hero_Damage_Rando() { InitRandomizer(); } private protected override void InitRandomizer() { RandomizerName = "Hornet Damage Randomizer"; RandomizerDescription = "Randomizes the damage Hornet does."; if (CuteRandoCore.RegisterRandomizer(new Randomizer_Info(RandomizerName, RandomizerEventType.GameStartup, AccessTools.Method(typeof(Hero_Damage_Rando), "GameStartup", (Type[])null, (Type[])null), this))) { base.InitRandomizer(); } } private protected override void Register() { } private protected override void Unregister() { } private void GameStartup() { //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown Chainloader.PluginInfos.TryGetValue("io.github.hk-speedrunning.debugmod", out var value); if (Harmony.GetPatchInfo((MethodBase)AccessTools.Method(typeof(PlayerData), "get_nailDamage", (Type[])null, (Type[])null))?.Postfixes?.FirstOrDefault((Func)((Patch patch) => patch.owner == "io.github.hk-speedrunning.debugmod")) != null) { CuteRandoCore.harmony.Patch((MethodBase)AccessTools.Method(((object)value.Instance).GetType(), "Get_NailDamage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Hero_Damage_Rando), "DebugModGetNailDamagePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { CuteRandoCore.harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerData), "get_nailDamage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Hero_Damage_Rando), "PlayerDataGetNailDamagePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void DebugModGetNailDamagePostfix(ref int __result) { PlayerDataGetNailDamagePostfix(ref __result); } private static void PlayerDataGetNailDamagePostfix(ref int __result) { if (Instance.coreEnableRandomization && __result != 0 && Instance.PlayerNailDamageRando) { Instance.NailDamage(ref __result); } } private void NailDamage(ref int nailDamage) { checked { switch (ConsistancySetting) { case PlayerNailDamageConsistancy.NeedleUpgradeLevel: { if (!nailUpgradeDamages.TryGetValue(nailDamage, out var value)) { value = RollDamage(CuteRandoCore.RNGSeed(nailDamage.ToString())); nailUpgradeDamages.Add(nailDamage, value); } nailDamage += value; break; } case PlayerNailDamageConsistancy.PerSave: if (saveNailDamageOffset.Equals(int.MinValue)) { saveNailDamageOffset = RollDamage(Smol_Randomizer.Settings.Settings.SaveData.SaveSeed); } nailDamage += saveNailDamageOffset; break; case PlayerNailDamageConsistancy.None: nailDamage += RollDamage(); break; default: throw new NotImplementedException(); } if (nailDamage <= 0 && PlayerNailDamageMinimum) { nailDamage = 1; } } int RollDamage(int seed = int.MinValue) { return CuteRandoCore.RandoHelper(checked(PlayerNailDamageShift * -1), PlayerNailDamageShift, seed); } } private protected override void ResetAllLists() { nailUpgradeDamages.Clear(); saveNailDamageOffset = int.MinValue; } private protected override void InitSettings() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Expected O, but got Unknown ConfigFile configFile = Smol_Randomizer.Settings.Settings.ConfigFile; playerNailDamageRando = configFile.Bind(RandomizerName, "Randomize Hornets Damage", defaultPlayerNailDamageRando, new ConfigDescription("Enable/Disable Randomization of Hornet's Needle Damage.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); consistancySetting = configFile.Bind(RandomizerName, "Damage Consistancy", defaultConsistancySetting, new ConfigDescription("Randomize Hornet's needle damage in a consistant way.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 2 } })); playerNailDamageShift = configFile.Bind(RandomizerName, "Damage Shift", defaultPlayerNailDamageShift, new ConfigDescription("Shifts Hornet's needle damage within a range of the set value.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 20), new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); playerNailDamageMinimum = configFile.Bind(RandomizerName, "Hornet Damage Minimum", defaultPlayerNailDamageMinimum, new ConfigDescription("Sets the minimum damage that Hornet's needle can to to 1.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 0 } })); playerNailDamageShift.SettingChanged += OnSettingsUpdated; playerNailDamageRando.SettingChanged += SettingMenu.OnRandomizerEnable; SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)playerNailDamageRando); } private protected override void OnSettingsUpdated(object sender, EventArgs args) { ResetAllLists(); } } internal enum PlayerNailDamageConsistancy { None, NeedleUpgradeLevel, PerSave } internal abstract class Rando_Base { private protected bool coreEnableRandomization; public virtual string RandomizerName { get; private protected set; } public virtual string RandomizerDescription { get; private protected set; } private protected virtual void InitRandomizer() { coreEnableRandomization = Smol_Randomizer.Settings.Settings.EnableRandomizer; Register(); AddRandoDescription(); InitSettings(); Smol_Randomizer.Settings.Settings.enableRandomizer.SettingChanged += RandoCoreSetting; RandoPerSaveData.OnSettingsLoaded += OnSettingsLoaded; SettingMenu.OnResetClicked += OnResetClicked; } private protected abstract void Register(); private protected abstract void Unregister(); private protected void OnSettingsLoaded(bool hasSaveData) { ResetAllLists(); } private protected void OnResetClicked(string randoName) { if (randoName == RandomizerName) { ResetAllLists(); } } private protected abstract void InitSettings(); private protected abstract void OnSettingsUpdated(object sender, EventArgs args); private protected abstract void ResetAllLists(); private protected void AddRandoDescription() { CuteRandoCore.AddRandoDescription(RandomizerName, RandomizerDescription); } private protected void RandoCoreSetting(object sender, EventArgs args) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) coreEnableRandomization = (bool)((SettingChangedEventArgs)args).ChangedSetting.BoxedValue; if (coreEnableRandomization) { Register(); } else { Unregister(); } } } internal class World_Currency_Drop_Rando : Rando_Base { private static readonly Lazy instance = new Lazy(() => new World_Currency_Drop_Rando()); private readonly Dictionary sceneMultiplier = new Dictionary(); private readonly Dictionary sceneACMultiplier = new Dictionary(); private float consistantMultiplier; private float consistantACMultiplier; private string currentScene = ""; private Randomizer_Info eventActiveLimitRegion; private Randomizer_Info eventOnSceneLoad; private ConfigEntry consistencySetting; public readonly RandomizerConsistencyB defaultConsistencySetting; private ConfigEntry shardChanceEnable; public readonly bool defaultShardChanceEnable; private ConfigEntry shardChanceMultiplier; public readonly FloatRange defaultShardChanceMultiplier = new FloatRange(1f, 3f); private ConfigEntry architectChanceEnable; public readonly bool defaultArchitectChanceEnable; private ConfigEntry architectCrestMultiplier; public readonly FloatRange defaultArchitectCrestMultiplier = new FloatRange(1f, 3f); private bool architectCrestChanging; private bool shardChanceChanging; public static World_Currency_Drop_Rando Instance => instance.Value; public RandomizerConsistencyB ConsistencySetting { get { return consistencySetting.Value; } internal set { consistencySetting.Value = value; } } public bool ShardChanceEnable { get { return shardChanceEnable.Value; } internal set { shardChanceEnable.Value = value; } } public FloatRange ShardChanceMultiplier { get { return shardChanceMultiplier.Value; } internal set { shardChanceMultiplier.Value = value; } } public bool ArchitectChanceEnable { get { return architectChanceEnable.Value; } internal set { architectChanceEnable.Value = value; } } public FloatRange ArchitectCrestMultiplier { get { return architectCrestMultiplier.Value; } internal set { architectCrestMultiplier.Value = value; } } private World_Currency_Drop_Rando() { InitRandomizer(); } private protected override void InitRandomizer() { RandomizerName = "World Currency Drop Randomizer"; RandomizerDescription = "Randomizes the quantity of shards dropped from certain walls."; eventActiveLimitRegion = new Randomizer_Info(RandomizerName, RandomizerEventType.ActiveLimitRegion, AccessTools.Method(typeof(World_Currency_Drop_Rando), "SetCurrency", (Type[])null, (Type[])null), this); eventOnSceneLoad = new Randomizer_Info(RandomizerName, RandomizerEventType.OnSceneLoad, AccessTools.Method(typeof(World_Currency_Drop_Rando), "OnSceneLoad", (Type[])null, (Type[])null), this); base.InitRandomizer(); if (ConsistencySetting == RandomizerConsistencyB.Scene) { shardChanceChanging = true; architectCrestChanging = true; UpdateConsistantMultipliers(); } } private protected override void Register() { CuteRandoCore.RegisterRandomizer(eventActiveLimitRegion); CuteRandoCore.RegisterRandomizer(eventOnSceneLoad); } private protected override void Unregister() { CuteRandoCore.UnregisterRandomizer(eventActiveLimitRegion); CuteRandoCore.UnregisterRandomizer(eventOnSceneLoad); } private void OnSceneLoad(Scene scene, LoadSceneMode _) { currentScene = ((Scene)(ref scene)).name; } private void SetCurrency(ICurrencyLimitRegion region) { if (!coreEnableRandomization || region == null || (!ArchitectChanceEnable && !ShardChanceEnable)) { return; } float value; float value2; switch (ConsistencySetting) { case RandomizerConsistencyB.PerSave: value = consistantMultiplier; value2 = consistantACMultiplier; break; case RandomizerConsistencyB.Scene: if (!sceneMultiplier.TryGetValue(currentScene, out value)) { value = CuteRandoCore.RandoHelper(ShardChanceMultiplier.AsTuple(), CuteRandoCore.RNGSeed(currentScene)); sceneMultiplier[currentScene] = value; } if (!sceneACMultiplier.TryGetValue(currentScene, out value2)) { value2 = CuteRandoCore.RandoHelper(ArchitectCrestMultiplier.AsTuple(), CuteRandoCore.RNGSeed(currentScene)); sceneACMultiplier[currentScene] = value2; } break; case RandomizerConsistencyB.None: value = CuteRandoCore.RandoHelper(ShardChanceMultiplier.AsTuple()); value2 = CuteRandoCore.RandoHelper(ArchitectCrestMultiplier.AsTuple()); break; default: throw new NotImplementedException(); } Array obj = (Array)CuteRandoCore.TraverseHelper(region, "dropChances").GetValue(); Traverse val = CuteRandoCore.TraverseHelper(region, "architectProbabilities"); float[] array = new float[obj.Length]; int num = 0; foreach (object item in obj) { float num2 = (float)CuteRandoCore.TraverseHelper(item, "Probability").GetValue(); if ((int)CuteRandoCore.TraverseHelper(item, "dropAmount").GetValue() > 0) { if (ShardChanceEnable) { num2 *= value; CuteRandoCore.TraverseHelper(item, "Probability").SetValue((object)num2); } if (ArchitectChanceEnable) { array[num] = num2 * value2; } } else if (ArchitectChanceEnable) { array[num] = num2; } num = checked(num + 1); } if (ArchitectChanceEnable) { val.SetValue((object)array); } } private protected override void ResetAllLists() { shardChanceChanging = true; architectCrestChanging = true; UpdateConsistantMultipliers(); sceneMultiplier.Clear(); sceneACMultiplier.Clear(); } private void UpdateConsistantMultipliers() { if (shardChanceChanging) { consistantMultiplier = CuteRandoCore.RandoHelper(ShardChanceMultiplier.AsTuple(), CuteRandoCore.RNGSeed("consistantMultiplier")); } if (architectCrestChanging) { consistantACMultiplier = CuteRandoCore.RandoHelper(ArchitectCrestMultiplier.AsTuple(), CuteRandoCore.RNGSeed("consistantACMultiplier")); } architectCrestChanging = false; shardChanceChanging = false; } private protected override void InitSettings() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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 //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Expected O, but got Unknown ConfigFile configFile = Smol_Randomizer.Settings.Settings.ConfigFile; consistencySetting = configFile.Bind(RandomizerName, "Drop Chance Consistancy", defaultConsistencySetting, new ConfigDescription("Sets how consistant the chance for world drops are.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 4 } })); shardChanceEnable = configFile.Bind(RandomizerName, "Wall Shard Drop Chance", defaultShardChanceEnable, new ConfigDescription("Enable wall shard drop chance multiplier.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 3 } })); shardChanceMultiplier = configFile.Bind(RandomizerName, "Drop Chance Multiplier", defaultShardChanceMultiplier, new ConfigDescription("Wall shard drop chance multiplier.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 2, CustomDrawer = Smol_Randomizer.Settings.Settings.RangeDrawer } })); architectChanceEnable = configFile.Bind(RandomizerName, "Architect Shard Drop Chance", defaultArchitectChanceEnable, new ConfigDescription("Enable Architect Crest wall shard drop chance multiplier.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1 } })); architectCrestMultiplier = configFile.Bind(RandomizerName, "Architect Crest Multiplier", defaultArchitectCrestMultiplier, new ConfigDescription("Architect Crest wall shard multiplier.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 0, CustomDrawer = Smol_Randomizer.Settings.Settings.RangeDrawer } })); shardChanceEnable.SettingChanged += OnSettingsUpdated; architectChanceEnable.SettingChanged += OnSettingsUpdated; if (!shardChanceEnable.Value && !architectChanceEnable.Value) { SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)shardChanceEnable); } else if (shardChanceEnable.Value) { SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)shardChanceEnable); } else { SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)architectChanceEnable); } } private protected override void OnSettingsUpdated(object sender, EventArgs args) { if (!shardChanceEnable.Value && !architectChanceEnable.Value) { Unregister(); SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)shardChanceEnable); } if (shardChanceEnable.Value || architectChanceEnable.Value) { Register(); if (shardChanceEnable.Value) { SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)shardChanceEnable); } else { SettingMenu.UpdateSubMenuColor((ConfigEntryBase)(object)architectChanceEnable); } } ResetAllLists(); } } }