Decompiled source of QolElements v2.6.2
plugins/QolElements.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Dolso; using Dolso.RoO; using EntityStates; using EntityStates.Railgunner.Reload; using EntityStates.Seeker; using EntityStates.Toolbot; using EntityStates.VagrantNovaItem; using HG; using HG.GeneralSerializer; using HG.Reflection; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using QolElements.Elements; using QolElements.Elements.BandOverlay; using Rewired.ComponentControls.Effects; using RiskOfOptions; using RiskOfOptions.Components.Options; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.ContentManagement; using RoR2.EntityLogic; using RoR2.HudOverlay; using RoR2.Items; using RoR2.Networking; using RoR2.Projectile; using RoR2.Skills; using RoR2.UI; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] namespace Dolso { internal static class log { private static readonly ManualLogSource logger = Logger.CreateLogSource(Assembly.GetExecutingAssembly().GetName().Name); internal static void info(object data) { logger.LogInfo(data); } internal static void message(object data) { logger.LogMessage(data); } internal static void warning(object data) { logger.LogWarning(data); } internal static void error(object data) { logger.LogError(data); } internal static void fatal(object data) { logger.LogFatal(data); } internal static void LogError(this ILCursor c, object data) { logger.LogError((object)$"ILCursor failure, skipping: {data}\n{c}"); } internal static void LogErrorCaller(this ILCursor c, object data) { logger.LogError((object)$"ILCursor failed in {new StackFrame(1).GetMethod().Name}, skipping: {data}\n{c}"); } } internal static class HookManager { internal delegate bool ConfigEnabled<T>(T configValue); private class HookedConfig<T> { private readonly ConfigEnabled<T> enabled; private readonly IDetour detour; internal HookedConfig(ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, IDetour detour) { this.enabled = enabled; this.detour = detour; configEntry.SettingChanged += ConfigChanged; ConfigChanged(configEntry, null); } private void ConfigChanged(object sender, EventArgs args) { if (enabled(((ConfigEntry<T>)sender).Value)) { if (!detour.IsApplied) { detour.Apply(); } } else if (detour.IsApplied) { detour.Undo(); } } } internal const BindingFlags allFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static readonly ConfigEnabled<bool> boolConfigEnabled = BoolEnabled; private static ILHookConfig ilHookConfig = new ILHookConfig { ManualApply = true }; private static HookConfig onHookConfig = new HookConfig { ManualApply = true }; internal static void Hook(Type typeFrom, string fromMethod, Manipulator ilHook) { Hook(GetMethod(typeFrom, fromMethod), ilHook); } internal static void Hook(Delegate fromMethod, Manipulator ilHook) { Hook(fromMethod.Method, ilHook); } internal static void Hook(MethodBase fromMethod, Manipulator ilHook) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) try { new ILHook(fromMethod, ilHook, ref ilHookConfig).Apply(); } catch (Exception e) { e.LogHookError(fromMethod, ((Delegate)(object)ilHook).Method); } } internal static void Hook(Type typeFrom, string fromMethod, Delegate onHook) { Hook(GetMethod(typeFrom, fromMethod), onHook.Method, onHook.Target); } internal static void Hook(Delegate fromMethod, Delegate onHook) { Hook(fromMethod.Method, onHook.Method, onHook.Target); } internal static void Hook(MethodBase fromMethod, Delegate onHook) { Hook(fromMethod, onHook.Method, onHook.Target); } internal static void Hook(MethodBase fromMethod, MethodInfo onHook, object target = null) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) try { new Hook(fromMethod, onHook, target, ref onHookConfig).Apply(); } catch (Exception e) { e.LogHookError(fromMethod, onHook); } } internal static void HookConfig(this ConfigEntry<bool> configEntry, Type typeFrom, string fromMethod, Delegate hook) { configEntry.HookConfig(boolConfigEnabled, GetMethod(typeFrom, fromMethod), hook.Method, hook.Target); } internal static void HookConfig(this ConfigEntry<bool> configEntry, MethodBase fromMethod, Delegate hook) { configEntry.HookConfig(boolConfigEnabled, fromMethod, hook.Method, hook.Target); } internal static void HookConfig(this ConfigEntry<bool> configEntry, MethodBase fromMethod, MethodInfo hook) { configEntry.HookConfig(boolConfigEnabled, fromMethod, hook); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, Type typeFrom, string fromMethod, Delegate hook) { configEntry.HookConfig(enabled, GetMethod(typeFrom, fromMethod), hook.Method, hook.Target); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase fromMethod, Delegate hook) { configEntry.HookConfig(enabled, fromMethod, hook.Method, hook.Target); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase fromMethod, MethodInfo hook, object target = null) { try { new HookedConfig<T>(configEntry, enabled, ManualDetour(fromMethod, hook, target)); } catch (Exception e) { e.LogHookError(fromMethod, hook); } } internal static IDetour ManualDetour(Type typeFrom, string fromMethod, Delegate hook) { return ManualDetour(GetMethod(typeFrom, fromMethod), hook.Method, hook.Target); } internal static IDetour ManualDetour(MethodBase fromMethod, Delegate hook) { return ManualDetour(fromMethod, hook.Method, hook.Target); } internal static IDetour ManualDetour(MethodBase fromMethod, MethodInfo hook, object target = null) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown try { ParameterInfo[] parameters = hook.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(ILContext)) { return (IDetour)new ILHook(fromMethod, (Manipulator)hook.CreateDelegate(typeof(Manipulator)), ref ilHookConfig); } return (IDetour)new Hook(fromMethod, hook, target, ref onHookConfig); } catch (Exception e) { e.LogHookError(fromMethod, hook); return null; } } internal static MethodInfo GetMethod(Type typeFrom, string methodName) { if (typeFrom == null || methodName == null) { log.error($"Null argument in GetMethod: type={typeFrom}, name={methodName}"); return null; } MethodInfo[] array = (from a in typeFrom.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where a.Name == methodName select a).ToArray(); switch (array.Length) { case 1: return array[0]; case 0: log.error($"Failed to find method: {typeFrom}::{methodName}"); return null; default: { string text = $"{array.Length} ambiguous matches found for: {typeFrom}::{methodName}, may be incorrect"; MethodInfo[] array2 = array; for (int i = 0; i < array2.Length; i++) { text = text + "\n" + array2[i]; } log.warning(text); return array[0]; } } } internal static MethodInfo GetMethod(Type typeFrom, string methodName, params Type[] parameters) { if (typeFrom == null || methodName == null) { log.error($"Null argument in GetMethod: type={typeFrom}, name={methodName}"); return null; } MethodInfo? method = typeFrom.GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameters, null); if (method == null) { log.error($"Failed to find method: {typeFrom}::{methodName}_{parameters.Length}"); } return method; } internal static void SetPriority(string[] beforeIL = null, string[] beforeOn = null, string[] afterIL = null, string[] afterOn = null) { ilHookConfig.Before = beforeIL; onHookConfig.Before = beforeOn; ilHookConfig.After = afterIL; onHookConfig.After = afterOn; } internal static void LogHookError(this Exception e, MethodBase fromMethod, MethodInfo hook) { log.error((fromMethod == null) ? $"null from-method for hook: {hook.Name}\n{e}" : $"Failed to hook: {fromMethod.DeclaringType}::{fromMethod.Name} - {hook.Name}\n{e}"); } private static bool BoolEnabled(bool configValue) { return configValue; } } internal static class Utilities { private static GameObject _prefabParent; internal static GameObject CreatePrefab(GameObject gameObject, string name = null) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)_prefabParent)) { _prefabParent = new GameObject("DolsoPrefabs"); Object.DontDestroyOnLoad((Object)(object)_prefabParent); ((Object)_prefabParent).hideFlags = (HideFlags)61; _prefabParent.SetActive(false); } GameObject val = Object.Instantiate<GameObject>(gameObject, _prefabParent.transform); if (name != null) { ((Object)val).name = name; } return val; } internal static Task<TObj> GetAddressableAsync<TObj>(string addressable) where TObj : Object { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Addressables.LoadAssetAsync<TObj>((object)addressable).Task; } internal static Task<GameObject> GetAddressableAsync(string addressable) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Addressables.LoadAssetAsync<GameObject>((object)addressable).Task; } internal static void DoAddressable<TObj>(string addressable, Action<TObj> callback) where TObj : Object { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<TObj> val = Addressables.LoadAssetAsync<TObj>((object)addressable); val.Completed += delegate(AsyncOperationHandle<TObj> a) { callback(a.Result); }; } internal static void DoAddressable(string addressable, Action<GameObject> callback) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable); val.Completed += delegate(AsyncOperationHandle<GameObject> a) { callback(a.Result); }; } internal static void AddressableAddComp<TComp>(string addressable, Action<TComp> callback = null) where TComp : Component { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable); val.Completed += delegate(AsyncOperationHandle<GameObject> a) { TComp obj = a.Result.AddComponent<TComp>(); callback?.Invoke(obj); }; } internal static void AddressableAddCompSingle<Comp>(string addressable) where Comp : Component { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable); val.Completed += delegate(AsyncOperationHandle<GameObject> a) { if (!Object.op_Implicit((Object)(object)a.Result.GetComponent<Comp>())) { a.Result.AddComponent<Comp>(); } }; } internal static void ModifyStateConfig(this EntityStateConfiguration stateConfig, string fieldName, object newValue) { SerializedField[] serializedFields = stateConfig.serializedFieldsCollection.serializedFields; for (int i = 0; i < serializedFields.Length; i++) { if (serializedFields[i].fieldName == fieldName) { Object val = (Object)((newValue is Object) ? newValue : null); if (val != null) { serializedFields[i].fieldValue.objectValue = val; } else if (newValue != null && StringSerializer.CanSerializeType(newValue.GetType())) { serializedFields[i].fieldValue.stringValue = StringSerializer.Serialize(newValue.GetType(), newValue); } else { log.error("Invalid value for SerializedField: " + newValue); } return; } } log.error("Failed to find " + fieldName + " for " + ((Object)stateConfig).name); } internal static bool IsKeyDown(this KeyboardShortcut key, bool onlyJustPressed) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if ((onlyJustPressed && !Input.GetKeyDown(((KeyboardShortcut)(ref key)).MainKey)) || (!onlyJustPressed && !Input.GetKey(((KeyboardShortcut)(ref key)).MainKey))) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref key)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } return true; } } internal static class RiskofOptions { internal const string RooGuid = "com.rune580.riskofoptions"; internal static bool enabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); internal static void SetSprite(Sprite sprite) { ModSettingsManager.SetModIcon(sprite); } internal static void SetSpriteDefaultIcon() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) try { string fullName = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)).FullName; Texture2D val = new Texture2D(256, 256); if (ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(fullName, "icon.png")))) { ModSettingsManager.SetModIcon(Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f))); } else { log.error("Failed to load icon.png"); } } catch (Exception ex) { log.error("Failed to load icon.png\n" + ex); } } internal static void AddOption(ConfigEntryBase entry) { AddOption(entry, string.Empty, string.Empty); } internal static void AddOption(ConfigEntryBase entry, string categoryName = "", string name = "", bool restartRequired = false) { //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) Type settingType = entry.SettingType; object obj; if (!(settingType == typeof(float))) { obj = ((!(settingType == typeof(string))) ? ((!(settingType == typeof(bool))) ? ((!(settingType == typeof(int))) ? ((!(settingType == typeof(Color))) ? ((!(settingType == typeof(KeyboardShortcut))) ? ((object)((!settingType.IsEnum) ? ((ChoiceOption)null) : new ChoiceOption(entry, new ChoiceConfig()))) : ((object)new KeyBindOption((ConfigEntry<KeyboardShortcut>)(object)entry, new KeyBindConfig()))) : ((object)new ColorOption((ConfigEntry<Color>)(object)entry, new ColorOptionConfig()))) : ((object)new IntFieldOption((ConfigEntry<int>)(object)entry, new IntFieldConfig()))) : ((object)new CheckBoxOption((ConfigEntry<bool>)(object)entry, new CheckBoxConfig()))) : ((object)new StringInputFieldOption((ConfigEntry<string>)(object)entry, new InputFieldConfig { submitOn = (SubmitEnum)6, lineType = (LineType)0 }))); } else if (entry.Description.AcceptableValues is AcceptableValueRange<float>) { obj = (object)new SliderOption((ConfigEntry<float>)(object)entry, new SliderConfig { min = ((AcceptableValueRange<float>)(object)entry.Description.AcceptableValues).MinValue, max = ((AcceptableValueRange<float>)(object)entry.Description.AcceptableValues).MaxValue, FormatString = "{0:f2}", description = entry.DescWithDefault("{0:f2}") }); } else { ConfigEntry<float> obj2 = (ConfigEntry<float>)(object)entry; FloatFieldConfig val = new FloatFieldConfig(); ((NumericFieldConfig<float>)val).FormatString = "{0:f2}"; ((BaseOptionConfig)val).description = entry.DescWithDefault("{0:f2}"); obj = (object)new FloatFieldOption(obj2, val); } BaseOption val2 = (BaseOption)obj; if (val2 == null) { return; } BaseOptionConfig config = val2.GetConfig(); config.category = categoryName; config.name = name; config.restartRequired = restartRequired; if (config.description == "") { config.description = entry.DescWithDefault(); } try { ModSettingsManager.AddOption(val2); } catch (Exception arg) { log.error($"AddOption {entry.Definition} failed\n{arg}"); } } internal static void AddOption(ConfigEntry<float> entry, float min, float max, string format = "{0:f2}") { AddFloatSlider(entry, min, max, format); } internal static void AddFloatSlider(ConfigEntry<float> entry, float min, float max, string format = "{0:f2}", string categoryName = "") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new SliderOption(entry, new SliderConfig { min = min, max = max, FormatString = format, category = categoryName, description = ((ConfigEntryBase)(object)entry).DescWithDefault(format) })); } internal static void AddIntSlider(ConfigEntry<int> entry, int min, int max, string categoryName = "") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new IntSliderOption(entry, new IntSliderConfig { min = min, max = max, category = categoryName, description = ((ConfigEntryBase)(object)entry).DescWithDefault() })); } private static string DescWithDefault(this ConfigEntryBase entry, string format = "{0}") { return string.Format("{1}\n[Default: " + format + "]", entry.DefaultValue, entry.Description.Description); } } internal class TextHud { private static readonly Queue<TextHud> hudsToUpdate; internal bool resetOnTargetChanged = true; internal TextAlignmentOptions alignment = (TextAlignmentOptions)257; internal readonly ConfigEntry<bool> toggleEntry; private readonly ConfigEntry<int> fontsizeEntry; private readonly ConfigEntry<Vector2> positionEntry; private readonly string hudName; private GameObject objhud; private HGTextMeshProUGUI textMesh; private string textToUpdate; internal static HUD hud { get { if (HUD.instancesList.Count <= 0) { return null; } return HUD.instancesList[0]; } } internal bool enabled { get { if (toggleEntry == null) { return true; } return toggleEntry.Value; } } internal int fontSize { get { if (fontsizeEntry == null) { return -1; } return fontsizeEntry.Value; } } internal Vector2 position { get { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (positionEntry == null) { return new Vector2(1776.5f, 173f); } return positionEntry.Value; } } static TextHud() { hudsToUpdate = new Queue<TextHud>(); RoR2Application.onLateUpdate += LateUpdate; } private TextHud(ConfigFile configFile, string name, Vector2? defaultPosition, bool? defaultToggle, int? defaultFontSize) { //IL_000d: 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) hudName = name; if (defaultPosition.HasValue) { positionEntry = configFile.Bind<Vector2>(name, "Position", defaultPosition.Value, "Position of " + name + ", starting from bottom left corner"); } if (defaultToggle.HasValue) { toggleEntry = configFile.Bind<bool>(name, "Toggle", defaultToggle.Value, "Toggles " + name); } if (defaultFontSize.HasValue) { fontsizeEntry = configFile.Bind<int>(name, "Font size", defaultFontSize.Value, "Font size of " + name); } DoHooks(); } internal TextHud(ConfigFile configFile, string name) : this(configFile, name, null, null, null) { } internal TextHud(ConfigFile configFile, string name, Vector2 defaultPosition) : this(configFile, name, defaultPosition, null, null) { }//IL_0003: Unknown result type (might be due to invalid IL or missing references) internal TextHud(ConfigFile configFile, string name, Vector2 defaultPosition, bool defaultToggle) : this(configFile, name, defaultPosition, defaultToggle, null) { }//IL_0003: Unknown result type (might be due to invalid IL or missing references) internal TextHud(ConfigFile configFile, string name, Vector2 defaultPosition, int defaultFontSize) : this(configFile, name, defaultPosition, null, defaultFontSize) { }//IL_0003: Unknown result type (might be due to invalid IL or missing references) internal TextHud(ConfigFile configFile, string name, Vector2 defaultPosition, bool defaultToggle, int defaultFontSize) : this(configFile, name, (Vector2?)defaultPosition, (bool?)defaultToggle, (int?)defaultFontSize) { }//IL_0003: Unknown result type (might be due to invalid IL or missing references) internal void UpdateText(string text) { if (!hudsToUpdate.Contains(this)) { hudsToUpdate.Enqueue(this); } textToUpdate = text; } internal void ClearText() { if (Object.op_Implicit((Object)(object)objhud) && !string.IsNullOrEmpty(((TMP_Text)textMesh).text)) { UpdateText(string.Empty); } } private static void LateUpdate() { while (hudsToUpdate.Count > 0) { TextHud textHud = hudsToUpdate.Dequeue(); if (textHud.enabled) { if ((Object)(object)textHud.objhud == (Object)null) { textHud.InitHud(); } ((TMP_Text)textHud.textMesh).SetText(textHud.textToUpdate, true); } textHud.textToUpdate = null; } } internal void DestroyHUD() { Object.Destroy((Object)(object)objhud); } private void InitHud() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0036: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) objhud = new GameObject(hudName); RectTransform val = objhud.AddComponent<RectTransform>(); if (Object.op_Implicit((Object)(object)hud)) { SetTransform(val, hud); } val.sizeDelta = Vector2.zero; val.pivot = new Vector2(0.5f, 0.5f); val.anchoredPosition = position; textMesh = objhud.AddComponent<HGTextMeshProUGUI>(); ((TMP_Text)textMesh).fontSizeMin = 6f; if (fontSize >= 0) { ((TMP_Text)textMesh).fontSize = fontSize; } ((TMP_Text)textMesh).outlineColor = Color32.op_Implicit(Color.black); ((TMP_Text)textMesh).enableWordWrapping = false; ((TMP_Text)textMesh).alignment = alignment; } private void SetTransform(RectTransform textRect, HUD hud) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)hud.mainUIPanel.transform; ((Transform)textRect).SetParent(hud.mainUIPanel.transform, false); textRect.anchoredPosition3D = new Vector3(position.x, position.y, 0f - val.anchoredPosition3D.z); Vector2 anchorMax = (textRect.anchorMin = -val.anchorMin / (val.anchorMax - val.anchorMin)); textRect.anchorMax = anchorMax; } private void DoHooks() { HUD.onHudTargetChangedGlobal += Reset_OnHudTargetChanged; if (toggleEntry != null) { toggleEntry.SettingChanged += Toggle_Changed; } if (positionEntry != null) { positionEntry.SettingChanged += Position_Changed; } if (fontsizeEntry != null) { fontsizeEntry.SettingChanged += FontSize_Changed; } } private void Reset_OnHudTargetChanged(HUD obj) { if (Object.op_Implicit((Object)(object)objhud)) { if (!Object.op_Implicit((Object)(object)objhud.transform.parent)) { Transform transform = objhud.transform; SetTransform((RectTransform)(object)((transform is RectTransform) ? transform : null), hud); } if (resetOnTargetChanged) { ClearText(); } } } private void Toggle_Changed(object sender, EventArgs e) { if (Object.op_Implicit((Object)(object)objhud) && !enabled) { Object.Destroy((Object)(object)objhud); } } private void Position_Changed(object sender, EventArgs e) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)objhud)) { objhud.GetComponent<RectTransform>().anchoredPosition = position; } } private void FontSize_Changed(object sender, EventArgs e) { if (Object.op_Implicit((Object)(object)objhud) && fontSize > 0) { ((TMP_Text)textMesh).fontSize = fontSize; } } internal void AddRoOVector2Option() { AddRoOVector2Option(hudName); } internal void AddRoOVector2Option(string category) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_0049: 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) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (RiskofOptions.enabled) { new Vector2ScreenOption(positionEntry, hudName + " text", category, new Vector2ScreenOption.DotInfo(((int)alignment == 257) ? new Vector2(0f, 1f) : new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), new Vector2(0.5f, 0.5f), Vector2.op_Implicit(Vector3.zero)), toggleEntry, fontsizeEntry); } } } } namespace Dolso.RoO { internal class RooSliderInput2 : MonoBehaviour { internal UnityEvent<float> onValueChanged = new UnityEvent<float>(); internal string formatString = "F0"; private Slider slider; private TMP_InputField inputField; private float _value; internal float value { get { return _value; } set { if (_value != value) { _value = value; onValueChanged.Invoke(_value); } UpdateControls(); } } private void Awake() { slider = ((Component)this).GetComponentInChildren<Slider>(); inputField = ((Component)this).GetComponentInChildren<TMP_InputField>(); } internal void Setup(float min, float max) { slider.minValue = min; slider.maxValue = max; ((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)SliderChanged); ((UnityEvent<string>)(object)inputField.onEndEdit).AddListener((UnityAction<string>)OnTextEdited); ((UnityEvent<string>)(object)inputField.onSubmit).AddListener((UnityAction<string>)OnTextEdited); } internal void SetWholeNumbers(bool wholeNumbers) { slider.wholeNumbers = wholeNumbers; } private void UpdateControls() { if (formatString.StartsWith("F")) { slider.value = value; inputField.text = value.ToString(formatString, CultureInfo.InvariantCulture); } else { int num = (int)value; slider.value = num; inputField.text = num.ToString(formatString, CultureInfo.InvariantCulture); } } private void SliderChanged(float newValue) { value = newValue; } private void OnTextEdited(string newText) { if (float.TryParse(newText, out var result)) { value = Mathf.Clamp(result, slider.minValue, slider.maxValue); } else { value = _value; } } } internal class Vector2ScreenBehaviour : MonoBehaviour { private static Sprite checkOn; private static Sprite checkOff; private RooSliderInput2 sliderX; private RooSliderInput2 sliderY; private RooSliderInput2 sliderSize; private ChildLocator childLocator; private RectTransform positionDot; private RectTransform positionRect; private Vector2ScreenOption option; private Image checkBox; private bool boxState; private ref readonly Vector2ScreenOption.DotInfo dotinfo => ref option.dotInfo; private ConfigEntry<Vector2> positionEntry => option.positionEntry; private ConfigEntry<bool> toggleEntry => option.toggleEntry; private ConfigEntry<int> fontSizeEntry => option.fontSizeEntry; private ConfigEntry<float> scaleEntry => option.scaleEntry; internal static void LoadImages(AsyncOperationHandle<GameObject> handle) { CarouselController component = handle.Result.GetComponent<CarouselController>(); checkOn = component.choices[1].customSprite; checkOff = component.choices[0].customSprite; } internal void SetStartingValues(Vector2ScreenOption option) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Expected O, but got Unknown //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) this.option = option; positionDot.anchorMin = dotinfo.dotAnchor; positionDot.anchorMax = dotinfo.dotAnchor; positionDot.pivot = dotinfo.dotAnchor; positionRect.anchorMin = dotinfo.rectAnchor; positionRect.anchorMax = dotinfo.rectAnchor; positionRect.pivot = dotinfo.rectPivot; positionRect.sizeDelta = dotinfo.rectSize; Vector2 val = CalcMinMax(1920f, 0); sliderX = BuildSlider("PositionX", val.x, val.y); sliderX.formatString = "F0"; sliderX.onValueChanged.AddListener((UnityAction<float>)XChanged); Vector2 val2 = CalcMinMax(1080f, 1); sliderY = BuildSlider("PositionY", val2.x, val2.y); sliderY.formatString = "F0"; sliderY.onValueChanged.AddListener((UnityAction<float>)YChanged); sliderX.value = positionEntry.Value.x; sliderY.value = positionEntry.Value.y; if (toggleEntry != null) { boxState = toggleEntry.Value; ((UnityEvent)((Button)((Component)childLocator.FindChild("Toggle")).GetComponent<HGButton>()).onClick).AddListener(new UnityAction(ToggleChanged)); checkBox = ((Component)childLocator.FindChild("ToggleBox")).GetComponent<Image>(); checkBox.sprite = (boxState ? checkOn : checkOff); } else { ((Component)childLocator.FindChild("ToggleParent")).gameObject.SetActive(false); ((Component)childLocator.FindChild("ToggleText")).gameObject.SetActive(false); RectTransform component = ((Component)childLocator.FindChild("Size")).GetComponent<RectTransform>(); component.anchoredPosition += new Vector2(0f, 66f); } if (fontSizeEntry != null) { sliderSize = BuildSlider("Size", 5f, option.maxScale); sliderSize.formatString = "0"; sliderSize.onValueChanged.AddListener((UnityAction<float>)FontSizeChanged); sliderSize.value = fontSizeEntry.Value; } else if (scaleEntry != null) { sliderSize = BuildSlider("Size", 5f, option.maxScale); sliderSize.formatString = "F1"; sliderSize.onValueChanged.AddListener((UnityAction<float>)ScaleChanged); sliderSize.SetWholeNumbers(wholeNumbers: false); sliderSize.value = scaleEntry.Value; } else { ((Component)childLocator.FindChild("Size")).gameObject.SetActive(false); SetSize(option.maxScale * Vector2.one); } } private void Awake() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown childLocator = ((Component)this).GetComponent<ChildLocator>(); positionDot = ((Component)childLocator.FindChild("PositionDot")).GetComponent<RectTransform>(); positionRect = ((Component)childLocator.FindChild("PositionRect")).GetComponent<RectTransform>(); ((UnityEvent)((Button)((Component)childLocator.FindChild("Apply")).GetComponent<HGButton>()).onClick).AddListener(new UnityAction(Apply)); ((UnityEvent)((Button)((Component)childLocator.FindChild("Cancel")).GetComponent<HGButton>()).onClick).AddListener(new UnityAction(Close)); ((UnityEvent)((Button)((Component)childLocator.FindChild("Default")).GetComponent<HGButton>()).onClick).AddListener(new UnityAction(SetToDefault)); ((Component)this).GetComponent<RooEscapeRouter>().escapePressed.AddListener(new UnityAction(Close)); } private RooSliderInput2 BuildSlider(string childName, float min, float max) { RooSliderInput2 rooSliderInput = ((Component)childLocator.FindChild(childName)).gameObject.AddComponent<RooSliderInput2>(); rooSliderInput.Setup(min, max); return rooSliderInput; } private Vector2 CalcMinMax(float length, int index) { //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) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) Vector2 val = dotinfo.rectSize; float num = 0f - ((Vector2)(ref val))[index]; val = dotinfo.dotAnchor; float num2 = ((Vector2)(ref val))[index]; val = dotinfo.rectPivot; float num3 = num * (num2 - ((Vector2)(ref val))[index]); float num4 = 0f - length; val = dotinfo.rectAnchor; float num5 = num4 * ((Vector2)(ref val))[index] + num3; val = dotinfo.rectAnchor; float num6 = length * (1f - ((Vector2)(ref val))[index]) + num3; return new Vector2(num5, num6); } private void XChanged(float newValue) { //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) //IL_001a: Unknown result type (might be due to invalid IL or missing references) Vector2 anchoredPosition = positionRect.anchoredPosition; anchoredPosition.x = newValue; positionRect.anchoredPosition = anchoredPosition; } private void YChanged(float newValue) { //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) //IL_001a: Unknown result type (might be due to invalid IL or missing references) Vector2 anchoredPosition = positionRect.anchoredPosition; anchoredPosition.y = newValue; positionRect.anchoredPosition = anchoredPosition; } private void ToggleChanged() { boxState = !boxState; checkBox.sprite = (boxState ? checkOn : checkOff); } private void FontSizeChanged(float newValue) { //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) SetSize(newValue * Vector2.one); } private void ScaleChanged(float newValue) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) SetSize(newValue * dotinfo.rectSize); } private void SetSize(Vector2 size) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (((Vector2)(ref size)).sqrMagnitude < 16f) { positionDot.sizeDelta = ((Vector2)(ref size)).normalized * 4f; } else { positionDot.sizeDelta = size; } } private void SetToDefault() { //IL_000b: 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) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) Vector2 val = (Vector2)((ConfigEntryBase)positionEntry).DefaultValue; sliderX.value = val.x; sliderY.value = val.y; if (toggleEntry != null) { boxState = (bool)((ConfigEntryBase)toggleEntry).DefaultValue; checkBox.sprite = (boxState ? checkOn : checkOff); } if (fontSizeEntry != null) { sliderSize.value = (int)((ConfigEntryBase)fontSizeEntry).DefaultValue; } else if (scaleEntry != null) { sliderSize.value = (float)((ConfigEntryBase)scaleEntry).DefaultValue; } } private void Apply() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) positionEntry.Value = new Vector2((float)Math.Round(sliderX.value, 2), (float)Math.Round(sliderY.value, 2)); if (toggleEntry != null) { toggleEntry.Value = boxState; } if (fontSizeEntry != null) { fontSizeEntry.Value = Mathf.RoundToInt(sliderSize.value); } else if (scaleEntry != null) { scaleEntry.Value = sliderSize.value; } Close(); } private void Close() { Object.DestroyImmediate((Object)(object)((Component)this).gameObject); } } internal class Vector2ScreenOption { internal readonly struct DotInfo { internal readonly Vector2 dotAnchor; internal readonly Vector2 rectAnchor; internal readonly Vector2 rectPivot; internal readonly Vector2 rectSize; internal DotInfo(Vector2 dotAnchor, Vector2 rectAnchor, Vector2 rectPivot, Vector2 rectSize) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) this.dotAnchor = dotAnchor; this.rectAnchor = rectAnchor; this.rectPivot = rectPivot; this.rectSize = rectSize; } } private static GameObject prefab; internal readonly ConfigEntry<Vector2> positionEntry; internal readonly ConfigEntry<bool> toggleEntry; internal readonly ConfigEntry<int> fontSizeEntry; internal readonly ConfigEntry<float> scaleEntry; internal readonly DotInfo dotInfo; internal readonly float maxScale; internal Vector2ScreenOption(ConfigEntry<Vector2> positionEntry, DotInfo dotInfo, float dotSize = 16f) : this(positionEntry, ((ConfigEntryBase)positionEntry).Definition.Key, ((ConfigEntryBase)positionEntry).Definition.Section, dotInfo, null, null, null, dotSize) { } internal Vector2ScreenOption(ConfigEntry<Vector2> positionEntry, string name, string category, DotInfo dotInfo, float dotSize = 16f) : this(positionEntry, name, category, dotInfo, null, null, null, dotSize) { } internal Vector2ScreenOption(ConfigEntry<Vector2> positionEntry, DotInfo dotInfo, ConfigEntry<float> scaleEntry, float maxScale = 3f) : this(positionEntry, ((ConfigEntryBase)positionEntry).Definition.Key, ((ConfigEntryBase)positionEntry).Definition.Section, dotInfo, null, null, scaleEntry, maxScale) { } internal Vector2ScreenOption(ConfigEntry<Vector2> positionEntry, string name, string category, DotInfo dotInfo, ConfigEntry<float> scaleEntry, float maxScale = 3f) : this(positionEntry, name, category, dotInfo, null, null, scaleEntry, maxScale) { } internal Vector2ScreenOption(ConfigEntry<Vector2> positionEntry, string name, string category, DotInfo dotInfo, ConfigEntry<bool> toggleEntry = null, ConfigEntry<int> fontSizeEntry = null) : this(positionEntry, name, category, dotInfo, toggleEntry, fontSizeEntry, null, (fontSizeEntry == null) ? 16 : 36) { } private Vector2ScreenOption(ConfigEntry<Vector2> positionEntry, string name, string category, DotInfo dotInfo, ConfigEntry<bool> toggleEntry, ConfigEntry<int> fontSizeEntry, ConfigEntry<float> scaleEntry, float maxScale) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown this.positionEntry = positionEntry; this.dotInfo = dotInfo; this.maxScale = maxScale; this.toggleEntry = toggleEntry; this.fontSizeEntry = fontSizeEntry; this.scaleEntry = scaleEntry; ModSettingsManager.AddOption((BaseOption)new GenericButtonOption(name, category, "Position of " + name, "Open", new UnityAction(CreateOptionWindow))); if (!Object.op_Implicit((Object)(object)prefab)) { EnsureAssets(); } } internal static void LoadAssets(string assetFolder) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/UI/SettingsEntryButton, Bool.prefab"); val.Completed += Vector2ScreenBehaviour.LoadImages; if (!Path.IsPathRooted(assetFolder)) { assetFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), assetFolder, "dolso"); } AssetBundle obj = AssetBundle.LoadFromFile(assetFolder); prefab = obj.LoadAsset<GameObject>("TextHud Screen"); obj.Unload(false); } private static void EnsureAssets() { string text = Directory.EnumerateFiles(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dolso", SearchOption.AllDirectories).FirstOrDefault(); if (text != null) { LoadAssets(text); } else { log.warning("failed to find dolso assetbundle"); } } private void CreateOptionWindow() { Object.Instantiate<GameObject>(prefab).AddComponent<Vector2ScreenBehaviour>().SetStartingValues(this); } } } namespace QolElements { internal static class Assets { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static BankCallback <>9__9_0; internal void <SoundbankLoad>b__9_0(uint id, IntPtr ptr, AKRESULT akResult, object cookie) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((int)akResult == 1) { soundbankLoaded = true; } else { log.error(string.Format("Error loading bank: {0}, Error code: {1}", "QolElementsSoundbank.bnk", akResult)); } } } private const string folderName = "Assets"; private const string soundbankName = "QolElementsSoundbank.bnk"; internal static AssetBundle assetBundle; private static bool soundDirAdded; private static bool soundbankLoaded; private static string assetDirectory => Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Assets"); internal static void AssetsLoad(string bundleName) { if (!Object.op_Implicit((Object)(object)assetBundle) || ((Object)assetBundle).name != bundleName) { try { assetBundle = AssetBundle.LoadFromFile(Path.Combine(assetDirectory, bundleName)); } catch (Exception ex) { log.error("Failed to load assetbundle\n" + ex); } } } internal static void AssetsUnload() { assetBundle.Unload(false); } internal static void SoundbankLoad(bool enable) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown if (!soundDirAdded) { if (!enable) { return; } SoundDirectoryLoad(); } if (!enable || soundbankLoaded) { return; } object obj = <>c.<>9__9_0; if (obj == null) { BankCallback val = delegate(uint id, IntPtr ptr, AKRESULT akResult, object cookie) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((int)akResult == 1) { soundbankLoaded = true; } else { log.error(string.Format("Error loading bank: {0}, Error code: {1}", "QolElementsSoundbank.bnk", akResult)); } }; <>c.<>9__9_0 = val; obj = (object)val; } AkBankManager.LoadBankAsync("QolElementsSoundbank.bnk", (BankCallback)obj); } private static void SoundDirectoryLoad() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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) //IL_000d: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) AKRESULT val = AkSoundEngine.AddBasePath(assetDirectory); if ((int)val != 1) { log.error($"Error adding base path: {assetDirectory}, Error code: {val}"); } else { soundDirAdded = true; } } } internal static class Config { internal static ConfigFile configFile; private const string GENESISFALL = "Genesis Fall"; internal static ConfigEntry<Color> genesisFallColor; internal static ConfigEntry<bool> genesisFallConfirmToggle; internal static ConfigEntry<Color> genesisFallConfirmColor; internal static ConfigEntry<bool> genesisFallConfirmBarOverflow; internal static ConfigEntry<FallMode> genesisFallMode; private const string MISC = "Misc"; internal static ConfigEntry<bool> podToggle; internal static ConfigEntry<bool> OoBIToggle; internal static ConfigEntry<bool> clayApocAudioToggle; internal static ConfigEntry<bool> fistIndicatorToggle; internal static ConfigEntry<SpinPredictor.Mode> spinPredictorMode; internal static ConfigEntry<bool> mountainInteractToggle; internal static ConfigEntry<bool> mountainRewardToggle; private const string SURVIVOR = "Survivors"; internal static ConfigEntry<bool> autoReloadToggle; internal static ConfigEntry<float> autoReloadPortion; internal static ConfigEntry<bool> multRetoolToggle; internal static ConfigEntry<bool> meditateToggle; internal static ConfigEntry<float> meditateDuration; internal static ConfigEntry<bool> chefCleaverToggle; private const string LUNAR = "Lunar"; internal static ConfigEntry<bool> lunarShopToggle; internal static ConfigEntry<int> extraEulogies; internal static ConfigEntry<bool> resetEulogiesOnLoad; internal static ConfigEntry<bool> seerToggle; internal static ConfigEntry<float> seerGoldChance; internal static ConfigEntry<float> seerSotSGoldChance; internal static ConfigEntry<float> seerVoidChance; private const string EQUIPMODE = "Equipment Mode"; internal static ConfigEntry<float> equipmentHoldFreq; internal static ConfigEntry<float> equipmentToggleFreq; internal static ConfigEntry<KeyboardShortcut> equipmentKey; private const string BANDOVERLAY = "Band Overlay"; internal static ConfigEntry<Vector2> bandOverlayPosition; internal static ConfigEntry<float> bandOverlayScale; internal static ConfigEntry<BandMode> bandOverlayMode; internal static ConfigEntry<string> bandOverlayList; internal static ConfigEntry<bool> bandOverlayPlaySound; internal static void DoConfig(ConfigFile bepConfigFile) { //IL_001a: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Expected O, but got Unknown //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04ab: Expected O, but got Unknown //IL_04dd: Unknown result type (might be due to invalid IL or missing references) //IL_04e7: Expected O, but got Unknown //IL_0505: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Unknown result type (might be due to invalid IL or missing references) configFile = bepConfigFile; CountSpawns.monsterHud = new TextHud(configFile, "Monster Counter", new Vector2(3f, 43f), defaultToggle: true, 15) { resetOnTargetChanged = false }; GenesisTimer.genesisTextHud = new TextHud(configFile, "Genesis Timer", new Vector2(1100f, 650f), defaultToggle: true, 18); PingHud.pingHud = new TextHud(configFile, "Ping Hud", new Vector2(1895f, 1063f), defaultToggle: true, 13) { resetOnTargetChanged = false }; Equipment.modeText = new TextHud(configFile, "Equipment Mode") { resetOnTargetChanged = false }; Seeker.orbsTextHud = new TextHud(configFile, "Seeker Orb Counter", new Vector2(1070f, 490f), defaultToggle: true, 16); Seeker.sojournTextHud = new TextHud(configFile, "Sojourn Duration", new Vector2(1070f, 474f), defaultToggle: true, 18); genesisFallMode = configFile.Bind<FallMode>("Genesis Fall", "Mode", FallMode.GenesisOnly, "If Genesis Fall should diabled, only when you have Genesis Loop, or always active"); genesisFallColor = configFile.Bind<Color>("Genesis Fall", "Color", new Color(1f, 1f, 0f, 1f), "Genesis Fall ColorRGBA, hexadecimal"); genesisFallConfirmToggle = configFile.Bind<bool>("Genesis Fall", "Enough fall toggle", true, "Toggles if when fall dmg will put you below low health threshold, change fall color"); genesisFallConfirmColor = configFile.Bind<Color>("Genesis Fall", "Enough fall color", new Color(0f, 0f, 1f, 1f), "ColorRGBA, hexadecimal"); genesisFallConfirmBarOverflow = configFile.Bind<bool>("Genesis Fall", "Bar overflow", true, "Toggles if damage indictator should overflow past bar when damage is more than your hp. Only active when above low hp threshold"); autoReloadToggle = configFile.Bind<bool>("Misc", "Railgun auto reload toggle", true, "Toggles auto reloading railgunner"); autoReloadPortion = configFile.Bind<float>("Misc", "Railgun auto reload portion", 0.3f, new ConfigDescription("At which point in the boost window to auto reload", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); multRetoolToggle = configFile.Bind<bool>("Misc", "Mult Retool toggle", true, "Extend Mult's retool cooldown so that it smoothly swap spams"); podToggle = configFile.Bind<bool>("Misc", "Drop pod disabler", false, "If stage 1 drop pod should be diabled"); OoBIToggle = configFile.Bind<bool>("Misc", "Out of Bounds Indicator toggle", false, "Shows if you are about to run into a teleport wall"); clayApocAudioToggle = configFile.Bind<bool>("Misc", "Clay Apothecary Loudener", true, "Increases the volume on its teleport slam"); fistIndicatorToggle = configFile.Bind<bool>("Misc", "Teleport Slam Indicator", true, "Replaces the Stone Titan's fist attack and Clay Apothecary's teleport slam attack indicator with a sphere"); spinPredictorMode = configFile.Bind<SpinPredictor.Mode>("Misc", "Mithrix Spin Predictor", SpinPredictor.Mode.Off, "How the clientside predictor should be displayed"); meditateToggle = configFile.Bind<bool>("Misc", "Auto Meditate toggle", true, "If Seeker's Meditate inputs should be done automatically"); meditateDuration = configFile.Bind<float>("Misc", "Auto Meditate duration", 1.5f, "The duration of automatic meditate"); chefCleaverToggle = configFile.Bind<bool>("Survivors", "Auto Cleaver toggle", true, "Makes Chef's cleavers auto return when reaching max range, or letting go of primary button"); mountainInteractToggle = configFile.Bind<bool>("Mountain Counter", "On shrine interact toggle", true, "Toggles if when hitting mountain shrine, add mountain count after chat message"); mountainRewardToggle = configFile.Bind<bool>("Mountain Counter", "On boss reward toggle", true, "Toggles if when dropping boss rewards, to send chat message detailing item distribution"); lunarShopToggle = configFile.Bind<bool>("Lunar", "Lunar shop disabler", false, "Disable being able to buy lunar items in bazaar"); seerToggle = configFile.Bind<bool>("Lunar", "Seer Override Toggle", true, "Toggles Dream Seer overide chance"); seerGoldChance = configFile.Bind<float>("Lunar", "Seer Override Gilded Coast", 0.05f, "Chance of Gilded Coast option appearing insead of a normal stage. Vanilla chance is 0.05"); seerSotSGoldChance = configFile.Bind<float>("Lunar", "Seer Override SotS Gilded Coast", 0.1f, "Second roll for Gilded Coast that happens with SotS dlc. Vanilla chance is 0.1"); seerVoidChance = configFile.Bind<float>("Lunar", "Seer Override Deep Void", 0.05f, "Chance of Deep Void option appearing insead of a normal stage, after min stages have passed. Vanilla chance is 0.05"); extraEulogies = configFile.Bind<int>("IntrinsicEulogy", "Instrinsic Eulogies", 0, "Sets the amount of hidden extra eulogies."); resetEulogiesOnLoad = configFile.Bind<bool>("IntrinsicEulogy", "Reset Eulogies on Load", false, "Reset the amount of Instrinsic Eulogies on game load"); if (resetEulogiesOnLoad.Value && extraEulogies.Value != 0) { extraEulogies.Value = 0; } equipmentHoldFreq = configFile.Bind<float>("Equipment Mode", "Hold Frequency", 15f, new ConfigDescription("The frequency of automatic equipment usage while in Hold mode", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>())); equipmentToggleFreq = configFile.Bind<float>("Equipment Mode", "Toggle Frequency", 10f, new ConfigDescription("The frequency of automatic equipment usage while in Toggle mode", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>())); equipmentKey = configFile.Bind<KeyboardShortcut>("Equipment Mode", "Key", new KeyboardShortcut((KeyCode)286, Array.Empty<KeyCode>()), "The key for switching equipment mode"); bandOverlayPosition = configFile.Bind<Vector2>("Band Overlay", "Image Position", new Vector2(-230f, -70f), "Position of image"); bandOverlayScale = configFile.Bind<float>("Band Overlay", "Image Scale", 1f, "Scale of image"); bandOverlayMode = configFile.Bind<BandMode>("Band Overlay", "Mode", BandMode.DepleteAndNotify, "How the overlay presents band cooldown"); bandOverlayPlaySound = configFile.Bind<bool>("Band Overlay", "Play Sound", true, "If should play sound when band becomes ready"); bandOverlayList = configFile.Bind<string>("Band Overlay", "Survivor List", "Loader, Railgunner, Magrider", " Survivors listed here will have Band Overlay enabled. Case insensitive, english names, seperated by ', ' or ','.\n If an entry is 'all' then Band Overlay will be enabled for all bodies.\n If using internal names they must match exactly, use the body_list command to view them"); if (RiskofOptions.enabled) { DoOptions(); } } private static void DoOptions() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) RiskofOptions.SetSpriteDefaultIcon(); Vector2ScreenOption.LoadAssets("Assets"); CountSpawns.monsterHud.AddRoOVector2Option("Misc"); PingHud.pingHud.AddRoOVector2Option("Misc"); Seeker.orbsTextHud.AddRoOVector2Option("Survivors"); Seeker.sojournTextHud.AddRoOVector2Option("Survivors"); GenesisTimer.genesisTextHud.AddRoOVector2Option("Genesis Fall"); new Vector2ScreenOption(bandOverlayPosition, new Vector2ScreenOption.DotInfo(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(50f, 50f)), bandOverlayScale); RiskofOptions.AddOption((ConfigEntryBase)(object)autoReloadToggle, "Survivors"); RiskofOptions.AddFloatSlider(autoReloadPortion, 0f, 1f, "{0:f2}", "Survivors"); RiskofOptions.AddOption((ConfigEntryBase)(object)meditateToggle, "Survivors"); RiskofOptions.AddFloatSlider(meditateDuration, 0f, 5f, "{0:f2}", "Survivors"); RiskofOptions.AddOption((ConfigEntryBase)(object)multRetoolToggle, "Survivors"); RiskofOptions.AddOption((ConfigEntryBase)(object)chefCleaverToggle, "Survivors"); RiskofOptions.AddOption((ConfigEntryBase)(object)genesisFallMode); RiskofOptions.AddOption((ConfigEntryBase)(object)genesisFallColor); RiskofOptions.AddOption((ConfigEntryBase)(object)genesisFallConfirmToggle); RiskofOptions.AddOption((ConfigEntryBase)(object)genesisFallConfirmColor); RiskofOptions.AddOption((ConfigEntryBase)(object)genesisFallConfirmBarOverflow); RiskofOptions.AddOption((ConfigEntryBase)(object)podToggle); RiskofOptions.AddOption((ConfigEntryBase)(object)OoBIToggle); RiskofOptions.AddOption((ConfigEntryBase)(object)clayApocAudioToggle); RiskofOptions.AddOption((ConfigEntryBase)(object)spinPredictorMode); RiskofOptions.AddOption((ConfigEntryBase)(object)fistIndicatorToggle); RiskofOptions.AddOption((ConfigEntryBase)(object)lunarShopToggle); RiskofOptions.AddIntSlider(extraEulogies, 0, 20); RiskofOptions.AddOption((ConfigEntryBase)(object)resetEulogiesOnLoad); RiskofOptions.AddOption((ConfigEntryBase)(object)seerToggle); RiskofOptions.AddOption(seerGoldChance, 0f, 1f); RiskofOptions.AddOption(seerSotSGoldChance, 0f, 1f); RiskofOptions.AddOption(seerVoidChance, 0f, 1f); RiskofOptions.AddOption((ConfigEntryBase)(object)mountainInteractToggle); RiskofOptions.AddOption((ConfigEntryBase)(object)mountainRewardToggle); RiskofOptions.AddOption(equipmentHoldFreq, 1f, 60f, "{0:0} hz"); RiskofOptions.AddOption(equipmentToggleFreq, 1f, 60f, "{0:0} hz"); RiskofOptions.AddOption((ConfigEntryBase)(object)equipmentKey); RiskofOptions.AddOption((ConfigEntryBase)(object)bandOverlayMode); RiskofOptions.AddOption((ConfigEntryBase)(object)bandOverlayPlaySound); RiskofOptions.AddOption((ConfigEntryBase)(object)bandOverlayList); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void qolReloadConfig(ConCommandArgs args) { configFile.Reload(); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("dolso.qolelements", "QoLElements", "2.6.2")] public class Main : BaseUnityPlugin { private void Awake() { Config.DoConfig(((BaseUnityPlugin)this).Config); SetupElementAttribute.ScanAndExecute(); Config.podToggle.HookConfig(typeof(Stage).GetConstructor(Type.EmptyTypes), (Action<Action<Stage>, Stage>)delegate(Action<Stage> orig, Stage self) { orig(self); self.usePod = false; }); Config.autoReloadToggle.HookConfig(typeof(Reloading), "FixedUpdate", (Action<Action<Reloading>, Reloading>)delegate(Action<Reloading> orig, Reloading self) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown orig(self); if (((EntityState)self).fixedAge >= self.adjustedBoostWindowDelay + Config.autoReloadPortion.Value * self.adjustedBoostWindowDuration) { ((EntityState)self).outer.SetNextState((EntityState)new BoostConfirm()); } }); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(AudioChanges.DoSetup)); } private void Update() { PingHud.Update(); Equipment.Update(); } private void FixedUpdate() { Equipment.FixedUpdate(); } } } namespace QolElements.Elements { internal static class AudioChanges { private static bool eenabled => Config.clayApocAudioToggle.Value; internal static void DoSetup() { Config.clayApocAudioToggle.SettingChanged += delegate { LoadElement(fromSetting: true); }; LoadElement(fromSetting: false); } private static void LoadElement(bool fromSetting) { Assets.SoundbankLoad(eenabled); if (eenabled || fromSetting) { Utilities.DoAddressable("RoR2/DLC1/ClayGrenadier/ClayGrenadierMortarProjectile.prefab", delegate(GameObject a) { a.GetComponent<ProjectileController>().startSound = (eenabled ? "qol_clayGrenadier_attack1_launch" : "Play_clayGrenadier_attack1_launch"); }); } } } internal static class CountSpawns { internal static TextHud monsterHud; private static bool eenabled => monsterHud.enabled; [SetupElement] private static void SetupElement() { monsterHud.toggleEntry.SettingChanged += delegate { LoadElement(fromSetting: true); }; LoadElement(fromSetting: false); } private static void LoadElement(bool fromSetting) { if (eenabled) { TeamComponent.onJoinTeamGlobal += JoinedTeam; TeamComponent.onLeaveTeamGlobal += LeftTeam; } else if (fromSetting) { TeamComponent.onJoinTeamGlobal -= JoinedTeam; TeamComponent.onLeaveTeamGlobal -= LeftTeam; } } private static void JoinedTeam(TeamComponent self, TeamIndex teamIndex) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if ((int)teamIndex == 2) { MakeMonsterText(TeamComponent.GetTeamMembers(teamIndex).Count, TeamCatalog.GetTeamDef(teamIndex).softCharacterLimit); } } private static void LeftTeam(TeamComponent self, TeamIndex teamIndex) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if ((int)teamIndex == 2) { MakeMonsterText(TeamComponent.GetTeamMembers(teamIndex).Count, TeamCatalog.GetTeamDef(teamIndex).softCharacterLimit); } } private static void MakeMonsterText(int count, int limit) { //IL_002c: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) Color green = default(Color); if (count < limit) { float num = (float)count / (float)limit; ((Color)(ref green))..ctor(1f, 1f - num / 3f, 1f - num); } else { green = Color.green; } monsterHud.UpdateText(Util.GenerateColoredString(count.ToString(), Color32.op_Implicit(green))); } } internal static class Equipment { private static float timer = 1f / 15f; public static EquipMode currentMode = EquipMode.Normal; private static float lastEquipTimeStamp; internal static TextHud modeText; [SetupElement] private static void SetupElement() { HUD.onHudTargetChangedGlobal += delegate { UpdateText(); }; } internal static void Update() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) if (!Config.equipmentKey.Value.IsKeyDown(onlyJustPressed: true)) { return; } switch (currentMode) { case EquipMode.Normal: currentMode = EquipMode.Hold; lastEquipTimeStamp = Time.realtimeSinceStartup; break; case EquipMode.Hold: if (Time.realtimeSinceStartup - lastEquipTimeStamp < 2f) { currentMode = EquipMode.Toggle; } else { currentMode = EquipMode.Normal; } break; case EquipMode.Toggle: currentMode = EquipMode.Normal; break; } UpdateText(); } private static void UpdateText() { if (currentMode == EquipMode.Normal) { modeText.UpdateText(string.Empty); } else { modeText.UpdateText($"<size=18>{currentMode.ToString()}</size>"); } } internal static void FixedUpdate() { if (currentMode == EquipMode.Normal) { return; } LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); if (!Object.op_Implicit((Object)(object)val)) { return; } float num; if (currentMode == EquipMode.Hold) { num = 1f / Config.equipmentHoldFreq.Value; if (!val.inputBank.activateEquipment.down) { timer = num; return; } } else { num = 1f / Config.equipmentToggleFreq.Value; } timer += Time.deltaTime; if (timer >= num) { timer -= num; val.requestEquipmentFire = true; } } } public enum EquipMode { Normal, Hold, Toggle } internal class FallDamage : MonoBehaviour { private static bool barStyleSet; private static BarStyle fallBarStyle; private HUD hud; private HealthBar healthBar; private UIElementAllocator<Image> barAllocator; private BarInfo fallinfo; private static bool eenabled => Config.genesisFallMode.Value != FallMode.Disabled; private bool fraility { get { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 if (Object.op_Implicit((Object)(object)Run.instance)) { if ((int)Run.instance.selectedDifficulty < 5) { return RunArtifactManager.instance.IsArtifactEnabled(Artifacts.weakAssKneesArtifactDef); } return true; } return false; } } [SetupElement] private static void SetupElement() { Config.genesisFallMode.SettingChanged += delegate { LoadElement(fromSetting: true); }; LoadElement(fromSetting: false); Config.genesisFallMode.HookConfig((FallMode a) => eenabled, typeof(HealthBar), "UpdateBarInfos", new Action<ILContext>(DisableLowHealth_IL_HealthBar_UpdateBarInfos)); } private static void LoadElement(bool fromSetting) { if (!eenabled) { return; } if (!barStyleSet) { Utilities.DoAddressable<HealthBarStyle>("RoR2/Base/Common/HUDHealthBar.asset", (Action<HealthBarStyle>)delegate(HealthBarStyle healthBars) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) healthBars.lowHealthOverStyle.baseColor = new Color(0.4f, 0.4f, 0.4f, 1f); BarStyle val = default(BarStyle); val.sprite = healthBars.cullBarStyle.sprite; val.imageType = healthBars.cullBarStyle.imageType; val.sizeDelta = healthBars.cullBarStyle.sizeDelta; fallBarStyle = val; barStyleSet = true; }); } Utilities.AddressableAddCompSingle<FallDamage>("RoR2/Base/UI/HUDSimple.prefab"); } private static void DisableLowHealth_IL_HealthBar_UpdateBarInfos(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchLdflda<BarInfoCollection>(a, "lowHealthOverBarInfo") }) && val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, typeof(HealthComponent), "get_isHealthLow") })) { val.Emit(OpCodes.Pop); val.Emit(OpCodes.Ldc_I4_0); } else { log.error("Genesis Fall: Failed HealthBar_hasLowHealthItem IL hook"); } } private void Awake() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) hud = ((Component)this).GetComponent<HUD>(); healthBar = hud.healthBar; barAllocator = new UIElementAllocator<Image>(healthBar.barContainer, healthBar.style.barPrefab, true, false); fallinfo = new BarInfo { enabled = false, sprite = fallBarStyle.sprite, imageType = fallBarStyle.imageType, sizeDelta = fallBarStyle.sizeDelta }; } private void FixedUpdate() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_0449: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) CharacterBody val = (Object.op_Implicit((Object)(object)healthBar.source) ? healthBar.source.body : null); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.characterMotor) || Config.genesisFallMode.Value == FallMode.Disabled) { return; } Inventory inventory = val.inventory; if ((Config.genesisFallMode.Value == FallMode.GenesisOnly && (!Object.op_Implicit((Object)(object)inventory) || inventory.GetItemCount(Items.NovaOnLowHealth) <= 0)) || ((Object.op_Implicit((Object)(object)inventory) && inventory.GetItemCount(Items.FallBoots) != 0) ? 1 : 0) > (false ? 1 : 0) || (val.bodyFlags & 1) != 0 || val.HasBuff(Buffs.IgnoreFallDamage)) { return; } Ray val2 = new Ray(val.footPosition, Vector3.down); LayerIndex val3 = LayerIndex.world; int num = LayerMask.op_Implicit(((LayerIndex)(ref val3)).mask); val3 = LayerIndex.collideWithCharacterHullOnly; RaycastHit val4 = default(RaycastHit); float num2; if (Physics.Raycast(val2, ref val4, 300f, num | LayerMask.op_Implicit(((LayerIndex)(ref val3)).mask), (QueryTriggerInteraction)2)) { num2 = Vector3.Distance(((RaycastHit)(ref val4)).point, val.footPosition); } else { Ray val5 = new Ray(val.footPosition + new Vector3(0f, -200f, 0f), Vector3.up); val3 = LayerIndex.collideWithCharacterHullOnly; num2 = ((!Physics.Raycast(val5, ref val4, 200f, LayerMask.op_Implicit(((LayerIndex)(ref val3)).mask), (QueryTriggerInteraction)2)) ? 300f : (Vector3.Distance(((RaycastHit)(ref val4)).point, val.footPosition) + 2f * val.characterMotor.capsuleHeight)); } float y = val.characterMotor.velocity.y; float num3 = (float)Math.Sqrt(y * y - 2f * Physics.gravity.y * num2); if (num3 > val.jumpPower + 20f) { float num4 = Math.Max(num3 - val.jumpPower - 20f, 0f) / 60f; if (fraility) { num4 *= 2f; } float num5 = ((val.armor >= 0f) ? (1f - val.armor / (val.armor + 100f)) : (2f - 100f / (100f - val.armor))); num4 = (num4 * num5 * val.maxHealth / val.cursePenalty - (float)(healthBar.source.itemCounts.armorPlate * 5)) / (val.maxHealth + val.maxShield); HealthBarValues healthBarValues = healthBar.source.GetHealthBarValues(); fallinfo.normalizedXMin = Math.Max(healthBarValues.healthFraction + healthBarValues.shieldFraction + healthBarValues.barrierFraction - num4, -1f); fallinfo.normalizedXMax = healthBarValues.healthFraction + healthBarValues.shieldFraction; if (fallinfo.normalizedXMin < fallinfo.normalizedXMax) { fallinfo.enabled = true; if (!Config.genesisFallConfirmToggle.Value || (fallinfo.normalizedXMin < HealthComponent.lowHealthFraction && healthBarValues.healthFraction + healthBarValues.shieldFraction > HealthComponent.lowHealthFraction)) { fallinfo.color = Config.genesisFallConfirmColor.Value; if (!Config.genesisFallConfirmBarOverflow.Value) { Math.Max(fallinfo.normalizedXMin, 0f); } } else { fallinfo.color = Config.genesisFallColor.Value; fallinfo.normalizedXMin = Math.Max(fallinfo.normalizedXMin, 0f); } } else { fallinfo.enabled = false; } } else { fallinfo.enabled = false; } if (fallinfo.enabled) { barAllocator.AllocateElements(1); Image obj = barAllocator.elements[0]; obj.type = fallinfo.imageType; obj.sprite = fallinfo.sprite; ((Graphic)obj).color = fallinfo.color; RectTransform val6 = (RectTransform)((Component)obj).transform; val6.anchorMin = new Vector2(fallinfo.normalizedXMin, 0f); val6.anchorMax = new Vector2(fallinfo.normalizedXMax, 1f); val6.anchoredPosition = Vector2.zero; val6.sizeDelta = new Vector2(fallinfo.sizeDelta * 0.5f + 1f, fallinfo.sizeDelta + 1f); } else { barAllocator.AllocateElements(0); } } } public enum FallMode { Disabled, GenesisOnly, Always } internal static class FistIndicator { private static GameObject originalTitanFist; private static GameObject originalClaySlam; private static Material materialRed; private static Material materialBlue; private static bool eenabled => Config.fistIndicatorToggle.Value; [SetupElement] private static void SetupElement() { Config.fistIndicatorToggle.SettingChanged += delegate { LoadElement(fromSetting: true); }; LoadElement(fromSetting: false); } private static async void LoadElement(bool fromSetting) { if (eenabled) { Assets.AssetsLoad("qolelements"); GameObject sphere = GameObject.CreatePrimitive((PrimitiveType)0); Object.Destroy((Object)(object)sphere.GetComponent<SphereCollider>()); MeshRenderer component = sphere.GetComponent<MeshRenderer>(); ((Renderer)component).allowOcclusionWhenDynamic = false; ((Renderer)component).sharedMaterial = Assets.assetBundle.LoadAsset<Material>("redpixel.mat"); materialRed = await CreateCloudMaterial("red120.png"); materialBlue = await CreateCloudMaterial("blue120.png"); Utilities.DoAddressable("RoR2/Base/Titan/TitanPreFistProjectile.prefab", delegate(GameObject titan) { if (!Object.op_Implicit((Object)(object)originalTitanFist)) { originalTitanFist = Utilities.CreatePrefab(titan); } ModIndicator(titan, "TeamAreaIndicator, GroundOnly", sphere, 2.3333333f); }); Utilities.DoAddressable("RoR2/DLC1/ClayGrenadier/ClayGrenadierMortarProjectile.prefab", delegate(GameObject clay) { if (!Object.op_Implicit((Object)(object)originalClaySlam)) { originalClaySlam = Utilities.CreatePrefab(clay); } ModIndicator(clay, "Expander/TeamAreaIndicator, GroundOnly", sphere, 2.5714285f); }); if (fromSetting) { Assets.AssetsUnload(); } } else if (fromSetting) { RestoreIndicator(await Utilities.GetAddressableAsync("RoR2/Base/Titan/TitanPreFistProjectile.prefab"), "TeamAreaIndicator, GroundOnly", originalTitanFist); RestoreIndicator(await Utilities.GetAddressableAsync("RoR2/DLC1/ClayGrenadier/ClayGrenadierMortarProjectile.prefab"), "Expander/TeamAreaIndicator, GroundOnly", originalClaySlam); } } private static void ModIndicator(GameObject projectile, string childIndicator, GameObject sphere, float diameter) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) TeamAreaIndicator component = ((Component)projectile.transform.Find(childIndicator)).GetComponent<TeamAreaIndicator>(); component.teamMaterialPairs[0].sharedMaterial = materialRed; component.teamMaterialPairs[1].sharedMaterial = materialBlue; MeshFilter component2 = ((Component)((Component)component).transform.Find("Mesh")).GetComponent<MeshFilter>(); ((Component)component2).transform.localScale = new Vector3(diameter, diameter, diameter); component2.sharedMesh = sphere.GetComponent<MeshFilter>().sharedMesh; ((Renderer)((Component)component2).GetComponent<MeshRenderer>()).material = component.teamMaterialPairs[0].sharedMaterial; } private static void RestoreIndicator(GameObject projectile, string childIndicator, GameObject original) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) TeamAreaIndicator component = ((Component)projectile.transform.Find(childIndicator)).GetComponent<TeamAreaIndicator>(); TeamAreaIndicator component2 = ((Component)original.transform.Find(childIndicator)).GetComponent<TeamAreaIndicator>(); component.teamMaterialPairs[0].sharedMaterial = component2.teamMaterialPairs[0].sharedMaterial; component.teamMaterialPairs[1].sharedMaterial = component2.teamMaterialPairs[1].sharedMaterial; MeshFilter component3 = ((Component)((Component)component).transform.Find("Mesh")).GetComponent<MeshFilter>(); MeshFilter component4 = ((Component)((Component)component2).transform.Find("Mesh")).GetComponent<MeshFilter>(); ((Component)component3).transform.localScale = ((Component)component4).transform.localScale; component3.sharedMesh = component4.sharedMesh; } private static async Task<Material> CreateCloudMaterial(string texture) { Material val = new Material(await Utilities.GetAddressableAsync<Shader>("RoR2/Base/Shaders/HGCloudRemap.shader")); val.EnableKeyword("DISABLEREMAP"); val.SetTexture("_MainTex", (Texture)(object)Assets.assetBundle.LoadAsset<Texture2D>(texture)); val.SetFloat("_SrcBlend", 3f); val.SetFloat("_DstBlend", 1f); return val; } } internal class GenesisTimer : MonoBehaviour { internal static TextHud genesisTextHud; private EntityStateMachine stateMachine; private NetworkedBodyAttachment bodyAttachment; private float alpha = 255f; private static bool eenabled => genesisTextHud.enabled; [SetupElement] private static void SetupElement() { genesisTextHud.toggleEntry.SettingChanged += delegate { LoadElement(fromSetting: true); }; LoadElement(fromSetting: false); genesisTextHud.toggleEntry.HookConfig(typeof(DetonateState), "OnEnter", new Action<Action<DetonateState>, DetonateState>(Scale_On_DetonateState_OnEnter)); } private static void LoadElement(bool fromSetting) { if (eenabled) { Utilities.AddressableAddCompSingle<GenesisTimer>("RoR2/Base/NovaOnLowHealth/VagrantNovaItemBodyAttachment.prefab"); } } private static void Scale_On_DetonateState_OnEnter(Action<DetonateState> orig, DetonateState self) { orig(self); int itemStack = ((BaseVagrantNovaItemState)self).GetItemStack(); if (itemStack > 1) { self.duration /= (float)itemStack; } } private void OnEnable() { stateMachine = ((Component)this).GetComponent<EntityStateMachine>(); if (!Object.op_Implicit((Object)(object)stateMachine)) { log.warning("Genesis: null stateMachine"); } bodyAttachment = ((Component)this).GetComponent<NetworkedBodyAttachment>(); if (!Object.op_Implicit((Object)(object)bodyAttachment)) { log.error("Genesis: Failed to get body attachment"); } } private void FixedUpdate() { if (!genesisTextHud.enabled) { return; } if (Object.op_Implicit((Object)(object)TextHud.hud)) { CharacterMaster targetMaster = TextHud.hud.targetMaster; CharacterBody attachedBody = bodyAttachment.attachedBody; if ((Object)(object)targetMaster != (Object)(object)((attachedBody != null) ? attachedBody.master : null)) { return; } } EntityState state = stateMachine.state; if (state == null) { log.warning("Genesis: null State"); } float num = 0f - state.fixedAge; BaseVagrantNovaItemState val = (BaseVagrantNovaItemState)(object)((state is BaseVagrantNovaItemState) ? state : null); num = ((state is RechargeState) ? (num + Recharge(val)) : ((state is ChargeState) ? (num + Charge(val)) : ((!(state is DetonateState)) ? 0f : (num + Detonate((DetonateState)(object)((val is DetonateState) ? val : null)))))); if (num <= 0f) { if (!(alpha <= 0f)) { alpha -= 0.75f; if (alpha > 0f) { genesisTextHud.UpdateText($"<color=#999999{(byte)alpha:X2}>Ready</color>"); } else { genesisTextHud.UpdateText(""); } } } else { alpha = 255f; genesisTextHud.UpdateText(string.Format("<color=#ffe5{0:X2}ff>{1}</color>", (byte)Mathf.Clamp(15f * (num - 1.5f), 0f, 255f), (num < 2.8f) ? num.ToString("0.0") : num.ToString("0"))); } } private float Recharge(BaseVagrantNovaItemState state) { return RechargeState.baseDuration / (float)(state.GetItemStack() + 1) + Charge(state); } private float Charge(BaseVagrantNovaItemState state) { return ChargeState.baseDuration / (Object.op_Implicit((Object)(object)((BaseBodyAttachmentState)state).attachedBody) ? ((BaseBodyAttachmentState)state).attachedBody.attackSpeed : 1f); } private float Detonate(DetonateState state) { return state.duration + Recharge((BaseVagrantNovaItemState)(object)state); } private void OnDisable() { if (genesisTextHud.enabled && Object.op_Implicit((Object)(object)TextHud.hud)) { CharacterMaster targetMaster = TextHud.hud.targetMaster; CharacterBody attachedBody = bodyAttachment.attachedBody; if ((Object)(object)targetMaster != (Object)(object)((attachedBody != null) ? attachedBody.master : null)) { genesisTextHud.ClearText(); } } } } internal static class IntrinsicEulogy { [SetupElement] private static void SetupElement() { Config.extraEulogies.HookConfig((int a) => a > 0, typeof(RandomlyLunarUtils), "CheckForLunarReplacement", new Action<ILContext>(AddElugoies_IL_RandomlyLunarUtils_CheckForLunarReplacement)); } private static void AddElugoies_IL_RandomlyLunarUtils_CheckForLunarReplacement(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCall(a, "RoR2.Util", "GetItemCountGlobal") })) { log.error("Failed eulogy IL hook"); return; } val.Emit(OpCodes.Ldsfld, typeof(Config).GetField("extraEulogies", BindingFlags.Static | BindingFlags.NonPublic)); val.Emit<ConfigEntry<int>>(OpCodes.Call, "get_Value"); val.Emit(OpCodes.Add); } } internal static class LoadoutSwapper { private static readonly Dictionary<CharacterMaster, Loadout> subscribedMasters = new Dictionary<CharacterMaster, Loadout>(); [ConCommand(/*Could not decode attribute arguments.*/)] private static void CCSetLoadout(ConCommandArgs args) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)((ConCommandArgs)(ref args)).senderBody)) { throw new ConCommandException("no valid body."); } BodyIndex bodyIndex = ((ConCommandArgs)(ref args)).senderBody.bodyIndex; GenericSkill[] prefabSkillSlots = BodyLoadoutManager.allBodyInfos[bodyIndex].prefabSkillSlots; UserProfile userProfile = ((ConCommandArgs)(ref args)).GetSenderLocalUser().userProfile; Loadout val = new Loadout(); userProfile.CopyLoadout(val); if (((ConCommandArgs)(ref args)).Count == 0) { PrintSlots(((ConCommandArgs)(ref args)).senderBody, prefabSkillSlots); return; } int argInt = ((ConCommandArgs)(ref args)).GetArgInt(0); if (argInt >= prefabSkillSlots.Length) { Debug.LogError((object)$"Value provided for 'slotIndex' is outside range [0, {prefabSkillSlots.Length}) for body {Language.GetString(((ConCommandArgs)(ref args)).senderBody.baseNameToken)}, printing valid indexes"); PrintSlots(((ConCommandArgs)(ref args)).senderBody, prefabSkillSlots); return; } if (((ConCommandArgs)(ref args)).Count == 1) { PrintSkills(((ConCommandArgs)(ref args)).senderBody, prefabSkillSlots, argInt); return; } int argInt2 = ((ConCommandArgs)(ref args)).GetArgInt(1); if (argInt2 >= prefabSkillSlots[argInt].skillFamily.variants.Length) { Debug.LogError((object)$"Value provided for 'skillIndex' is outside range [0, {prefabSkillSlots[argInt].skillFamily.variants.Length}) for skill family {argInt}, printing valid indexes"); PrintSkills(((ConCommandArgs)(ref args)).senderBody, prefabSkillSlots, argInt); return; } val.bodyLoadoutManager.SetSkillVariant(bodyIndex, argInt, (uint)argInt2); userProfile.SetLoadout(val); CharacterMaster senderMaster = ((ConCommandArgs)(ref args)).senderMaster; if (Object.op_Implicit((Object)(object)senderMaster)) { val.Copy(senderMaster.loadout); if (NetworkServer.active) { ((NetworkBehaviour)senderMaster).SetDirtyBit(16u); } else { List<CharacterMaster> list = new List<CharacterMaster>(); foreach (KeyValuePair<CharacterMaster, Loadout> subscribedMaster in subscribedMasters) { if (!Object.op_Implicit((Object)(object)subscribedMaster.Key)) { list.Add(subscribedMaster.Key); } } foreach (CharacterMaster item in list) { subscribedMasters.Remove(item); } if (!subscribedMasters.ContainsKey(senderMaster)) { senderMaster.onBodyStart += CharacterMaster_onBodyStart; subscribedMasters.Add(senderMaster, val); } } } SetBodySkills(((ConCommandArgs)(ref args)).senderBody, val); Debug.Log((object)("Set to: " + Language.GetString(((ConCommandArgs)(ref args)).senderBody.skillLocator.allSkills[argInt].skillNameToken))); } private static void SetBodySkills(CharacterBody body, Loadout loadout) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < body.skillLocator.allSkills.Length; i++) { uint num = loadout.bodyLoadoutManager.GetSkillVariant(body.bodyIndex, i); GenericSkill obj = body.skillLocator.allSkills[i]; Variant[] variants = obj.skillFamily.variants; if (!ArrayUtils.IsInBounds<Variant>(variants, num)) { num = 0u; } obj.SetBaseSkill(variants[num].skillDef); } } private static void CharacterMaster_onBodyStart(CharacterBody body) { if (subscribedMasters.TryGetValue(body.master, out var value)) { SetBodySkills(body, value); } } private static void PrintSlots(CharacterBody body, GenericSkill[] skillSlots) { StringBuilder stringBuilder = StringBuilderPool.RentStringBuilder(); for (int i = 0; i < skillSlots.Length; i++) { Variant[] variants = skill