diff --git a/MareSynchronos/Factories/CharacterDataFactory.cs b/MareSynchronos/Factories/CharacterDataFactory.cs index 27cf632..9ad813a 100644 --- a/MareSynchronos/Factories/CharacterDataFactory.cs +++ b/MareSynchronos/Factories/CharacterDataFactory.cs @@ -195,10 +195,24 @@ public class CharacterDataFactory AddReplacementsFromTexture(new Utf8String(((HumanExt*)human)->Decal->FileName()).ToString(), cache, 0, "Decal", false); AddReplacementsFromTexture(new Utf8String(((HumanExt*)human)->LegacyBodyDecal->FileName()).ToString(), cache, 0, "Legacy Decal", false); - - AddReplacementSkeleton(((HumanExt*)human)->Human.RaceSexId, cache); + var minion = ((Character*)_dalamudUtil.PlayerPointer)->CompanionObject; + if (minion != null) + { + var minionDrawObj = ((CharacterBase*)minion->Character.GameObject.GetDrawObject()); + for (var mdlIdx = 0; mdlIdx < minionDrawObj->SlotCount; mdlIdx++) + { + var mdl = (RenderModel*)minionDrawObj->ModelArray[mdlIdx]; + if (mdl == null || mdl->ResourceHandle == null) + { + continue; + } + + AddReplacementsFromRenderModel(mdl, cache, 0, "Companion"); + } + } + st.Stop(); Logger.Verbose("Building Character Data took " + st.Elapsed); diff --git a/MareSynchronos/Managers/CachedPlayer.cs b/MareSynchronos/Managers/CachedPlayer.cs index e061429..dbb164b 100644 --- a/MareSynchronos/Managers/CachedPlayer.cs +++ b/MareSynchronos/Managers/CachedPlayer.cs @@ -5,11 +5,13 @@ using System.Threading; using System.Threading.Tasks; using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Logging; +using FFXIVClientStructs.FFXIV.Client.Game.Character; using MareSynchronos.API; using MareSynchronos.FileCacheDB; using MareSynchronos.Utils; using MareSynchronos.WebAPI; using MareSynchronos.WebAPI.Utils; +using Penumbra.GameData.ByteString; using Penumbra.GameData.Structs; namespace MareSynchronos.Managers; @@ -182,7 +184,7 @@ public class CachedPlayer return missingFiles; } - private void ApplyCharacterData(CharacterCacheDto cache, Dictionary moddedPaths) + private unsafe void ApplyCharacterData(CharacterCacheDto cache, Dictionary moddedPaths) { if (PlayerCharacter is null) return; _ipcManager.PenumbraRemoveTemporaryCollection(PlayerName!); @@ -193,6 +195,15 @@ public class CachedPlayer $"Request Redraw for {PlayerName}"); _ipcManager.PenumbraSetTemporaryMods(tempCollection, moddedPaths, cache.ManipulationData); _ipcManager.GlamourerApplyAll(cache.GlamourerData, PlayerCharacter!); + var minion = ((Character*)PlayerCharacter.Address)->CompanionObject; + if (minion != null) + { + var compName = new Utf8String(minion->Character.GameObject.GetName()).ToString(); + if (compName != null) + { + _ipcManager.PenumbraRedraw(compName); + } + } } public void DisposePlayer() diff --git a/MareSynchronos/Managers/PlayerManager.cs b/MareSynchronos/Managers/PlayerManager.cs index f0f0da9..a433022 100644 --- a/MareSynchronos/Managers/PlayerManager.cs +++ b/MareSynchronos/Managers/PlayerManager.cs @@ -7,6 +7,9 @@ using System.Threading; using System.Threading.Tasks; using MareSynchronos.API; using Penumbra.GameData.Structs; +using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; +using FFXIVClientStructs.FFXIV.Client.Game.Character; +using Penumbra.GameData.ByteString; namespace MareSynchronos.Managers { @@ -25,6 +28,7 @@ namespace MareSynchronos.Managers private CancellationTokenSource? _playerChangedCts; private DateTime _lastPlayerObjectCheck; private CharacterEquipment? _currentCharacterEquipment; + private string _lastMinionName = string.Empty; public PlayerManager(ApiController apiController, IpcManager ipcManager, CharacterDataFactory characterDataFactory, DalamudUtil dalamudUtil) @@ -57,14 +61,23 @@ namespace MareSynchronos.Managers _dalamudUtil.FrameworkUpdate -= DalamudUtilOnFrameworkUpdate; } - private void DalamudUtilOnFrameworkUpdate() + private unsafe void DalamudUtilOnFrameworkUpdate() { if (!_dalamudUtil.IsPlayerPresent || !_ipcManager.Initialized || !_apiController.IsConnected) return; if (DateTime.Now < _lastPlayerObjectCheck.AddSeconds(0.25)) return; - if (_dalamudUtil.IsPlayerPresent && !_currentCharacterEquipment!.CompareAndUpdate(_dalamudUtil.PlayerCharacter)) + var minion = ((Character*)_dalamudUtil.PlayerPointer)->CompanionObject; + string minionName = ""; + if (minion != null) { + minionName = new Utf8String(minion->Character.GameObject.GetName()).ToString(); + } + + if (_dalamudUtil.IsPlayerPresent + && (!_currentCharacterEquipment!.CompareAndUpdate(_dalamudUtil.PlayerCharacter) || minionName != _lastMinionName)) + { + _lastMinionName = minionName; OnPlayerChanged(); }