mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2026-02-21 06:57:44 +01:00
dupidu
This commit is contained in:
parent
e3a58340b3
commit
6a4b5fc3b2
15 changed files with 740 additions and 300 deletions
|
|
@ -48,11 +48,33 @@ public unsafe partial struct DrawObject : IEquatable<DrawObject>, IDesignable
|
|||
public CharacterEquip Equip
|
||||
=> new((CharacterArmor*)Pointer->EquipSlotData);
|
||||
|
||||
public unsafe CharacterWeapon MainHand
|
||||
=> CharacterWeapon.Empty;
|
||||
public CharacterWeapon MainHand
|
||||
{
|
||||
get
|
||||
{
|
||||
var child = (byte*)Pointer->CharacterBase.DrawObject.Object.ChildObject;
|
||||
if (child == null)
|
||||
return CharacterWeapon.Empty;
|
||||
|
||||
return *(CharacterWeapon*)(child + 0x8F0);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe CharacterWeapon OffHand
|
||||
=> CharacterWeapon.Empty;
|
||||
{
|
||||
get
|
||||
{
|
||||
var child = Pointer->CharacterBase.DrawObject.Object.ChildObject;
|
||||
if (child == null)
|
||||
return CharacterWeapon.Empty;
|
||||
|
||||
var sibling = (byte*) child->NextSiblingObject;
|
||||
if (sibling == null)
|
||||
return CharacterWeapon.Empty;
|
||||
|
||||
return *(CharacterWeapon*)(child + 0x8F0);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe bool VisorEnabled
|
||||
=> (*(byte*)(Address + 0x90) & 0x40) != 0;
|
||||
|
|
@ -113,6 +135,7 @@ public unsafe partial struct Actor : IEquatable<Actor>, IDesignable
|
|||
ident = GetIdentifier();
|
||||
return true;
|
||||
}
|
||||
|
||||
ident = IIdentifier.Invalid;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -156,16 +179,16 @@ public unsafe partial struct Actor : IEquatable<Actor>, IDesignable
|
|||
public CharacterEquip Equip
|
||||
=> new((CharacterArmor*)Pointer->EquipSlotData);
|
||||
|
||||
public unsafe CharacterWeapon MainHand
|
||||
public CharacterWeapon MainHand
|
||||
{
|
||||
get => *(CharacterWeapon*)(Address + 0x06C0 + 0x10);
|
||||
set => *(CharacterWeapon*)(Address + 0x06C0 + 0x10) = value;
|
||||
get => *(CharacterWeapon*)&Pointer->DrawData.MainHandModel;
|
||||
set => *(CharacterWeapon*)&Pointer->DrawData.MainHandModel = value;
|
||||
}
|
||||
|
||||
public unsafe CharacterWeapon OffHand
|
||||
public CharacterWeapon OffHand
|
||||
{
|
||||
get => *(CharacterWeapon*)(Address + 0x06C0 + 0x10 + 0x68);
|
||||
set => *(CharacterWeapon*)(Address + 0x06C0 + 0x10 + 0x68) = value;
|
||||
get => *(CharacterWeapon*)&Pointer->DrawData.OffHandModel;
|
||||
set => *(CharacterWeapon*)&Pointer->DrawData.OffHandModel = value;
|
||||
}
|
||||
|
||||
public unsafe bool VisorEnabled
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
using System;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Logging;
|
||||
using Dalamud.Utility.Signatures;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using Glamourer.Customization;
|
||||
using Glamourer.State;
|
||||
using Glamourer.Structs;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using CustomizeData = Penumbra.GameData.Structs.CustomizeData;
|
||||
using Race = Penumbra.GameData.Enums.Race;
|
||||
|
||||
namespace Glamourer.Interop;
|
||||
|
|
@ -66,27 +70,30 @@ public unsafe partial class RedrawManager
|
|||
return _flagSlotForUpdateHook.Original(drawObject, slotIdx, data);
|
||||
}
|
||||
|
||||
|
||||
public bool ChangeEquip(DrawObject drawObject, EquipSlot slot, CharacterArmor data)
|
||||
public bool ChangeEquip(DrawObject drawObject, uint slotIdx, CharacterArmor data)
|
||||
{
|
||||
if (!drawObject)
|
||||
return false;
|
||||
|
||||
var slotIndex = slot.ToIndex();
|
||||
if (slotIndex > 9)
|
||||
if (slotIdx > 9)
|
||||
return false;
|
||||
|
||||
return FlagSlotForUpdateDetour(drawObject.Pointer, slotIndex, &data) != 0;
|
||||
return FlagSlotForUpdateDetour(drawObject.Pointer, slotIdx, &data) != 0;
|
||||
}
|
||||
|
||||
public bool ChangeEquip(Actor actor, EquipSlot slot, CharacterArmor data)
|
||||
=> actor && ChangeEquip(actor.DrawObject, slot, data);
|
||||
=> actor && ChangeEquip(actor.DrawObject, slot.ToIndex(), data);
|
||||
|
||||
public bool ChangeEquip(DrawObject drawObject, EquipSlot slot, CharacterArmor data)
|
||||
=> ChangeEquip(drawObject, slot.ToIndex(), data);
|
||||
|
||||
public bool ChangeEquip(Actor actor, uint slotIdx, CharacterArmor data)
|
||||
=> actor && ChangeEquip(actor.DrawObject, slotIdx, data);
|
||||
}
|
||||
|
||||
public unsafe partial class RedrawManager
|
||||
{
|
||||
// The character weapon object manipulated is inside the actual character.
|
||||
public const int CharacterWeaponOffset = 0x6C0;
|
||||
public static readonly int CharacterWeaponOffset = (int) Marshal.OffsetOf<Character>("DrawData");
|
||||
|
||||
public delegate void LoadWeaponDelegate(IntPtr offsetCharacter, uint slot, ulong weapon, byte redrawOnEquality, byte unk2,
|
||||
byte skipGameObject,
|
||||
|
|
@ -219,7 +226,7 @@ public unsafe partial class RedrawManager : IDisposable
|
|||
var gameObjectCustomize = new Customize((CustomizeData*)actor.Pointer->CustomizeData);
|
||||
if (gameObjectCustomize.Equals(customize))
|
||||
customize.Load(save.Data.Customize);
|
||||
|
||||
|
||||
// Compare game object equip data against draw object equip data for transformations.
|
||||
// Apply each piece of equip that should be applied if they correspond.
|
||||
var gameObjectEquip = new CharacterEquip((CharacterArmor*)actor.Pointer->EquipSlotData);
|
||||
|
|
@ -262,14 +269,24 @@ public unsafe partial class RedrawManager : IDisposable
|
|||
[Signature("E8 ?? ?? ?? ?? 41 0F B6 C5 66 41 89 86")]
|
||||
private readonly ChangeCustomizeDelegate _changeCustomize = null!;
|
||||
|
||||
public bool UpdateCustomize(DrawObject drawObject, Customize customize)
|
||||
public bool UpdateCustomize(Actor actor, Customize customize)
|
||||
{
|
||||
if (!drawObject.Valid)
|
||||
if (!actor.Valid || !actor.DrawObject.Valid)
|
||||
return false;
|
||||
|
||||
return _changeCustomize(drawObject.Pointer, (byte*)customize.Data, 1);
|
||||
|
||||
var d = actor.DrawObject;
|
||||
if (NeedsRedraw(d.Customize, customize))
|
||||
{
|
||||
Glamourer.Penumbra.RedrawObject(actor.Character, RedrawType.Redraw, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return _changeCustomize(d.Pointer, (byte*)customize.Data, 1);
|
||||
}
|
||||
|
||||
public static bool NeedsRedraw(Customize lhs, Customize rhs)
|
||||
=> lhs.Race != rhs.Race || lhs.Gender != rhs.Gender || lhs.Face != rhs.Face || lhs.Race == Race.Hyur && lhs.Clan != rhs.Clan;
|
||||
|
||||
|
||||
public static void SetVisor(Human* data, bool on)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue