Glamourer/GlamourerOld/DrawObjectManager.cs
Ottermandias 2d6fd6015d .
2023-06-09 17:57:40 +02:00

84 lines
3.4 KiB
C#

using System;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using Glamourer.Api;
using Glamourer.Customization;
using Glamourer.Interop;
using Glamourer.Services;
using Glamourer.State;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
using CustomizeData = Penumbra.GameData.Structs.CustomizeData;
namespace Glamourer;
public class DrawObjectManager : IDisposable
{
private readonly ItemManager _items;
private readonly ActorService _actors;
private readonly ActiveDesign.Manager _manager;
private readonly PenumbraAttach _penumbra;
public DrawObjectManager(ItemManager items, ActorService actors, ActiveDesign.Manager manager,
PenumbraAttach penumbra)
{
_items = items;
_actors = actors;
_manager = manager;
_penumbra = penumbra;
//_interop.EquipUpdate += FixEquipment;
_penumbra.CreatingCharacterBase += ApplyActiveDesign;
}
private void FixEquipment(DrawObject drawObject, EquipSlot slot, ref CharacterArmor item)
{
var customize = drawObject.Customize;
var (changed, newArmor) = _items.ResolveRestrictedGear(item, slot, customize.Race, customize.Gender);
if (!changed)
return;
Glamourer.Log.Verbose(
$"Invalid armor {item.Set.Value}-{item.Variant} for {customize.Gender} {customize.Race} changed to {newArmor.Set.Value}-{newArmor.Variant}.");
item = newArmor;
}
private unsafe void ApplyActiveDesign(nint gameObjectPtr, string collectionName, nint modelIdPtr, nint customizePtr, nint equipDataPtr)
{
var gameObject = (Actor)gameObjectPtr;
ref var modelId = ref *(uint*)modelIdPtr;
// Do not apply anything if the game object model id does not correspond to the draw object model id.
// This is the case if the actor is transformed to a different creature.
if (gameObject.ModelId != modelId)
return;
var identifier = _actors.AwaitedService.FromObject((GameObject*)gameObjectPtr, out _, true, true, false);
if (!identifier.IsValid || !_manager.TryGetValue(identifier, out var design))
return;
// Compare game object customize data against draw object customize data for transformations.
// Apply customization if they correspond and there is customization to apply.
var gameObjectCustomize = gameObject.Customize;
var customize = new Customize(*(CustomizeData*)customizePtr);
if (gameObjectCustomize.Equals(customize))
customize.Load(design.ModelData.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 = gameObject.Equip;
var equip = new CharacterEquip((CharacterArmor*)equipDataPtr);
if (gameObjectEquip.Equals(equip))
{
foreach (var slot in EquipSlotExtensions.EquipmentSlots)
{
(_, equip[slot]) =
_items.ResolveRestrictedGear(design.ModelData.Armor(slot), slot, customize.Race, customize.Gender);
}
}
}
public void Dispose()
{
_penumbra.CreatingCharacterBase -= ApplyActiveDesign;
//_interop.EquipUpdate -= FixEquipment;
}
}