ResourceTree: Use DrawObject as equipment source + CS-ify a bit more

This commit is contained in:
Exter-N 2023-10-27 02:13:57 +02:00
parent 00dc5f48b1
commit 5085aa500c

View file

@ -50,9 +50,14 @@ public class ResourceTree
{ {
var character = (Character*)GameObjectAddress; var character = (Character*)GameObjectAddress;
var model = (CharacterBase*)DrawObjectAddress; var model = (CharacterBase*)DrawObjectAddress;
var human = model->GetModelType() == CharacterBase.ModelType.Human ? (Human*)model : null; var modelType = model->GetModelType();
var equipment = new ReadOnlySpan<CharacterArmor>(&character->DrawData.Head, 10); var human = modelType == CharacterBase.ModelType.Human ? (Human*)model : null;
// var customize = new ReadOnlySpan<byte>( character->CustomizeData, 26 ); var equipment = modelType switch
{
CharacterBase.ModelType.Human => new ReadOnlySpan<CharacterArmor>(&human->Head, 10),
CharacterBase.ModelType.DemiHuman => new ReadOnlySpan<CharacterArmor>(&character->DrawData.Head, 10),
_ => ReadOnlySpan<CharacterArmor>.Empty,
};
ModelId = character->CharacterData.ModelCharaId; ModelId = character->CharacterData.ModelCharaId;
CustomizeData = character->DrawData.CustomizeData; CustomizeData = character->DrawData.CustomizeData;
RaceCode = human != null ? (GenderRace)human->RaceSexId : GenderRace.Unknown; RaceCode = human != null ? (GenderRace)human->RaceSexId : GenderRace.Unknown;
@ -91,50 +96,51 @@ public class ResourceTree
private unsafe void AddHumanResources(GlobalResolveContext globalContext, Human* human) private unsafe void AddHumanResources(GlobalResolveContext globalContext, Human* human)
{ {
var firstSubObject = (CharacterBase*)human->CharacterBase.DrawObject.Object.ChildObject; var subObjectIndex = 0;
if (firstSubObject != null) var weaponIndex = 0;
var subObjectNodes = new List<ResourceNode>();
foreach (var baseSubObject in human->CharacterBase.DrawObject.Object.ChildObjects)
{ {
var subObjectNodes = new List<ResourceNode>(); if (baseSubObject->GetObjectType() != FFXIVClientStructs.FFXIV.Client.Graphics.Scene.ObjectType.CharacterBase)
var subObject = firstSubObject; continue;
var subObjectIndex = 0; var subObject = (CharacterBase*)baseSubObject;
do
var weapon = subObject->GetModelType() == CharacterBase.ModelType.Weapon ? (Weapon*)subObject : null;
var subObjectNamePrefix = weapon != null ? "Weapon" : "Fashion Acc.";
// This way to tell apart MainHand and OffHand is not always accurate, but seems good enough for what we're doing with it.
var subObjectContext = globalContext.CreateContext(
weapon != null ? (weaponIndex > 0 ? EquipSlot.OffHand : EquipSlot.MainHand) : EquipSlot.Unknown,
weapon != null ? new CharacterArmor(weapon->ModelSetId, (byte)weapon->Variant, (byte)weapon->ModelUnknown) : default
);
for (var i = 0; i < subObject->SlotCount; ++i)
{ {
var weapon = subObject->GetModelType() == CharacterBase.ModelType.Weapon ? (Weapon*)subObject : null; var imc = (ResourceHandle*)subObject->IMCArray[i];
var subObjectNamePrefix = weapon != null ? "Weapon" : "Fashion Acc."; var imcNode = subObjectContext.CreateNodeFromImc(imc);
var subObjectContext = globalContext.CreateContext( if (imcNode != null)
weapon != null ? EquipSlot.MainHand : EquipSlot.Unknown,
weapon != null ? new CharacterArmor(weapon->ModelSetId, (byte)weapon->Variant, (byte)weapon->ModelUnknown) : default
);
for (var i = 0; i < subObject->SlotCount; ++i)
{ {
var imc = (ResourceHandle*)subObject->IMCArray[i]; if (globalContext.WithUiData)
var imcNode = subObjectContext.CreateNodeFromImc(imc); imcNode.FallbackName = $"{subObjectNamePrefix} #{subObjectIndex}, IMC #{i}";
if (imcNode != null) subObjectNodes.Add(imcNode);
{
if (globalContext.WithUiData)
imcNode.FallbackName = $"{subObjectNamePrefix} #{subObjectIndex}, IMC #{i}";
subObjectNodes.Add(imcNode);
}
var mdl = subObject->Models[i];
var mdlNode = subObjectContext.CreateNodeFromRenderModel(mdl);
if (mdlNode != null)
{
if (globalContext.WithUiData)
mdlNode.FallbackName = $"{subObjectNamePrefix} #{subObjectIndex}, Model #{i}";
subObjectNodes.Add(mdlNode);
}
} }
AddSkeleton(subObjectNodes, subObjectContext, subObject->Skeleton, $"{subObjectNamePrefix} #{subObjectIndex}, "); var mdl = subObject->Models[i];
var mdlNode = subObjectContext.CreateNodeFromRenderModel(mdl);
if (mdlNode != null)
{
if (globalContext.WithUiData)
mdlNode.FallbackName = $"{subObjectNamePrefix} #{subObjectIndex}, Model #{i}";
subObjectNodes.Add(mdlNode);
}
}
subObject = (CharacterBase*)subObject->DrawObject.Object.NextSiblingObject; AddSkeleton(subObjectNodes, subObjectContext, subObject->Skeleton, $"{subObjectNamePrefix} #{subObjectIndex}, ");
++subObjectIndex;
} while (subObject != null && subObject != firstSubObject);
Nodes.InsertRange(0, subObjectNodes); ++subObjectIndex;
if (weapon != null)
++weaponIndex;
} }
Nodes.InsertRange(0, subObjectNodes);
var context = globalContext.CreateContext(EquipSlot.Unknown, default); var context = globalContext.CreateContext(EquipSlot.Unknown, default);