feat(ui): port retail item appraisal reports
Follow ItemExamineUI's EoR dispatch and wording for item assessment instead of the generic projection. Resolve material and creature names through installed DAT maps, cover specialized item branches and item-XP curves, and narrow AP-110 to the remaining live/localized preview seams.
This commit is contained in:
parent
2c00d53db2
commit
d78d09cfbc
12 changed files with 1258 additions and 193 deletions
91
src/AcDream.App/UI/Layout/RetailAppraisalNameResolver.cs
Normal file
91
src/AcDream.App/UI/Layout/RetailAppraisalNameResolver.cs
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
using AcDream.Content;
|
||||
using DatReaderWriter;
|
||||
using DatReaderWriter.DBObjs;
|
||||
using DatReaderWriter.Types;
|
||||
|
||||
namespace AcDream.App.UI.Layout;
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the authored enum display names consumed by retail's appraisal
|
||||
/// helpers. Material names follow
|
||||
/// <c>MaterialTypeEnumMapper::MaterialTypeToString @ 0x005CD500</c>;
|
||||
/// creature and heritage names follow
|
||||
/// <c>AppraisalSystem::InqCreatureDisplayName @ 0x005B59E0</c> and
|
||||
/// <c>InqHeritageGroupDisplayName @ 0x005B4710</c>.
|
||||
/// </summary>
|
||||
public sealed class RetailAppraisalNameResolver
|
||||
{
|
||||
private const uint MaterialClientEnum = 0x10000001u;
|
||||
private const uint MaterialSubEnum = 1u;
|
||||
|
||||
public static RetailAppraisalNameResolver Empty { get; } = new(
|
||||
new Dictionary<uint, string>(),
|
||||
new CreatureDisplayNameResolver(new Dictionary<uint, string>()));
|
||||
|
||||
private readonly IReadOnlyDictionary<uint, string> _materials;
|
||||
private readonly CreatureDisplayNameResolver _creatures;
|
||||
|
||||
public RetailAppraisalNameResolver(
|
||||
IReadOnlyDictionary<uint, string> materials,
|
||||
CreatureDisplayNameResolver creatures)
|
||||
{
|
||||
_materials = materials
|
||||
?? throw new ArgumentNullException(nameof(materials));
|
||||
_creatures = creatures
|
||||
?? throw new ArgumentNullException(nameof(creatures));
|
||||
}
|
||||
|
||||
public static RetailAppraisalNameResolver Load(
|
||||
IDatReaderWriter dats,
|
||||
CreatureDisplayNameResolver creatures)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(dats);
|
||||
ArgumentNullException.ThrowIfNull(creatures);
|
||||
|
||||
var materials = new Dictionary<uint, string>();
|
||||
uint masterDid = (uint)dats.Portal.Db.Header.MasterMapId;
|
||||
EnumIDMap? master = masterDid == 0u
|
||||
? null
|
||||
: dats.Get<EnumIDMap>(masterDid);
|
||||
if (master is not null
|
||||
&& master.ClientEnumToID.TryGetValue(
|
||||
MaterialClientEnum,
|
||||
out uint materialRootMapDid)
|
||||
&& dats.Get<EnumIDMap>(materialRootMapDid) is { } materialRootMap
|
||||
&& materialRootMap.ClientEnumToID.TryGetValue(
|
||||
MaterialSubEnum,
|
||||
out uint materialMapDid)
|
||||
&& dats.Get<DualEnumIDMap>(materialMapDid) is { } materialMap)
|
||||
{
|
||||
foreach ((uint id, PStringBase<byte> text)
|
||||
in materialMap.ClientEnumToName)
|
||||
{
|
||||
materials.TryAdd(id, Normalize(text.Value));
|
||||
}
|
||||
}
|
||||
|
||||
return new RetailAppraisalNameResolver(materials, creatures);
|
||||
}
|
||||
|
||||
public string ResolveCreature(int creatureType)
|
||||
=> _creatures.Resolve(creatureType);
|
||||
|
||||
public string ResolveHeritage(int heritageGroup)
|
||||
=> heritageGroup switch
|
||||
{
|
||||
2 => "Gharu'ndim",
|
||||
5 => "Umbraen",
|
||||
13 => "Olthoi",
|
||||
_ => CharacterIdentityText.HeritageGroupDisplayName(heritageGroup)
|
||||
?? string.Empty,
|
||||
};
|
||||
|
||||
public string ResolveMaterial(int materialType)
|
||||
=> materialType > 0
|
||||
&& _materials.TryGetValue((uint)materialType, out string? name)
|
||||
? name
|
||||
: string.Empty;
|
||||
|
||||
private static string Normalize(string value)
|
||||
=> value.Replace('_', ' ');
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue