mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Final fixes for GameData.
This commit is contained in:
parent
702f8e3967
commit
ea40d5bc9c
20 changed files with 133 additions and 153 deletions
|
|
@ -29,7 +29,7 @@ namespace Penumbra.GameData.Enums
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static partial class GameData
|
public static partial class Names
|
||||||
{
|
{
|
||||||
public static readonly Dictionary< string, BodySlot > StringToBodySlot = new()
|
public static readonly Dictionary< string, BodySlot > StringToBodySlot = new()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ namespace Penumbra.GameData.Enums
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static partial class GameData
|
public static partial class Names
|
||||||
{
|
{
|
||||||
public static readonly Dictionary< string, CustomizationType > SuffixToCustomizationType = new()
|
public static readonly Dictionary< string, CustomizationType > SuffixToCustomizationType = new()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ namespace Penumbra.GameData.Enums
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static partial class GameData
|
public static partial class Names
|
||||||
{
|
{
|
||||||
public static readonly Dictionary< string, EquipSlot > SuffixToEquipSlot = new()
|
public static readonly Dictionary< string, EquipSlot > SuffixToEquipSlot = new()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ namespace Penumbra.GameData.Enums
|
||||||
Environment,
|
Environment,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static partial class GameData
|
public static partial class Names
|
||||||
{
|
{
|
||||||
public static readonly Dictionary< string, FileType > ExtensionToFileType = new()
|
public static readonly Dictionary< string, FileType > ExtensionToFileType = new()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ namespace Penumbra.GameData.Enums
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static partial class GameData
|
public static partial class Names
|
||||||
{
|
{
|
||||||
public static GenderRace GenderRaceFromCode( string code )
|
public static GenderRace GenderRaceFromCode( string code )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
49
Penumbra.GameData/GameData.cs
Normal file
49
Penumbra.GameData/GameData.cs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
using Lumina.Excel.GeneratedSheets;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
|
using Penumbra.GameData.Util;
|
||||||
|
|
||||||
|
namespace Penumbra.GameData
|
||||||
|
{
|
||||||
|
public static class GameData
|
||||||
|
{
|
||||||
|
internal static ObjectIdentification? Identification;
|
||||||
|
internal static readonly GamePathParser GamePathParser = new();
|
||||||
|
|
||||||
|
public static IObjectIdentifier GetIdentifier( DalamudPluginInterface pi )
|
||||||
|
{
|
||||||
|
Identification ??= new ObjectIdentification( pi );
|
||||||
|
return Identification;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IObjectIdentifier GetIdentifier( )
|
||||||
|
{
|
||||||
|
if( Identification == null )
|
||||||
|
{
|
||||||
|
throw new Exception( "Object Identification was not initialized." );
|
||||||
|
}
|
||||||
|
return Identification;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IGamePathParser GetGamePathParser()
|
||||||
|
=> GamePathParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IObjectIdentifier
|
||||||
|
{
|
||||||
|
public void Identify( IDictionary< string, object? > set, GamePath path );
|
||||||
|
|
||||||
|
public Dictionary< string, object? > Identify( GamePath path );
|
||||||
|
public Item? Identify( SetId setId, WeaponType weaponType, ushort variant, EquipSlot slot );
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IGamePathParser
|
||||||
|
{
|
||||||
|
public ObjectType PathToObjectType( GamePath path );
|
||||||
|
public GameObjectInfo GetFileInfo( GamePath path );
|
||||||
|
public string VfxToKey( GamePath path );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,7 @@ using Penumbra.GameData.Util;
|
||||||
|
|
||||||
namespace Penumbra.GameData
|
namespace Penumbra.GameData
|
||||||
{
|
{
|
||||||
public static class GamePathParser
|
internal class GamePathParser : IGamePathParser
|
||||||
{
|
{
|
||||||
private const string CharacterFolder = "chara";
|
private const string CharacterFolder = "chara";
|
||||||
private const string EquipmentFolder = "equipment";
|
private const string EquipmentFolder = "equipment";
|
||||||
|
|
@ -31,7 +31,7 @@ namespace Penumbra.GameData
|
||||||
private const string WorldFolder2 = "bg";
|
private const string WorldFolder2 = "bg";
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
private static readonly Dictionary<FileType, Dictionary<ObjectType, Regex[]>> Regexes = new()
|
private readonly Dictionary<FileType, Dictionary<ObjectType, Regex[]>> _regexes = new()
|
||||||
{ { FileType.Font, new Dictionary< ObjectType, Regex[] >(){ { ObjectType.Font, new Regex[]{ new(@"common/font/(?'fontname'.*)_(?'id'\d\d)(_lobby)?\.fdt") } } } }
|
{ { FileType.Font, new Dictionary< ObjectType, Regex[] >(){ { ObjectType.Font, new Regex[]{ new(@"common/font/(?'fontname'.*)_(?'id'\d\d)(_lobby)?\.fdt") } } } }
|
||||||
, { FileType.Texture, new Dictionary< ObjectType, Regex[] >()
|
, { FileType.Texture, new Dictionary< ObjectType, Regex[] >()
|
||||||
{ { ObjectType.Icon, new Regex[]{ new(@"ui/icon/(?'group'\d*)(/(?'lang'[a-z]{2}))?(/(?'hq'hq))?/(?'id'\d*)\.tex") } }
|
{ { ObjectType.Icon, new Regex[]{ new(@"ui/icon/(?'group'\d*)(/(?'lang'[a-z]{2}))?(/(?'hq'hq))?/(?'id'\d*)\.tex") } }
|
||||||
|
|
@ -68,7 +68,7 @@ namespace Penumbra.GameData
|
||||||
};
|
};
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
public static ObjectType PathToObjectType( GamePath path )
|
public ObjectType PathToObjectType( GamePath path )
|
||||||
{
|
{
|
||||||
if( path.Empty )
|
if( path.Empty )
|
||||||
{
|
{
|
||||||
|
|
@ -120,16 +120,16 @@ namespace Penumbra.GameData
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static (FileType, ObjectType, Match?) ParseGamePath( GamePath path )
|
private (FileType, ObjectType, Match?) ParseGamePath( GamePath path )
|
||||||
{
|
{
|
||||||
if( !GameData.Enums.GameData.ExtensionToFileType.TryGetValue( Extension( path ), out var fileType ) )
|
if( !Enums.Names.ExtensionToFileType.TryGetValue( Extension( path ), out var fileType ) )
|
||||||
{
|
{
|
||||||
fileType = FileType.Unknown;
|
fileType = FileType.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
var objectType = PathToObjectType( path );
|
var objectType = PathToObjectType( path );
|
||||||
|
|
||||||
if( !Regexes.TryGetValue( fileType, out var objectDict ) )
|
if( !_regexes.TryGetValue( fileType, out var objectDict ) )
|
||||||
{
|
{
|
||||||
return ( fileType, objectType, null );
|
return ( fileType, objectType, null );
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +157,7 @@ namespace Penumbra.GameData
|
||||||
return extIdx < 0 ? "" : filename.Substring( extIdx );
|
return extIdx < 0 ? "" : filename.Substring( extIdx );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GameObjectInfo HandleEquipment( FileType fileType, ObjectType objectType, GroupCollection groups )
|
private static GameObjectInfo HandleEquipment( FileType fileType, GroupCollection groups )
|
||||||
{
|
{
|
||||||
var setId = ushort.Parse( groups[ "id" ].Value );
|
var setId = ushort.Parse( groups[ "id" ].Value );
|
||||||
if( fileType == FileType.Imc )
|
if( fileType == FileType.Imc )
|
||||||
|
|
@ -165,8 +165,8 @@ namespace Penumbra.GameData
|
||||||
return GameObjectInfo.Equipment( fileType, setId );
|
return GameObjectInfo.Equipment( fileType, setId );
|
||||||
}
|
}
|
||||||
|
|
||||||
var gr = GameData.Enums.GameData.GenderRaceFromCode( groups[ "race" ].Value );
|
var gr = Enums.Names.GenderRaceFromCode( groups[ "race" ].Value );
|
||||||
var slot = GameData.Enums.GameData.SuffixToEquipSlot[ groups[ "slot" ].Value ];
|
var slot = Enums.Names.SuffixToEquipSlot[ groups[ "slot" ].Value ];
|
||||||
if( fileType == FileType.Model )
|
if( fileType == FileType.Model )
|
||||||
{
|
{
|
||||||
return GameObjectInfo.Equipment( fileType, setId, gr, slot );
|
return GameObjectInfo.Equipment( fileType, setId, gr, slot );
|
||||||
|
|
@ -176,7 +176,7 @@ namespace Penumbra.GameData
|
||||||
return GameObjectInfo.Equipment( fileType, setId, gr, slot, variant );
|
return GameObjectInfo.Equipment( fileType, setId, gr, slot, variant );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GameObjectInfo HandleWeapon( FileType fileType, ObjectType objectType, GroupCollection groups )
|
private static GameObjectInfo HandleWeapon( FileType fileType, GroupCollection groups )
|
||||||
{
|
{
|
||||||
var weaponId = ushort.Parse( groups[ "weapon" ].Value );
|
var weaponId = ushort.Parse( groups[ "weapon" ].Value );
|
||||||
var setId = ushort.Parse( groups[ "id" ].Value );
|
var setId = ushort.Parse( groups[ "id" ].Value );
|
||||||
|
|
@ -189,7 +189,7 @@ namespace Penumbra.GameData
|
||||||
return GameObjectInfo.Weapon( fileType, setId, weaponId, variant );
|
return GameObjectInfo.Weapon( fileType, setId, weaponId, variant );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GameObjectInfo HandleMonster( FileType fileType, ObjectType objectType, GroupCollection groups )
|
private static GameObjectInfo HandleMonster( FileType fileType, GroupCollection groups )
|
||||||
{
|
{
|
||||||
var monsterId = ushort.Parse( groups[ "monster" ].Value );
|
var monsterId = ushort.Parse( groups[ "monster" ].Value );
|
||||||
var bodyId = ushort.Parse( groups[ "id" ].Value );
|
var bodyId = ushort.Parse( groups[ "id" ].Value );
|
||||||
|
|
@ -202,7 +202,7 @@ namespace Penumbra.GameData
|
||||||
return GameObjectInfo.Monster( fileType, monsterId, bodyId, variant );
|
return GameObjectInfo.Monster( fileType, monsterId, bodyId, variant );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GameObjectInfo HandleDemiHuman( FileType fileType, ObjectType objectType, GroupCollection groups )
|
private static GameObjectInfo HandleDemiHuman( FileType fileType, GroupCollection groups )
|
||||||
{
|
{
|
||||||
var demiHumanId = ushort.Parse( groups[ "id" ].Value );
|
var demiHumanId = ushort.Parse( groups[ "id" ].Value );
|
||||||
var equipId = ushort.Parse( groups[ "equip" ].Value );
|
var equipId = ushort.Parse( groups[ "equip" ].Value );
|
||||||
|
|
@ -211,7 +211,7 @@ namespace Penumbra.GameData
|
||||||
return GameObjectInfo.DemiHuman( fileType, demiHumanId, equipId );
|
return GameObjectInfo.DemiHuman( fileType, demiHumanId, equipId );
|
||||||
}
|
}
|
||||||
|
|
||||||
var slot = GameData.Enums.GameData.SuffixToEquipSlot[ groups[ "slot" ].Value ];
|
var slot = Enums.Names.SuffixToEquipSlot[ groups[ "slot" ].Value ];
|
||||||
if( fileType == FileType.Model )
|
if( fileType == FileType.Model )
|
||||||
{
|
{
|
||||||
return GameObjectInfo.DemiHuman( fileType, demiHumanId, equipId, slot );
|
return GameObjectInfo.DemiHuman( fileType, demiHumanId, equipId, slot );
|
||||||
|
|
@ -221,7 +221,7 @@ namespace Penumbra.GameData
|
||||||
return GameObjectInfo.DemiHuman( fileType, demiHumanId, equipId, slot, variant );
|
return GameObjectInfo.DemiHuman( fileType, demiHumanId, equipId, slot, variant );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GameObjectInfo HandleCustomization( FileType fileType, ObjectType objectType, GroupCollection groups )
|
private static GameObjectInfo HandleCustomization( FileType fileType, GroupCollection groups )
|
||||||
{
|
{
|
||||||
if( groups[ "skin" ].Success )
|
if( groups[ "skin" ].Success )
|
||||||
{
|
{
|
||||||
|
|
@ -236,9 +236,11 @@ namespace Penumbra.GameData
|
||||||
return GameObjectInfo.Customization( fileType, tmpType, id );
|
return GameObjectInfo.Customization( fileType, tmpType, id );
|
||||||
}
|
}
|
||||||
|
|
||||||
var gr = GameData.Enums.GameData.GenderRaceFromCode( groups[ "race" ].Value );
|
var gr = Enums.Names.GenderRaceFromCode( groups[ "race" ].Value );
|
||||||
var bodySlot = GameData.Enums.GameData.StringToBodySlot[ groups[ "type" ].Value ];
|
var bodySlot = Enums.Names.StringToBodySlot[ groups[ "type" ].Value ];
|
||||||
var type = groups[ "slot" ].Success ? GameData.Enums.GameData.SuffixToCustomizationType[ groups[ "slot" ].Value ] : CustomizationType.Skin;
|
var type = groups[ "slot" ].Success
|
||||||
|
? Enums.Names.SuffixToCustomizationType[ groups[ "slot" ].Value ]
|
||||||
|
: CustomizationType.Skin;
|
||||||
if( fileType == FileType.Material )
|
if( fileType == FileType.Material )
|
||||||
{
|
{
|
||||||
var variant = byte.Parse( groups[ "variant" ].Value );
|
var variant = byte.Parse( groups[ "variant" ].Value );
|
||||||
|
|
@ -248,7 +250,7 @@ namespace Penumbra.GameData
|
||||||
return GameObjectInfo.Customization( fileType, type, id, gr, bodySlot );
|
return GameObjectInfo.Customization( fileType, type, id, gr, bodySlot );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GameObjectInfo HandleIcon( FileType fileType, ObjectType objectType, GroupCollection groups )
|
private static GameObjectInfo HandleIcon( FileType fileType, GroupCollection groups )
|
||||||
{
|
{
|
||||||
var hq = groups[ "hq" ].Success;
|
var hq = groups[ "hq" ].Success;
|
||||||
var id = uint.Parse( groups[ "id" ].Value );
|
var id = uint.Parse( groups[ "id" ].Value );
|
||||||
|
|
@ -268,7 +270,7 @@ namespace Penumbra.GameData
|
||||||
return GameObjectInfo.Icon( fileType, id, hq, language );
|
return GameObjectInfo.Icon( fileType, id, hq, language );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GameObjectInfo HandleMap( FileType fileType, ObjectType objectType, GroupCollection groups )
|
private static GameObjectInfo HandleMap( FileType fileType, GroupCollection groups )
|
||||||
{
|
{
|
||||||
var map = Encoding.ASCII.GetBytes( groups[ "id" ].Value );
|
var map = Encoding.ASCII.GetBytes( groups[ "id" ].Value );
|
||||||
var variant = byte.Parse( groups[ "variant" ].Value );
|
var variant = byte.Parse( groups[ "variant" ].Value );
|
||||||
|
|
@ -281,7 +283,7 @@ namespace Penumbra.GameData
|
||||||
return GameObjectInfo.Map( fileType, map[ 0 ], map[ 1 ], map[ 2 ], map[ 3 ], variant );
|
return GameObjectInfo.Map( fileType, map[ 0 ], map[ 1 ], map[ 2 ], map[ 3 ], variant );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameObjectInfo GetFileInfo( GamePath path )
|
public GameObjectInfo GetFileInfo( GamePath path )
|
||||||
{
|
{
|
||||||
var (fileType, objectType, match) = ParseGamePath( path );
|
var (fileType, objectType, match) = ParseGamePath( path );
|
||||||
if( match == null || !match.Success )
|
if( match == null || !match.Success )
|
||||||
|
|
@ -294,14 +296,14 @@ namespace Penumbra.GameData
|
||||||
var groups = match.Groups;
|
var groups = match.Groups;
|
||||||
switch( objectType )
|
switch( objectType )
|
||||||
{
|
{
|
||||||
case ObjectType.Accessory: return HandleEquipment( fileType, objectType, groups );
|
case ObjectType.Accessory: return HandleEquipment( fileType, groups );
|
||||||
case ObjectType.Equipment: return HandleEquipment( fileType, objectType, groups );
|
case ObjectType.Equipment: return HandleEquipment( fileType, groups );
|
||||||
case ObjectType.Weapon: return HandleWeapon( fileType, objectType, groups );
|
case ObjectType.Weapon: return HandleWeapon( fileType, groups );
|
||||||
case ObjectType.Map: return HandleMap( fileType, objectType, groups );
|
case ObjectType.Map: return HandleMap( fileType, groups );
|
||||||
case ObjectType.Monster: return HandleMonster( fileType, objectType, groups );
|
case ObjectType.Monster: return HandleMonster( fileType, groups );
|
||||||
case ObjectType.DemiHuman: return HandleDemiHuman( fileType, objectType, groups );
|
case ObjectType.DemiHuman: return HandleDemiHuman( fileType, groups );
|
||||||
case ObjectType.Character: return HandleCustomization( fileType, objectType, groups );
|
case ObjectType.Character: return HandleCustomization( fileType, groups );
|
||||||
case ObjectType.Icon: return HandleIcon( fileType, objectType, groups );
|
case ObjectType.Icon: return HandleIcon( fileType, groups );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
|
|
@ -312,19 +314,19 @@ namespace Penumbra.GameData
|
||||||
return new GameObjectInfo { FileType = fileType, ObjectType = objectType };
|
return new GameObjectInfo { FileType = fileType, ObjectType = objectType };
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Regex VfxRegexTmb = new( @"chara/action/(?'key'[^\s]+?)\.tmb" );
|
private readonly Regex _vfxRegexTmb = new( @"chara/action/(?'key'[^\s]+?)\.tmb" );
|
||||||
private static readonly Regex VfxRegexPap = new( @"chara/human/c0101/animation/a0001/[^\s]+?/(?'key'[^\s]+?)\.pap" );
|
private readonly Regex _vfxRegexPap = new( @"chara/human/c0101/animation/a0001/[^\s]+?/(?'key'[^\s]+?)\.pap" );
|
||||||
|
|
||||||
public static string VfxToKey( GamePath path )
|
public string VfxToKey( GamePath path )
|
||||||
{
|
{
|
||||||
var match = VfxRegexTmb.Match( path );
|
var match = _vfxRegexTmb.Match( path );
|
||||||
if( match.Success )
|
if( match.Success )
|
||||||
{
|
{
|
||||||
return match.Groups[ "key" ].Value.ToLowerInvariant();
|
return match.Groups[ "key" ].Value.ToLowerInvariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
match = VfxRegexPap.Match( path );
|
match = _vfxRegexPap.Match( path );
|
||||||
return match.Success ? match.Groups[ "key" ].Value.ToLowerInvariant() : string.Empty;
|
return match.Success ? match.Groups[ "key" ].Value.ToLowerInvariant() : string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -11,7 +11,7 @@ using Race = Penumbra.GameData.Enums.Race;
|
||||||
|
|
||||||
namespace Penumbra.GameData
|
namespace Penumbra.GameData
|
||||||
{
|
{
|
||||||
internal class ObjectIdentification
|
internal class ObjectIdentification : IObjectIdentifier
|
||||||
{
|
{
|
||||||
private readonly List< (ulong, HashSet< Item >) > _weapons;
|
private readonly List< (ulong, HashSet< Item >) > _weapons;
|
||||||
private readonly List< (ulong, HashSet< Item >) > _equipment;
|
private readonly List< (ulong, HashSet< Item >) > _equipment;
|
||||||
|
|
@ -267,7 +267,7 @@ namespace Penumbra.GameData
|
||||||
|
|
||||||
private void IdentifyVfx( IDictionary< string, object? > set, GamePath path )
|
private void IdentifyVfx( IDictionary< string, object? > set, GamePath path )
|
||||||
{
|
{
|
||||||
var key = GamePathParser.VfxToKey( path );
|
var key = GameData.GamePathParser.VfxToKey( path );
|
||||||
if( key.Length == 0 || !_actions.TryGetValue( key, out var actions ) )
|
if( key.Length == 0 || !_actions.TryGetValue( key, out var actions ) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
@ -287,11 +287,18 @@ namespace Penumbra.GameData
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var info = GamePathParser.GetFileInfo( path );
|
var info = GameData.GamePathParser.GetFileInfo( path );
|
||||||
IdentifyParsed( set, info );
|
IdentifyParsed( set, info );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Dictionary< string, object? > Identify( GamePath path )
|
||||||
|
{
|
||||||
|
Dictionary< string, object? > ret = new();
|
||||||
|
Identify( ret, path );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
public Item? Identify( SetId setId, WeaponType weaponType, ushort variant, EquipSlot slot )
|
public Item? Identify( SetId setId, WeaponType weaponType, ushort variant, EquipSlot slot )
|
||||||
{
|
{
|
||||||
switch( slot )
|
switch( slot )
|
||||||
|
|
@ -313,4 +320,4 @@ namespace Penumbra.GameData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Dalamud.Plugin;
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
|
||||||
using Penumbra.GameData.Enums;
|
|
||||||
using Penumbra.GameData.Structs;
|
|
||||||
using Penumbra.GameData.Util;
|
|
||||||
|
|
||||||
namespace Penumbra.GameData
|
|
||||||
{
|
|
||||||
public static class ObjectIdentifier
|
|
||||||
{
|
|
||||||
private static ObjectIdentification? _identification = null;
|
|
||||||
|
|
||||||
public static bool Initialize( DalamudPluginInterface pi )
|
|
||||||
{
|
|
||||||
if( _identification != null )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_identification = new ObjectIdentification( pi );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch( Exception e )
|
|
||||||
{
|
|
||||||
_identification = null;
|
|
||||||
PluginLog.Error( $"Failure while initializing Object Identifier:\n{e}" );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Verify()
|
|
||||||
{
|
|
||||||
if( _identification == null )
|
|
||||||
{
|
|
||||||
throw new Exception( "Object Identifier not initialized." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Identify( IDictionary< string, object? > set, GamePath path )
|
|
||||||
{
|
|
||||||
Verify();
|
|
||||||
_identification!.Identify( set, path );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary< string, object? > Identify( GamePath path )
|
|
||||||
{
|
|
||||||
Dictionary< string, object? > ret = new();
|
|
||||||
Identify( ret, path );
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Item? Identify( SetId setId, WeaponType weaponType, ushort variant, EquipSlot slot )
|
|
||||||
{
|
|
||||||
Verify();
|
|
||||||
return _identification!.Identify( setId, weaponType, variant, slot );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -123,7 +123,7 @@ namespace Penumbra.GameData.Structs
|
||||||
|
|
||||||
public GenderRace GenderRace
|
public GenderRace GenderRace
|
||||||
{
|
{
|
||||||
get => GameData.Enums.GameData.GenderRaceFromByte( _genderRaceByte );
|
get => Names.GenderRaceFromByte( _genderRaceByte );
|
||||||
set => _genderRaceByte = value.ToByte();
|
set => _genderRaceByte = value.ToByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,9 @@ namespace Penumbra.GameData.Util
|
||||||
{
|
{
|
||||||
return rhs switch
|
return rhs switch
|
||||||
{
|
{
|
||||||
string path => string.Compare( _path, path, StringComparison.InvariantCulture ),
|
string path => string.Compare( _path, path, StringComparison.InvariantCulture ),
|
||||||
GamePath path => string.Compare( _path, path._path, StringComparison.InvariantCulture ),
|
GamePath path => string.Compare( _path, path._path, StringComparison.InvariantCulture ),
|
||||||
_ => -1,
|
_ => -1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@ namespace Penumbra.GameData.Util
|
||||||
public override object ReadJson( JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer )
|
public override object ReadJson( JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer )
|
||||||
{
|
{
|
||||||
var token = JToken.Load( reader );
|
var token = JToken.Load( reader );
|
||||||
return token.ToObject<GamePath>();
|
return token.ToObject< GamePath >();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanWrite
|
public override bool CanWrite
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ namespace Penumbra.Importer
|
||||||
|
|
||||||
public Info( GamePath fileName )
|
public Info( GamePath fileName )
|
||||||
{
|
{
|
||||||
PrimaryType = GamePathParser.PathToObjectType( fileName );
|
PrimaryType = GameData.GameData.GetGamePathParser().PathToObjectType( fileName );
|
||||||
PrimaryId = 0;
|
PrimaryId = 0;
|
||||||
SecondaryType = BodySlot.Unknown;
|
SecondaryType = BodySlot.Unknown;
|
||||||
SecondaryId = 0;
|
SecondaryId = 0;
|
||||||
|
|
@ -113,14 +113,14 @@ namespace Penumbra.Importer
|
||||||
{
|
{
|
||||||
case ObjectType.Equipment:
|
case ObjectType.Equipment:
|
||||||
case ObjectType.Accessory:
|
case ObjectType.Accessory:
|
||||||
if( GameData.Enums.GameData.SuffixToEquipSlot.TryGetValue( match.Groups[ "Slot" ].Value, out var tmpSlot ) )
|
if( GameData.Enums.Names.SuffixToEquipSlot.TryGetValue( match.Groups[ "Slot" ].Value, out var tmpSlot ) )
|
||||||
{
|
{
|
||||||
EquipSlot = tmpSlot;
|
EquipSlot = tmpSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ObjectType.Character:
|
case ObjectType.Character:
|
||||||
if( GameData.Enums.GameData.SuffixToCustomizationType.TryGetValue( match.Groups[ "Slot" ].Value, out var tmpCustom ) )
|
if( GameData.Enums.Names.SuffixToCustomizationType.TryGetValue( match.Groups[ "Slot" ].Value, out var tmpCustom ) )
|
||||||
{
|
{
|
||||||
CustomizationType = tmpCustom;
|
CustomizationType = tmpCustom;
|
||||||
}
|
}
|
||||||
|
|
@ -130,7 +130,7 @@ namespace Penumbra.Importer
|
||||||
}
|
}
|
||||||
|
|
||||||
if( match.Groups[ "SecondaryType" ].Success
|
if( match.Groups[ "SecondaryType" ].Success
|
||||||
&& GameData.Enums.GameData.StringToBodySlot.TryGetValue( match.Groups[ "SecondaryType" ].Value, out SecondaryType ) )
|
&& GameData.Enums.Names.StringToBodySlot.TryGetValue( match.Groups[ "SecondaryType" ].Value, out SecondaryType ) )
|
||||||
{
|
{
|
||||||
SecondaryId = ushort.Parse( match.Groups[ "SecondaryId" ].Value );
|
SecondaryId = ushort.Parse( match.Groups[ "SecondaryId" ].Value );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ namespace Penumbra.Meta
|
||||||
|
|
||||||
public static class GmpEntryExtension
|
public static class GmpEntryExtension
|
||||||
{
|
{
|
||||||
public static GmpEntry Apply( this GmpEntry entry, MetaManipulation manipulation )
|
public static GmpEntry Apply( this ref GmpEntry entry, MetaManipulation manipulation )
|
||||||
{
|
{
|
||||||
if( manipulation.Type != MetaType.Gmp )
|
if( manipulation.Type != MetaType.Gmp )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ namespace Penumbra.Mod
|
||||||
var duplicates = FindOrCreateDuplicates( _mod );
|
var duplicates = FindOrCreateDuplicates( _mod );
|
||||||
if( !inOption1 )
|
if( !inOption1 )
|
||||||
{
|
{
|
||||||
duplicates.AddFile( relName2, relName2.ToGamePath() );
|
duplicates.AddFile( relName1, relName2.ToGamePath() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !inOption2 )
|
if( !inOption2 )
|
||||||
|
|
|
||||||
|
|
@ -31,18 +31,19 @@ namespace Penumbra.Mod
|
||||||
|
|
||||||
public void ComputeChangedItems()
|
public void ComputeChangedItems()
|
||||||
{
|
{
|
||||||
|
var identifier = GameData.GameData.GetIdentifier();
|
||||||
ChangedItems.Clear();
|
ChangedItems.Clear();
|
||||||
foreach( var file in Resources.ModFiles.Select( f => new RelPath( f, BasePath ) ) )
|
foreach( var file in Resources.ModFiles.Select( f => new RelPath( f, BasePath ) ) )
|
||||||
{
|
{
|
||||||
foreach( var path in ModFunctions.GetAllFiles( file, Meta ) )
|
foreach( var path in ModFunctions.GetAllFiles( file, Meta ) )
|
||||||
{
|
{
|
||||||
ObjectIdentifier.Identify( ChangedItems, path );
|
identifier.Identify( ChangedItems, path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach( var path in Meta.FileSwaps.Keys )
|
foreach( var path in Meta.FileSwaps.Keys )
|
||||||
{
|
{
|
||||||
ObjectIdentifier.Identify( ChangedItems, path );
|
identifier.Identify( ChangedItems, path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ namespace Penumbra.Mod
|
||||||
|
|
||||||
if( ret.Count == 0 )
|
if( ret.Count == 0 )
|
||||||
{
|
{
|
||||||
ret.Add( relPath.ToGamePath( ) );
|
ret.Add( relPath.ToGamePath() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
using System;
|
|
||||||
using Dalamud.Game.Command;
|
using Dalamud.Game.Command;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using EmbedIO;
|
using EmbedIO;
|
||||||
using EmbedIO.WebApi;
|
using EmbedIO.WebApi;
|
||||||
using Penumbra.API;
|
using Penumbra.API;
|
||||||
using Penumbra.GameData;
|
|
||||||
using Penumbra.Interop;
|
using Penumbra.Interop;
|
||||||
using Penumbra.Meta;
|
|
||||||
using Penumbra.Meta.Files;
|
using Penumbra.Meta.Files;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using Penumbra.UI;
|
using Penumbra.UI;
|
||||||
|
|
@ -41,7 +38,7 @@ namespace Penumbra
|
||||||
{
|
{
|
||||||
PluginInterface = pluginInterface;
|
PluginInterface = pluginInterface;
|
||||||
Service< DalamudPluginInterface >.Set( PluginInterface );
|
Service< DalamudPluginInterface >.Set( PluginInterface );
|
||||||
ObjectIdentifier.Initialize( PluginInterface );
|
GameData.GameData.GetIdentifier( PluginInterface );
|
||||||
|
|
||||||
Configuration = Configuration.Load( PluginInterface );
|
Configuration = Configuration.Load( PluginInterface );
|
||||||
|
|
||||||
|
|
@ -72,7 +69,7 @@ namespace Penumbra
|
||||||
SettingsInterface = new SettingsInterface( this );
|
SettingsInterface = new SettingsInterface( this );
|
||||||
|
|
||||||
PluginInterface.UiBuilder.DisableGposeUiHide = true;
|
PluginInterface.UiBuilder.DisableGposeUiHide = true;
|
||||||
PluginInterface.UiBuilder.OnBuildUi += SettingsInterface.Draw;
|
PluginInterface.UiBuilder.OnBuildUi += SettingsInterface.Draw;
|
||||||
|
|
||||||
if( Configuration.EnableHttpApi )
|
if( Configuration.EnableHttpApi )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,8 @@ namespace Penumbra.UI
|
||||||
if( ImGui.BeginTable( "##ActorTable", 13, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.ScrollX,
|
if( ImGui.BeginTable( "##ActorTable", 13, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.ScrollX,
|
||||||
new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 4 * actors.Count ) ) )
|
new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 4 * actors.Count ) ) )
|
||||||
{
|
{
|
||||||
|
var identifier = GameData.GameData.GetIdentifier( _plugin.PluginInterface );
|
||||||
|
|
||||||
foreach( var actor in actors )
|
foreach( var actor in actors )
|
||||||
{
|
{
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
|
|
@ -65,17 +67,17 @@ namespace Penumbra.UI
|
||||||
ImGui.Text( "(not set)" );
|
ImGui.Text( "(not set)" );
|
||||||
}
|
}
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( ObjectIdentifier.Identify( actor.Value.Mainhand.Set, actor.Value.Mainhand.Type, actor.Value.Mainhand.Variant, EquipSlot.MainHand )?.Name.ToString() ?? "Unknown" );
|
ImGui.Text( identifier.Identify( actor.Value.Mainhand.Set, actor.Value.Mainhand.Type, actor.Value.Mainhand.Variant, EquipSlot.MainHand )?.Name.ToString() ?? "Unknown" );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( ObjectIdentifier.Identify( actor.Value.Head.Set, actor.Value.Head.Variant, 0, EquipSlot.Head )?.Name.ToString() ?? "Unknown" );
|
ImGui.Text( identifier.Identify( actor.Value.Head.Set, actor.Value.Head.Variant, 0, EquipSlot.Head )?.Name.ToString() ?? "Unknown" );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( ObjectIdentifier.Identify( actor.Value.Body.Set, actor.Value.Body.Variant, 0, EquipSlot.Body )?.Name.ToString() ?? "Unknown" );
|
ImGui.Text( identifier.Identify( actor.Value.Body.Set, actor.Value.Body.Variant, 0, EquipSlot.Body )?.Name.ToString() ?? "Unknown" );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( ObjectIdentifier.Identify( actor.Value.Hands.Set, actor.Value.Hands.Variant, 0, EquipSlot.Hands )?.Name.ToString() ?? "Unknown" );
|
ImGui.Text( identifier.Identify( actor.Value.Hands.Set, actor.Value.Hands.Variant, 0, EquipSlot.Hands )?.Name.ToString() ?? "Unknown" );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( ObjectIdentifier.Identify( actor.Value.Legs.Set, actor.Value.Legs.Variant, 0, EquipSlot.Legs )?.Name.ToString() ?? "Unknown" );
|
ImGui.Text( identifier.Identify( actor.Value.Legs.Set, actor.Value.Legs.Variant, 0, EquipSlot.Legs )?.Name.ToString() ?? "Unknown" );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( ObjectIdentifier.Identify( actor.Value.Feet.Set, actor.Value.Feet.Variant, 0, EquipSlot.Feet )?.Name.ToString() ?? "Unknown" );
|
ImGui.Text( identifier.Identify( actor.Value.Feet.Set, actor.Value.Feet.Variant, 0, EquipSlot.Feet )?.Name.ToString() ?? "Unknown" );
|
||||||
|
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
@ -95,17 +97,17 @@ namespace Penumbra.UI
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( ObjectIdentifier.Identify( actor.Value.Offhand.Set, actor.Value.Offhand.Type, actor.Value.Offhand.Variant, EquipSlot.Offhand )?.Name.ToString() ?? "Unknown" );
|
ImGui.Text( identifier.Identify( actor.Value.Offhand.Set, actor.Value.Offhand.Type, actor.Value.Offhand.Variant, EquipSlot.Offhand )?.Name.ToString() ?? "Unknown" );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( ObjectIdentifier.Identify( actor.Value.Ear.Set, actor.Value.Ear.Variant, 0, EquipSlot.Ears )?.Name.ToString() ?? "Unknown" );
|
ImGui.Text( identifier.Identify( actor.Value.Ear.Set, actor.Value.Ear.Variant, 0, EquipSlot.Ears )?.Name.ToString() ?? "Unknown" );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( ObjectIdentifier.Identify( actor.Value.Neck.Set, actor.Value.Neck.Variant, 0, EquipSlot.Neck )?.Name.ToString() ?? "Unknown" );
|
ImGui.Text( identifier.Identify( actor.Value.Neck.Set, actor.Value.Neck.Variant, 0, EquipSlot.Neck )?.Name.ToString() ?? "Unknown" );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( ObjectIdentifier.Identify( actor.Value.Wrist.Set, actor.Value.Wrist.Variant, 0, EquipSlot.Wrists )?.Name.ToString() ?? "Unknown" );
|
ImGui.Text( identifier.Identify( actor.Value.Wrist.Set, actor.Value.Wrist.Variant, 0, EquipSlot.Wrists )?.Name.ToString() ?? "Unknown" );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( ObjectIdentifier.Identify( actor.Value.LFinger.Set, actor.Value.LFinger.Variant, 0, EquipSlot.RingL )?.Name.ToString() ?? "Unknown" );
|
ImGui.Text( identifier.Identify( actor.Value.LFinger.Set, actor.Value.LFinger.Variant, 0, EquipSlot.RingL )?.Name.ToString() ?? "Unknown" );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( ObjectIdentifier.Identify( actor.Value.RFinger.Set, actor.Value.RFinger.Variant, 0, EquipSlot.RingL )?.Name.ToString() ?? "Unknown" );
|
ImGui.Text( identifier.Identify( actor.Value.RFinger.Set, actor.Value.RFinger.Variant, 0, EquipSlot.RingL )?.Name.ToString() ?? "Unknown" );
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,22 +13,6 @@ using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.UI
|
namespace Penumbra.UI
|
||||||
{
|
{
|
||||||
internal static class ListRemoveExtension
|
|
||||||
{
|
|
||||||
// Remove the entry at idx from the list if the new string is empty, otherwise replace it.
|
|
||||||
public static void RemoveOrChange( this List< string > list, string newString, int idx )
|
|
||||||
{
|
|
||||||
if( newString.Length == 0 )
|
|
||||||
{
|
|
||||||
list.RemoveAt( idx );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
list[ idx ] = newString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public partial class SettingsInterface
|
public partial class SettingsInterface
|
||||||
{
|
{
|
||||||
private partial class PluginDetails
|
private partial class PluginDetails
|
||||||
|
|
|
||||||
|
|
@ -742,7 +742,7 @@ namespace Penumbra.UI
|
||||||
CustomCombo( "Equipment Slot", EqdpEquipSlots, out var equipSlot, ref _newManipEquipSlot );
|
CustomCombo( "Equipment Slot", EqdpEquipSlots, out var equipSlot, ref _newManipEquipSlot );
|
||||||
CustomCombo( "Race", Races, out var race, ref _newManipRace );
|
CustomCombo( "Race", Races, out var race, ref _newManipRace );
|
||||||
CustomCombo( "Gender", Genders, out var gender, ref _newManipGender );
|
CustomCombo( "Gender", Genders, out var gender, ref _newManipGender );
|
||||||
newManip = MetaManipulation.Eqdp( equipSlot, GameData.Enums.GameData.CombinedRace( gender, race ), ( ushort )_newManipSetId,
|
newManip = MetaManipulation.Eqdp( equipSlot, GameData.Enums.Names.CombinedRace( gender, race ), ( ushort )_newManipSetId,
|
||||||
new EqdpEntry() );
|
new EqdpEntry() );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -771,7 +771,7 @@ namespace Penumbra.UI
|
||||||
|
|
||||||
CustomCombo( "Race", Races, out var race, ref _newManipRace );
|
CustomCombo( "Race", Races, out var race, ref _newManipRace );
|
||||||
CustomCombo( "Gender", Genders, out var gender, ref _newManipGender );
|
CustomCombo( "Gender", Genders, out var gender, ref _newManipGender );
|
||||||
newManip = MetaManipulation.Est( objectType, equipSlot, GameData.Enums.GameData.CombinedRace( gender, race ), bodySlot,
|
newManip = MetaManipulation.Est( objectType, equipSlot, GameData.Enums.Names.CombinedRace( gender, race ), bodySlot,
|
||||||
( ushort )_newManipSetId, 0 );
|
( ushort )_newManipSetId, 0 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue