feat(ui): port retail creature appraisal presentation
Render assessed creatures through the shared private viewport with retail heading, bounding-box camera, and light. Build the exact authored nine-row stat list and resolve creature names from the retail EnumMapper while keeping remaining font/sequencer adaptations explicit. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
f1a7912160
commit
7eaa68a5f4
26 changed files with 2780 additions and 237 deletions
100
tests/AcDream.App.Tests/UI/Layout/CreatureAppraisalRowsTests.cs
Normal file
100
tests/AcDream.App.Tests/UI/Layout/CreatureAppraisalRowsTests.cs
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
using AcDream.App.UI.Layout;
|
||||
using AcDream.Core.Net.Messages;
|
||||
|
||||
namespace AcDream.App.Tests.UI.Layout;
|
||||
|
||||
public sealed class CreatureAppraisalRowsTests
|
||||
{
|
||||
[Fact]
|
||||
public void FailedAssessmentShowsOnlyHealthPercentAndUnknownOtherValues()
|
||||
{
|
||||
var profile = Profile(
|
||||
health: 25u,
|
||||
healthMax: 100u,
|
||||
highlights: (ushort)0,
|
||||
colors: (ushort)0);
|
||||
|
||||
IReadOnlyList<CreatureAppraisalRow> rows =
|
||||
CreatureAppraisalRows.Build(profile, success: false);
|
||||
|
||||
Assert.All(
|
||||
rows,
|
||||
row => Assert.Equal(
|
||||
CreatureAppraisalValueStyle.Incomplete,
|
||||
row.Style));
|
||||
Assert.Equal("25 %", rows[6].Value);
|
||||
Assert.Equal("???", rows[0].Value);
|
||||
Assert.Equal("???", rows[7].Value);
|
||||
Assert.Equal("???", rows[8].Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnchantmentBitsSelectRetailPositiveAndNegativeStyles()
|
||||
{
|
||||
var profile = Profile(
|
||||
health: 100u,
|
||||
healthMax: 100u,
|
||||
highlights: (ushort)((1 << 0) | (1 << 6)),
|
||||
colors: (ushort)(1 << 0));
|
||||
|
||||
IReadOnlyList<CreatureAppraisalRow> rows =
|
||||
CreatureAppraisalRows.Build(profile, success: true);
|
||||
|
||||
Assert.Equal(CreatureAppraisalValueStyle.Positive, rows[0].Style);
|
||||
Assert.Equal(CreatureAppraisalValueStyle.Negative, rows[6].Style);
|
||||
Assert.Equal(CreatureAppraisalValueStyle.Normal, rows[1].Style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AuthoredRowTemplateCarriesRetailOverlappingLabelValueGeometry()
|
||||
{
|
||||
ElementInfo template =
|
||||
FixtureLoader.LoadExaminationRowTemplateInfos();
|
||||
|
||||
Assert.Equal(CreatureAppraisalRowTemplateFactory.TemplateId, template.Id);
|
||||
Assert.Equal((292f, 20f), (template.Width, template.Height));
|
||||
ElementInfo label = Assert.Single(
|
||||
template.Children,
|
||||
child => child.Id == CreatureAppraisalRowTemplateFactory.LabelId);
|
||||
ElementInfo value = Assert.Single(
|
||||
template.Children,
|
||||
child => child.Id == CreatureAppraisalRowTemplateFactory.ValueId);
|
||||
Assert.Equal((0f, 128f), (label.X, label.Width));
|
||||
Assert.Equal((27f, 256f), (value.X, value.Width));
|
||||
Assert.Equal(0x40000001u, label.FontDid);
|
||||
Assert.Equal(0x40000001u, value.FontDid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreatureNameResolverUsesLoadedRetailMappingAndSafeFallback()
|
||||
{
|
||||
var resolver = new CreatureDisplayNameResolver(
|
||||
new Dictionary<uint, string> { [77u] = "Ghost" });
|
||||
|
||||
Assert.Equal("Ghost", resolver.Resolve(77));
|
||||
Assert.Equal(string.Empty, resolver.Resolve(0));
|
||||
Assert.Equal(string.Empty, resolver.Resolve(999));
|
||||
}
|
||||
|
||||
private static AppraiseInfoParser.CreatureProfile Profile(
|
||||
uint health,
|
||||
uint healthMax,
|
||||
ushort highlights,
|
||||
ushort colors)
|
||||
=> new(
|
||||
Flags: 0x09u,
|
||||
Health: health,
|
||||
HealthMax: healthMax,
|
||||
Strength: null,
|
||||
Endurance: null,
|
||||
Quickness: null,
|
||||
Coordination: null,
|
||||
Focus: null,
|
||||
Self: null,
|
||||
Stamina: 50u,
|
||||
Mana: 75u,
|
||||
StaminaMax: 100u,
|
||||
ManaMax: 100u,
|
||||
AttributeHighlights: highlights,
|
||||
AttributeColors: colors);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue