mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-23 17:09:22 +01:00
ResourceTree: Use DrawObject as equipment source + CS-ify a bit more
This commit is contained in:
parent
00dc5f48b1
commit
5085aa500c
1 changed files with 45 additions and 39 deletions
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue