using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FishNet; using FishNet.Managing; using HarmonyLib; using Microsoft.CodeAnalysis; using SpongeMods.ModMenu; using SpongeMods.UILib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("FishNet.Runtime")] [assembly: AssemblyCompany("SpongeMods")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Combat readouts built on the Sponge UI toolkit.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+a149c533da6d929b7267867242f5011f9c2152dc")] [assembly: AssemblyProduct("SpongeMods.EnhancedGUI")] [assembly: AssemblyTitle("SpongeMods.EnhancedGUI")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SpongeMods.EnhancedGUI { internal sealed class Board { private readonly List _rows = new List(); private readonly List _visible = new List(); private readonly RectTransform _root; private readonly Palette _palette; private readonly float _width; private readonly float _height; private readonly float _gap; public int Limit = 6; public Readout Style = (Readout)2; public Board(string name, Placement placement, float width, float height, float gap, Palette palette) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) _palette = palette; _width = width; _height = height; _gap = gap; _root = Stage.NewRect(name, (RectTransform)null); _root.sizeDelta = new Vector2(width, height); ((Placement)(ref placement)).ApplyTo(_root); } public void Refresh(List candidates, float deltaTime) { //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) _visible.Clear(); for (int i = 0; i < candidates.Count; i++) { ITracked tracked = candidates[i]; if (tracked != null && tracked.Alive) { _visible.Add(tracked); } } _visible.Sort(delegate(ITracked left, ITracked right) { int num2 = left.Weight.CompareTo(right.Weight); return (num2 == 0) ? string.CompareOrdinal(left.Title, right.Title) : num2; }); if (_visible.Count > Limit) { _visible.RemoveRange(Limit, _visible.Count - Limit); } while (_rows.Count < _visible.Count) { _rows.Add(NewRow(_rows.Count)); } for (int num = 0; num < _rows.Count; num++) { Meter val = _rows[num]; if (num >= _visible.Count) { val.Visible(false); continue; } ITracked tracked2 = _visible[num]; val.Visible(true); val.Style = Style; val.Caption(tracked2.Title); val.Set(tracked2.Value, tracked2.Ceiling); val.Step(deltaTime); } ((Component)_root).gameObject.SetActive(_visible.Count > 0); } private Meter NewRow(int index) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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) //IL_00a1: Expected O, but got Unknown Meter val = new Meter("Row" + index, _root, _width, _height, _palette); RectTransform rect = val.Rect; rect.anchorMin = new Vector2(0f, 1f); rect.anchorMax = new Vector2(0f, 1f); rect.pivot = new Vector2(0f, 1f); rect.anchoredPosition = new Vector2(0f, (float)(-index) * (_height + _gap + _height * 0.7f)); return val; } public void Hide() { if ((Object)(object)_root != (Object)null) { ((Component)_root).gameObject.SetActive(false); } } public void Destroy() { _rows.Clear(); _visible.Clear(); if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)((Component)_root).gameObject); } } } internal sealed class Countdown { private readonly Label _label; private const float TenthsBelow = 10f; public Countdown(Placement placement, float size, Palette palette) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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) //IL_0026: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) _label = new Label("BossCountdown", (RectTransform)null, size, palette.Ink, true) { Alignment = (TextAnchor)4 }; ((Placement)(ref placement)).ApplyTo(_label.Rect); _label.Rect.sizeDelta = new Vector2(320f, size * 1.6f); _label.Visible(false); } public void Refresh(bool showLabel, Palette palette) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) float num = Remaining(); if (num <= 0f) { _label.Visible(false); return; } _label.Visible(true); _label.Text = (showLabel ? "BOSS LEAVES IN " : string.Empty) + Format(num); _label.Colour = ((num <= 10f) ? palette.Alert : palette.Ink); } public void Hide() { _label.Visible(false); } public void Destroy() { if ((Object)(object)_label.Rect != (Object)null) { Object.Destroy((Object)(object)((Component)_label.Rect).gameObject); } } private static float Remaining() { if ((Object)(object)BossManager.Boss == (Object)null) { return 0f; } NetworkManager networkManager = InstanceFinder.NetworkManager; if ((Object)(object)networkManager == (Object)null || (Object)(object)networkManager.TimeManager == (Object)null) { return 0f; } uint tick = networkManager.TimeManager.Tick; uint bossLeavesTick = BossManager.BossLeavesTick; if (bossLeavesTick <= tick) { return 0f; } return (float)((double)(bossLeavesTick - tick) * networkManager.TimeManager.TickDelta); } private static string Format(float seconds) { CultureInfo invariantCulture = CultureInfo.InvariantCulture; if (seconds < 10f) { return seconds.ToString("0.0", invariantCulture) + "s"; } int num = Mathf.CeilToInt(seconds); int num2 = num / 60; int num3 = num % 60; if (num2 <= 0) { return num3.ToString(invariantCulture) + "s"; } return num2.ToString(invariantCulture) + ":" + num3.ToString("00", invariantCulture); } } [BepInPlugin("SpongeMods.EnhancedGUI", "Sponge's Enhanced GUI", "1.0.0")] [BepInDependency("SpongeMods.UILib", "1.0.0")] [BepInDependency("SpongeMods.ModMenu", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { public const string Id = "SpongeMods.EnhancedGUI"; public const string Version = "1.0.0"; private static ManualLogSource _log; private Settings _settings; private Board _board; private Countdown _countdown; private Palette _palette; private readonly List _subjects = new List(); private BossSubject _bossSubject; private Creature _bossSeen; private AmmoSubject _ammoSubject; private Weapon _weaponSeen; private int _layoutSignature; private void Awake() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) _log = ((BaseUnityPlugin)this).Logger; _settings = new Settings(((BaseUnityPlugin)this).Config); try { new Harmony("SpongeMods.EnhancedGUI").PatchAll(); } catch (Exception ex) { _log.LogError((object)("Creature tracking could not be installed, so fish health bars will not appear: " + ex.Message)); } Rebuild(); Tabs.Register(_settings); _log.LogInfo((object)"Enhanced GUI ready."); } private void OnDestroy() { Roster.Clear(); } private void Rebuild() { //IL_003f: 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) _board?.Destroy(); _countdown?.Destroy(); _palette = _settings.BuildPalette(); _board = new Board("EnhancedGUI.Board", _settings.BoardPlacement(), _settings.BarWidth.Value, _settings.BarHeight.Value, _settings.RowGap.Value, _palette); _countdown = new Countdown(_settings.TimerPlacement(), _settings.TimerSize.Value, _palette); _layoutSignature = LayoutSignature(); } private int LayoutSignature() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) return ((((((((((((17 * 31 + ((object)_settings.BoardAnchor.Value/*cast due to .constrained prefix*/).GetHashCode()) * 31 + _settings.BoardX.Value.GetHashCode()) * 31 + _settings.BoardY.Value.GetHashCode()) * 31 + _settings.BarWidth.Value.GetHashCode()) * 31 + _settings.BarHeight.Value.GetHashCode()) * 31 + _settings.RowGap.Value.GetHashCode()) * 31 + ((object)_settings.TimerAnchor.Value/*cast due to .constrained prefix*/).GetHashCode()) * 31 + _settings.TimerX.Value.GetHashCode()) * 31 + _settings.TimerY.Value.GetHashCode()) * 31 + _settings.TimerSize.Value.GetHashCode()) * 31 + _settings.AccentColour.Value.GetHashCode()) * 31 + _settings.AlertColour.Value.GetHashCode()) * 31 + _settings.Opacity.Value.GetHashCode(); } private void Update() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) if (LayoutSignature() != _layoutSignature) { Rebuild(); } Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer == (Object)null) { _board.Hide(); _countdown.Hide(); return; } float unscaledDeltaTime = Time.unscaledDeltaTime; _subjects.Clear(); CollectBoss(); CollectCreatures(localPlayer); CollectAmmo(localPlayer); _board.Limit = _settings.MaxRows.Value; _board.Style = _settings.NumberStyle.Value; _board.Refresh(_subjects, unscaledDeltaTime); if (_settings.ShowTimer.Value) { _countdown.Refresh(_settings.TimerCaption.Value, _palette); } else { _countdown.Hide(); } } private void CollectBoss() { if (!_settings.ShowBoss.Value) { return; } Creature boss = BossManager.Boss; if ((Object)(object)boss == (Object)null) { _bossSubject = null; _bossSeen = null; return; } if (_bossSubject == null || (Object)(object)_bossSeen != (Object)(object)boss) { _bossSubject = new BossSubject(boss); _bossSeen = boss; } _subjects.Add(_bossSubject); } private void CollectCreatures(Player player) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (_settings.ShowCreatures.Value) { Vector3 eye = (((Object)(object)player.Transform != (Object)null) ? player.Transform.position : ((Component)player).transform.position); Roster.Collect(_subjects, eye, _settings.CreatureRange.Value, _settings.DamagedOnly.Value); } } private void CollectAmmo(Player player) { if (!_settings.ShowAmmo.Value) { return; } Weapon val = (Weapon)(((Object)(object)player.Holding != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val == (Object)null) { _ammoSubject = null; _weaponSeen = null; return; } if (_ammoSubject == null || (Object)(object)_weaponSeen != (Object)(object)val) { _ammoSubject = new AmmoSubject(val); _weaponSeen = val; } _subjects.Add(_ammoSubject); } } internal static class Roster { private static readonly Dictionary _known = new Dictionary(); private static readonly List _stale = new List(); public static void Add(Creature creature) { if (!((Object)(object)creature == (Object)null) && !_known.ContainsKey(creature)) { _known[creature] = new CreatureSubject(creature, Describe(creature)); } } public static void Remove(Creature creature) { if ((Object)(object)creature != (Object)null) { _known.Remove(creature); } } public static void Clear() { _known.Clear(); } public static void Collect(List into, Vector3 eye, float radius, bool onlyDamaged) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) float num = radius * radius; Creature boss = BossManager.Boss; foreach (KeyValuePair item in _known) { Creature key = item.Key; if ((Object)(object)key == (Object)null) { _stale.Add(key); } else { if (key.IsDead || (Object)(object)key == (Object)(object)boss || (onlyDamaged && key.Hp >= key.MaxHp)) { continue; } if (radius > 0f) { Vector3 val = ((Component)key).transform.position - eye; if (((Vector3)(ref val)).sqrMagnitude > num) { continue; } } into.Add(item.Value); } } if (_stale.Count != 0) { for (int i = 0; i < _stale.Count; i++) { _known.Remove(_stale[i]); } _stale.Clear(); } } private static string Describe(Creature creature) { string name = ((Item)creature).GetName(); if (!string.IsNullOrEmpty(name)) { return name; } return ((Object)creature).name; } } [HarmonyPatch(typeof(Creature), "OnStartClient")] internal static class CreatureSpawnPatch { private static void Postfix(Creature __instance) { Roster.Add(__instance); } } [HarmonyPatch(typeof(Creature), "OnStopClient")] internal static class CreatureDespawnPatch { private static void Postfix(Creature __instance) { Roster.Remove(__instance); } } internal sealed class Settings { public readonly ConfigEntry ShowBoss; public readonly ConfigEntry ShowTimer; public readonly ConfigEntry ShowCreatures; public readonly ConfigEntry ShowAmmo; public readonly ConfigEntry BoardAnchor; public readonly ConfigEntry BoardX; public readonly ConfigEntry BoardY; public readonly ConfigEntry BarWidth; public readonly ConfigEntry BarHeight; public readonly ConfigEntry RowGap; public readonly ConfigEntry MaxRows; public readonly ConfigEntry TimerAnchor; public readonly ConfigEntry TimerX; public readonly ConfigEntry TimerY; public readonly ConfigEntry TimerSize; public readonly ConfigEntry TimerCaption; public readonly ConfigEntry NumberStyle; public readonly ConfigEntry CreatureRange; public readonly ConfigEntry DamagedOnly; public readonly ConfigEntry AccentColour; public readonly ConfigEntry AlertColour; public readonly ConfigEntry Opacity; public Settings(ConfigFile file) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Expected O, but got Unknown //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Expected O, but got Unknown //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Expected O, but got Unknown //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Expected O, but got Unknown //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Expected O, but got Unknown ShowBoss = file.Bind("Readouts", "Boss health", true, "Show a health bar for the active boss."); ShowTimer = file.Bind("Readouts", "Boss timer", true, "Show how long before the boss leaves."); ShowCreatures = file.Bind("Readouts", "Fish health", true, "Show health bars for nearby creatures."); ShowAmmo = file.Bind("Readouts", "Ammo", true, "Show rounds remaining in the held weapon."); BoardAnchor = file.Bind("Layout", "Anchor", (Anchor)2, "Screen corner or edge the bars are measured from."); BoardX = file.Bind("Layout", "Offset X", 32f, "Distance inward from the anchor, horizontally."); BoardY = file.Bind("Layout", "Offset Y", 96f, "Distance inward from the anchor, vertically."); BarWidth = file.Bind("Layout", "Bar width", 300f, new ConfigDescription("Bar width in reference pixels.", (AcceptableValueBase)(object)new AcceptableValueRange(80f, 900f), Array.Empty())); BarHeight = file.Bind("Layout", "Bar height", 20f, new ConfigDescription("Bar height in reference pixels.", (AcceptableValueBase)(object)new AcceptableValueRange(6f, 90f), Array.Empty())); RowGap = file.Bind("Layout", "Row gap", 8f, new ConfigDescription("Blank space between bars.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 60f), Array.Empty())); MaxRows = file.Bind("Layout", "Max bars", 6, new ConfigDescription("Most bars drawn at once.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 16), Array.Empty())); TimerAnchor = file.Bind("Timer", "Anchor", (Anchor)1, "Screen corner or edge the countdown is measured from."); TimerX = file.Bind("Timer", "Offset X", 0f, "Distance inward from the anchor, horizontally."); TimerY = file.Bind("Timer", "Offset Y", 64f, "Distance inward from the anchor, vertically."); TimerSize = file.Bind("Timer", "Text size", 26f, new ConfigDescription("Countdown text size.", (AcceptableValueBase)(object)new AcceptableValueRange(8f, 96f), Array.Empty())); TimerCaption = file.Bind("Timer", "Show caption", true, "Prefix the countdown with a short label."); NumberStyle = file.Bind("Numbers", "Style", (Readout)2, "How values are written beside each bar: none, current, current over maximum, or a percentage."); CreatureRange = file.Bind("Numbers", "Creature range", 60f, new ConfigDescription("How far away a creature can be and still get a bar. Zero shows them at any distance.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 400f), Array.Empty())); DamagedOnly = file.Bind("Numbers", "Damaged only", true, "Only show a bar once a creature has actually been hurt. Turning this off shows every creature in range, which gets noisy on a busy lake."); AccentColour = file.Bind("Theme", "Accent", "#FFBA42", "Bar colour at full health, as #RRGGBB."); AlertColour = file.Bind("Theme", "Alert", "#FF5C52", "Bar colour approaching empty, as #RRGGBB."); Opacity = file.Bind("Theme", "Opacity", 0.92f, new ConfigDescription("Backdrop opacity.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); } public Palette BuildPalette() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0013: 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) //IL_001d: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) Palette val = new Palette(); val.Accent = Parse(AccentColour.Value, val.Accent); val.Alert = Parse(AlertColour.Value, val.Alert); val.Surface = Palette.Fade(val.Surface, Opacity.Value); return val; } private static Color Parse(string text, Color fallback) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); if (string.IsNullOrEmpty(text) || !ColorUtility.TryParseHtmlString(text.Trim(), ref result)) { return fallback; } return result; } public Placement BoardPlacement() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) return new Placement(BoardAnchor.Value, BoardX.Value, BoardY.Value); } public Placement TimerPlacement() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) return new Placement(TimerAnchor.Value, TimerX.Value, TimerY.Value); } } internal sealed class BossSubject : ITracked { private readonly Creature _creature; public string Title => "BOSS"; public float Value { get { if (!((Object)(object)_creature != (Object)null)) { return 0f; } return _creature.Hp; } } public float Ceiling => Mathf.Max(1, BossManager.BossMaxHp); public int Weight => 0; public bool Alive { get { if ((Object)(object)_creature != (Object)null) { return !_creature.IsDead; } return false; } } public object Key => _creature; public BossSubject(Creature creature) { _creature = creature; } } internal sealed class CreatureSubject : ITracked { private readonly Creature _creature; private readonly string _title; public string Title => _title; public float Value { get { if (!((Object)(object)_creature != (Object)null)) { return 0f; } return _creature.Hp; } } public float Ceiling { get { if (!((Object)(object)_creature != (Object)null)) { return 1f; } return Mathf.Max(1, _creature.MaxHp); } } public int Weight => 10; public bool Alive { get { if ((Object)(object)_creature != (Object)null) { return !_creature.IsDead; } return false; } } public object Key => _creature; public CreatureSubject(Creature creature, string title) { _creature = creature; _title = title; } } internal sealed class AmmoSubject : ITracked { private readonly Weapon _weapon; public string Title => "AMMO"; public float Value { get { if (!((Object)(object)_weapon != (Object)null)) { return 0f; } return _weapon.Ammo; } } public float Ceiling { get { if ((Object)(object)_weapon == (Object)null || (Object)(object)_weapon.Attachments == (Object)null) { return 1f; } return Mathf.Max(1, _weapon.Attachments.AmmoPerMag); } } public int Weight => 100; public bool Alive => (Object)(object)_weapon != (Object)null; public object Key => _weapon; public AmmoSubject(Weapon weapon) { _weapon = weapon; } } internal static class Tabs { public static void Register(Settings settings) { SpongeMenu.Tab("SpongeMods.EnhancedGUI", "Readouts", 10).Heading("What is shown").Toggle("Boss health", settings.ShowBoss) .Toggle("Boss timer", settings.ShowTimer) .Toggle("Fish health", settings.ShowCreatures) .Toggle("Ammo", settings.ShowAmmo) .Heading("Fish health bars") .Choice("Numbers", settings.NumberStyle) .Number("Range", settings.CreatureRange) .Toggle("Only once hurt", settings.DamagedOnly) .Note("Showing every fish in range rather than only the hurt ones gets noisy on a busy lake. Range zero means any distance.") .Heading("Boss timer") .Toggle("Show the caption", settings.TimerCaption); SpongeMenu.Tab("SpongeMods.EnhancedGUI", "Readout layout", 11).Heading("Health bars").Choice("Corner", settings.BoardAnchor) .Number("Across", settings.BoardX, -400f, 400f) .Number("Down", settings.BoardY, -400f, 400f) .Number("Bar width", settings.BarWidth) .Number("Bar height", settings.BarHeight) .Number("Gap between bars", settings.RowGap) .Number("Most bars at once", settings.MaxRows) .Heading("Boss timer") .Choice("Corner", settings.TimerAnchor) .Number("Across", settings.TimerX, -400f, 400f) .Number("Down", settings.TimerY, -400f, 400f) .Number("Text size", settings.TimerSize) .Heading("Colours") .Field("Full", settings.AccentColour, "#FFBA42") .Field("Empty", settings.AlertColour, "#FF5C52") .Number("Backdrop opacity", settings.Opacity) .Note("Colours are written as #RRGGBB. A value that is not a colour is ignored and the current one stays."); } } internal interface ITracked { string Title { get; } float Value { get; } float Ceiling { get; } int Weight { get; } bool Alive { get; } object Key { get; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }