mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-31 21:03:48 +01:00
More state-keeping for when the game object changes an item but with identical model information...
This commit is contained in:
parent
9c42872456
commit
c6d24d83da
4 changed files with 111 additions and 36 deletions
|
|
@ -1,32 +1,33 @@
|
|||
using System;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Utility.Signatures;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using Glamourer.Events;
|
||||
using Glamourer.Interop.Structs;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace Glamourer.Interop;
|
||||
|
||||
public unsafe class UpdateSlotService : IDisposable
|
||||
{
|
||||
public readonly SlotUpdating Event;
|
||||
public readonly SlotUpdating SlotUpdatingEvent;
|
||||
public readonly EquipmentLoading EquipmentLoadingEvent;
|
||||
|
||||
public UpdateSlotService(SlotUpdating slotUpdating)
|
||||
public UpdateSlotService(SlotUpdating slotUpdating, EquipmentLoading equipmentLoadingEvent)
|
||||
{
|
||||
Event = slotUpdating;
|
||||
SlotUpdatingEvent = slotUpdating;
|
||||
EquipmentLoadingEvent = equipmentLoadingEvent;
|
||||
SignatureHelper.Initialise(this);
|
||||
_flagSlotForUpdateHook.Enable();
|
||||
_loadEquipmentHook.Enable();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
=> _flagSlotForUpdateHook.Dispose();
|
||||
|
||||
private delegate ulong FlagSlotForUpdateDelegateIntern(nint drawObject, uint slot, CharacterArmor* data);
|
||||
|
||||
[Signature(Sigs.FlagSlotForUpdate, DetourName = nameof(FlagSlotForUpdateDetour))]
|
||||
private readonly Hook<FlagSlotForUpdateDelegateIntern> _flagSlotForUpdateHook = null!;
|
||||
{
|
||||
_flagSlotForUpdateHook.Dispose();
|
||||
_loadEquipmentHook.Dispose();
|
||||
}
|
||||
|
||||
public void UpdateSlot(Model drawObject, EquipSlot slot, CharacterArmor data)
|
||||
{
|
||||
|
|
@ -45,14 +46,34 @@ public unsafe class UpdateSlotService : IDisposable
|
|||
public void UpdateStain(Model drawObject, EquipSlot slot, StainId stain)
|
||||
=> UpdateArmor(drawObject, slot, drawObject.GetArmor(slot), stain);
|
||||
|
||||
private delegate ulong FlagSlotForUpdateDelegateIntern(nint drawObject, uint slot, CharacterArmor* data);
|
||||
|
||||
[Signature(Sigs.FlagSlotForUpdate, DetourName = nameof(FlagSlotForUpdateDetour))]
|
||||
private readonly Hook<FlagSlotForUpdateDelegateIntern> _flagSlotForUpdateHook = null!;
|
||||
|
||||
private delegate void LoadEquipmentDelegateIntern(DrawDataContainer* drawDataContainer, uint slotIdx, CharacterArmor data, bool force);
|
||||
|
||||
// TODO: use client structs.
|
||||
[Signature("E8 ?? ?? ?? ?? 41 B5 ?? FF C6", DetourName = nameof(LoadEquipmentDetour))]
|
||||
private readonly Hook<LoadEquipmentDelegateIntern> _loadEquipmentHook = null!;
|
||||
|
||||
private ulong FlagSlotForUpdateDetour(nint drawObject, uint slotIdx, CharacterArmor* data)
|
||||
{
|
||||
var slot = slotIdx.ToEquipSlot();
|
||||
var returnValue = ulong.MaxValue;
|
||||
Event.Invoke(drawObject, slot, ref *data, ref returnValue);
|
||||
SlotUpdatingEvent.Invoke(drawObject, slot, ref *data, ref returnValue);
|
||||
Glamourer.Log.Information($"[FlagSlotForUpdate] Called with 0x{drawObject:X} for slot {slot} with {*data} ({returnValue}).");
|
||||
return returnValue == ulong.MaxValue ? _flagSlotForUpdateHook.Original(drawObject, slotIdx, data) : returnValue;
|
||||
}
|
||||
|
||||
private void LoadEquipmentDetour(DrawDataContainer* drawDataContainer, uint slotIdx, CharacterArmor data, bool force)
|
||||
{
|
||||
var slot = slotIdx.ToEquipSlot();
|
||||
EquipmentLoadingEvent.Invoke(drawDataContainer->Parent, slot, data);
|
||||
Glamourer.Log.Information($"[LoadEquipment] Called with 0x{(ulong)drawDataContainer:X} for slot {slot} with {data} ({force}).");
|
||||
_loadEquipmentHook.Original(drawDataContainer, slotIdx, data, force);
|
||||
}
|
||||
|
||||
private ulong FlagSlotForUpdateInterop(Model drawObject, EquipSlot slot, CharacterArmor armor)
|
||||
=> _flagSlotForUpdateHook.Original(drawObject.Address, slot.ToIndex(), &armor);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue