mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-01-02 05:43:42 +01:00
Add some migration things.
This commit is contained in:
parent
0d939b12f4
commit
56e284a99e
17 changed files with 515 additions and 80 deletions
|
|
@ -35,7 +35,7 @@ public sealed unsafe class LoadAreaVfx : FastHook<LoadAreaVfx.Delegate>
|
|||
var last = _state.SetAnimationData(newData);
|
||||
_crashHandler.LogAnimation(newData.AssociatedGameObject, newData.ModCollection, AnimationInvocationType.LoadAreaVfx);
|
||||
var ret = Task.Result.Original(vfxId, pos, caster, unk1, unk2, unk3);
|
||||
Penumbra.Log.Information(
|
||||
Penumbra.Log.Excessive(
|
||||
$"[Load Area VFX] Invoked with {vfxId}, [{pos[0]} {pos[1]} {pos[2]}], 0x{(nint)caster:X}, {unk1}, {unk2}, {unk3} -> 0x{ret:X}.");
|
||||
_state.RestoreAnimationData(last);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -94,9 +94,6 @@ public unsafe class ResourceLoader : IDisposable, IService
|
|||
|
||||
CompareHash(ComputeHash(path.Path, parameters), hash, path);
|
||||
|
||||
if (path.ToString() == "vfx/common/eff/abi_cnj022g.avfx")
|
||||
;
|
||||
|
||||
// If no replacements are being made, we still want to be able to trigger the event.
|
||||
var (resolvedPath, data) = _incMode.Value
|
||||
? (null, ResolveData.Invalid)
|
||||
|
|
|
|||
|
|
@ -81,11 +81,12 @@ internal partial record ResolveContext
|
|||
// Resolving a material path through the game's code can dereference null pointers for materials that involve IMC metadata.
|
||||
return ModelType switch
|
||||
{
|
||||
ModelType.Human when SlotIndex < 10 && mtrlFileName[8] != (byte)'b' => ResolveEquipmentMaterialPath(modelPath, imc, mtrlFileName),
|
||||
ModelType.DemiHuman => ResolveEquipmentMaterialPath(modelPath, imc, mtrlFileName),
|
||||
ModelType.Weapon => ResolveWeaponMaterialPath(modelPath, imc, mtrlFileName),
|
||||
ModelType.Monster => ResolveMonsterMaterialPath(modelPath, imc, mtrlFileName),
|
||||
_ => ResolveMaterialPathNative(mtrlFileName),
|
||||
ModelType.Human when SlotIndex is < 10 or 16 && mtrlFileName[8] != (byte)'b'
|
||||
=> ResolveEquipmentMaterialPath(modelPath, imc, mtrlFileName),
|
||||
ModelType.DemiHuman => ResolveEquipmentMaterialPath(modelPath, imc, mtrlFileName),
|
||||
ModelType.Weapon => ResolveWeaponMaterialPath(modelPath, imc, mtrlFileName),
|
||||
ModelType.Monster => ResolveMonsterMaterialPath(modelPath, imc, mtrlFileName),
|
||||
_ => ResolveMaterialPathNative(mtrlFileName),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -96,7 +97,7 @@ internal partial record ResolveContext
|
|||
var fileName = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(mtrlFileName);
|
||||
|
||||
Span<byte> pathBuffer = stackalloc byte[260];
|
||||
pathBuffer = AssembleMaterialPath(pathBuffer, modelPath.Path.Span, variant, fileName);
|
||||
pathBuffer = AssembleMaterialPath(pathBuffer, modelPath.Path.Span, variant, fileName);
|
||||
|
||||
return Utf8GamePath.FromSpan(pathBuffer, out var path) ? path.Clone() : Utf8GamePath.Empty;
|
||||
}
|
||||
|
|
@ -126,7 +127,7 @@ internal partial record ResolveContext
|
|||
WriteZeroPaddedNumber(mirroredFileName[4..8], mirroredSetId);
|
||||
|
||||
Span<byte> pathBuffer = stackalloc byte[260];
|
||||
pathBuffer = AssembleMaterialPath(pathBuffer, modelPath.Path.Span, variant, mirroredFileName);
|
||||
pathBuffer = AssembleMaterialPath(pathBuffer, modelPath.Path.Span, variant, mirroredFileName);
|
||||
|
||||
var weaponPosition = pathBuffer.IndexOf("/weapon/w"u8);
|
||||
if (weaponPosition >= 0)
|
||||
|
|
@ -145,7 +146,7 @@ internal partial record ResolveContext
|
|||
var fileName = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(mtrlFileName);
|
||||
|
||||
Span<byte> pathBuffer = stackalloc byte[260];
|
||||
pathBuffer = AssembleMaterialPath(pathBuffer, modelPath.Path.Span, variant, fileName);
|
||||
pathBuffer = AssembleMaterialPath(pathBuffer, modelPath.Path.Span, variant, fileName);
|
||||
|
||||
return Utf8GamePath.FromSpan(pathBuffer, out var path) ? path.Clone() : Utf8GamePath.Empty;
|
||||
}
|
||||
|
|
@ -166,7 +167,8 @@ internal partial record ResolveContext
|
|||
return entry.MaterialId;
|
||||
}
|
||||
|
||||
private static Span<byte> AssembleMaterialPath(Span<byte> materialPathBuffer, ReadOnlySpan<byte> modelPath, byte variant, ReadOnlySpan<byte> mtrlFileName)
|
||||
private static Span<byte> AssembleMaterialPath(Span<byte> materialPathBuffer, ReadOnlySpan<byte> modelPath, byte variant,
|
||||
ReadOnlySpan<byte> mtrlFileName)
|
||||
{
|
||||
var modelPosition = modelPath.IndexOf("/model/"u8);
|
||||
if (modelPosition < 0)
|
||||
|
|
@ -187,8 +189,8 @@ internal partial record ResolveContext
|
|||
{
|
||||
for (var i = destination.Length; i-- > 0;)
|
||||
{
|
||||
destination[i] = (byte)('0' + number % 10);
|
||||
number /= 10;
|
||||
destination[i] = (byte)('0' + number % 10);
|
||||
number /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -197,13 +199,17 @@ internal partial record ResolveContext
|
|||
ByteString? path;
|
||||
try
|
||||
{
|
||||
Penumbra.Log.Information($"{(nint)CharacterBase:X} {ModelType} {SlotIndex} 0x{(ulong)mtrlFileName:X}");
|
||||
Penumbra.Log.Information($"{new ByteString(mtrlFileName)}");
|
||||
path = CharacterBase->ResolveMtrlPathAsByteString(SlotIndex, mtrlFileName);
|
||||
}
|
||||
catch (AccessViolationException)
|
||||
{
|
||||
Penumbra.Log.Error($"Access violation during attempt to resolve material path\nDraw object: {(nint)CharacterBase:X} (of type {ModelType})\nSlot index: {SlotIndex}\nMaterial file name: {(nint)mtrlFileName:X} ({new string((sbyte*)mtrlFileName)})");
|
||||
Penumbra.Log.Error(
|
||||
$"Access violation during attempt to resolve material path\nDraw object: {(nint)CharacterBase:X} (of type {ModelType})\nSlot index: {SlotIndex}\nMaterial file name: {(nint)mtrlFileName:X} ({new string((sbyte*)mtrlFileName)})");
|
||||
return Utf8GamePath.Empty;
|
||||
}
|
||||
|
||||
return Utf8GamePath.FromByteString(path, out var gamePath) ? gamePath : Utf8GamePath.Empty;
|
||||
}
|
||||
|
||||
|
|
@ -235,30 +241,23 @@ internal partial record ResolveContext
|
|||
var characterRaceCode = (GenderRace)human->RaceSexId;
|
||||
switch (partialSkeletonIndex)
|
||||
{
|
||||
case 0:
|
||||
return (characterRaceCode, "base", 1);
|
||||
case 0: return (characterRaceCode, "base", 1);
|
||||
case 1:
|
||||
var faceId = human->FaceId;
|
||||
var tribe = human->Customize[(int)Dalamud.Game.ClientState.Objects.Enums.CustomizeIndex.Tribe];
|
||||
var modelType = human->Customize[(int)Dalamud.Game.ClientState.Objects.Enums.CustomizeIndex.ModelType];
|
||||
if (faceId < 201)
|
||||
{
|
||||
faceId -= tribe switch
|
||||
{
|
||||
0xB when modelType == 4 => 100,
|
||||
0xE | 0xF => 100,
|
||||
_ => 0,
|
||||
};
|
||||
}
|
||||
return ResolveHumanExtraSkeletonData(characterRaceCode, EstType.Face, faceId);
|
||||
case 2:
|
||||
return ResolveHumanExtraSkeletonData(characterRaceCode, EstType.Hair, human->HairId);
|
||||
case 3:
|
||||
return ResolveHumanEquipmentSkeletonData(EquipSlot.Head, EstType.Head);
|
||||
case 4:
|
||||
return ResolveHumanEquipmentSkeletonData(EquipSlot.Body, EstType.Body);
|
||||
default:
|
||||
return (0, string.Empty, 0);
|
||||
case 2: return ResolveHumanExtraSkeletonData(characterRaceCode, EstType.Hair, human->HairId);
|
||||
case 3: return ResolveHumanEquipmentSkeletonData(EquipSlot.Head, EstType.Head);
|
||||
case 4: return ResolveHumanEquipmentSkeletonData(EquipSlot.Body, EstType.Body);
|
||||
default: return (0, string.Empty, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -269,7 +268,8 @@ internal partial record ResolveContext
|
|||
return ResolveHumanExtraSkeletonData(ResolveEqdpRaceCode(slot, equipment.Set), type, equipment.Set);
|
||||
}
|
||||
|
||||
private (GenderRace RaceCode, string Slot, PrimaryId Set) ResolveHumanExtraSkeletonData(GenderRace raceCode, EstType type, PrimaryId primary)
|
||||
private (GenderRace RaceCode, string Slot, PrimaryId Set) ResolveHumanExtraSkeletonData(GenderRace raceCode, EstType type,
|
||||
PrimaryId primary)
|
||||
{
|
||||
var metaCache = Global.Collection.MetaCache;
|
||||
var skeletonSet = metaCache?.GetEstEntry(type, raceCode, primary) ?? default;
|
||||
|
|
|
|||
|
|
@ -73,11 +73,11 @@ public class ResourceTree
|
|||
|
||||
var genericContext = globalContext.CreateContext(model);
|
||||
|
||||
for (var i = 0; i < model->SlotCount; ++i)
|
||||
for (var i = 0u; i < model->SlotCount; ++i)
|
||||
{
|
||||
var slotContext = i < equipment.Length
|
||||
? globalContext.CreateContext(model, (uint)i, ((uint)i).ToEquipSlot(), equipment[i])
|
||||
: globalContext.CreateContext(model, (uint)i);
|
||||
? globalContext.CreateContext(model, i, i.ToEquipSlot(), equipment[(int)i])
|
||||
: globalContext.CreateContext(model, i);
|
||||
|
||||
var imc = (ResourceHandle*)model->IMCArray[i];
|
||||
var imcNode = slotContext.CreateNodeFromImc(imc);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue