From 0a6584bc324a55f98d40d985564e68c46ef058e9 Mon Sep 17 00:00:00 2001 From: Stanley Dimant Date: Sat, 2 Jul 2022 12:53:24 +0200 Subject: [PATCH] add weapon sync --- .../Factories/CharacterDataFactory.cs | 56 +++++++++++++++++-- MareSynchronos/Interop/Human.cs | 9 +-- MareSynchronos/Interop/Weapon.cs | 23 ++++++++ MareSynchronos/Managers/IpcManager.cs | 4 ++ 4 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 MareSynchronos/Interop/Weapon.cs diff --git a/MareSynchronos/Factories/CharacterDataFactory.cs b/MareSynchronos/Factories/CharacterDataFactory.cs index 138f190..58fcc2f 100644 --- a/MareSynchronos/Factories/CharacterDataFactory.cs +++ b/MareSynchronos/Factories/CharacterDataFactory.cs @@ -70,10 +70,10 @@ namespace MareSynchronos.Factories GlamourerString = _ipcManager.GlamourerGetCharacterCustomization(_dalamudUtil.PlayerCharacter), ManipulationString = _ipcManager.PenumbraGetMetaManipulations(_dalamudUtil.PlayerName) }; - var drawObject = (Human*)((Character*)_dalamudUtil.PlayerPointer)->GameObject.GetDrawObject(); - for (var mdlIdx = 0; mdlIdx < drawObject->CharacterBase.SlotCount; ++mdlIdx) + var human = (Human*)((Character*)_dalamudUtil.PlayerPointer)->GameObject.GetDrawObject(); + for (var mdlIdx = 0; mdlIdx < human->CharacterBase.SlotCount; ++mdlIdx) { - var mdl = (RenderModel*)drawObject->CharacterBase.ModelArray[mdlIdx]; + var mdl = (RenderModel*)human->CharacterBase.ModelArray[mdlIdx]; if (mdl == null || mdl->ResourceHandle == null || mdl->ResourceHandle->Category != ResourceCategory.Chara) { continue; @@ -125,14 +125,60 @@ namespace MareSynchronos.Factories } } + var weapon = (RenderModel*)human->Weapon->WeaponRenderModel->RenderModel; + + var weaponPath = new Utf8String(weapon->ResourceHandle->FileName()).ToString(); + FileReplacement weaponReplacement = CreateFileReplacement(weaponPath); + cache.AddFileReplacement(weaponReplacement); + + Logger.Debug("Weapon " + string.Join(", ", weaponReplacement.GamePaths)); + Logger.Debug("\t\t=> " + weaponReplacement.ResolvedPath); + + for (var mtrlIdx = 0; mtrlIdx < weapon->MaterialCount; mtrlIdx++) + { + var mtrl = (Material*)weapon->Materials[mtrlIdx]; + if (mtrl == null) continue; + + var mtrlPath = new Utf8String(mtrl->ResourceHandle->FileName()).ToString().Split("|")[2]; + + var mtrlFileReplacement = CreateFileReplacement(mtrlPath); + Logger.Debug("\tWeapon Material " + string.Join(", ", mtrlFileReplacement.GamePaths)); + Logger.Debug("\t\t\t=> " + mtrlFileReplacement.ResolvedPath); + + cache.AddFileReplacement(mtrlFileReplacement); + + var mtrlResourceHandle = (MtrlResource*)mtrl->ResourceHandle; + for (var resIdx = 0; resIdx < mtrlResourceHandle->NumTex; resIdx++) + { + var texPath = new Utf8String(mtrlResourceHandle->TexString(resIdx)).ToString(); + + if (string.IsNullOrEmpty(texPath)) continue; + + var texFileReplacement = CreateFileReplacement(texPath, true); + Logger.Debug("\t\tWeapon Texture " + string.Join(", ", texFileReplacement.GamePaths)); + Logger.Debug("\t\t\t\t=> " + texFileReplacement.ResolvedPath); + + cache.AddFileReplacement(texFileReplacement); + + if (texPath.Contains("/--")) continue; + + var texDoubleMinusFileReplacement = + CreateFileReplacement(texPath.Insert(texPath.LastIndexOf('/') + 1, "--"), true); + + Logger.Debug("\t\tWeapon Texture-- " + string.Join(", ", texDoubleMinusFileReplacement.GamePaths)); + Logger.Debug("\t\t\t\t=> " + texDoubleMinusFileReplacement.ResolvedPath); + cache.AddFileReplacement(texDoubleMinusFileReplacement); + } + } + var tattooDecalFileReplacement = - CreateFileReplacement(new Utf8String(drawObject->Decal->FileName()).ToString()); + CreateFileReplacement(new Utf8String(human->Decal->FileName()).ToString()); cache.AddFileReplacement(tattooDecalFileReplacement); Logger.Debug("Decal " + string.Join(", ", tattooDecalFileReplacement.GamePaths)); Logger.Debug("\t\t=> " + tattooDecalFileReplacement.ResolvedPath); var legacyDecalFileReplacement = - CreateFileReplacement(new Utf8String(drawObject->LegacyBodyDecal->FileName()).ToString()); + CreateFileReplacement(new Utf8String(human->LegacyBodyDecal->FileName()).ToString()); cache.AddFileReplacement(legacyDecalFileReplacement); Logger.Debug("Legacy Decal " + string.Join(", ", legacyDecalFileReplacement.GamePaths)); Logger.Debug("\t\t=> " + legacyDecalFileReplacement.ResolvedPath); diff --git a/MareSynchronos/Interop/Human.cs b/MareSynchronos/Interop/Human.cs index 7727ecd..b4dd347 100644 --- a/MareSynchronos/Interop/Human.cs +++ b/MareSynchronos/Interop/Human.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using Penumbra.Interop.Structs; @@ -13,6 +9,7 @@ namespace MareSynchronos.Interop public unsafe struct Human { [FieldOffset(0x0)] public CharacterBase CharacterBase; + [FieldOffset(0x30)] public Weapon* Weapon; [FieldOffset(0x8F0)] public fixed byte CustomizeData[0x1A]; [FieldOffset(0x8F0)] public byte Race; [FieldOffset(0x8F1)] public byte Sex; @@ -53,8 +50,8 @@ namespace MareSynchronos.Interop [FieldOffset(0x93E)] public ushort TailEarId; // tXXXX/zXXXX(viera) [FieldOffset(0x9D6)] public ushort Unknown; // 80 3F in memory - [FieldOffset(0x9D8)] public IntPtr VfxMaybe; - [FieldOffset(0x9E0)] public IntPtr Unk; + [FieldOffset(0x9D8)] public IntPtr Buffer1; + [FieldOffset(0x9E0)] public IntPtr Buffer; [FieldOffset(0x9E8)] public ResourceHandle* Decal; [FieldOffset(0x9F0)] public ResourceHandle* LegacyBodyDecal; [FieldOffset(0x9F8)] public IntPtr Unk2; diff --git a/MareSynchronos/Interop/Weapon.cs b/MareSynchronos/Interop/Weapon.cs new file mode 100644 index 0000000..df8ab8e --- /dev/null +++ b/MareSynchronos/Interop/Weapon.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; +using Penumbra.Interop.Structs; + +namespace MareSynchronos.Interop +{ + [StructLayout(LayoutKind.Explicit)] + public unsafe struct Weapon + { + [FieldOffset(0xA8)] public WeaponDrawObject* WeaponRenderModel; + } + + [StructLayout(LayoutKind.Explicit)] + public unsafe struct WeaponDrawObject + { + [FieldOffset(0x00)] public RenderModel* RenderModel; + } +} diff --git a/MareSynchronos/Managers/IpcManager.cs b/MareSynchronos/Managers/IpcManager.cs index fb8e9c8..bbc432d 100644 --- a/MareSynchronos/Managers/IpcManager.cs +++ b/MareSynchronos/Managers/IpcManager.cs @@ -198,6 +198,10 @@ namespace MareSynchronos.Managers if (!CheckPenumbraApi()) return; Logger.Debug("Assigning temp mods for " + collectionName); + foreach (var mod in modPaths) + { + Logger.Verbose(mod.Key + " => " + mod.Value); + } var ret = _penumbraSetTemporaryMod.InvokeFunc("MareSynchronos", collectionName, modPaths, manipulationData, 0); }