Improve GamePaths and parsing, add support for identifying skeletons and phybs.

This commit is contained in:
Ottermandias 2025-02-27 13:08:41 +01:00
parent 8860d1e39a
commit c6de7ddebd
17 changed files with 65 additions and 83 deletions

View file

@ -43,8 +43,8 @@ internal partial record ResolveContext
private Utf8GamePath ResolveEquipmentModelPath()
{
var path = IsEquipmentSlot(SlotIndex)
? GamePaths.Equipment.Mdl.Path(Equipment.Set, ResolveModelRaceCode(), SlotIndex.ToEquipSlot())
: GamePaths.Accessory.Mdl.Path(Equipment.Set, ResolveModelRaceCode(), SlotIndex.ToEquipSlot());
? GamePaths.Mdl.Equipment(Equipment.Set, ResolveModelRaceCode(), SlotIndex.ToEquipSlot())
: GamePaths.Mdl.Accessory(Equipment.Set, ResolveModelRaceCode(), SlotIndex.ToEquipSlot());
return Utf8GamePath.FromString(path, out var gamePath) ? gamePath : Utf8GamePath.Empty;
}
@ -122,7 +122,7 @@ internal partial record ResolveContext
var setIdHigh = Equipment.Set.Id / 100;
// All MCH (20??) weapons' materials C are one and the same
if (setIdHigh is 20 && mtrlFileName[14] == (byte)'c')
return Utf8GamePath.FromString(GamePaths.Weapon.Mtrl.Path(2001, 1, 1, "c"), out var path) ? path : Utf8GamePath.Empty;
return Utf8GamePath.FromString(GamePaths.Mtrl.Weapon(2001, 1, 1, "c"), out var path) ? path : Utf8GamePath.Empty;
// Some offhands share materials with the corresponding mainhand
if (ItemData.AdaptOffhandImc(Equipment.Set, out var mirroredSetId))
@ -230,7 +230,7 @@ internal partial record ResolveContext
if (set == 0)
return Utf8GamePath.Empty;
var path = GamePaths.Skeleton.Sklb.Path(raceCode, slot, set);
var path = GamePaths.Sklb.Customization(raceCode, slot, set);
return Utf8GamePath.FromString(path, out var gamePath) ? gamePath : Utf8GamePath.Empty;
}
@ -300,7 +300,7 @@ internal partial record ResolveContext
if (set.Id is 0)
return Utf8GamePath.Empty;
var path = GamePaths.Skeleton.Skp.Path(raceCode, slot, set);
var path = GamePaths.Skp.Customization(raceCode, slot, set);
return Utf8GamePath.FromString(path, out var gamePath) ? gamePath : Utf8GamePath.Empty;
}
@ -328,7 +328,7 @@ internal partial record ResolveContext
if (set.Id is 0)
return Utf8GamePath.Empty;
var path = GamePaths.Skeleton.Phyb.Path(raceCode, slot, set);
var path = GamePaths.Phyb.Customization(raceCode, slot, set);
return Utf8GamePath.FromString(path, out var gamePath) ? gamePath : Utf8GamePath.Empty;
}
@ -354,7 +354,7 @@ internal partial record ResolveContext
if (decal is 0)
return Utf8GamePath.Empty;
var path = GamePaths.Equipment.Decal.Path(decal);
var path = GamePaths.Tex.EquipDecal(decal);
return Utf8GamePath.FromString(path, out var gamePath) ? gamePath : Utf8GamePath.Empty;
}
}

View file

@ -355,13 +355,10 @@ internal unsafe partial record ResolveContext(
if (sklbHandle is null)
return null;
if (!Utf8GamePath.FromString(GamePaths.Skeleton.Sklb.MaterialAnimationSkeletonPath, out var path))
return null;
if (Global.Nodes.TryGetValue((path, (nint)sklbHandle), out var cached))
if (Global.Nodes.TryGetValue((GamePaths.Sklb.MaterialAnimationSkeletonUtf8, (nint)sklbHandle), out var cached))
return cached;
var node = CreateNode(ResourceType.Sklb, 0, (ResourceHandle*)sklbHandle, path);
var node = CreateNode(ResourceType.Sklb, 0, (ResourceHandle*)sklbHandle, GamePaths.Sklb.MaterialAnimationSkeletonUtf8);
node.ForceInternal = true;
return node;
@ -455,11 +452,12 @@ internal unsafe partial record ResolveContext(
internal ResourceNode.UiData GuessUiDataFromPath(Utf8GamePath gamePath)
{
const string customization = "Customization: ";
foreach (var obj in Global.Identifier.Identify(gamePath.ToString()))
{
var name = obj.Key;
if (obj.Value is IdentifiedCustomization)
name = name[14..].Trim();
if (name.StartsWith(customization))
name = name.AsSpan(14).Trim().ToString();
if (name is not "Unknown")
return new ResourceNode.UiData(name, obj.Value.GetIcon().ToFlag());
}

View file

@ -207,8 +207,8 @@ public class ResourceTree(
var decalId = (byte)(human->Customize[(int)CustomizeIndex.Facepaint] & 0x7F);
var decalPath = decalId is not 0
? GamePaths.Human.Decal.FaceDecalPath(decalId)
: GamePaths.Tex.TransparentPath;
? GamePaths.Tex.FaceDecal(decalId)
: GamePaths.Tex.Transparent;
if (genericContext.CreateNodeFromTex(human->Decal, decalPath) is { } decalNode)
{
if (globalContext.WithUiData)
@ -223,8 +223,8 @@ public class ResourceTree(
var hasLegacyDecal = (human->Customize[(int)CustomizeIndex.FaceFeatures] & 0x80) != 0;
var legacyDecalPath = hasLegacyDecal
? GamePaths.Human.Decal.LegacyDecalPath
: GamePaths.Tex.TransparentPath;
? GamePaths.Tex.LegacyDecal
: GamePaths.Tex.Transparent;
if (genericContext.CreateNodeFromTex(human->LegacyBodyDecal, legacyDecalPath) is { } legacyDecalNode)
{
legacyDecalNode.ForceProtected = !hasLegacyDecal;