mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2026-02-19 05:57:42 +01:00
.
This commit is contained in:
parent
803fd1b247
commit
1aba34f34a
11 changed files with 631 additions and 32 deletions
72
Glamourer/Interop/MetaService.cs
Normal file
72
Glamourer/Interop/MetaService.cs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
using System;
|
||||
using Dalamud.Hooking;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using Glamourer.Events;
|
||||
using Glamourer.Interop.Structs;
|
||||
using static OtterGui.Raii.ImRaii;
|
||||
|
||||
namespace Glamourer.Interop;
|
||||
|
||||
public unsafe class MetaService : IDisposable
|
||||
{
|
||||
private readonly HeadGearVisibilityChanged _headGearEvent;
|
||||
private readonly WeaponVisibilityChanged _weaponEvent;
|
||||
|
||||
private delegate void HideHatGearDelegate(DrawDataContainer* drawData, uint id, byte value);
|
||||
private delegate void HideWeaponsDelegate(DrawDataContainer* drawData, bool value);
|
||||
|
||||
private readonly Hook<HideHatGearDelegate> _hideHatGearHook;
|
||||
private readonly Hook<HideWeaponsDelegate> _hideWeaponsHook;
|
||||
|
||||
public MetaService(WeaponVisibilityChanged weaponEvent, HeadGearVisibilityChanged headGearEvent)
|
||||
{
|
||||
_weaponEvent = weaponEvent;
|
||||
_headGearEvent = headGearEvent;
|
||||
_hideHatGearHook = Hook<HideHatGearDelegate>.FromAddress((nint)DrawDataContainer.MemberFunctionPointers.HideHeadgear, HideHatDetour);
|
||||
_hideWeaponsHook = Hook<HideWeaponsDelegate>.FromAddress((nint)DrawDataContainer.MemberFunctionPointers.HideWeapons, HideWeaponsDetour);
|
||||
_hideHatGearHook.Enable();
|
||||
_hideWeaponsHook.Enable();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_hideHatGearHook.Dispose();
|
||||
_hideWeaponsHook.Dispose();
|
||||
}
|
||||
|
||||
public void SetHatState(Actor actor, bool value)
|
||||
{
|
||||
if (!actor.IsCharacter)
|
||||
return;
|
||||
|
||||
_hideHatGearHook.Original(&actor.AsCharacter->DrawData, 0, (byte) (value ? 1 : 0));
|
||||
}
|
||||
|
||||
public void SetWeaponState(Actor actor, bool value)
|
||||
{
|
||||
if (!actor.IsCharacter)
|
||||
return;
|
||||
|
||||
_hideWeaponsHook.Original(&actor.AsCharacter->DrawData, value);
|
||||
}
|
||||
|
||||
private void HideHatDetour(DrawDataContainer* drawData, uint id, byte value)
|
||||
{
|
||||
Actor actor = drawData->Parent;
|
||||
var v = value == 0;
|
||||
_headGearEvent.Invoke(actor, ref v);
|
||||
value = (byte) (v ? 0 : 1);
|
||||
Glamourer.Log.Information($"[MetaService] Hide Hat triggered with 0x{(nint)drawData:X} {id} {value} for {actor.Utf8Name}.");
|
||||
_hideHatGearHook.Original(drawData, id, value);
|
||||
}
|
||||
|
||||
private void HideWeaponsDetour(DrawDataContainer* drawData, bool value)
|
||||
{
|
||||
Actor actor = drawData->Parent;
|
||||
value = !value;
|
||||
_weaponEvent.Invoke(actor, ref value);
|
||||
value = !value;
|
||||
Glamourer.Log.Information($"[MetaService] Hide Weapon triggered with 0x{(nint)drawData:X} {value} for {actor.Utf8Name}.");
|
||||
_hideWeaponsHook.Original(drawData, value);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ using Dalamud.Hooking;
|
|||
using Dalamud.Utility.Signatures;
|
||||
using Glamourer.Events;
|
||||
using Glamourer.Interop.Structs;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
||||
namespace Glamourer.Interop;
|
||||
|
||||
|
|
@ -39,7 +40,7 @@ public class VisorService : IDisposable
|
|||
if (oldState == on)
|
||||
return false;
|
||||
|
||||
SetupVisorHook(human, (ushort)human.AsHuman->HeadSetID, on);
|
||||
SetupVisorHook(human, human.GetArmor(EquipSlot.Head).Set.Value, on);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -50,17 +51,15 @@ public class VisorService : IDisposable
|
|||
|
||||
private void SetupVisorDetour(nint human, ushort modelId, bool on)
|
||||
{
|
||||
var callOriginal = true;
|
||||
var originalOn = on;
|
||||
// Invoke an event that can change the requested value
|
||||
// and also control whether the function should be called at all.
|
||||
Event.Invoke(human, ref on, ref callOriginal);
|
||||
Event.Invoke(human, ref on);
|
||||
|
||||
Glamourer.Log.Excessive(
|
||||
$"[SetVisorState] Invoked from game on 0x{human:X} switching to {on} (original {originalOn}, call original {callOriginal}).");
|
||||
$"[SetVisorState] Invoked from game on 0x{human:X} switching to {on} (original {originalOn}).");
|
||||
|
||||
if (callOriginal)
|
||||
SetupVisorHook(human, modelId, on);
|
||||
SetupVisorHook(human, modelId, on);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -92,4 +92,4 @@ public unsafe class WeaponService : IDisposable
|
|||
var weapon = new CharacterWeapon(value.Value) { Stain = stain.Value };
|
||||
LoadWeapon(character, slot, weapon);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue