diff --git a/Glamourer/Interop/ScalingService.cs b/Glamourer/Interop/ScalingService.cs index f29f41b..1575450 100644 --- a/Glamourer/Interop/ScalingService.cs +++ b/Glamourer/Interop/ScalingService.cs @@ -2,12 +2,12 @@ using Dalamud.Hooking; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Game.Character; -using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; +using Glamourer.Interop.Structs; using Character = FFXIVClientStructs.FFXIV.Client.Game.Character.Character; namespace Glamourer.Interop; -// TODO: Use clientstructs sigs. +// TODO: Use client structs sigs. public unsafe class ScalingService : IDisposable { public ScalingService() @@ -33,54 +33,47 @@ public unsafe class ScalingService : IDisposable private readonly Hook _setupOrnamentHook = null!; [Signature("E8 ?? ?? ?? ?? 48 85 C0 48 0F 45 F8")] - private readonly delegate* unmanaged GetParentGameObject = null!; + private readonly delegate* unmanaged _getParentGameObject = null!; private void SetupMountDetour(Character.MountContainer* container, short mountId, uint unk1, uint unk2, uint unk3, byte unk4) { - var oldRace = container->OwnerObject->Character.DrawData.CustomizeData.Race; - var oldSex = container->OwnerObject->Character.DrawData.CustomizeData.Sex; - var oldClan = container->OwnerObject->Character.DrawData.CustomizeData.Clan; - var drawObject = container->OwnerObject->Character.GameObject.DrawObject; - if (drawObject != null - && drawObject->Object.GetObjectType() is ObjectType.CharacterBase - && ((CharacterBase*)drawObject)->GetModelType() is CharacterBase.ModelType.Human) - { - container->OwnerObject->Character.DrawData.CustomizeData.Race = ((Human*)drawObject)->Customize.Race; - container->OwnerObject->Character.DrawData.CustomizeData.Sex = ((Human*)drawObject)->Customize.Sex; - container->OwnerObject->Character.DrawData.CustomizeData.Clan = ((Human*)drawObject)->Customize.Clan; - } - + var (race, clan, gender) = GetRelevantCustomize(&container->OwnerObject->Character); + SetCustomize(&container->OwnerObject->Character, container->OwnerObject->Character.GameObject.DrawObject); _setupMountHook.Original(container, mountId, unk1, unk2, unk3, unk4); - container->OwnerObject->Character.DrawData.CustomizeData.Race = oldRace; - container->OwnerObject->Character.DrawData.CustomizeData.Sex = oldSex; - container->OwnerObject->Character.DrawData.CustomizeData.Clan = oldClan; + SetCustomize(&container->OwnerObject->Character, race, clan, gender); } private void SetupOrnamentDetour(Ornament* ornament, uint* unk1, float* unk2) { - var character = GetParentGameObject(ornament); + var character = _getParentGameObject(ornament); if (character == null) { _setupOrnamentHook.Original(ornament, unk1, unk2); return; } - var oldRace = character->DrawData.CustomizeData.Race; - var oldSex = character->DrawData.CustomizeData.Sex; - var oldClan = character->DrawData.CustomizeData.Clan; - var drawObject = character->GameObject.DrawObject; - if (drawObject != null - && drawObject->Object.GetObjectType() is ObjectType.CharacterBase - && ((CharacterBase*)drawObject)->GetModelType() is CharacterBase.ModelType.Human) - { - character->DrawData.CustomizeData.Race = ((Human*)drawObject)->Customize.Race; - character->DrawData.CustomizeData.Sex = ((Human*)drawObject)->Customize.Sex; - character->DrawData.CustomizeData.Clan = ((Human*)drawObject)->Customize.Clan; - } - + var (race, clan, gender) = GetRelevantCustomize(character); + SetCustomize(character, character->GameObject.DrawObject); _setupOrnamentHook.Original(ornament, unk1, unk2); - character->DrawData.CustomizeData.Race = oldRace; - character->DrawData.CustomizeData.Sex = oldSex; - character->DrawData.CustomizeData.Clan = oldClan; + SetCustomize(character, race, clan, gender); + } + + /// We do not change the Customize gender because the functions use the GetGender() vfunc, which uses the game objects gender value. + private static (byte Race, byte Clan, byte Gender) GetRelevantCustomize(Character* character) + => (character->DrawData.CustomizeData.Race, character->DrawData.CustomizeData.Clan, character->GameObject.Gender); + + private static void SetCustomize(Character* character, Model model) + { + if (!model.IsHuman) + return; + + SetCustomize(character, model.AsHuman->Customize.Race, model.AsHuman->Customize.Clan, model.AsHuman->Customize.Sex); + } + + private static void SetCustomize(Character* character, byte race, byte clan, byte gender) + { + character->DrawData.CustomizeData.Race = race; + character->DrawData.CustomizeData.Clan = clan; + character->GameObject.Gender = gender; } }