using Dalamud.Interface; using HSUI.Config; using HSUI.Config.Attributes; using HSUI.Enums; using HSUI.Helpers; using HSUI.Interface.Bars; using HSUI.Interface.GeneralElements; using Dalamud.Bindings.ImGui; using Lumina.Excel; using Lumina.Excel.Sheets; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Numerics; namespace HSUI.Interface.StatusEffects { [Section("Buffs and Debuffs")] [SubSection("Player Buffs", 0)] public class PlayerBuffsListConfig : UnitFrameStatusEffectsListConfig { public new static PlayerBuffsListConfig DefaultConfig() { var screenSize = ImGui.GetMainViewport().Size; var pos = new Vector2(screenSize.X * 0.38f, -screenSize.Y * 0.45f); var iconConfig = new StatusEffectIconConfig(); iconConfig.DispellableBorderConfig.Enabled = false; return new PlayerBuffsListConfig(pos, HUDConstants.DefaultStatusEffectsListSize, true, false, true, GrowthDirections.Left | GrowthDirections.Down, iconConfig); } public PlayerBuffsListConfig(Vector2 position, Vector2 size, bool showBuffs, bool showDebuffs, bool showPermanentEffects, GrowthDirections growthDirections, StatusEffectIconConfig iconConfig) : base(position, size, showBuffs, showDebuffs, showPermanentEffects, growthDirections, iconConfig) { } } [Section("Buffs and Debuffs")] [SubSection("Player Debuffs", 0)] public class PlayerDebuffsListConfig : UnitFrameStatusEffectsListConfig { public new static PlayerDebuffsListConfig DefaultConfig() { var screenSize = ImGui.GetMainViewport().Size; var pos = new Vector2(screenSize.X * 0.38f, -screenSize.Y * 0.45f + HUDConstants.DefaultStatusEffectsListSize.Y); var iconConfig = new StatusEffectIconConfig(); return new PlayerDebuffsListConfig(pos, HUDConstants.DefaultStatusEffectsListSize, false, true, true, GrowthDirections.Left | GrowthDirections.Down, iconConfig); } public PlayerDebuffsListConfig(Vector2 position, Vector2 size, bool showBuffs, bool showDebuffs, bool showPermanentEffects, GrowthDirections growthDirections, StatusEffectIconConfig iconConfig) : base(position, size, showBuffs, showDebuffs, showPermanentEffects, growthDirections, iconConfig) { } } [Section("Buffs and Debuffs")] [SubSection("Target Buffs", 0)] public class TargetBuffsListConfig : UnitFrameStatusEffectsListConfig { public new static TargetBuffsListConfig DefaultConfig() { var pos = new Vector2(0, -1); var iconConfig = new StatusEffectIconConfig(); iconConfig.DispellableBorderConfig.Enabled = false; var config = new TargetBuffsListConfig(pos, HUDConstants.DefaultStatusEffectsListSize, true, false, true, GrowthDirections.Right | GrowthDirections.Up, iconConfig); config.AnchorToUnitFrame = true; config.UnitFrameAnchor = DrawAnchor.TopLeft; return config; } public TargetBuffsListConfig(Vector2 position, Vector2 size, bool showBuffs, bool showDebuffs, bool showPermanentEffects, GrowthDirections growthDirections, StatusEffectIconConfig iconConfig) : base(position, size, showBuffs, showDebuffs, showPermanentEffects, growthDirections, iconConfig) { } } [Section("Buffs and Debuffs")] [SubSection("Target Debuffs", 0)] public class TargetDebuffsListConfig : UnitFrameStatusEffectsListConfig { public new static TargetDebuffsListConfig DefaultConfig() { var pos = new Vector2(0, -85); var iconConfig = new StatusEffectIconConfig(); iconConfig.DispellableBorderConfig.Enabled = false; var config = new TargetDebuffsListConfig(pos, HUDConstants.DefaultStatusEffectsListSize, false, true, true, GrowthDirections.Right | GrowthDirections.Up, iconConfig); config.AnchorToUnitFrame = true; config.UnitFrameAnchor = DrawAnchor.TopLeft; return config; } public TargetDebuffsListConfig(Vector2 position, Vector2 size, bool showBuffs, bool showDebuffs, bool showPermanentEffects, GrowthDirections growthDirections, StatusEffectIconConfig iconConfig) : base(position, size, showBuffs, showDebuffs, showPermanentEffects, growthDirections, iconConfig) { } } [Section("Buffs and Debuffs")] [SubSection("Focus Target Buffs", 0)] public class FocusTargetBuffsListConfig : UnitFrameStatusEffectsListConfig { public new static FocusTargetBuffsListConfig DefaultConfig() { var pos = new Vector2(0, -1); var iconConfig = new StatusEffectIconConfig(); iconConfig.DispellableBorderConfig.Enabled = false; var config = new FocusTargetBuffsListConfig(pos, HUDConstants.DefaultStatusEffectsListSize, true, false, true, GrowthDirections.Right | GrowthDirections.Up, iconConfig); config.AnchorToUnitFrame = true; config.UnitFrameAnchor = DrawAnchor.TopLeft; return config; } public FocusTargetBuffsListConfig(Vector2 position, Vector2 size, bool showBuffs, bool showDebuffs, bool showPermanentEffects, GrowthDirections growthDirections, StatusEffectIconConfig iconConfig) : base(position, size, showBuffs, showDebuffs, showPermanentEffects, growthDirections, iconConfig) { } } [Section("Buffs and Debuffs")] [SubSection("Focus Target Debuffs", 0)] public class FocusTargetDebuffsListConfig : UnitFrameStatusEffectsListConfig { public new static FocusTargetDebuffsListConfig DefaultConfig() { var pos = new Vector2(0, -85); var iconConfig = new StatusEffectIconConfig(); iconConfig.DispellableBorderConfig.Enabled = false; var config = new FocusTargetDebuffsListConfig(pos, HUDConstants.DefaultStatusEffectsListSize, false, true, true, GrowthDirections.Right | GrowthDirections.Up, iconConfig); config.AnchorToUnitFrame = true; config.UnitFrameAnchor = DrawAnchor.TopLeft; return config; } public FocusTargetDebuffsListConfig(Vector2 position, Vector2 size, bool showBuffs, bool showDebuffs, bool showPermanentEffects, GrowthDirections growthDirections, StatusEffectIconConfig iconConfig) : base(position, size, showBuffs, showDebuffs, showPermanentEffects, growthDirections, iconConfig) { } } public abstract class UnitFrameStatusEffectsListConfig : StatusEffectsListConfig { [Checkbox("Anchor to Unit Frame")] [Order(16)] public bool AnchorToUnitFrame = false; [Anchor("Unit Frame Anchor")] [Order(17, collapseWith = nameof(AnchorToUnitFrame))] public DrawAnchor UnitFrameAnchor = DrawAnchor.TopLeft; [NestedConfig("Visibility", 200)] public VisibilityConfig VisibilityConfig = new VisibilityConfig(); public UnitFrameStatusEffectsListConfig(Vector2 position, Vector2 size, bool showBuffs, bool showDebuffs, bool showPermanentEffects, GrowthDirections growthDirections, StatusEffectIconConfig iconConfig) : base(position, size, showBuffs, showDebuffs, showPermanentEffects, growthDirections, iconConfig) { } } public class StatusEffectsListConfig : MovablePluginConfigObject { public bool ShowBuffs; public bool ShowDebuffs; [DragInt2("Size", min = 1, max = 4000)] [Order(15)] public Vector2 Size; [DragInt2("Icon Padding", min = 0, max = 500)] [Order(19)] public Vector2 IconPadding = new(2, 2); [Checkbox("Preview", isMonitored = true)] [Order(20)] public bool Preview; [Checkbox("Fill Rows First", spacing = true)] [Order(25)] public bool FillRowsFirst = true; [Combo("Icons Growth Direction", "Right and Down", "Right and Up", "Left and Down", "Left and Up", "Centered and Up", "Centered and Down", "Centered and Left", "Centered and Right" )] [Order(30)] public int Directions; [DragInt("Limit (-1 for no limit)", min = -1, max = 1000)] [Order(35)] public int Limit = -1; [Checkbox("Permanent Effects", spacing = true)] [Order(40)] public bool ShowPermanentEffects; [Checkbox("Permanent Effects First")] [Order(41)] public bool ShowPermanentFirst; [Checkbox("Only My Effects", spacing = true)] [Order(42)] public bool ShowOnlyMine = false; [Checkbox("My Effects First")] [Order(43)] public bool ShowMineFirst = false; [Checkbox("Pet As Own Effect")] [Order(44)] public bool IncludePetAsOwn = false; [Checkbox("Sort by Duration", spacing = true, help = "If enabled, \"Permanent Effects First\" and \"My Effects First\" will be ignored!")] [Order(45)] public bool SortByDuration = false; [RadioSelector("Ascending", "Descending")] [Order(46, collapseWith = nameof(SortByDuration))] public StatusEffectDurationSortType DurationSortType = StatusEffectDurationSortType.Ascending; [Checkbox("Tooltips", spacing = true)] [Order(47)] public bool ShowTooltips = true; [Checkbox("Disable Interaction", help = "Enabling this will disable right clicking buffs off, or the shortcut to blacklist/whitelist a status effect.")] [Order(48)] public bool DisableInteraction = false; [Checkbox("Hide when Dead")] [Order(49)] public bool HideWhenDead = true; [NestedConfig("Icons", 65)] public StatusEffectIconConfig IconConfig; [NestedConfig("Filter Status Effects", 70, separator = true, spacing = false, collapsingHeader = false)] public StatusEffectsBlacklistConfig BlacklistConfig = new StatusEffectsBlacklistConfig(); public StatusEffectsListConfig(Vector2 position, Vector2 size, bool showBuffs, bool showDebuffs, bool showPermanentEffects, GrowthDirections growthDirections, StatusEffectIconConfig iconConfig) { Position = position; Size = size; ShowBuffs = showBuffs; ShowDebuffs = showDebuffs; ShowPermanentEffects = showPermanentEffects; SetGrowthDirections(growthDirections); IconConfig = iconConfig; Strata = StrataLevel.HIGH; } private void SetGrowthDirections(GrowthDirections growthDirections) { Directions = LayoutHelper.IndexFromGrowthDirections(growthDirections); } } [Exportable(false)] [Disableable(false)] public class StatusEffectIconConfig : PluginConfigObject { [DragInt2("Icon Size", min = 1, max = 1000)] [Order(5)] public Vector2 Size = new(40, 40); [Checkbox("Crop Icon", spacing = true)] [Order(20)] public bool CropIcon = true; [NestedConfig("Border", 25, collapseWith = nameof(CropIcon), collapsingHeader = false)] public StatusEffectIconBorderConfig BorderConfig = new(); [NestedConfig("Shadow", 26, collapseWith = nameof(CropIcon), collapsingHeader = false)] public ShadowConfig ShadowConfig = new ShadowConfig() { Enabled = false }; [NestedConfig("Dispellable Effects Border", 30, collapseWith = nameof(CropIcon), collapsingHeader = false)] public StatusEffectIconBorderConfig DispellableBorderConfig = new(new PluginConfigColor(new Vector4(141f / 255f, 206f / 255f, 229f / 255f, 100f / 100f)), 2); [NestedConfig("My Effects Border", 35, collapseWith = nameof(CropIcon), collapsingHeader = false)] public StatusEffectIconBorderConfig OwnedBorderConfig = new(new PluginConfigColor(new Vector4(35f / 255f, 179f / 255f, 69f / 255f, 100f / 100f)), 1); [NestedConfig("Duration", 50)] public LabelConfig DurationLabelConfig; [NestedConfig("Stacks", 60)] public LabelConfig StacksLabelConfig; public StatusEffectIconConfig(LabelConfig? durationLabelConfig = null, LabelConfig? stacksLabelConfig = null) { DurationLabelConfig = durationLabelConfig ?? StatusEffectsListsDefaults.DefaultDurationLabelConfig(); StacksLabelConfig = stacksLabelConfig ?? StatusEffectsListsDefaults.DefaultStacksLabelConfig(); } } [Exportable(false)] public class StatusEffectIconBorderConfig : PluginConfigObject { [ColorEdit4("Color")] [Order(5)] public PluginConfigColor Color = new(Vector4.UnitW); [DragInt("Thickness", min = 1, max = 100)] [Order(10)] public int Thickness = 1; public StatusEffectIconBorderConfig() { } public StatusEffectIconBorderConfig(PluginConfigColor color, int thickness) { Color = color; Thickness = thickness; } } internal class StatusEffectsListsDefaults { internal static LabelConfig DefaultDurationLabelConfig() { return new LabelConfig(Vector2.Zero, "", DrawAnchor.Center, DrawAnchor.Center); } internal static LabelConfig DefaultStacksLabelConfig() { var config = new LabelConfig(new Vector2(16, -11), "", DrawAnchor.Center, DrawAnchor.Center); config.Color = new(Vector4.UnitW); config.OutlineColor = new(Vector4.One); config.ShadowConfig.Color = new(Vector4.One); return config; } } public enum FilterType { Blacklist, Whitelist } [Exportable(false)] public class StatusEffectsBlacklistConfig : PluginConfigObject { [RadioSelector(typeof(FilterType))] [Order(5)] public FilterType FilterType; public SortedList List = new SortedList(); [JsonIgnore] private string? _errorMessage = null; [JsonIgnore] private string? _importString = null; [JsonIgnore] private bool _clearingList = false; private string KeyName(Status status) { return $"{status.Name}[{status.RowId.ToString()}]"; } public bool StatusAllowed(Status status) { bool inList = List.Any(pair => pair.Value == status.RowId); if ((inList && FilterType == FilterType.Blacklist) || (!inList && FilterType == FilterType.Whitelist)) { return false; } return true; } public bool AddNewEntry(Status? status) { if (status != null && status.HasValue && !List.ContainsKey(KeyName(status.Value))) { List.Add(KeyName(status.Value), status.Value.RowId); _input = ""; return true; } return false; } private bool AddNewEntry(string input, ExcelSheet? sheet) { if (input.Length > 0 && sheet != null) { List statusToAdd = new List(); // try id if (uint.TryParse(input, out uint uintValue)) { if (uintValue > 0) { Status? status = sheet.GetRow(uintValue); if (status != null && status.HasValue) { statusToAdd.Add(status.Value); } } } // try name if (statusToAdd.Count == 0) { var enumerator = sheet.GetEnumerator(); while (enumerator.MoveNext()) { Status item = enumerator.Current; if (item.Name.ToString().ToLower() == input.ToLower()) { statusToAdd.Add(item); } } } bool added = false; foreach (Status status in statusToAdd) { added |= AddNewEntry(status); } return added; } return false; } private string ExportList() { string exportString = ""; for (int i = 0; i < List.Keys.Count; i++) { exportString += List.Keys[i] + "|"; exportString += List.Values[i] + "|"; } return exportString; } private string? ImportList(string importString) { SortedList tmpList = new SortedList(); try { string[] strings = importString.Trim().Split("|", StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < strings.Length; i += 2) { if (i + 1 >= strings.Length) { break; } string key = strings[i]; uint value = uint.Parse(strings[i + 1]); tmpList.Add(key, value); } } catch { return "Error importing list!"; } List = tmpList; return null; } [JsonIgnore] private string _input = ""; [ManualDraw] public bool Draw(ref bool changed) { if (!Enabled) { return false; } var flags = ImGuiTableFlags.RowBg | ImGuiTableFlags.Borders | ImGuiTableFlags.BordersOuter | ImGuiTableFlags.BordersInner | ImGuiTableFlags.ScrollY | ImGuiTableFlags.SizingFixedSame; var sheet = Plugin.DataManager.GetExcelSheet(); var iconSize = new Vector2(30, 30); var indexToRemove = -1; if (ImGui.BeginChild("Filter Effects", new Vector2(0, 360), false, ImGuiWindowFlags.NoSavedSettings | ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse)) { ImGui.Text(" "); ImGui.SameLine(); ImGui.Text("Type an ID or Name"); ImGui.Text(" "); ImGui.SameLine(); ImGui.PushItemWidth(300); if (ImGui.InputText("", ref _input, 64, ImGuiInputTextFlags.EnterReturnsTrue)) { changed |= AddNewEntry(_input, sheet); ImGui.SetKeyboardFocusHere(-1); } // add ImGui.SameLine(); ImGui.PushFont(UiBuilder.IconFont); if (ImGui.Button(FontAwesomeIcon.Plus.ToIconString(), new Vector2(0, 0))) { changed |= AddNewEntry(_input, sheet); ImGui.SetKeyboardFocusHere(-2); } // export ImGui.SameLine(); ImGui.SetCursorPosX(ImGui.GetCursorPosX() + 154); if (ImGui.Button(FontAwesomeIcon.Upload.ToIconString(), new Vector2(0, 0))) { ImGui.SetClipboardText(ExportList()); ImGui.OpenPopup("export_succes_popup"); } ImGui.PopFont(); ImGuiHelper.SetTooltip("Export List to Clipboard"); // export success popup if (ImGui.BeginPopup("export_succes_popup")) { ImGui.Text("List exported to clipboard!"); ImGui.EndPopup(); } // import ImGui.SameLine(); ImGui.PushFont(UiBuilder.IconFont); if (ImGui.Button(FontAwesomeIcon.Download.ToIconString(), new Vector2(0, 0))) { _importString = ImGui.GetClipboardText(); } ImGui.PopFont(); ImGuiHelper.SetTooltip("Import List from Clipboard"); // clear ImGui.SameLine(); ImGui.PushFont(UiBuilder.IconFont); if (ImGui.Button(FontAwesomeIcon.Trash.ToIconString(), new Vector2(0, 0))) { _clearingList = true; } ImGui.PopFont(); ImGuiHelper.SetTooltip("Clear List"); ImGui.Text(" "); ImGui.SameLine(); if (ImGui.BeginTable("table", 4, flags, new Vector2(583, List.Count > 0 ? 200 : 40))) { ImGui.TableSetupColumn("Icon", ImGuiTableColumnFlags.WidthFixed, 0, 0); ImGui.TableSetupColumn("ID", ImGuiTableColumnFlags.WidthFixed, 0, 1); ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthStretch, 0, 2); ImGui.TableSetupColumn("", ImGuiTableColumnFlags.WidthFixed, 0, 3); ImGui.TableSetupScrollFreeze(0, 1); ImGui.TableHeadersRow(); for (int i = 0; i < List.Count; i++) { var id = List.Values[i]; var name = List.Keys[i]; var row = sheet?.GetRow(id); if (_input != "" && !name.ToUpper().Contains(_input.ToUpper())) { continue; } ImGui.PushID(i.ToString()); ImGui.TableNextRow(ImGuiTableRowFlags.None, iconSize.Y); // icon if (ImGui.TableSetColumnIndex(0)) { if (row != null) { DrawHelper.DrawIcon(row, ImGui.GetCursorPos(), iconSize, false, true); } } // id if (ImGui.TableSetColumnIndex(1)) { ImGui.Text(id.ToString()); } // name if (ImGui.TableSetColumnIndex(2)) { ImGui.Text(row != null && row.HasValue ? row.Value.Name.ToString() : name); } // remove if (ImGui.TableSetColumnIndex(3)) { ImGui.PushFont(UiBuilder.IconFont); ImGui.PushStyleColor(ImGuiCol.Button, Vector4.Zero); ImGui.PushStyleColor(ImGuiCol.ButtonActive, Vector4.Zero); ImGui.PushStyleColor(ImGuiCol.ButtonHovered, Vector4.Zero); if (ImGui.Button(FontAwesomeIcon.Trash.ToIconString(), iconSize)) { changed = true; indexToRemove = i; } ImGui.PopFont(); ImGui.PopStyleColor(3); } ImGui.PopID(); } ImGui.EndTable(); } ImGui.Text(" "); ImGui.SameLine(); ImGui.Text("Tip: You can [Ctrl + Alt + Shift] + Left Click on a status effect to automatically add it to the list."); } if (indexToRemove >= 0) { List.RemoveAt(indexToRemove); } ImGui.EndChild(); // error message if (_errorMessage != null) { if (ImGuiHelper.DrawErrorModal(_errorMessage)) { _errorMessage = null; } } // import confirmation if (_importString != null) { string[] message = new string[] { "All the elements in the list will be replaced.", "Are you sure you want to import?" }; var (didConfirm, didClose) = ImGuiHelper.DrawConfirmationModal("Import?", message); if (didConfirm) { _errorMessage = ImportList(_importString); changed = true; } if (didConfirm || didClose) { _importString = null; } } // clear confirmation if (_clearingList) { string message = "Are you sure you want to clear the list?"; var (didConfirm, didClose) = ImGuiHelper.DrawConfirmationModal("Clear List?", message); if (didConfirm) { List.Clear(); changed = true; } if (didConfirm || didClose) { _clearingList = false; } } return false; } } public class StatusEffectsBlacklistConfigConverter : PluginConfigObjectConverter { public StatusEffectsBlacklistConfigConverter() { NewTypeFieldConverter converter; converter = new NewTypeFieldConverter("FilterType", FilterType.Blacklist, (oldValue) => { return oldValue ? FilterType.Whitelist : FilterType.Blacklist; }); FieldConvertersMap.Add("UseAsWhitelist", converter); } public override bool CanConvert(Type objectType) { return objectType == typeof(StatusEffectsBlacklistConfig); } } [Section("Buffs and Debuffs")] [SubSection("Custom Effects", 0)] public class CustomEffectsListConfig : StatusEffectsListConfig { public new static CustomEffectsListConfig DefaultConfig() { var iconConfig = new StatusEffectIconConfig(); iconConfig.DispellableBorderConfig.Enabled = false; iconConfig.Size = new Vector2(30, 30); var pos = new Vector2(0, HUDConstants.BaseHUDOffsetY); var size = new Vector2(250, iconConfig.Size.Y * 3 + 10); var config = new CustomEffectsListConfig(pos, size, true, true, false, GrowthDirections.Centered | GrowthDirections.Up, iconConfig); config.Enabled = false; config.Directions = 5; // pre-populated white list config.BlacklistConfig.FilterType = FilterType.Whitelist; ExcelSheet? sheet = Plugin.DataManager.GetExcelSheet(); if (sheet != null) { // Left Eye config.BlacklistConfig.AddNewEntry(sheet.GetRow(1184)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(1454)); // Battle Litany config.BlacklistConfig.AddNewEntry(sheet.GetRow(786)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(1414)); // Brotherhood config.BlacklistConfig.AddNewEntry(sheet.GetRow(1185)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(2174)); // Battle Voice config.BlacklistConfig.AddNewEntry(sheet.GetRow(141)); // Devilment config.BlacklistConfig.AddNewEntry(sheet.GetRow(1825)); // Technical Finish config.BlacklistConfig.AddNewEntry(sheet.GetRow(1822)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(2050)); // Standard Finish config.BlacklistConfig.AddNewEntry(sheet.GetRow(1821)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(2024)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(2105)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(2113)); // Embolden config.BlacklistConfig.AddNewEntry(sheet.GetRow(1239)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(1297)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(2282)); // Devotion config.BlacklistConfig.AddNewEntry(sheet.GetRow(1213)); // Divination config.BlacklistConfig.AddNewEntry(sheet.GetRow(1878)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(2034)); // Chain Stratagem config.BlacklistConfig.AddNewEntry(sheet.GetRow(1221)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(1406)); // Radiant Finale config.BlacklistConfig.AddNewEntry(sheet.GetRow(2722)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(2964)); // Arcane Circle config.BlacklistConfig.AddNewEntry(sheet.GetRow(2599)); // Searing Light config.BlacklistConfig.AddNewEntry(sheet.GetRow(2703)); // Trick Attack config.BlacklistConfig.AddNewEntry(sheet.GetRow(638)); // ------ AST Card Buffs ------- // The Balance config.BlacklistConfig.AddNewEntry(sheet.GetRow(829)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(1338)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(1882)); // The Bole config.BlacklistConfig.AddNewEntry(sheet.GetRow(830)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(1339)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(1883)); // The Arrow config.BlacklistConfig.AddNewEntry(sheet.GetRow(831)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(1884)); // The Spear config.BlacklistConfig.AddNewEntry(sheet.GetRow(832)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(1885)); // The Ewer config.BlacklistConfig.AddNewEntry(sheet.GetRow(833)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(1340)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(1886)); // The Spire config.BlacklistConfig.AddNewEntry(sheet.GetRow(834)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(1341)); config.BlacklistConfig.AddNewEntry(sheet.GetRow(1887)); } return config; } public CustomEffectsListConfig(Vector2 position, Vector2 size, bool showBuffs, bool showDebuffs, bool showPermanentEffects, GrowthDirections growthDirections, StatusEffectIconConfig iconConfig) : base(position, size, showBuffs, showDebuffs, showPermanentEffects, growthDirections, iconConfig) { } } public enum StatusEffectDurationSortType { Ascending, Descending } }