diff --git a/Glamourer/GameData/NpcCustomizeSet.cs b/Glamourer/GameData/NpcCustomizeSet.cs index a8f3e1b..a5a32fa 100644 --- a/Glamourer/GameData/NpcCustomizeSet.cs +++ b/Glamourer/GameData/NpcCustomizeSet.cs @@ -199,7 +199,7 @@ public class NpcCustomizeSet : IAsyncDataContainer, IReadOnlyList } // Sort non-alphanumeric entries at the end instead of the beginning. - var lastWeird = _data.FindIndex(d => char.IsAsciiLetterOrDigit(d.Name[0])); + var lastWeird = _data.FindIndex(d => char.IsAsciiLetterOrDigit((char)d.Name[0])); if (lastWeird is not -1) { _data.AddRange(_data.Take(lastWeird)); diff --git a/Glamourer/Gui/Tabs/NpcCombo.cs b/Glamourer/Gui/Tabs/NpcCombo.cs deleted file mode 100644 index 86eb766..0000000 --- a/Glamourer/Gui/Tabs/NpcCombo.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Glamourer.GameData; -using OtterGui.Widgets; - -namespace Glamourer.Gui.Tabs; - -public class NpcCombo(NpcCustomizeSet npcCustomizeSet) - : FilterComboCache(npcCustomizeSet, MouseWheelType.None, Glamourer.Log) -{ - protected override string ToString(NpcData obj) - => obj.Name; -} diff --git a/Glamourer/Gui/Tabs/UnlocksTab/UnlockOverview.cs b/Glamourer/Gui/Tabs/UnlocksTab/UnlockOverview.cs index 7a61f9e..7d645a9 100644 --- a/Glamourer/Gui/Tabs/UnlocksTab/UnlockOverview.cs +++ b/Glamourer/Gui/Tabs/UnlocksTab/UnlockOverview.cs @@ -1,18 +1,13 @@ using Dalamud.Game.Text.SeStringHandling; -using Dalamud.Interface.Utility; using Glamourer.GameData; using Glamourer.Interop; using Glamourer.Interop.Penumbra; using Glamourer.Services; using Glamourer.Unlocks; -using Dalamud.Bindings.ImGui; using ImSharp; using Luna; -using OtterGui.Raii; -using OtterGui.Text; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; -using ImGuiClip = OtterGui.ImGuiClip; namespace Glamourer.Gui.Tabs.UnlocksTab; @@ -40,7 +35,7 @@ public class UnlockOverview( private void DrawSelector() { - using var child = ImRaii.Child("Selector", new Vector2(200 * Im.Style.GlobalScale, -1), true); + using var child = Im.Child.Begin("Selector"u8, Im.ContentRegion.Available with { X = 200 * Im.Style.GlobalScale }, true); if (!child) return; @@ -49,7 +44,7 @@ public class UnlockOverview( if (type.IsOffhandType() || type.IsBonus() || !items.ItemData.ByType.TryGetValue(type, out var value) || value.Count == 0) continue; - if (ImGui.Selectable(type.ToName(), _selected1 == type)) + if (Im.Selectable(type.ToNameU8(), _selected1 == type)) { _selected1 = type; _selected2 = SubRace.Unknown; @@ -58,7 +53,7 @@ public class UnlockOverview( } } - if (ImGui.Selectable("Bonus Items", _selected4 == BonusItemFlag.Glasses)) + if (Im.Selectable("Bonus Items"u8, _selected4 is BonusItemFlag.Glasses)) { _selected1 = FullEquipType.Unknown; _selected2 = SubRace.Unknown; @@ -68,10 +63,10 @@ public class UnlockOverview( foreach (var (clan, gender) in CustomizeManager.AllSets()) { - if (customizations.Manager.GetSet(clan, gender).HairStyles.Count == 0) + if (customizations.Manager.GetSet(clan, gender).HairStyles.Count is 0) continue; - if (ImGui.Selectable($"{(gender is Gender.Male ? '♂' : '♀')} {clan.ToShortName()} Hair & Paint", + if (Im.Selectable($"{(gender is Gender.Male ? '♂' : '♀')} {clan.ToShortName()} Hair & Paint", _selected2 == clan && _selected3 == gender)) { _selected1 = FullEquipType.Unknown; @@ -92,7 +87,7 @@ public class UnlockOverview( private void DrawPanel() { - using var child = ImRaii.Child("Panel", -Vector2.One, true); + using var child = Im.Child.Begin("Panel"u8, Im.ContentRegion.Available, true); if (!child) return; @@ -112,8 +107,8 @@ public class UnlockOverview( var set = customizations.Manager.GetSet(_selected2, _selected3); var spacing = IconSpacing; - using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing); - var iconSize = ImGuiHelpers.ScaledVector2(128); + using var style = ImStyleDouble.ItemSpacing.Push(spacing); + var iconSize = ImEx.ScaledVector(128); var iconsPerRow = IconsPerRow(iconSize.X, spacing.X); var counter = 0; @@ -125,22 +120,22 @@ public class UnlockOverview( var unlocked = customizeUnlocks.IsUnlocked(customize, out var time); var icon = customizations.Manager.GetIcon(customize.IconId); var hasIcon = icon.TryGetWrap(out var wrap, out _); - ImGui.Image(wrap?.Handle ?? icon.GetWrapOrEmpty().Handle, iconSize, Vector2.Zero, Vector2.One, + Im.Image.Draw(wrap?.Id ?? icon.GetWrapOrEmpty().Id, iconSize, Vector2.Zero, Vector2.One, unlocked || codes.Enabled(CodeService.CodeFlag.Shirts) ? Vector4.One : UnavailableTint); if (favorites.Contains(_selected3, _selected2, customize.Index, customize.Value)) Im.Window.DrawList.Shape.Rectangle(Im.Item.UpperLeftCorner, Im.Item.LowerRightCorner, _favoriteColor, 12 * Im.Style.GlobalScale, ImDrawFlagsRectangle.RoundCornersAll, 6 * Im.Style.GlobalScale); - if (hasIcon && ImGui.IsItemHovered()) + if (hasIcon && Im.Item.Hovered()) { - using var tt = ImRaii.Tooltip(); + using var tt = Im.Tooltip.Begin(); var size = new Vector2(wrap!.Width, wrap.Height); if (size.X >= iconSize.X && size.Y >= iconSize.Y) - ImGui.Image(wrap.Handle, size); - ImGui.TextUnformatted(unlockData.Name); - ImGui.TextUnformatted($"{customize.Index.ToNameU8()} {customize.Value.Value}"); - ImGui.TextUnformatted(unlocked ? $"Unlocked on {time:g}" : "Not unlocked."); + Im.Image.Draw(wrap.Id, size); + Im.Text(unlockData.Name); + Im.Text($"{customize.Index.ToNameU8()} {customize.Value.Value}"); + Im.Text(unlocked ? $"Unlocked on {time:g}" : "Not unlocked."u8); } if (counter != iconsPerRow - 1) @@ -158,36 +153,10 @@ public class UnlockOverview( private void DrawBonusItems() { var spacing = IconSpacing; - using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing); - var iconSize = ImGuiHelpers.ScaledVector2(64); + var iconSize = ImEx.ScaledVector(64); var iconsPerRow = IconsPerRow(iconSize.X, spacing.X); - var numRows = (items.DictBonusItems.Count + iconsPerRow - 1) / iconsPerRow; - var numVisibleRows = (int)(Math.Ceiling(Im.ContentRegion.Available.Y / (iconSize.Y + spacing.Y)) + 0.5f) + 1; - - var skips = ImGuiClip.GetNecessarySkips(iconSize.Y + spacing.Y); - var start = skips * iconsPerRow; - var end = Math.Min(numVisibleRows * iconsPerRow + skips * iconsPerRow, items.DictBonusItems.Count); - var counter = 0; - - foreach (var item in items.DictBonusItems.Values.Skip(start).Take(end - start)) - { - DrawItem(item); - if (counter != iconsPerRow - 1) - { - Im.Line.Same(); - ++counter; - } - else - { - counter = 0; - } - } - - if (ImGui.GetCursorPosX() != 0) - Im.Line.New(); - var remainder = numRows - numVisibleRows - skips; - if (remainder > 0) - ImGuiClip.DrawEndDummy(remainder, iconSize.Y + spacing.Y); + Im.ListClipper.DrawGrouped(items.DictBonusItems.Values, DrawItem, items.DictBonusItems.Count, iconsPerRow, iconSize.Y + spacing.Y, spacing.X); + return; void DrawItem(EquipItem item) { @@ -196,9 +165,9 @@ public class UnlockOverview( if (!textures.TryLoadIcon(item.IconId.Id, out var iconHandle)) return; - var (icon, size) = (iconHandle.Handle, new Vector2(iconHandle.Width, iconHandle.Height)); + var (icon, size) = (iconHandle.Id, new Vector2(iconHandle.Width, iconHandle.Height)); - ImGui.Image(icon, iconSize, Vector2.Zero, Vector2.One, + Im.Image.Draw(icon, iconSize, Vector2.Zero, Vector2.One, unlocked || codes.Enabled(CodeService.CodeFlag.Shirts) ? Vector4.One : UnavailableTint); if (favorites.Contains(item)) Im.Window.DrawList.Shape.Rectangle(Im.Item.UpperLeftCorner, Im.Item.LowerRightCorner, _favoriteColor, @@ -207,17 +176,18 @@ public class UnlockOverview( var mods = DrawModdedMarker(item, iconSize); // TODO handle clicking - if (ImGui.IsItemHovered()) + if (Im.Item.Hovered()) { - using var tt = ImRaii.Tooltip(); + using var style = Im.Style.PushDefault(); + using var tt = Im.Tooltip.Begin(); if (size.X >= iconSize.X && size.Y >= iconSize.Y) - ImGui.Image(icon, size); - ImUtf8.Text(item.Name); - ImUtf8.Text($"{item.Type.ToName()}"); - ImUtf8.Text($"{item.Id.Id}"); - ImUtf8.Text($"{item.PrimaryId.Id}-{item.Variant.Id}"); + Im.Image.Draw(icon, size); + Im.Text(item.Name); + Im.Text(item.Type.ToNameU8()); + Im.Text($"{item.Id.Id}"); + Im.Text($"{item.PrimaryId.Id}-{item.Variant.Id}"); // TODO - ImUtf8.Text("Always Unlocked"u8); // : $"Unlocked on {time:g}" : "Not Unlocked."); + Im.Text("Always Unlocked"u8); // : $"Unlocked on {time:g}" : "Not Unlocked."); // TODO //tooltip.CreateTooltip(item, string.Empty, false); DrawModTooltip(mods); @@ -231,34 +201,9 @@ public class UnlockOverview( return; var spacing = IconSpacing; - using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing); - var iconSize = ImGuiHelpers.ScaledVector2(64); + var iconSize = ImEx.ScaledVector(64); var iconsPerRow = IconsPerRow(iconSize.X, spacing.X); - var numRows = (value.Count + iconsPerRow - 1) / iconsPerRow; - var numVisibleRows = (int)(Math.Ceiling(Im.ContentRegion.Available.Y / (iconSize.Y + spacing.Y)) + 0.5f) + 1; - - var skips = ImGuiClip.GetNecessarySkips(iconSize.Y + spacing.Y); - var end = Math.Min(numVisibleRows * iconsPerRow + skips * iconsPerRow, value.Count); - var counter = 0; - for (var idx = skips * iconsPerRow; idx < end; ++idx) - { - DrawItem(value[idx]); - if (counter != iconsPerRow - 1) - { - Im.Line.Same(); - ++counter; - } - else - { - counter = 0; - } - } - - if (ImGui.GetCursorPosX() != 0) - Im.Line.New(); - var remainder = numRows - numVisibleRows - skips; - if (remainder > 0) - ImGuiClip.DrawEndDummy(remainder, iconSize.Y + spacing.Y); + Im.ListClipper.DrawGrouped(value, DrawItem, iconsPerRow, iconSize.Y + spacing.Y, spacing.X); return; void DrawItem(EquipItem item) @@ -267,9 +212,9 @@ public class UnlockOverview( if (!textures.TryLoadIcon(item.IconId.Id, out var iconHandle)) return; - var (icon, size) = (iconHandle.Handle, new Vector2(iconHandle.Width, iconHandle.Height)); + var (icon, size) = (iconHandle.Id, new Vector2(iconHandle.Width, iconHandle.Height)); - ImGui.Image(icon, iconSize, Vector2.Zero, Vector2.One, + Im.Image.Draw(icon, iconSize, Vector2.Zero, Vector2.One, unlocked || codes.Enabled(CodeService.CodeFlag.Shirts) ? Vector4.One : UnavailableTint); if (favorites.Contains(item)) Im.Window.DrawList.Shape.Rectangle(Im.Item.UpperLeftCorner, Im.Item.LowerRightCorner, ColorId.FavoriteStarOn.Value(), @@ -277,49 +222,50 @@ public class UnlockOverview( var mods = DrawModdedMarker(item, iconSize); - if (ImGui.IsItemClicked()) + if (Im.Item.Clicked()) Glamourer.Messager.Chat.Print(new SeStringBuilder().AddItemLink(item.ItemId.Id, false).BuiltString); if (Im.Item.RightClicked() && tooltip.Player(out var state)) tooltip.ApplyItem(state, item); - if (ImGui.IsItemHovered()) + if (Im.Item.Hovered()) { - using var tt = ImRaii.Tooltip(); + using var style = Im.Style.PushDefault(); + using var tt = Im.Tooltip.Begin(); if (size.X >= iconSize.X && size.Y >= iconSize.Y) - ImGui.Image(icon, size); - ImGui.TextUnformatted(item.Name); + Im.Image.Draw(icon, size); + Im.Text(item.Name); var slot = item.Type.ToSlot(); - ImGui.TextUnformatted($"{item.Type.ToName()} ({slot.ToName()})"); + Im.Text($"{item.Type.ToNameU8()} ({slot.ToNameU8()})"); if (item.Type.ValidOffhand().IsOffhandType()) - ImGui.TextUnformatted( - $"{item.Weapon()}{(items.ItemData.TryGetValue(item.ItemId, EquipSlot.OffHand, out var offhand) ? $" | {offhand.Weapon()}" : string.Empty)}"); + Im.Text( + $"{item.Weapon()}{(items.ItemData.TryGetValue(item.ItemId, EquipSlot.OffHand, out var offhand) ? $" | {offhand.Weapon()}" : StringU8.Empty)}"); else - ImGui.TextUnformatted(slot is EquipSlot.MainHand ? $"{item.Weapon()}" : $"{item.Armor()}"); - ImGui.TextUnformatted( - unlocked ? time == DateTimeOffset.MinValue ? "Always Unlocked" : $"Unlocked on {time:g}" : "Not Unlocked."); + Im.Text(slot is EquipSlot.MainHand ? $"{item.Weapon()}" : $"{item.Armor()}"); + Im.Text( + unlocked ? time == DateTimeOffset.MinValue ? "Always Unlocked"u8 : $"Unlocked on {time:g}" : "Not Unlocked."u8); if (item.Level.Value <= 1) { if (item.JobRestrictions.Id <= 1 || item.JobRestrictions.Id >= jobs.AllJobGroups.Count) - ImGui.TextUnformatted("For Everyone"); + Im.Text("For Everyone"u8); else - ImGui.TextUnformatted($"For all {jobs.AllJobGroups[item.JobRestrictions.Id].Name}"); + Im.Text($"For all {jobs.AllJobGroups[item.JobRestrictions.Id].Name}"); } else { if (item.JobRestrictions.Id <= 1 || item.JobRestrictions.Id >= jobs.AllJobGroups.Count) - ImGui.TextUnformatted($"For Everyone of at least Level {item.Level}"); + Im.Text($"For Everyone of at least Level {item.Level}"); else - ImGui.TextUnformatted($"For all {jobs.AllJobGroups[item.JobRestrictions.Id].Name} of at least Level {item.Level}"); + Im.Text($"For all {jobs.AllJobGroups[item.JobRestrictions.Id].Name} of at least Level {item.Level}"); } if (item.Flags.HasFlag(ItemFlags.IsDyable1)) - ImGui.TextUnformatted(item.Flags.HasFlag(ItemFlags.IsDyable2) ? "Dyable (2 Slots)" : "Dyable"); + Im.Text(item.Flags.HasFlag(ItemFlags.IsDyable2) ? "Dyable (2 Slots)"u8 : "Dyable"u8); if (item.Flags.HasFlag(ItemFlags.IsTradable)) - ImGui.TextUnformatted("Tradable"); + Im.Text("Tradable"u8); if (item.Flags.HasFlag(ItemFlags.IsCrestWorthy)) - ImGui.TextUnformatted("Can apply Crest"); + Im.Text("Can apply Crest"u8); DrawModTooltip(mods); tooltip.CreateTooltip(item, string.Empty, false); } @@ -327,7 +273,7 @@ public class UnlockOverview( } private static Vector2 IconSpacing - => ImGuiHelpers.ScaledVector2(2); + => ImEx.ScaledVector(2); private static int IconsPerRow(float iconWidth, float iconSpacing) => (int)(Im.ContentRegion.Available.X / (iconWidth + iconSpacing)); @@ -339,7 +285,7 @@ public class UnlockOverview( if (mods.Length is 0) return mods; - var center = ImGui.GetItemRectMin() + new Vector2(iconSize.X * 0.85f, iconSize.Y * 0.15f); + var center = Im.Item.UpperLeftCorner + new Vector2(iconSize.X * 0.85f, iconSize.Y * 0.15f); Im.Window.DrawList.Shape.CircleFilled(center, iconSize.X * 0.1f, _moddedColor); Im.Window.DrawList.Shape.Circle(center, iconSize.X * 0.1f, Rgba32.Black); return mods; diff --git a/Glamourer/Gui/Tabs/UnlocksTab/UnlockTable.cs b/Glamourer/Gui/Tabs/UnlocksTab/UnlockTable.cs index 5aa09eb..acbd1d6 100644 --- a/Glamourer/Gui/Tabs/UnlocksTab/UnlockTable.cs +++ b/Glamourer/Gui/Tabs/UnlocksTab/UnlockTable.cs @@ -1,6 +1,5 @@ using Dalamud.Game.Text.SeStringHandling; using Dalamud.Interface; -using Dalamud.Interface.Utility; using Glamourer.Events; using Glamourer.Interop; using Glamourer.Interop.Penumbra; diff --git a/Glamourer/Services/ServiceManager.cs b/Glamourer/Services/ServiceManager.cs index 0f24085..f9e63f9 100644 --- a/Glamourer/Services/ServiceManager.cs +++ b/Glamourer/Services/ServiceManager.cs @@ -179,6 +179,5 @@ public static class StaticServiceManager .AddSingleton() .AddSingleton() .AddSingleton() - .AddSingleton() .AddSingleton(); } diff --git a/Glamourer/Unlocks/CustomizeUnlockManager.cs b/Glamourer/Unlocks/CustomizeUnlockManager.cs index bd13f99..6fcdde0 100644 --- a/Glamourer/Unlocks/CustomizeUnlockManager.cs +++ b/Glamourer/Unlocks/CustomizeUnlockManager.cs @@ -10,6 +10,7 @@ using Lumina.Excel.Sheets; using Penumbra.GameData; using Penumbra.GameData.Enums; using Penumbra.GameData.Interop; +using StringU8 = ImSharp.StringU8; namespace Glamourer.Unlocks; @@ -21,7 +22,7 @@ public class CustomizeUnlockManager : IDisposable, ISavable private readonly ActorObjectManager _objects; private readonly Dictionary _unlocked = new(); - public readonly IReadOnlyDictionary Unlockable; + public readonly IReadOnlyDictionary Unlockable; public IReadOnlyDictionary Unlocked => _unlocked; @@ -172,10 +173,10 @@ public class CustomizeUnlockManager : IDisposable, ISavable "customization"); /// Create a list of all unlockable hairstyles and face paints. - private static Dictionary CreateUnlockableCustomizations(CustomizeService customizations, + private static Dictionary CreateUnlockableCustomizations(CustomizeService customizations, IDataManager gameData) { - var ret = new Dictionary(); + var ret = new Dictionary(); var sheet = gameData.GetExcelSheet(ClientLanguage.English); foreach (var (clan, gender) in CustomizeManager.AllSets()) { @@ -183,24 +184,24 @@ public class CustomizeUnlockManager : IDisposable, ISavable foreach (var hair in list.HairStyles) { var x = sheet.FirstOrNull(f => f.FeatureID == hair.Value.Value); - if (x?.IsPurchasable == true) + if (x?.IsPurchasable is true) { - var name = x.Value.FeatureID == 61 + var name = x.Value.FeatureID is 61 ? "Eternal Bond" : x.Value.HintItem.ValueNullable?.Name.ExtractText().Replace("Modern Aesthetics - ", string.Empty) ?? string.Empty; - ret.TryAdd(hair, (x.Value.UnlockLink, name)); + ret.TryAdd(hair, (x.Value.UnlockLink, new StringU8(name))); } } foreach (var paint in list.FacePaints) { var x = sheet.FirstOrNull(f => f.FeatureID == paint.Value.Value); - if (x?.IsPurchasable == true) + if (x?.IsPurchasable is true) { var name = x.Value.HintItem.ValueNullable?.Name.ExtractText().Replace("Modern Cosmetics - ", string.Empty) ?? string.Empty; - ret.TryAdd(paint, (x.Value.UnlockLink, name)); + ret.TryAdd(paint, (x.Value.UnlockLink, new StringU8(name))); } } } diff --git a/Luna b/Luna index ab62092..3d46034 160000 --- a/Luna +++ b/Luna @@ -1 +1 @@ -Subproject commit ab620925015405133533c8811793f64082804d59 +Subproject commit 3d460349da4ab862961bbb3170ccf4f0fedf0eca diff --git a/Penumbra.GameData b/Penumbra.GameData index ab77b93..6f39fad 160000 --- a/Penumbra.GameData +++ b/Penumbra.GameData @@ -1 +1 @@ -Subproject commit ab77b934eecc097ca1bf0d6243c8cd0dd4ffa155 +Subproject commit 6f39fadad5333c73cc1d90219828f169c3bbaa2a