diff --git a/CustomizePlus.GameData/CustomizePlus.GameData.csproj b/CustomizePlus.GameData/CustomizePlus.GameData.csproj index 51c26da..ad75ed3 100644 --- a/CustomizePlus.GameData/CustomizePlus.GameData.csproj +++ b/CustomizePlus.GameData/CustomizePlus.GameData.csproj @@ -1,7 +1,7 @@ - net7.0-windows + net8.0-windows enable enable true diff --git a/CustomizePlus.GameData/Data/Actor.cs b/CustomizePlus.GameData/Data/Actor.cs deleted file mode 100644 index 8c74256..0000000 --- a/CustomizePlus.GameData/Data/Actor.cs +++ /dev/null @@ -1,116 +0,0 @@ -using Penumbra.GameData.Actors; -using System; -using FFXIVClientStructs.FFXIV.Client.Game.Character; -using FFXIVClientStructs.FFXIV.Client.Game.Object; -using Penumbra.GameData.Enums; -using Penumbra.GameData.Structs; -using Penumbra.String; - -namespace CustomizePlus.GameData.Data; - -public readonly unsafe struct Actor : IEquatable -{ - private Actor(nint address) - => Address = address; - - public static readonly Actor Null = new(nint.Zero); - - public readonly nint Address; - - public GameObject* AsObject - => (GameObject*)Address; - - public Character* AsCharacter - => (Character*)Address; - - public bool Valid - => Address != nint.Zero; - - public bool IsCharacter - => Valid && AsObject->IsCharacter(); - - public static implicit operator Actor(nint? pointer) - => new(pointer ?? nint.Zero); - - public static implicit operator Actor(GameObject* pointer) - => new((nint)pointer); - - public static implicit operator Actor(Character* pointer) - => new((nint)pointer); - - public static implicit operator nint(Actor actor) - => actor.Address; - - public bool IsGPoseOrCutscene - => Index.Index is >= (int)ScreenActor.CutsceneStart and < (int)ScreenActor.CutsceneEnd; - - public ActorIdentifier GetIdentifier(ActorManager actors) - => actors.FromObject(AsObject, out _, true, true, false); - - public ByteString Utf8Name - => Valid ? new ByteString(AsObject->Name) : ByteString.Empty; - - public bool Identifier(ActorManager actors, out ActorIdentifier ident) - { - if (Valid) - { - ident = GetIdentifier(actors); - return ident.IsValid; - } - - ident = ActorIdentifier.Invalid; - return false; - } - - public ObjectIndex Index - => Valid ? AsObject->ObjectIndex : ObjectIndex.AnyIndex; - - public Model Model - => Valid ? AsObject->DrawObject : null; - - public byte Job - => IsCharacter ? AsCharacter->CharacterData.ClassJob : (byte)0; - - public static implicit operator bool(Actor actor) - => actor.Address != nint.Zero; - - public static bool operator true(Actor actor) - => actor.Address != nint.Zero; - - public static bool operator false(Actor actor) - => actor.Address == nint.Zero; - - public static bool operator !(Actor actor) - => actor.Address == nint.Zero; - - public bool Equals(Actor other) - => Address == other.Address; - - public override bool Equals(object? obj) - => obj is Actor other && Equals(other); - - public override int GetHashCode() - => Address.GetHashCode(); - - public static bool operator ==(Actor lhs, Actor rhs) - => lhs.Address == rhs.Address; - - public static bool operator !=(Actor lhs, Actor rhs) - => lhs.Address != rhs.Address; - /* - /// Only valid for characters. - public CharacterArmor GetArmor(EquipSlot slot) - => ((CharacterArmor*)&AsCharacter->DrawData.Head)[slot.ToIndex()]; - - public CharacterWeapon GetMainhand() - => new(AsCharacter->DrawData.Weapon(DrawDataContainer.WeaponSlot.MainHand).ModelId.Value); - - public CharacterWeapon GetOffhand() - => new(AsCharacter->DrawData.Weapon(DrawDataContainer.WeaponSlot.OffHand).ModelId.Value); - - public Customize GetCustomize() - => *(Customize*)&AsCharacter->DrawData.CustomizeData; - */ - public override string ToString() - => $"0x{Address:X}"; -} diff --git a/CustomizePlus.GameData/Data/ActorData.cs b/CustomizePlus.GameData/Data/ActorData.cs index 6e49129..95d3540 100644 --- a/CustomizePlus.GameData/Data/ActorData.cs +++ b/CustomizePlus.GameData/Data/ActorData.cs @@ -1,4 +1,6 @@ -namespace CustomizePlus.GameData.Data; +using Penumbra.GameData.Interop; + +namespace CustomizePlus.GameData.Data; /// /// A single actor with its label and the list of associated game objects. diff --git a/CustomizePlus.GameData/Data/Model.cs b/CustomizePlus.GameData/Data/Model.cs deleted file mode 100644 index 5db6a0f..0000000 --- a/CustomizePlus.GameData/Data/Model.cs +++ /dev/null @@ -1,199 +0,0 @@ -using System; -using FFXIVClientStructs.FFXIV.Client.Game.Character; -using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; -using Penumbra.GameData.Enums; -using Penumbra.GameData.Structs; -using Object = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.Object; -using ObjectType = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.ObjectType; - -namespace CustomizePlus.GameData.Data; - -public readonly unsafe struct Model : IEquatable -{ - private Model(nint address) - => Address = address; - - public readonly nint Address; - - public static readonly Model Null = new(0); - - public DrawObject* AsDrawObject - => (DrawObject*)Address; - - public CharacterBase* AsCharacterBase - => (CharacterBase*)Address; - - public Weapon* AsWeapon - => (Weapon*)Address; - - public Human* AsHuman - => (Human*)Address; - - public static implicit operator Model(nint? pointer) - => new(pointer ?? nint.Zero); - - public static implicit operator Model(Object* pointer) - => new((nint)pointer); - - public static implicit operator Model(DrawObject* pointer) - => new((nint)pointer); - - public static implicit operator Model(Human* pointer) - => new((nint)pointer); - - public static implicit operator Model(CharacterBase* pointer) - => new((nint)pointer); - - public static implicit operator nint(Model model) - => model.Address; - - public bool Valid - => Address != nint.Zero; - - public bool IsCharacterBase - => Valid && AsDrawObject->Object.GetObjectType() == ObjectType.CharacterBase; - - public bool IsHuman - => IsCharacterBase && AsCharacterBase->GetModelType() == CharacterBase.ModelType.Human; - - public bool IsWeapon - => IsCharacterBase && AsCharacterBase->GetModelType() == CharacterBase.ModelType.Weapon; - - public static implicit operator bool(Model actor) - => actor.Address != nint.Zero; - - public static bool operator true(Model actor) - => actor.Address != nint.Zero; - - public static bool operator false(Model actor) - => actor.Address == nint.Zero; - - public static bool operator !(Model actor) - => actor.Address == nint.Zero; - - public bool Equals(Model other) - => Address == other.Address; - - public override bool Equals(object? obj) - => obj is Model other && Equals(other); - - public override int GetHashCode() - => Address.GetHashCode(); - - public static bool operator ==(Model lhs, Model rhs) - => lhs.Address == rhs.Address; - - public static bool operator !=(Model lhs, Model rhs) - => lhs.Address != rhs.Address; - /* - /// Only valid for humans. - public CharacterArmor GetArmor(EquipSlot slot) - => ((CharacterArmor*)&AsHuman->Head)[slot.ToIndex()]; - - public Customize GetCustomize() - => *(Customize*)&AsHuman->Customize; - - public (Model Address, CharacterWeapon Data) GetMainhand() - { - Model weapon = AsDrawObject->Object.ChildObject; - return !weapon.IsWeapon - ? (Null, CharacterWeapon.Empty) - : (weapon, new CharacterWeapon(weapon.AsWeapon->ModelSetId, weapon.AsWeapon->SecondaryId, (Variant)weapon.AsWeapon->Variant, - (StainId)weapon.AsWeapon->ModelUnknown)); - } - - public (Model Address, CharacterWeapon Data) GetOffhand() - { - var mainhand = AsDrawObject->Object.ChildObject; - if (mainhand == null) - return (Null, CharacterWeapon.Empty); - - Model offhand = mainhand->NextSiblingObject; - if (offhand == mainhand || !offhand.IsWeapon) - return (Null, CharacterWeapon.Empty); - - return (offhand, new CharacterWeapon(offhand.AsWeapon->ModelSetId, offhand.AsWeapon->SecondaryId, (Variant)offhand.AsWeapon->Variant, - (StainId)offhand.AsWeapon->ModelUnknown)); - } - - /// Obtain the mainhand and offhand and their data by guesstimating which child object is which. - public (Model Mainhand, Model Offhand, CharacterWeapon MainData, CharacterWeapon OffData) GetWeapons() - { - var (first, second, count) = GetChildrenWeapons(); - switch (count) - { - case 0: return (Null, Null, CharacterWeapon.Empty, CharacterWeapon.Empty); - case 1: - return (first, Null, new CharacterWeapon(first.AsWeapon->ModelSetId, first.AsWeapon->SecondaryId, - (Variant)first.AsWeapon->Variant, - (StainId)first.AsWeapon->ModelUnknown), CharacterWeapon.Empty); - default: - var (main, off) = DetermineMainhand(first, second); - var mainData = new CharacterWeapon(main.AsWeapon->ModelSetId, main.AsWeapon->SecondaryId, (Variant)main.AsWeapon->Variant, - (StainId)main.AsWeapon->ModelUnknown); - var offData = new CharacterWeapon(off.AsWeapon->ModelSetId, off.AsWeapon->SecondaryId, (Variant)off.AsWeapon->Variant, - (StainId)off.AsWeapon->ModelUnknown); - return (main, off, mainData, offData); - } - } - - /// Obtain the mainhand and offhand and their data by using the drawdata container from the corresponding actor. - public (Model Mainhand, Model Offhand, CharacterWeapon MainData, CharacterWeapon OffData) GetWeapons(Actor actor) - { - if (!Valid || !actor.IsCharacter || actor.Model.Address != Address) - return (Null, Null, CharacterWeapon.Empty, CharacterWeapon.Empty); - - Model main = actor.AsCharacter->DrawData.Weapon(DrawDataContainer.WeaponSlot.MainHand).DrawObject; - var mainData = CharacterWeapon.Empty; - if (main.IsWeapon) - mainData = new CharacterWeapon(main.AsWeapon->ModelSetId, main.AsWeapon->SecondaryId, (Variant)main.AsWeapon->Variant, - (StainId)main.AsWeapon->ModelUnknown); - else - main = Null; - Model off = actor.AsCharacter->DrawData.Weapon(DrawDataContainer.WeaponSlot.OffHand).DrawObject; - var offData = CharacterWeapon.Empty; - if (off.IsWeapon) - offData = new CharacterWeapon(off.AsWeapon->ModelSetId, off.AsWeapon->SecondaryId, (Variant)off.AsWeapon->Variant, - (StainId)off.AsWeapon->ModelUnknown); - else - off = Null; - return (main, off, mainData, offData); - } - - private (Model, Model, int) GetChildrenWeapons() - { - Span weapons = stackalloc Model[2]; - weapons[0] = Null; - weapons[1] = Null; - var count = 0; - - if (!Valid || AsDrawObject->Object.ChildObject == null) - return (weapons[0], weapons[1], count); - - Model starter = AsDrawObject->Object.ChildObject; - var iterator = starter; - do - { - if (iterator.IsWeapon) - weapons[count++] = iterator; - if (count == 2) - return (weapons[0], weapons[1], count); - - iterator = iterator.AsDrawObject->Object.NextSiblingObject; - } while (iterator.Address != starter.Address); - - return (weapons[0], weapons[1], count); - } - - /// I don't know a safe way to do this but in experiments this worked. - /// The first uint at +0x8 was set to non-zero for the mainhand and zero for the offhand. - private static (Model Mainhand, Model Offhand) DetermineMainhand(Model first, Model second) - { - var discriminator1 = *(ulong*)(first.Address + 0x10); - var discriminator2 = *(ulong*)(second.Address + 0x10); - return discriminator1 == 0 && discriminator2 != 0 ? (second, first) : (first, second); - } - */ - public override string ToString() - => $"0x{Address:X}"; -} diff --git a/CustomizePlus.GameData/Services/ObjectManager.cs b/CustomizePlus.GameData/Services/ObjectManager.cs index cf847c6..1de4eb9 100644 --- a/CustomizePlus.GameData/Services/ObjectManager.cs +++ b/CustomizePlus.GameData/Services/ObjectManager.cs @@ -5,6 +5,7 @@ using FFXIVClientStructs.FFXIV.Client.UI.Agent; using Penumbra.GameData.Actors; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; using System; using System.Collections; using System.Collections.Generic; @@ -14,25 +15,11 @@ namespace CustomizePlus.GameData.Services; -public class ObjectManager : IReadOnlyDictionary +public class ObjectManager(IFramework framework, IClientState clientState, global::Penumbra.GameData.Interop.ObjectManager objects, ActorManager actorManager, ITargetManager targetManager) + : IReadOnlyDictionary { - private readonly IFramework _framework; - private readonly IClientState _clientState; - private readonly IObjectTable _objects; - private readonly ActorManager _actorManager; - private readonly ITargetManager _targets; - - public IObjectTable Objects - => _objects; - - public ObjectManager(IFramework framework, IClientState clientState, IObjectTable objects, ActorManager actorManager, ITargetManager targets) - { - _framework = framework; - _clientState = clientState; - _objects = objects; - _actorManager = actorManager; - _targets = targets; - } + public global::Penumbra.GameData.Interop.ObjectManager Objects + => objects; public DateTime LastUpdate { get; private set; } @@ -48,39 +35,39 @@ public IReadOnlyDictionary Identifiers public void Update() { - var lastUpdate = _framework.LastUpdate; + var lastUpdate = framework.LastUpdate; if (lastUpdate <= LastUpdate) return; LastUpdate = lastUpdate; - World = (ushort)(_clientState.LocalPlayer?.CurrentWorld.Id ?? 0u); + World = (ushort)(clientState.LocalPlayer?.CurrentWorld.Id ?? 0u); _identifiers.Clear(); _allWorldIdentifiers.Clear(); _nonOwnedIdentifiers.Clear(); for (var i = 0; i < (int)ScreenActor.CutsceneStart; ++i) { - Actor character = _objects.GetObjectAddress(i); - if (character.Identifier(_actorManager, out var identifier)) + Actor character = objects[i]; + if (character.Identifier(actorManager, out var identifier)) HandleIdentifier(identifier, character); } for (var i = (int)ScreenActor.CutsceneStart; i < (int)ScreenActor.CutsceneEnd; ++i) { - Actor character = _objects.GetObjectAddress(i); + Actor character = objects[i]; // Technically the game does not create holes in cutscenes or GPose. // But for Brio compatibility, we allow holes in GPose. // Since GPose always has the event actor in the first cutscene slot, we can still optimize in this case. if (!character.Valid && i == (int)ScreenActor.CutsceneStart) break; - HandleIdentifier(character.GetIdentifier(_actorManager), character); + HandleIdentifier(character.GetIdentifier(actorManager), character); } void AddSpecial(ScreenActor idx, string label) { - Actor actor = _objects.GetObjectAddress((int)idx); - if (actor.Identifier(_actorManager, out var ident)) + Actor actor = objects[(int)idx]; + if (actor.Identifier(actorManager, out var ident)) { var data = new ActorData(actor, label); _identifiers.Add(ident, data); @@ -96,10 +83,10 @@ void AddSpecial(ScreenActor idx, string label) AddSpecial(ScreenActor.Card7, "Card Actor 7"); AddSpecial(ScreenActor.Card8, "Card Actor 8"); - for (var i = (int)ScreenActor.ScreenEnd; i < _objects.Length; ++i) + for (var i = (int)ScreenActor.ScreenEnd; i < objects.Count; ++i) { - Actor character = _objects.GetObjectAddress(i); - if (character.Identifier(_actorManager, out var identifier)) + Actor character = objects[i]; + if (character.Identifier(actorManager, out var identifier)) HandleIdentifier(identifier, character); } @@ -124,7 +111,7 @@ private void HandleIdentifier(ActorIdentifier identifier, Actor character) if (identifier.Type is IdentifierType.Player or IdentifierType.Owned) { - var allWorld = _actorManager.CreateIndividualUnchecked(identifier.Type, identifier.PlayerName, ushort.MaxValue, + var allWorld = actorManager.CreateIndividualUnchecked(identifier.Type, identifier.PlayerName, ushort.MaxValue, identifier.Kind, identifier.DataId); @@ -141,7 +128,7 @@ private void HandleIdentifier(ActorIdentifier identifier, Actor character) if (identifier.Type is IdentifierType.Owned) { - var nonOwned = _actorManager.CreateNpc(identifier.Kind, identifier.DataId); + var nonOwned = actorManager.CreateNpc(identifier.Kind, identifier.DataId); if (!_nonOwnedIdentifiers.TryGetValue(nonOwned, out var nonOwnedData)) { nonOwnedData = new ActorData(character, nonOwned.ToString()); @@ -155,26 +142,26 @@ private void HandleIdentifier(ActorIdentifier identifier, Actor character) } public Actor GPosePlayer - => _objects.GetObjectAddress((int)ScreenActor.GPosePlayer); + => objects[(int)ScreenActor.GPosePlayer]; public Actor Player - => _objects.GetObjectAddress(0); + => objects[0]; public unsafe Actor Target - => _clientState.IsGPosing ? TargetSystem.Instance()->GPoseTarget : TargetSystem.Instance()->Target; + => clientState.IsGPosing ? TargetSystem.Instance()->GPoseTarget : TargetSystem.Instance()->Target; public Actor Focus - => _targets.FocusTarget?.Address ?? nint.Zero; + => targetManager.FocusTarget?.Address ?? nint.Zero; public Actor MouseOver - => _targets.MouseOverTarget?.Address ?? nint.Zero; + => targetManager.MouseOverTarget?.Address ?? nint.Zero; public (ActorIdentifier Identifier, ActorData Data) PlayerData { get { Update(); - return Player.Identifier(_actorManager, out var ident) && _identifiers.TryGetValue(ident, out var data) + return Player.Identifier(actorManager, out var ident) && _identifiers.TryGetValue(ident, out var data) ? (ident, data) : (ident, ActorData.Invalid); } @@ -185,7 +172,7 @@ public Actor MouseOver get { Update(); - return Target.Identifier(_actorManager, out var ident) && _identifiers.TryGetValue(ident, out var data) + return Target.Identifier(actorManager, out var ident) && _identifiers.TryGetValue(ident, out var data) ? (ident, data) : (ident, ActorData.Invalid); } diff --git a/CustomizePlus/Api/Compatibility/CustomizePlusIpc.cs b/CustomizePlus/Api/Compatibility/CustomizePlusIpc.cs index eef02f9..7d800c5 100644 --- a/CustomizePlus/Api/Compatibility/CustomizePlusIpc.cs +++ b/CustomizePlus/Api/Compatibility/CustomizePlusIpc.cs @@ -21,6 +21,7 @@ using CustomizePlus.Armatures.Events; using CustomizePlus.Armatures.Data; using CustomizePlus.GameData.Extensions; +using Penumbra.GameData.Interop; namespace CustomizePlus.Api.Compatibility; diff --git a/CustomizePlus/Armatures/Services/ArmatureManager.cs b/CustomizePlus/Armatures/Services/ArmatureManager.cs index e0fec96..443cdec 100644 --- a/CustomizePlus/Armatures/Services/ArmatureManager.cs +++ b/CustomizePlus/Armatures/Services/ArmatureManager.cs @@ -1,26 +1,25 @@ using System; using System.Collections.Generic; using System.Linq; -using Dalamud.Plugin.Services; -using OtterGui.Log; -using OtterGui.Classes; -using Penumbra.GameData.Actors; using System.Numerics; -using CustomizePlus.Core.Data; -using CustomizePlus.Armatures.Events; using CustomizePlus.Armatures.Data; +using CustomizePlus.Armatures.Events; +using CustomizePlus.Core.Data; +using CustomizePlus.Core.Extensions; +using CustomizePlus.Game.Services; +using CustomizePlus.GameData.Extensions; +using CustomizePlus.GameData.Services; using CustomizePlus.Profiles; using CustomizePlus.Profiles.Data; -using CustomizePlus.Game.Services; -using CustomizePlus.Templates.Events; using CustomizePlus.Profiles.Events; -using CustomizePlus.Core.Extensions; -using CustomizePlus.GameData.Data; -using CustomizePlus.GameData.Services; -using CustomizePlus.GameData.Extensions; -using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; -using System.Drawing; +using CustomizePlus.Templates.Events; +using Dalamud.Plugin.Services; +using OtterGui.Classes; +using OtterGui.Log; +using Penumbra.GameData.Actors; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; +using ObjectManager = CustomizePlus.GameData.Services.ObjectManager; namespace CustomizePlus.Armatures.Services; diff --git a/CustomizePlus/Core/ServiceManagerBuilder.cs b/CustomizePlus/Core/ServiceManagerBuilder.cs index ae8ee9b..fca385e 100644 --- a/CustomizePlus/Core/ServiceManagerBuilder.cs +++ b/CustomizePlus/Core/ServiceManagerBuilder.cs @@ -33,6 +33,7 @@ using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; using OtterGui; +using OtterGui.Raii; namespace CustomizePlus.Core; @@ -61,7 +62,7 @@ public static ServiceManager CreateProvider(DalamudPluginInterface pi, Logger lo services.AddIServices(typeof(EquipItem).Assembly); services.AddIServices(typeof(Plugin).Assembly); services.AddIServices(typeof(ObjectManager).Assembly); - services.AddIServices(typeof(ImGuiUtil).Assembly); + services.AddIServices(typeof(ImRaii).Assembly); services.CreateProvider(); diff --git a/CustomizePlus/Core/Services/DalamudServices.cs b/CustomizePlus/Core/Services/DalamudServices.cs index 2eb2c18..ba97e6f 100644 --- a/CustomizePlus/Core/Services/DalamudServices.cs +++ b/CustomizePlus/Core/Services/DalamudServices.cs @@ -25,6 +25,8 @@ public static void AddServices(ServiceManager services, DalamudPluginInterface p .AddDalamudService(pi) .AddDalamudService(pi) .AddDalamudService(pi) - .AddDalamudService(pi); + .AddDalamudService(pi) + .AddDalamudService(pi) + .AddDalamudService(pi); } } \ No newline at end of file diff --git a/CustomizePlus/Core/Services/HookingService.cs b/CustomizePlus/Core/Services/HookingService.cs index cca048f..2246890 100644 --- a/CustomizePlus/Core/Services/HookingService.cs +++ b/CustomizePlus/Core/Services/HookingService.cs @@ -10,6 +10,7 @@ using CustomizePlus.Profiles; using CustomizePlus.Armatures.Services; using CustomizePlus.GameData.Data; +using Penumbra.GameData.Interop; namespace CustomizePlus.Core.Services; diff --git a/CustomizePlus/CustomizePlus.csproj b/CustomizePlus/CustomizePlus.csproj index ece3318..c28fabf 100644 --- a/CustomizePlus/CustomizePlus.csproj +++ b/CustomizePlus/CustomizePlus.csproj @@ -13,7 +13,7 @@ - net7.0-windows + net8.0-windows x64 enable preview @@ -24,12 +24,6 @@ bin\$(Configuration)\ - - - - - - PreserveNewest @@ -44,7 +38,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CustomizePlus/Game/Services/GameObjectService.cs b/CustomizePlus/Game/Services/GameObjectService.cs index efa1f81..4a5b7fa 100644 --- a/CustomizePlus/Game/Services/GameObjectService.cs +++ b/CustomizePlus/Game/Services/GameObjectService.cs @@ -1,11 +1,11 @@ -using Dalamud.Plugin.Services; -using Penumbra.GameData.Actors; -using System.Collections.Generic; +using System.Collections.Generic; using CustomizePlus.Core.Data; -using CustomizePlus.GameData.Data; -using CustomizePlus.GameData.Services; using CustomizePlus.GameData.Extensions; +using Dalamud.Plugin.Services; +using Penumbra.GameData.Actors; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; +using ObjectManager = CustomizePlus.GameData.Services.ObjectManager; namespace CustomizePlus.Game.Services; diff --git a/CustomizePlus/Profiles/ProfileManager.cs b/CustomizePlus/Profiles/ProfileManager.cs index 0e467ea..0494273 100644 --- a/CustomizePlus/Profiles/ProfileManager.cs +++ b/CustomizePlus/Profiles/ProfileManager.cs @@ -23,6 +23,7 @@ using CustomizePlus.GameData.Extensions; using CustomizePlus.Profiles.Enums; using Penumbra.GameData.Enums; +using Penumbra.GameData.Interop; namespace CustomizePlus.Profiles; diff --git a/CustomizePlus/UI/Windows/Controls/TemplateCombo.cs b/CustomizePlus/UI/Windows/Controls/TemplateCombo.cs index f2bfe43..fd9c595 100644 --- a/CustomizePlus/UI/Windows/Controls/TemplateCombo.cs +++ b/CustomizePlus/UI/Windows/Controls/TemplateCombo.cs @@ -30,7 +30,7 @@ protected TemplateComboBase( TemplateChanged templateChanged, //TabSelected tabSelected, PluginConfiguration configuration) - : base(generator, logger) + : base(generator, MouseWheelType.Control, logger) { _templateChanged = templateChanged; //TabSelected = tabSelected; diff --git a/submodules/OtterGui b/submodules/OtterGui index f8f3e0b..2bbb9b2 160000 --- a/submodules/OtterGui +++ b/submodules/OtterGui @@ -1 +1 @@ -Subproject commit f8f3e0b9bd39ed58f1233affc40df187b0c2b70e +Subproject commit 2bbb9b2a8a4479461b252594b9d1b788b551c13c diff --git a/submodules/Penumbra.Api b/submodules/Penumbra.Api index cfc5171..d2a1406 160000 --- a/submodules/Penumbra.Api +++ b/submodules/Penumbra.Api @@ -1 +1 @@ -Subproject commit cfc51714f74cae93608bc507775a9580cd1801de +Subproject commit d2a1406bc32f715c0687613f02e3f74caf7ceea9 diff --git a/submodules/Penumbra.GameData b/submodules/Penumbra.GameData index 260ac69..529e181 160000 --- a/submodules/Penumbra.GameData +++ b/submodules/Penumbra.GameData @@ -1 +1 @@ -Subproject commit 260ac69cd6f17050eaf9b7e0b5ce9a8843edfee4 +Subproject commit 529e18115023732794994bfb8df4818b68951ea4 diff --git a/submodules/Penumbra.String b/submodules/Penumbra.String index 620a7ed..14e00f7 160000 --- a/submodules/Penumbra.String +++ b/submodules/Penumbra.String @@ -1 +1 @@ -Subproject commit 620a7edf009b92288257ce7d64fffb8fba44d8b5 +Subproject commit 14e00f77d42bc677e02325660db765ef11932560