mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 18:27:24 +01:00
Update for 6.4, 0.1.2.0
This commit is contained in:
parent
956e1fc1a7
commit
f97829ab7f
8 changed files with 187 additions and 200 deletions
|
|
@ -1,181 +1,183 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.PlayerWatch;
|
||||
|
||||
namespace Glamourer
|
||||
namespace Glamourer;
|
||||
|
||||
public static class WriteExtensions
|
||||
{
|
||||
public static class WriteExtensions
|
||||
private static unsafe void Write(IntPtr characterPtr, EquipSlot slot, SetId? id, WeaponType? type, ushort? variant, StainId? stain)
|
||||
{
|
||||
private static unsafe void Write(IntPtr characterPtr, EquipSlot slot, SetId? id, WeaponType? type, ushort? variant, StainId? stain)
|
||||
void WriteWeapon(int offset)
|
||||
{
|
||||
void WriteWeapon(int offset)
|
||||
{
|
||||
var address = (byte*) characterPtr + offset;
|
||||
if (id.HasValue)
|
||||
*(ushort*) address = (ushort) id.Value;
|
||||
var address = (byte*)characterPtr + offset;
|
||||
if (id.HasValue)
|
||||
*(ushort*)address = (ushort)id.Value;
|
||||
|
||||
if (type.HasValue)
|
||||
*(ushort*) (address + 2) = (ushort) type.Value;
|
||||
if (type.HasValue)
|
||||
*(ushort*)(address + 2) = (ushort)type.Value;
|
||||
|
||||
if (variant.HasValue)
|
||||
*(ushort*) (address + 4) = variant.Value;
|
||||
if (variant.HasValue)
|
||||
*(ushort*)(address + 4) = variant.Value;
|
||||
|
||||
if (*(ushort*) address == 0)
|
||||
*(address + 6) = 0;
|
||||
else if (stain.HasValue)
|
||||
*(address + 6) = (byte) stain.Value;
|
||||
}
|
||||
|
||||
void WriteEquip(int offset)
|
||||
{
|
||||
var address = (byte*) characterPtr + offset;
|
||||
if (id.HasValue)
|
||||
*(ushort*) address = (ushort) id.Value;
|
||||
|
||||
if (variant < byte.MaxValue)
|
||||
*(address + 2) = (byte) variant.Value;
|
||||
|
||||
if (stain.HasValue)
|
||||
*(address + 3) = (byte) stain.Value;
|
||||
}
|
||||
|
||||
switch (slot)
|
||||
{
|
||||
case EquipSlot.MainHand:
|
||||
WriteWeapon(CharacterEquipment.MainWeaponOffset);
|
||||
break;
|
||||
case EquipSlot.OffHand:
|
||||
WriteWeapon(CharacterEquipment.OffWeaponOffset);
|
||||
break;
|
||||
case EquipSlot.Head:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset);
|
||||
break;
|
||||
case EquipSlot.Body:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 4);
|
||||
break;
|
||||
case EquipSlot.Hands:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 8);
|
||||
break;
|
||||
case EquipSlot.Legs:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 12);
|
||||
break;
|
||||
case EquipSlot.Feet:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 16);
|
||||
break;
|
||||
case EquipSlot.Ears:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 20);
|
||||
break;
|
||||
case EquipSlot.Neck:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 24);
|
||||
break;
|
||||
case EquipSlot.Wrists:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 28);
|
||||
break;
|
||||
case EquipSlot.RFinger:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 32);
|
||||
break;
|
||||
case EquipSlot.LFinger:
|
||||
WriteEquip(CharacterEquipment.EquipmentOffset + 36);
|
||||
break;
|
||||
default: throw new InvalidEnumArgumentException();
|
||||
}
|
||||
if (*(ushort*)address == 0)
|
||||
*(address + 6) = 0;
|
||||
else if (stain.HasValue)
|
||||
*(address + 6) = (byte)stain.Value;
|
||||
}
|
||||
|
||||
public static void Write(this Stain stain, IntPtr characterPtr, EquipSlot slot)
|
||||
=> Write(characterPtr, slot, null, null, null, stain.RowIndex);
|
||||
|
||||
public static void Write(this Item item, IntPtr characterAddress)
|
||||
void WriteEquip(int offset)
|
||||
{
|
||||
var (id, type, variant) = item.MainModel;
|
||||
Write(characterAddress, item.EquippableTo, id, type, variant, null);
|
||||
if (item.EquippableTo == EquipSlot.MainHand && item.HasSubModel)
|
||||
{
|
||||
var (subId, subType, subVariant) = item.SubModel;
|
||||
Write(characterAddress, EquipSlot.OffHand, subId, subType, subVariant, null);
|
||||
}
|
||||
var address = (byte*)characterPtr + offset;
|
||||
if (id.HasValue)
|
||||
*(ushort*)address = (ushort)id.Value;
|
||||
|
||||
if (variant < byte.MaxValue)
|
||||
*(address + 2) = (byte)variant.Value;
|
||||
|
||||
if (stain.HasValue)
|
||||
*(address + 3) = (byte)stain.Value;
|
||||
}
|
||||
|
||||
public static void Write(this CharacterArmor armor, IntPtr characterAddress, EquipSlot slot)
|
||||
=> Write(characterAddress, slot, armor.Set, null, armor.Variant, armor.Stain);
|
||||
|
||||
public static void Write(this CharacterWeapon weapon, IntPtr characterAddress, EquipSlot slot)
|
||||
=> Write(characterAddress, slot, weapon.Set, weapon.Type, weapon.Variant, weapon.Stain);
|
||||
|
||||
public static unsafe void Write(this CharacterEquipment equip, IntPtr characterAddress)
|
||||
var drawDataOffset = (int) Marshal.OffsetOf<Character>(nameof(Character.DrawData));
|
||||
switch (slot)
|
||||
{
|
||||
if (equip.IsSet == 0)
|
||||
return;
|
||||
|
||||
Write(characterAddress, EquipSlot.MainHand, equip.MainHand.Set, equip.MainHand.Type, equip.MainHand.Variant, equip.MainHand.Stain);
|
||||
Write(characterAddress, EquipSlot.OffHand, equip.OffHand.Set, equip.OffHand.Type, equip.OffHand.Variant, equip.OffHand.Stain);
|
||||
|
||||
fixed (CharacterArmor* equipment = &equip.Head)
|
||||
{
|
||||
Buffer.MemoryCopy(equipment, (byte*) characterAddress + CharacterEquipment.EquipmentOffset,
|
||||
CharacterEquipment.EquipmentSlots * sizeof(CharacterArmor), CharacterEquipment.EquipmentSlots * sizeof(CharacterArmor));
|
||||
}
|
||||
}
|
||||
|
||||
public static void Write(this CharacterEquipment equip, IntPtr characterAddress, CharacterEquipMask models, CharacterEquipMask stains)
|
||||
{
|
||||
if (models == CharacterEquipMask.All && stains == CharacterEquipMask.All)
|
||||
{
|
||||
equip.Write(characterAddress);
|
||||
return;
|
||||
}
|
||||
|
||||
if (models.HasFlag(CharacterEquipMask.MainHand))
|
||||
Write(characterAddress, EquipSlot.MainHand, equip.MainHand.Set, equip.MainHand.Type, equip.MainHand.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.MainHand))
|
||||
Write(characterAddress, EquipSlot.MainHand, null, null, null, equip.MainHand.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.OffHand))
|
||||
Write(characterAddress, EquipSlot.OffHand, equip.OffHand.Set, equip.OffHand.Type, equip.OffHand.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.OffHand))
|
||||
Write(characterAddress, EquipSlot.OffHand, null, null, null, equip.OffHand.Stain);
|
||||
|
||||
if (models.HasFlag(CharacterEquipMask.Head))
|
||||
Write(characterAddress, EquipSlot.Head, equip.Head.Set, null, equip.Head.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Head))
|
||||
Write(characterAddress, EquipSlot.Head, null, null, null, equip.Head.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.Body))
|
||||
Write(characterAddress, EquipSlot.Body, equip.Body.Set, null, equip.Body.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Body))
|
||||
Write(characterAddress, EquipSlot.Body, null, null, null, equip.Body.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.Hands))
|
||||
Write(characterAddress, EquipSlot.Hands, equip.Hands.Set, null, equip.Hands.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Hands))
|
||||
Write(characterAddress, EquipSlot.Hands, null, null, null, equip.Hands.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.Legs))
|
||||
Write(characterAddress, EquipSlot.Legs, equip.Legs.Set, null, equip.Legs.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Legs))
|
||||
Write(characterAddress, EquipSlot.Legs, null, null, null, equip.Legs.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.Feet))
|
||||
Write(characterAddress, EquipSlot.Feet, equip.Feet.Set, null, equip.Feet.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Feet))
|
||||
Write(characterAddress, EquipSlot.Feet, null, null, null, equip.Feet.Stain);
|
||||
|
||||
if (models.HasFlag(CharacterEquipMask.Ears))
|
||||
Write(characterAddress, EquipSlot.Ears, equip.Ears.Set, null, equip.Ears.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Ears))
|
||||
Write(characterAddress, EquipSlot.Ears, null, null, null, equip.Ears.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.Neck))
|
||||
Write(characterAddress, EquipSlot.Neck, equip.Neck.Set, null, equip.Neck.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Neck))
|
||||
Write(characterAddress, EquipSlot.Neck, null, null, null, equip.Neck.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.Wrists))
|
||||
Write(characterAddress, EquipSlot.Wrists, equip.Wrists.Set, null, equip.Wrists.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Wrists))
|
||||
Write(characterAddress, EquipSlot.Wrists, null, null, null, equip.Wrists.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.LFinger))
|
||||
Write(characterAddress, EquipSlot.LFinger, equip.LFinger.Set, null, equip.LFinger.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.LFinger))
|
||||
Write(characterAddress, EquipSlot.LFinger, null, null, null, equip.LFinger.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.RFinger))
|
||||
Write(characterAddress, EquipSlot.RFinger, equip.RFinger.Set, null, equip.RFinger.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.RFinger))
|
||||
Write(characterAddress, EquipSlot.RFinger, null, null, null, equip.RFinger.Stain);
|
||||
case EquipSlot.MainHand:
|
||||
WriteWeapon(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.MainHandModel)));
|
||||
break;
|
||||
case EquipSlot.OffHand:
|
||||
WriteWeapon(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.OffHandModel)));
|
||||
break;
|
||||
case EquipSlot.Head:
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Head)));
|
||||
break;
|
||||
case EquipSlot.Body:
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Top)));
|
||||
break;
|
||||
case EquipSlot.Hands:
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Arms)));
|
||||
break;
|
||||
case EquipSlot.Legs:
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Legs)));
|
||||
break;
|
||||
case EquipSlot.Feet:
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Feet)));
|
||||
break;
|
||||
case EquipSlot.Ears:
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Ear)));
|
||||
break;
|
||||
case EquipSlot.Neck:
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Neck)));
|
||||
break;
|
||||
case EquipSlot.Wrists:
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.Wrist)));
|
||||
break;
|
||||
case EquipSlot.RFinger:
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.RFinger)));
|
||||
break;
|
||||
case EquipSlot.LFinger:
|
||||
WriteEquip(drawDataOffset + (int)Marshal.OffsetOf<DrawDataContainer>(nameof(DrawDataContainer.LFinger)));
|
||||
break;
|
||||
default: throw new InvalidEnumArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Write(this Stain stain, IntPtr characterPtr, EquipSlot slot)
|
||||
=> Write(characterPtr, slot, null, null, null, stain.RowIndex);
|
||||
|
||||
public static void Write(this Item item, IntPtr characterAddress)
|
||||
{
|
||||
var (id, type, variant) = item.MainModel;
|
||||
Write(characterAddress, item.EquippableTo, id, type, variant, null);
|
||||
if (item.EquippableTo == EquipSlot.MainHand && item.HasSubModel)
|
||||
{
|
||||
var (subId, subType, subVariant) = item.SubModel;
|
||||
Write(characterAddress, EquipSlot.OffHand, subId, subType, subVariant, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Write(this CharacterArmor armor, IntPtr characterAddress, EquipSlot slot)
|
||||
=> Write(characterAddress, slot, armor.Set, null, armor.Variant, armor.Stain);
|
||||
|
||||
public static void Write(this CharacterWeapon weapon, IntPtr characterAddress, EquipSlot slot)
|
||||
=> Write(characterAddress, slot, weapon.Set, weapon.Type, weapon.Variant, weapon.Stain);
|
||||
|
||||
public static unsafe void Write(this CharacterEquipment equip, IntPtr characterAddress)
|
||||
{
|
||||
if (equip.IsSet == 0)
|
||||
return;
|
||||
|
||||
Write(characterAddress, EquipSlot.MainHand, equip.MainHand.Set, equip.MainHand.Type, equip.MainHand.Variant, equip.MainHand.Stain);
|
||||
Write(characterAddress, EquipSlot.OffHand, equip.OffHand.Set, equip.OffHand.Type, equip.OffHand.Variant, equip.OffHand.Stain);
|
||||
|
||||
fixed (CharacterArmor* equipment = &equip.Head)
|
||||
{
|
||||
Buffer.MemoryCopy(equipment, &((Character*)characterAddress)->DrawData.Head,
|
||||
CharacterEquipment.EquipmentSlots * sizeof(CharacterArmor), CharacterEquipment.EquipmentSlots * sizeof(CharacterArmor));
|
||||
}
|
||||
}
|
||||
|
||||
public static void Write(this CharacterEquipment equip, IntPtr characterAddress, CharacterEquipMask models, CharacterEquipMask stains)
|
||||
{
|
||||
if (models == CharacterEquipMask.All && stains == CharacterEquipMask.All)
|
||||
{
|
||||
equip.Write(characterAddress);
|
||||
return;
|
||||
}
|
||||
|
||||
if (models.HasFlag(CharacterEquipMask.MainHand))
|
||||
Write(characterAddress, EquipSlot.MainHand, equip.MainHand.Set, equip.MainHand.Type, equip.MainHand.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.MainHand))
|
||||
Write(characterAddress, EquipSlot.MainHand, null, null, null, equip.MainHand.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.OffHand))
|
||||
Write(characterAddress, EquipSlot.OffHand, equip.OffHand.Set, equip.OffHand.Type, equip.OffHand.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.OffHand))
|
||||
Write(characterAddress, EquipSlot.OffHand, null, null, null, equip.OffHand.Stain);
|
||||
|
||||
if (models.HasFlag(CharacterEquipMask.Head))
|
||||
Write(characterAddress, EquipSlot.Head, equip.Head.Set, null, equip.Head.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Head))
|
||||
Write(characterAddress, EquipSlot.Head, null, null, null, equip.Head.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.Body))
|
||||
Write(characterAddress, EquipSlot.Body, equip.Body.Set, null, equip.Body.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Body))
|
||||
Write(characterAddress, EquipSlot.Body, null, null, null, equip.Body.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.Hands))
|
||||
Write(characterAddress, EquipSlot.Hands, equip.Hands.Set, null, equip.Hands.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Hands))
|
||||
Write(characterAddress, EquipSlot.Hands, null, null, null, equip.Hands.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.Legs))
|
||||
Write(characterAddress, EquipSlot.Legs, equip.Legs.Set, null, equip.Legs.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Legs))
|
||||
Write(characterAddress, EquipSlot.Legs, null, null, null, equip.Legs.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.Feet))
|
||||
Write(characterAddress, EquipSlot.Feet, equip.Feet.Set, null, equip.Feet.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Feet))
|
||||
Write(characterAddress, EquipSlot.Feet, null, null, null, equip.Feet.Stain);
|
||||
|
||||
if (models.HasFlag(CharacterEquipMask.Ears))
|
||||
Write(characterAddress, EquipSlot.Ears, equip.Ears.Set, null, equip.Ears.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Ears))
|
||||
Write(characterAddress, EquipSlot.Ears, null, null, null, equip.Ears.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.Neck))
|
||||
Write(characterAddress, EquipSlot.Neck, equip.Neck.Set, null, equip.Neck.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Neck))
|
||||
Write(characterAddress, EquipSlot.Neck, null, null, null, equip.Neck.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.Wrists))
|
||||
Write(characterAddress, EquipSlot.Wrists, equip.Wrists.Set, null, equip.Wrists.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.Wrists))
|
||||
Write(characterAddress, EquipSlot.Wrists, null, null, null, equip.Wrists.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.LFinger))
|
||||
Write(characterAddress, EquipSlot.LFinger, equip.LFinger.Set, null, equip.LFinger.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.LFinger))
|
||||
Write(characterAddress, EquipSlot.LFinger, null, null, null, equip.LFinger.Stain);
|
||||
if (models.HasFlag(CharacterEquipMask.RFinger))
|
||||
Write(characterAddress, EquipSlot.RFinger, equip.RFinger.Set, null, equip.RFinger.Variant, null);
|
||||
if (stains.HasFlag(CharacterEquipMask.RFinger))
|
||||
Write(characterAddress, EquipSlot.RFinger, null, null, null, equip.RFinger.Stain);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,13 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Character = Dalamud.Game.ClientState.Objects.Types.Character;
|
||||
|
||||
namespace Glamourer.Customization
|
||||
{
|
||||
public unsafe struct LazyCustomization
|
||||
{
|
||||
public CharacterCustomization* Address;
|
||||
|
||||
public LazyCustomization(IntPtr characterPtr)
|
||||
=> Address = (CharacterCustomization*) (characterPtr + CharacterCustomization.CustomizationOffset);
|
||||
|
||||
public ref CharacterCustomization Value
|
||||
=> ref *Address;
|
||||
|
||||
public LazyCustomization(CharacterCustomization data)
|
||||
=> Address = &data;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct CharacterCustomization
|
||||
{
|
||||
public const int CustomizationOffset = 0x840;
|
||||
public const int CustomizationBytes = 26;
|
||||
|
||||
public static CharacterCustomization Default = new()
|
||||
|
|
@ -150,13 +134,13 @@ namespace Glamourer.Customization
|
|||
}
|
||||
}
|
||||
|
||||
public void Read(Character character)
|
||||
=> Read(character.Address + CustomizationOffset);
|
||||
public unsafe void Read(Character character)
|
||||
=> Read((nint) ((FFXIVClientStructs.FFXIV.Client.Game.Character.Character*)character.Address)->DrawData.CustomizeData.Data);
|
||||
|
||||
public CharacterCustomization(Character character)
|
||||
: this()
|
||||
{
|
||||
Read(character.Address + CustomizationOffset);
|
||||
Read(character);
|
||||
}
|
||||
|
||||
public byte this[CustomizationId id]
|
||||
|
|
@ -282,7 +266,7 @@ namespace Glamourer.Customization
|
|||
{
|
||||
fixed (Race* ptr = &Race)
|
||||
{
|
||||
Buffer.MemoryCopy(ptr, (byte*) characterAddress + CustomizationOffset, CustomizationBytes, CustomizationBytes);
|
||||
Buffer.MemoryCopy(ptr, ((FFXIVClientStructs.FFXIV.Client.Game.Character.Character*)characterAddress)->DrawData.CustomizeData.Data, CustomizationBytes, CustomizationBytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
<PlatformTarget>x64</PlatformTarget>
|
||||
<RootNamespace>Glamourer</RootNamespace>
|
||||
<AssemblyName>Glamourer</AssemblyName>
|
||||
<FileVersion>0.1.1.5</FileVersion>
|
||||
<AssemblyVersion>0.1.1.5</AssemblyVersion>
|
||||
<FileVersion>0.1.2.0</FileVersion>
|
||||
<AssemblyVersion>0.1.2.0</AssemblyVersion>
|
||||
<Company>SoftOtter</Company>
|
||||
<Product>Glamourer</Product>
|
||||
<Copyright>Copyright © 2020</Copyright>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
"Description": "Adds functionality to change and store appearance of players, customization and equip. Requires Penumbra to be installed and activated to work. Can also add preview options to the Changed Items tab for Penumbra.",
|
||||
"Tags": [ "Appearance", "Glamour", "Race", "Outfit", "Armor", "Clothes", "Skins", "Customization", "Design", "Character" ],
|
||||
"InternalName": "Glamourer",
|
||||
"AssemblyVersion": "0.1.1.5",
|
||||
"AssemblyVersion": "0.1.2.0",
|
||||
"RepoUrl": "https://github.com/Ottermandias/Glamourer",
|
||||
"ApplicableVersion": "any",
|
||||
"DalamudApiLevel": 8,
|
||||
|
|
|
|||
|
|
@ -4,18 +4,18 @@ public static class Offsets
|
|||
{
|
||||
public static class Character
|
||||
{
|
||||
public const int Wetness = 0x1B1F;
|
||||
public const int HatVisible = 0x85E;
|
||||
public const int VisorToggled = 0x85F;
|
||||
public const int WeaponHidden1 = 0x85F;
|
||||
public const int WeaponHidden2 = 0x73C;
|
||||
public const int Alpha = 0x1A18;
|
||||
public const int Wetness = 0x1B3A;
|
||||
public const int HatVisible = 0x876;
|
||||
public const int VisorToggled = 0x877;
|
||||
public const int WeaponHidden1 = 0x877;
|
||||
public const int WeaponHidden2 = 0x754;
|
||||
public const int Alpha = 0x1A4C;
|
||||
|
||||
public static class Flags
|
||||
{
|
||||
public const byte IsHatHidden = 0x01;
|
||||
public const byte IsVisorToggled = 0x08;
|
||||
public const byte IsWet = 0x40;
|
||||
public const byte IsWet = 0x20;
|
||||
public const byte IsWeaponHidden1 = 0x01;
|
||||
public const byte IsWeaponHidden2 = 0x02;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ namespace Penumbra.PlayerWatch;
|
|||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class CharacterEquipment
|
||||
{
|
||||
public const int MainWeaponOffset = 0x6E0;
|
||||
public const int OffWeaponOffset = 0x748;
|
||||
public const int EquipmentOffset = 0x818;
|
||||
public const int EquipmentSlots = 10;
|
||||
public const int WeaponSlots = 2;
|
||||
|
||||
|
|
@ -58,16 +55,16 @@ public class CharacterEquipment
|
|||
private unsafe CharacterEquipment(IntPtr actorAddress)
|
||||
{
|
||||
IsSet = 1;
|
||||
var actorPtr = (byte*)actorAddress.ToPointer();
|
||||
var actorPtr = (FFXIVClientStructs.FFXIV.Client.Game.Character.Character*)actorAddress.ToPointer();
|
||||
fixed (CharacterWeapon* main = &MainHand, off = &OffHand)
|
||||
{
|
||||
Buffer.MemoryCopy(actorPtr + MainWeaponOffset, main, sizeof(CharacterWeapon), sizeof(CharacterWeapon));
|
||||
Buffer.MemoryCopy(actorPtr + OffWeaponOffset, off, sizeof(CharacterWeapon), sizeof(CharacterWeapon));
|
||||
Buffer.MemoryCopy(&actorPtr->DrawData.MainHandModel, main, sizeof(CharacterWeapon), sizeof(CharacterWeapon));
|
||||
Buffer.MemoryCopy(&actorPtr->DrawData.OffHandModel, off, sizeof(CharacterWeapon), sizeof(CharacterWeapon));
|
||||
}
|
||||
|
||||
fixed (CharacterArmor* equipment = &Head)
|
||||
{
|
||||
Buffer.MemoryCopy(actorPtr + EquipmentOffset, equipment, EquipmentSlots * sizeof(CharacterArmor),
|
||||
Buffer.MemoryCopy(&actorPtr->DrawData.Head, equipment, EquipmentSlots * sizeof(CharacterArmor),
|
||||
EquipmentSlots * sizeof(CharacterArmor));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@
|
|||
<HintPath>$(DalamudLibPath)Dalamud.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="FFXIVClientStructs">
|
||||
<HintPath>$(DalamudLibPath)FFXIVClientStructs.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
"Description": "Adds functionality to change and store appearance of players, customization and equip. Requires Penumbra to be installed and activated to work. Can also add preview options to the Changed Items tab for Penumbra.",
|
||||
"Tags": [ "Appearance", "Glamour", "Race", "Outfit", "Armor", "Clothes", "Skins", "Customization", "Design", "Character" ],
|
||||
"InternalName": "Glamourer",
|
||||
"AssemblyVersion": "0.1.1.5",
|
||||
"TestingAssemblyVersion": "0.1.1.5",
|
||||
"AssemblyVersion": "0.1.2.0",
|
||||
"TestingAssemblyVersion": "0.1.2.0",
|
||||
"RepoUrl": "https://github.com/Ottermandias/Glamourer",
|
||||
"ApplicableVersion": "any",
|
||||
"DalamudApiLevel": 8,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue