Merge branch 'master' into dtme

# Conflicts:
#	Penumbra/UI/AdvancedWindow/ModEditWindow.Materials.ColorTable.cs
#	Penumbra/UI/AdvancedWindow/ModEditWindow.Materials.MtrlTab.cs
This commit is contained in:
Ottermandias 2024-08-04 15:36:17 +02:00
commit 30d10d5a26
44 changed files with 1740 additions and 443 deletions

View file

@ -1,9 +1,9 @@
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
using FFXIVClientStructs.Interop;
using OtterGui;
using OtterGui.Text.HelperObjects;
using Penumbra.Api.Enums;
using Penumbra.Collections;
using Penumbra.GameData.Data;
@ -16,7 +16,7 @@ using Penumbra.String;
using Penumbra.String.Classes;
using Penumbra.UI;
using static Penumbra.Interop.Structs.StructExtensions;
using ModelType = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CharacterBase.ModelType;
using CharaBase = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CharacterBase;
namespace Penumbra.Interop.ResourceTree;
@ -29,25 +29,25 @@ internal record GlobalResolveContext(
{
public readonly Dictionary<(Utf8GamePath, nint), ResourceNode> Nodes = new(128);
public unsafe ResolveContext CreateContext(CharacterBase* characterBase, uint slotIndex = 0xFFFFFFFFu,
public unsafe ResolveContext CreateContext(CharaBase* characterBase, uint slotIndex = 0xFFFFFFFFu,
EquipSlot slot = EquipSlot.Unknown, CharacterArmor equipment = default, SecondaryId secondaryId = default)
=> new(this, characterBase, slotIndex, slot, equipment, secondaryId);
}
internal unsafe partial record ResolveContext(
GlobalResolveContext Global,
Pointer<CharacterBase> CharacterBasePointer,
Pointer<CharaBase> CharacterBasePointer,
uint SlotIndex,
EquipSlot Slot,
CharacterArmor Equipment,
SecondaryId SecondaryId)
{
public CharacterBase* CharacterBase
public CharaBase* CharacterBase
=> CharacterBasePointer.Value;
private static readonly CiByteString ShpkPrefix = CiByteString.FromSpanUnsafe("shader/sm5/shpk"u8, true, true, true);
private ModelType ModelType
private CharaBase.ModelType ModelType
=> CharacterBase->GetModelType();
private ResourceNode? CreateNodeFromShpk(ShaderPackageResourceHandle* resourceHandle, CiByteString gamePath)
@ -75,11 +75,14 @@ internal unsafe partial record ResolveContext(
if (lastDirectorySeparator == -1 || lastDirectorySeparator > gamePath.Length - 3)
return null;
Span<byte> prefixed = stackalloc byte[260];
gamePath.Span[..(lastDirectorySeparator + 1)].CopyTo(prefixed);
prefixed[lastDirectorySeparator + 1] = (byte)'-';
prefixed[lastDirectorySeparator + 2] = (byte)'-';
gamePath.Span[(lastDirectorySeparator + 1)..].CopyTo(prefixed[(lastDirectorySeparator + 3)..]);
Span<byte> prefixed = stackalloc byte[CharaBase.PathBufferSize];
var writer = new SpanTextWriter(prefixed);
writer.Append(gamePath.Span[..(lastDirectorySeparator + 1)]);
writer.Append((byte)'-');
writer.Append((byte)'-');
writer.Append(gamePath.Span[(lastDirectorySeparator + 1)..]);
writer.EnsureNullTerminated();
if (!Utf8GamePath.FromSpan(prefixed[..(gamePath.Length + 2)], MetaDataComputation.None, out var tmp))
return null;
@ -350,7 +353,7 @@ internal unsafe partial record ResolveContext(
_ => string.Empty,
}
+ item.Name;
return new ResourceNode.UiData(name, ChangedItemDrawer.GetCategoryIcon(item.Name, item));
return new ResourceNode.UiData(name, item.Type.GetCategoryIcon().ToFlag());
}
var dataFromPath = GuessUiDataFromPath(gamePath);
@ -358,8 +361,8 @@ internal unsafe partial record ResolveContext(
return dataFromPath;
return isEquipment
? new ResourceNode.UiData(Slot.ToName(), ChangedItemDrawer.GetCategoryIcon(Slot.ToSlot()))
: new ResourceNode.UiData(null, ChangedItemDrawer.ChangedItemIcon.Unknown);
? new ResourceNode.UiData(Slot.ToName(), Slot.ToEquipType().GetCategoryIcon().ToFlag())
: new ResourceNode.UiData(null, ChangedItemIconFlag.Unknown);
}
internal ResourceNode.UiData GuessUiDataFromPath(Utf8GamePath gamePath)
@ -367,13 +370,13 @@ internal unsafe partial record ResolveContext(
foreach (var obj in Global.Identifier.Identify(gamePath.ToString()))
{
var name = obj.Key;
if (name.StartsWith("Customization:"))
if (obj.Value is IdentifiedCustomization)
name = name[14..].Trim();
if (name != "Unknown")
return new ResourceNode.UiData(name, ChangedItemDrawer.GetCategoryIcon(obj.Key, obj.Value));
return new ResourceNode.UiData(name, obj.Value.GetIcon().ToFlag());
}
return new ResourceNode.UiData(null, ChangedItemDrawer.ChangedItemIcon.Unknown);
return new ResourceNode.UiData(null, ChangedItemIconFlag.Unknown);
}
private static string? SafeGet(ReadOnlySpan<string> array, Index index)