Fix issues with accessories and with gender-locked gear.

This commit is contained in:
Ottermandias 2023-01-01 23:32:54 +01:00
parent 070d73a5a1
commit bc3a55eded
3 changed files with 54 additions and 17 deletions

View file

@ -34,7 +34,7 @@ public static class EquipmentSwap
swaps.Add( eqp );
}
var gmp = CreateGmp( manips, slotFrom, idFrom, idTo);
var gmp = CreateGmp( manips, slotFrom, idFrom, idTo );
if( gmp != null )
{
swaps.Add( gmp );
@ -52,9 +52,19 @@ public static class EquipmentSwap
_ => ( EstManipulation.EstType )0,
};
var skipFemale = false;
var skipMale = false;
var mtrlVariantTo = imcFileTo.GetEntry( ImcFile.PartIndex( slotFrom ), variantTo ).MaterialId;
foreach( var gr in Enum.GetValues< GenderRace >() )
{
switch( gr.Split().Item1 )
{
case Gender.Male when skipMale: continue;
case Gender.Female when skipFemale: continue;
case Gender.MaleNpc when skipMale: continue;
case Gender.FemaleNpc when skipFemale: continue;
}
if( CharacterUtility.EqdpIdx( gr, isAccessory ) < 0 )
{
continue;
@ -66,10 +76,26 @@ public static class EquipmentSwap
swaps.Add( est );
}
var eqdp = CreateEqdp( redirections, manips, slotFrom, gr, idFrom, idTo, mtrlVariantTo );
if( eqdp != null )
try
{
swaps.Add( eqdp );
var eqdp = CreateEqdp( redirections, manips, slotFrom, gr, idFrom, idTo, mtrlVariantTo );
if( eqdp != null )
{
swaps.Add( eqdp );
}
}
catch( ItemSwap.MissingFileException e )
{
switch( gr )
{
case GenderRace.MidlanderMale when e.Type == ResourceType.Mdl:
skipMale = true;
continue;
case GenderRace.MidlanderFemale when e.Type == ResourceType.Mdl:
skipFemale = true;
continue;
default: throw;
}
}
}
@ -79,7 +105,6 @@ public static class EquipmentSwap
swaps.Add( imc );
}
return affectedItems;
}
@ -106,8 +131,9 @@ public static class EquipmentSwap
public static FileSwap CreateMdl( Func< Utf8GamePath, FullPath > redirections, EquipSlot slot, GenderRace gr, SetId idFrom, SetId idTo, byte mtrlTo )
{
var mdlPathFrom = GamePaths.Equipment.Mdl.Path( idFrom, gr, slot );
var mdlPathTo = GamePaths.Equipment.Mdl.Path( idTo, gr, slot );
var accessory = slot.IsAccessory();
var mdlPathFrom = accessory ? GamePaths.Accessory.Mdl.Path( idFrom, gr, slot ) : GamePaths.Equipment.Mdl.Path( idFrom, gr, slot );
var mdlPathTo = accessory ? GamePaths.Accessory.Mdl.Path( idTo, gr, slot ) : GamePaths.Equipment.Mdl.Path( idTo, gr, slot );
var mdl = FileSwap.CreateSwap( ResourceType.Mdl, redirections, mdlPathFrom, mdlPathTo );
foreach( ref var fileName in mdl.AsMdl()!.Materials.AsSpan() )
@ -292,7 +318,7 @@ public static class EquipmentSwap
}
var newPath = ItemSwap.ReplaceAnyId( path, prefix, idFrom );
newPath = ItemSwap.AddSuffix( newPath, ".tex", $"_{Path.GetFileName( texture.Path ).GetStableHashCode():x8}", true );
newPath = ItemSwap.AddSuffix( newPath, ".tex", $"_{Path.GetFileName( texture.Path ).GetStableHashCode():x8}" );
if( newPath != path )
{
texture.Path = addedDashes ? newPath.Replace( "--", string.Empty ) : newPath;
@ -311,7 +337,7 @@ public static class EquipmentSwap
public static FileSwap CreateAtex( Func< Utf8GamePath, FullPath > redirections, ref string filePath, ref bool dataWasChanged )
{
var oldPath = filePath;
filePath = ItemSwap.AddSuffix( filePath, ".atex", $"_{Path.GetFileName( filePath ).GetStableHashCode():x8}", true );
filePath = ItemSwap.AddSuffix( filePath, ".atex", $"_{Path.GetFileName( filePath ).GetStableHashCode():x8}" );
dataWasChanged = true;
return FileSwap.CreateSwap( ResourceType.Atex, redirections, filePath, oldPath, oldPath );

View file

@ -23,6 +23,15 @@ public static class ItemSwap
public class IdUnavailableException : Exception
{ }
public class MissingFileException : Exception
{
public readonly ResourceType Type;
public MissingFileException( ResourceType type, object path )
: base($"Could not load {type} File Data for \"{path}\".")
=> Type = type;
}
private static bool LoadFile( FullPath path, out byte[] data )
{
if( path.FullName.Length > 0 )

View file

@ -7,6 +7,7 @@ using System.IO;
using System.Linq;
using System.Security.Cryptography;
using Penumbra.GameData.Enums;
using static Penumbra.Mods.ItemSwap.ItemSwap;
namespace Penumbra.Mods.ItemSwap;
@ -63,7 +64,7 @@ public sealed class FileSwap : Swap
public ResourceType Type;
/// <summary> The binary or parsed data of the file at SwapToModded. </summary>
public IWritable FileData = ItemSwap.GenericFile.Invalid;
public IWritable FileData = GenericFile.Invalid;
/// <summary> The path that would be requested without manipulated parent files. </summary>
public string SwapFromPreChangePath = string.Empty;
@ -114,12 +115,13 @@ public sealed class FileSwap : Swap
/// <param name="swapToRequest">The unmodded path to the file the game is supposed to load instead.</param>
/// <param name="swap">A full swap container with the actual file in memory.</param>
/// <returns>True if everything could be read correctly, false otherwise.</returns>
public static FileSwap CreateSwap( ResourceType type, Func< Utf8GamePath, FullPath > redirections, string swapFromRequest, string swapToRequest, string? swapFromPreChange = null )
public static FileSwap CreateSwap( ResourceType type, Func< Utf8GamePath, FullPath > redirections, string swapFromRequest, string swapToRequest,
string? swapFromPreChange = null )
{
var swap = new FileSwap
{
Type = type,
FileData = ItemSwap.GenericFile.Invalid,
FileData = GenericFile.Invalid,
DataWasChanged = false,
SwapFromPreChangePath = swapFromPreChange ?? swapFromRequest,
SwapFromChanged = swapFromPreChange != swapFromRequest,
@ -142,10 +144,10 @@ public sealed class FileSwap : Swap
swap.FileData = type switch
{
ResourceType.Mdl => ItemSwap.LoadMdl( swap.SwapToModded, out var f ) ? f : throw new Exception( $"Could not load file data for {swap.SwapToModded}." ),
ResourceType.Mtrl => ItemSwap.LoadMtrl( swap.SwapToModded, out var f ) ? f : throw new Exception( $"Could not load file data for {swap.SwapToModded}." ),
ResourceType.Avfx => ItemSwap.LoadAvfx( swap.SwapToModded, out var f ) ? f : throw new Exception( $"Could not load file data for {swap.SwapToModded}." ),
_ => ItemSwap.LoadFile( swap.SwapToModded, out var f ) ? f : throw new Exception( $"Could not load file data for {swap.SwapToModded}." ),
ResourceType.Mdl => LoadMdl( swap.SwapToModded, out var f ) ? f : throw new MissingFileException( type, swap.SwapToModded ),
ResourceType.Mtrl => LoadMtrl( swap.SwapToModded, out var f ) ? f : throw new MissingFileException( type, swap.SwapToModded ),
ResourceType.Avfx => LoadAvfx( swap.SwapToModded, out var f ) ? f : throw new MissingFileException( type, swap.SwapToModded ),
_ => LoadFile( swap.SwapToModded, out var f ) ? f : throw new MissingFileException( type, swap.SwapToModded ),
};
return swap;
@ -166,7 +168,7 @@ public sealed class FileSwap : Swap
var name =
$"{( oldFilename.StartsWith( "--" ) ? "--" : string.Empty )}{string.Join( null, hash.Select( c => c.ToString( "x2" ) ) )}.{swap.Type.ToString().ToLowerInvariant()}";
var newPath = path.Replace( oldFilename, name );
var newSwap = CreateSwap( swap.Type, redirections, newPath, swap.SwapToRequestPath.ToString());
var newSwap = CreateSwap( swap.Type, redirections, newPath, swap.SwapToRequestPath.ToString() );
path = newPath;
dataWasChanged = true;