mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 10:17:23 +01:00
Add new parameter to LoadWeapon hook.
This commit is contained in:
parent
65f789880d
commit
c9b291c2f3
1 changed files with 13 additions and 12 deletions
|
|
@ -13,7 +13,7 @@ public unsafe class WeaponService : IDisposable
|
||||||
private readonly WeaponLoading _event;
|
private readonly WeaponLoading _event;
|
||||||
private readonly ThreadLocal<bool> _inUpdate = new(() => false);
|
private readonly ThreadLocal<bool> _inUpdate = new(() => false);
|
||||||
|
|
||||||
private readonly delegate* unmanaged[Stdcall]<DrawDataContainer*, uint, ulong, byte, byte, byte, byte, void>
|
private readonly delegate* unmanaged[Stdcall]<DrawDataContainer*, uint, ulong, byte, byte, byte, byte, int, void>
|
||||||
_original;
|
_original;
|
||||||
|
|
||||||
public WeaponService(WeaponLoading @event, IGameInteropProvider interop)
|
public WeaponService(WeaponLoading @event, IGameInteropProvider interop)
|
||||||
|
|
@ -22,7 +22,7 @@ public unsafe class WeaponService : IDisposable
|
||||||
_loadWeaponHook =
|
_loadWeaponHook =
|
||||||
interop.HookFromAddress<LoadWeaponDelegate>((nint)DrawDataContainer.MemberFunctionPointers.LoadWeapon, LoadWeaponDetour);
|
interop.HookFromAddress<LoadWeaponDelegate>((nint)DrawDataContainer.MemberFunctionPointers.LoadWeapon, LoadWeaponDetour);
|
||||||
_original =
|
_original =
|
||||||
(delegate* unmanaged[Stdcall] < DrawDataContainer*, uint, ulong, byte, byte, byte, byte, void >)
|
(delegate* unmanaged[Stdcall] < DrawDataContainer*, uint, ulong, byte, byte, byte, byte, int, void >)
|
||||||
DrawDataContainer.MemberFunctionPointers.LoadWeapon;
|
DrawDataContainer.MemberFunctionPointers.LoadWeapon;
|
||||||
_loadWeaponHook.Enable();
|
_loadWeaponHook.Enable();
|
||||||
}
|
}
|
||||||
|
|
@ -36,13 +36,14 @@ public unsafe class WeaponService : IDisposable
|
||||||
// redrawOnEquality controls whether the game does anything if the new weapon is identical to the old one.
|
// redrawOnEquality controls whether the game does anything if the new weapon is identical to the old one.
|
||||||
// skipGameObject seems to control whether the new weapons are written to the game object or just influence the draw object. (1 = skip, 0 = change)
|
// skipGameObject seems to control whether the new weapons are written to the game object or just influence the draw object. (1 = skip, 0 = change)
|
||||||
// unk4 seemed to be the same as unk1.
|
// unk4 seemed to be the same as unk1.
|
||||||
|
// unk5 is new in 7.30 and is checked at the beginning of the function to call some timeline related function.
|
||||||
private delegate void LoadWeaponDelegate(DrawDataContainer* drawData, uint slot, ulong weapon, byte redrawOnEquality, byte unk2,
|
private delegate void LoadWeaponDelegate(DrawDataContainer* drawData, uint slot, ulong weapon, byte redrawOnEquality, byte unk2,
|
||||||
byte skipGameObject, byte unk4);
|
byte skipGameObject, byte unk4, byte unk5);
|
||||||
|
|
||||||
private readonly Hook<LoadWeaponDelegate> _loadWeaponHook;
|
private readonly Hook<LoadWeaponDelegate> _loadWeaponHook;
|
||||||
|
|
||||||
private void LoadWeaponDetour(DrawDataContainer* drawData, uint slot, ulong weaponValue, byte redrawOnEquality, byte unk2,
|
private void LoadWeaponDetour(DrawDataContainer* drawData, uint slot, ulong weaponValue, byte redrawOnEquality, byte unk2,
|
||||||
byte skipGameObject, byte unk4)
|
byte skipGameObject, byte unk4, byte unk5)
|
||||||
{
|
{
|
||||||
if (!_inUpdate.Value)
|
if (!_inUpdate.Value)
|
||||||
{
|
{
|
||||||
|
|
@ -64,21 +65,21 @@ public unsafe class WeaponService : IDisposable
|
||||||
else if (weaponValue == actor.GetMainhand().Value && weaponValue != 0)
|
else if (weaponValue == actor.GetMainhand().Value && weaponValue != 0)
|
||||||
_event.Invoke(actor, EquipSlot.MainHand, ref tmpWeapon);
|
_event.Invoke(actor, EquipSlot.MainHand, ref tmpWeapon);
|
||||||
|
|
||||||
_loadWeaponHook.Original(drawData, slot, weapon.Value, redrawOnEquality, unk2, skipGameObject, unk4);
|
_loadWeaponHook.Original(drawData, slot, weapon.Value, redrawOnEquality, unk2, skipGameObject, unk4, unk5);
|
||||||
|
|
||||||
if (tmpWeapon.Value != weapon.Value)
|
if (tmpWeapon.Value != weapon.Value)
|
||||||
{
|
{
|
||||||
if (tmpWeapon.Skeleton.Id == 0)
|
if (tmpWeapon.Skeleton.Id == 0)
|
||||||
tmpWeapon.Stains = StainIds.None;
|
tmpWeapon.Stains = StainIds.None;
|
||||||
_loadWeaponHook.Original(drawData, slot, tmpWeapon.Value, 1, unk2, 1, unk4);
|
_loadWeaponHook.Original(drawData, slot, tmpWeapon.Value, 1, unk2, 1, unk4, unk5);
|
||||||
}
|
}
|
||||||
|
|
||||||
Glamourer.Log.Excessive(
|
Glamourer.Log.Excessive(
|
||||||
$"Weapon reloaded for 0x{actor.Address:X} ({actor.Utf8Name}) with attributes {slot} {weapon.Value:X14}, {redrawOnEquality}, {unk2}, {skipGameObject}, {unk4}");
|
$"Weapon reloaded for 0x{actor.Address:X} ({actor.Utf8Name}) with attributes {slot} {weapon.Value:X14}, {redrawOnEquality}, {unk2}, {skipGameObject}, {unk4}, {unk5}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_loadWeaponHook.Original(drawData, slot, weaponValue, redrawOnEquality, unk2, skipGameObject, unk4);
|
_loadWeaponHook.Original(drawData, slot, weaponValue, redrawOnEquality, unk2, skipGameObject, unk4, unk5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,18 +90,18 @@ public unsafe class WeaponService : IDisposable
|
||||||
{
|
{
|
||||||
case EquipSlot.MainHand:
|
case EquipSlot.MainHand:
|
||||||
_inUpdate.Value = true;
|
_inUpdate.Value = true;
|
||||||
_original(&character.AsCharacter->DrawData, 0, weapon.Value, 1, 0, 1, 0);
|
_original(&character.AsCharacter->DrawData, 0, weapon.Value, 1, 0, 1, 0, 0);
|
||||||
_inUpdate.Value = false;
|
_inUpdate.Value = false;
|
||||||
return;
|
return;
|
||||||
case EquipSlot.OffHand:
|
case EquipSlot.OffHand:
|
||||||
_inUpdate.Value = true;
|
_inUpdate.Value = true;
|
||||||
_original(&character.AsCharacter->DrawData, 1, weapon.Value, 1, 0, 1, 0);
|
_original(&character.AsCharacter->DrawData, 1, weapon.Value, 1, 0, 1, 0, 0);
|
||||||
_inUpdate.Value = false;
|
_inUpdate.Value = false;
|
||||||
return;
|
return;
|
||||||
case EquipSlot.BothHand:
|
case EquipSlot.BothHand:
|
||||||
_inUpdate.Value = true;
|
_inUpdate.Value = true;
|
||||||
_original(&character.AsCharacter->DrawData, 0, weapon.Value, 1, 0, 1, 0);
|
_original(&character.AsCharacter->DrawData, 0, weapon.Value, 1, 0, 1, 0, 0);
|
||||||
_original(&character.AsCharacter->DrawData, 1, CharacterWeapon.Empty.Value, 1, 0, 1, 0);
|
_original(&character.AsCharacter->DrawData, 1, CharacterWeapon.Empty.Value, 1, 0, 1, 0, 0);
|
||||||
_inUpdate.Value = false;
|
_inUpdate.Value = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue