mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +01:00
Glamourer-related changes.
This commit is contained in:
parent
a7ace8a8c8
commit
9e0c38169f
15 changed files with 184 additions and 90 deletions
|
|
@ -6,7 +6,7 @@ using Dalamud.Plugin;
|
|||
using Lumina.Excel.GeneratedSheets;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using PseudoEquipItem = System.ValueTuple<string, uint, ushort, ushort, ushort, byte, byte>;
|
||||
using PseudoEquipItem = System.ValueTuple<string, ulong, ushort, ushort, ushort, byte, byte>;
|
||||
|
||||
namespace Penumbra.GameData.Data;
|
||||
|
||||
|
|
@ -51,6 +51,14 @@ internal sealed class EquipmentIdentificationList : KeyList<PseudoEquipItem>
|
|||
private static IEnumerable<PseudoEquipItem> CreateEquipmentList(DataManager gameData, ClientLanguage language)
|
||||
{
|
||||
var items = gameData.GetExcelSheet<Item>(language)!;
|
||||
return items.Where(i => ((EquipSlot)i.EquipSlotCategory.Row).IsEquipmentPiece()).Select(i => (PseudoEquipItem)EquipItem.FromArmor(i));
|
||||
return items.Where(i => ((EquipSlot)i.EquipSlotCategory.Row).IsEquipmentPiece())
|
||||
.Select(i => (PseudoEquipItem)EquipItem.FromArmor(i))
|
||||
.Concat(CustomList);
|
||||
}
|
||||
|
||||
private static IEnumerable<PseudoEquipItem> CustomList
|
||||
=> new[]
|
||||
{
|
||||
(PseudoEquipItem)EquipItem.FromIds(0, 0, 8100, 0, 1, FullEquipType.Body, "Reaper Shroud"),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Penumbra.GameData.Data;
|
|||
|
||||
public sealed class HumanModelList : DataSharer
|
||||
{
|
||||
public const string Tag = "HumanModels";
|
||||
public const string Tag = "HumanModels";
|
||||
public const int CurrentVersion = 1;
|
||||
|
||||
private readonly BitArray _humanModels;
|
||||
|
|
@ -24,6 +24,9 @@ public sealed class HumanModelList : DataSharer
|
|||
public bool IsHuman(uint modelId)
|
||||
=> modelId < _humanModels.Count && _humanModels[(int)modelId];
|
||||
|
||||
public int Count
|
||||
=> _humanModels.Count;
|
||||
|
||||
protected override void DisposeInternal()
|
||||
{
|
||||
DisposeTag(Tag);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using Dalamud.Plugin;
|
|||
using Lumina.Excel.GeneratedSheets;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using PseudoEquipItem = System.ValueTuple<string, uint, ushort, ushort, ushort, byte, byte>;
|
||||
using PseudoEquipItem = System.ValueTuple<string, ulong, ushort, ushort, ushort, byte, byte>;
|
||||
|
||||
namespace Penumbra.GameData.Data;
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IR
|
|||
{
|
||||
var list = items[(int)type];
|
||||
foreach (var item in list)
|
||||
dict.TryAdd(item.Item2, item);
|
||||
dict.TryAdd((uint) item.Item2, item);
|
||||
}
|
||||
|
||||
dict.TrimExcess();
|
||||
|
|
@ -68,7 +68,7 @@ public sealed class ItemData : DataSharer, IReadOnlyDictionary<FullEquipType, IR
|
|||
{
|
||||
var list = items[(int)type];
|
||||
foreach (var item in list)
|
||||
dict.TryAdd(item.Item2, item);
|
||||
dict.TryAdd((uint) item.Item2, item);
|
||||
}
|
||||
|
||||
dict.TrimExcess();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ using Lumina.Excel.GeneratedSheets;
|
|||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Dalamud.Game.ClientState.Objects.Enums;
|
||||
|
|
@ -23,11 +22,11 @@ internal sealed class ObjectIdentification : DataSharer, IObjectIdentifier
|
|||
{
|
||||
public const int IdentificationVersion = 1;
|
||||
|
||||
public IGamePathParser GamePathParser { get; } = new GamePathParser();
|
||||
public readonly IReadOnlyList<IReadOnlyList<uint>> BnpcNames;
|
||||
public readonly IReadOnlyList<IReadOnlyList<(string Name, ObjectKind Kind)>> ModelCharaToObjects;
|
||||
public readonly IReadOnlyDictionary<string, IReadOnlyList<Action>> Actions;
|
||||
private readonly ActorManager.ActorManagerData _actorData;
|
||||
public IGamePathParser GamePathParser { get; } = new GamePathParser();
|
||||
public readonly IReadOnlyList<IReadOnlyList<uint>> BnpcNames;
|
||||
public readonly IReadOnlyList<IReadOnlyList<(string Name, ObjectKind Kind, uint Id)>> ModelCharaToObjects;
|
||||
public readonly IReadOnlyDictionary<string, IReadOnlyList<Action>> Actions;
|
||||
private readonly ActorManager.ActorManagerData _actorData;
|
||||
|
||||
private readonly EquipmentIdentificationList _equipment;
|
||||
private readonly WeaponIdentificationList _weapons;
|
||||
|
|
@ -49,10 +48,8 @@ internal sealed class ObjectIdentification : DataSharer, IObjectIdentifier
|
|||
public void Identify(IDictionary<string, object?> set, string path)
|
||||
{
|
||||
if (path.EndsWith(".pap", StringComparison.OrdinalIgnoreCase) || path.EndsWith(".tmb", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (IdentifyVfx(set, path))
|
||||
return;
|
||||
}
|
||||
|
||||
var info = GamePathParser.GetFileInfo(path);
|
||||
IdentifyParsed(set, info);
|
||||
|
|
@ -73,6 +70,15 @@ internal sealed class ObjectIdentification : DataSharer, IObjectIdentifier
|
|||
_ => _equipment.Between(setId, slot, (byte)variant),
|
||||
};
|
||||
|
||||
public IReadOnlyList<uint> GetBnpcNames(uint bNpcId)
|
||||
=> bNpcId >= BnpcNames.Count ? Array.Empty<uint>() : BnpcNames[(int)bNpcId];
|
||||
|
||||
public IReadOnlyList<(string Name, ObjectKind Kind, uint Id)> ModelCharaNames(uint modelId)
|
||||
=> modelId >= ModelCharaToObjects.Count ? Array.Empty<(string Name, ObjectKind Kind, uint Id)>() : ModelCharaToObjects[(int)modelId];
|
||||
|
||||
public int NumModelChara
|
||||
=> ModelCharaToObjects.Count;
|
||||
|
||||
protected override void DisposeInternal()
|
||||
{
|
||||
_actorData.Dispose();
|
||||
|
|
@ -125,14 +131,14 @@ internal sealed class ObjectIdentification : DataSharer, IObjectIdentifier
|
|||
{
|
||||
var items = _equipment.Between(info.PrimaryId, info.EquipSlot, info.Variant);
|
||||
foreach (var item in items)
|
||||
set[item.Name.ToString()] = item;
|
||||
set[item.Name] = item;
|
||||
}
|
||||
|
||||
private void FindWeapon(IDictionary<string, object?> set, GameObjectInfo info)
|
||||
{
|
||||
var items = _weapons.Between(info.PrimaryId, info.SecondaryId, info.Variant);
|
||||
foreach (var item in items)
|
||||
set[item.Name.ToString()] = item;
|
||||
set[item.Name] = item;
|
||||
}
|
||||
|
||||
private void FindModel(IDictionary<string, object?> set, GameObjectInfo info)
|
||||
|
|
@ -142,10 +148,10 @@ internal sealed class ObjectIdentification : DataSharer, IObjectIdentifier
|
|||
return;
|
||||
|
||||
var models = _modelIdentifierToModelChara.Between(type, info.PrimaryId, (byte)info.SecondaryId, info.Variant);
|
||||
foreach (var model in models.Where(m => m.RowId < ModelCharaToObjects.Count))
|
||||
foreach (var model in models.Where(m => m.RowId != 0 && m.RowId < ModelCharaToObjects.Count))
|
||||
{
|
||||
var objectList = ModelCharaToObjects[(int)model.RowId];
|
||||
foreach (var (name, kind) in objectList)
|
||||
foreach (var (name, kind, _) in objectList)
|
||||
set[$"{name} ({kind.ToName()})"] = model;
|
||||
}
|
||||
}
|
||||
|
|
@ -172,10 +178,10 @@ internal sealed class ObjectIdentification : DataSharer, IObjectIdentifier
|
|||
case FileType.Shader:
|
||||
AddCounterString(set, FileType.Shader.ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (info.ObjectType)
|
||||
{
|
||||
{
|
||||
case ObjectType.LoadingScreen:
|
||||
case ObjectType.Map:
|
||||
case ObjectType.Interface:
|
||||
|
|
@ -246,46 +252,46 @@ internal sealed class ObjectIdentification : DataSharer, IObjectIdentifier
|
|||
return true;
|
||||
}
|
||||
|
||||
private IReadOnlyList<IReadOnlyList<(string Name, ObjectKind Kind)>> CreateModelObjects(ActorManager.ActorManagerData actors,
|
||||
private IReadOnlyList<IReadOnlyList<(string Name, ObjectKind Kind, uint Id)>> CreateModelObjects(ActorManager.ActorManagerData actors,
|
||||
DataManager gameData, ClientLanguage language)
|
||||
{
|
||||
var modelSheet = gameData.GetExcelSheet<ModelChara>(language)!;
|
||||
var ret = new List<ConcurrentBag<(string Name, ObjectKind Kind)>>((int)modelSheet.RowCount);
|
||||
|
||||
var ret = new List<ConcurrentBag<(string Name, ObjectKind Kind, uint Id)>>((int)modelSheet.RowCount);
|
||||
|
||||
for (var i = -1; i < modelSheet.Last().RowId; ++i)
|
||||
ret.Add(new ConcurrentBag<(string Name, ObjectKind Kind)>());
|
||||
ret.Add(new ConcurrentBag<(string Name, ObjectKind Kind, uint Id)>());
|
||||
|
||||
void AddChara(int modelChara, ObjectKind kind, uint dataId)
|
||||
void AddChara(int modelChara, ObjectKind kind, uint dataId, uint displayId)
|
||||
{
|
||||
if (modelChara == 0 || modelChara >= ret.Count)
|
||||
if (modelChara >= ret.Count)
|
||||
return;
|
||||
|
||||
if (actors.TryGetName(kind, dataId, out var name))
|
||||
ret[modelChara].Add((name, kind));
|
||||
ret[modelChara].Add((name, kind, displayId));
|
||||
}
|
||||
|
||||
var oTask = Task.Run(() =>
|
||||
{
|
||||
foreach (var ornament in gameData.GetExcelSheet<Ornament>(language)!)
|
||||
AddChara(ornament.Model, (ObjectKind)15, ornament.RowId);
|
||||
AddChara(ornament.Model, ObjectKind.Ornament, ornament.RowId, ornament.RowId);
|
||||
});
|
||||
|
||||
var mTask = Task.Run(() =>
|
||||
{
|
||||
foreach (var mount in gameData.GetExcelSheet<Mount>(language)!)
|
||||
AddChara((int)mount.ModelChara.Row, ObjectKind.MountType, mount.RowId);
|
||||
AddChara((int)mount.ModelChara.Row, ObjectKind.MountType, mount.RowId, mount.RowId);
|
||||
});
|
||||
|
||||
var cTask = Task.Run(() =>
|
||||
{
|
||||
foreach (var companion in gameData.GetExcelSheet<Companion>(language)!)
|
||||
AddChara((int)companion.Model.Row, ObjectKind.Companion, companion.RowId);
|
||||
AddChara((int)companion.Model.Row, ObjectKind.Companion, companion.RowId, companion.RowId);
|
||||
});
|
||||
|
||||
var eTask = Task.Run(() =>
|
||||
{
|
||||
foreach (var eNpc in gameData.GetExcelSheet<ENpcBase>(language)!)
|
||||
AddChara((int)eNpc.ModelChara.Row, ObjectKind.EventNpc, eNpc.RowId);
|
||||
AddChara((int)eNpc.ModelChara.Row, ObjectKind.EventNpc, eNpc.RowId, eNpc.RowId);
|
||||
});
|
||||
|
||||
var options = new ParallelOptions()
|
||||
|
|
@ -296,14 +302,14 @@ internal sealed class ObjectIdentification : DataSharer, IObjectIdentifier
|
|||
Parallel.ForEach(gameData.GetExcelSheet<BNpcBase>(language)!.Where(b => b.RowId < BnpcNames.Count), options, bNpc =>
|
||||
{
|
||||
foreach (var name in BnpcNames[(int)bNpc.RowId])
|
||||
AddChara((int)bNpc.ModelChara.Row, ObjectKind.BattleNpc, name);
|
||||
AddChara((int)bNpc.ModelChara.Row, ObjectKind.BattleNpc, name, bNpc.RowId);
|
||||
});
|
||||
|
||||
Task.WaitAll(oTask, mTask, cTask, eTask);
|
||||
|
||||
return ret.Select(s => s.Count > 0
|
||||
return ret.Select(s => !s.IsEmpty
|
||||
? s.ToArray()
|
||||
: Array.Empty<(string Name, ObjectKind Kind)>()).ToArray();
|
||||
: Array.Empty<(string Name, ObjectKind Kind, uint Id)>()).ToArray();
|
||||
}
|
||||
|
||||
public static unsafe ulong KeyFromCharacterBase(CharacterBase* drawObject)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ using Dalamud.Plugin;
|
|||
using Lumina.Excel.GeneratedSheets;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using PseudoEquipItem = System.ValueTuple<string, uint, ushort, ushort, ushort, byte, byte>;
|
||||
using PseudoEquipItem = System.ValueTuple<string, ulong, ushort, ushort, ushort, byte, byte>;
|
||||
|
||||
namespace Penumbra.GameData.Data;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue