diff --git a/Penumbra.GameData b/Penumbra.GameData index 61e06785..2f6acca6 160000 --- a/Penumbra.GameData +++ b/Penumbra.GameData @@ -1 +1 @@ -Subproject commit 61e067857c2cf62bf8426ff6b305e37990f7767a +Subproject commit 2f6acca678b71203763ac4404c3f054747c14f75 diff --git a/Penumbra/Interop/Hooks/Resources/ResolvePathHooksBase.cs b/Penumbra/Interop/Hooks/Resources/ResolvePathHooksBase.cs index a31dee4c..d55caf34 100644 --- a/Penumbra/Interop/Hooks/Resources/ResolvePathHooksBase.cs +++ b/Penumbra/Interop/Hooks/Resources/ResolvePathHooksBase.cs @@ -6,6 +6,7 @@ using Penumbra.Collections; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; using Penumbra.Interop.PathResolving; +using static FFXIVClientStructs.FFXIV.Client.Game.Character.ActionEffectHandler; namespace Penumbra.Interop.Hooks.Resources; @@ -223,6 +224,12 @@ public sealed unsafe class ResolvePathHooksBase : IDisposable [FieldOffset(2)] public Variant Variant; + [FieldOffset(8)] + public PrimaryId BonusModel; + + [FieldOffset(10)] + public Variant BonusVariant; + [FieldOffset(20)] public ushort VfxId; @@ -232,26 +239,50 @@ public sealed unsafe class ResolvePathHooksBase : IDisposable private nint ResolveVfxHuman(nint drawObject, nint pathBuffer, nint pathBufferSize, uint slotIndex, nint unkOutParam) { - if (slotIndex is <= 4 or >= 10) - return ResolveVfx(drawObject, pathBuffer, pathBufferSize, slotIndex, unkOutParam); + switch (slotIndex) + { + case <= 4: return ResolveVfx(drawObject, pathBuffer, pathBufferSize, slotIndex, unkOutParam); + case <= 10: + { + // Enable vfxs for accessories + var changedEquipData = (ChangedEquipData*)((Human*)drawObject)->ChangedEquipData; + if (changedEquipData == null) + return ResolveVfx(drawObject, pathBuffer, pathBufferSize, slotIndex, unkOutParam); - var changedEquipData = (ChangedEquipData*)((Human*)drawObject)->ChangedEquipData; - // Enable vfxs for accessories - if (changedEquipData == null) - return ResolveVfx(drawObject, pathBuffer, pathBufferSize, slotIndex, unkOutParam); + ref var slot = ref changedEquipData[slotIndex]; - ref var slot = ref changedEquipData[slotIndex]; + if (slot.Model == 0 || slot.Variant == 0 || slot.VfxId == 0) + return ResolveVfx(drawObject, pathBuffer, pathBufferSize, slotIndex, unkOutParam); - if (slot.Model == 0 || slot.Variant == 0 || slot.VfxId == 0) - return ResolveVfx(drawObject, pathBuffer, pathBufferSize, slotIndex, unkOutParam); + if (!Utf8.TryWrite(new Span((void*)pathBuffer, (int)pathBufferSize), + $"chara/accessory/a{slot.Model.Id:D4}/vfx/eff/va{slot.VfxId:D4}.avfx\0", + out _)) + return ResolveVfx(drawObject, pathBuffer, pathBufferSize, slotIndex, unkOutParam); - if (!Utf8.TryWrite(new Span((void*)pathBuffer, (int)pathBufferSize), - $"chara/accessory/a{slot.Model.Id:D4}/vfx/eff/va{slot.VfxId:D4}.avfx\0", - out _)) - return ResolveVfx(drawObject, pathBuffer, pathBufferSize, slotIndex, unkOutParam); + *(ulong*)unkOutParam = 4; + return ResolvePath(drawObject, pathBuffer); + } + case 16: + { + // Enable vfxs for glasses + var changedEquipData = (ChangedEquipData*)((Human*)drawObject)->ChangedEquipData; + if (changedEquipData == null) + return ResolveVfx(drawObject, pathBuffer, pathBufferSize, slotIndex, unkOutParam); - *(ulong*)unkOutParam = 4; - return ResolvePath(drawObject, pathBuffer); + ref var slot = ref changedEquipData[slotIndex - 6]; + + if (slot.BonusModel == 0 || slot.BonusVariant == 0 || slot.VfxId == 0) + return ResolveVfx(drawObject, pathBuffer, pathBufferSize, slotIndex, unkOutParam); + if (!Utf8.TryWrite(new Span((void*)pathBuffer, (int)pathBufferSize), + $"chara/equipment/e{slot.BonusModel.Id:D4}/vfx/eff/ve{slot.VfxId:D4}.avfx\0", + out _)) + return ResolveVfx(drawObject, pathBuffer, pathBufferSize, slotIndex, unkOutParam); + + *(ulong*)unkOutParam = 4; + return ResolvePath(drawObject, pathBuffer); + } + default: return ResolveVfx(drawObject, pathBuffer, pathBufferSize, slotIndex, unkOutParam); + } } private nint VFunc81(nint drawObject, int estType, nint unk)