fix(ui): keep spell components in authored foreground

Install examination formula icons as the template root UIRegion image, matching retail ClearImage/SetImage behavior while retaining the authored missing-component overlay. Add the real DAT template fixture and conformance coverage.

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-24 08:08:29 +02:00
parent d4ce64f56b
commit 2c3da8e153
14 changed files with 231 additions and 34 deletions

View file

@ -809,9 +809,8 @@ public sealed class AppraisalUiControllerTests
Assert.Equal(
new uint[] { 0x06000010u + 2_000u, 0x06000011u + 2_000u },
formula.Children
.SelectMany(cell => cell.Children)
.OfType<UiTextureElement>()
.Select(texture => texture.Texture));
.OfType<UiDatElement>()
.Select(cell => cell.RuntimeImageTexture!.Value));
}
private static AppraisalUiController? Bind(

View file

@ -116,6 +116,9 @@ public static class FixtureLoader
public static ElementInfo LoadExaminationRowTemplateInfos()
=> LoadInfos("examine_row_2100006B_10000166.json");
public static ElementInfo LoadExaminationComponentTemplateInfos()
=> LoadInfos("examine_component_2100006B_1000032E.json");
public static ImportedLayout LoadPowerbar()
=> LayoutImporter.Build(LoadPowerbarInfos(), _ => (0u, 0, 0), null);

View file

@ -134,6 +134,8 @@ public sealed class RetailLayoutFixtureGenerator
(0x2100006Bu, 0x100005F2u, "examine_2100006B_100005F2.json"),
(AppraisalUiController.LayoutId, CreatureAppraisalRowTemplateFactory.TemplateId,
"examine_row_2100006B_10000166.json"),
(AppraisalUiController.LayoutId, SpellExamineComponentTemplateFactory.TemplateId,
"examine_component_2100006B_1000032E.json"),
})
{
ElementInfo? panelPart = LayoutImporter.ImportInfos(dats, layoutId, rootId);

View file

@ -0,0 +1,35 @@
using AcDream.App.UI;
using AcDream.App.UI.Layout;
namespace AcDream.App.Tests.UI.Layout;
public sealed class SpellExamineComponentTemplateFactoryTests
{
[Theory]
[InlineData(true, false)]
[InlineData(false, true)]
public void Create_InstallsIconOnRetailRootAndKeepsMissingOverlayAboveIt(
bool owned,
bool missingVisible)
{
ElementInfo template =
FixtureLoader.LoadExaminationComponentTemplateInfos();
var factory = new SpellExamineComponentTemplateFactory(
template,
did => (did + 1_000u, 32, 32),
defaultFont: null);
UiDatElement root = Assert.IsType<UiDatElement>(
factory.Create(0xABCDu, owned));
UiDatElement missing = Assert.IsType<UiDatElement>(
Assert.Single(root.Children));
Assert.Equal(SpellExamineComponentTemplateFactory.TemplateId, root.ElementId);
Assert.Equal(0xABCDu, root.RuntimeImageTexture);
Assert.Empty(root.Children.OfType<UiTextureElement>());
Assert.Equal(
SpellExamineComponentTemplateFactory.MissingOverlayId,
missing.ElementId);
Assert.Equal(missingVisible, missing.Visible);
}
}

View file

@ -0,0 +1,117 @@
{
"Id": 268436270,
"Type": 3,
"X": 0,
"Y": 0,
"Width": 32,
"Height": 32,
"OriginalParentWidth": 0,
"OriginalParentHeight": 0,
"HasOriginalParentSize": false,
"Left": 0,
"Top": 0,
"Right": 0,
"Bottom": 0,
"ReadOrder": 1,
"ZLevel": 0,
"States": {
"4294967295": {
"Id": 4294967295,
"Name": "",
"PassToChildren": false,
"IncorporationFlags": 30,
"Image": null,
"Cursor": null,
"Properties": {
"Values": {}
}
}
},
"DefaultStateId": 0,
"FontDid": 0,
"HJustify": 1,
"VJustify": 1,
"FontColor": null,
"StateMedia": {},
"StateCursors": {},
"DefaultStateName": "",
"Children": [
{
"Id": 268436272,
"Type": 3,
"X": 0,
"Y": 0,
"Width": 32,
"Height": 32,
"OriginalParentWidth": 32,
"OriginalParentHeight": 32,
"HasOriginalParentSize": true,
"Left": 0,
"Top": 0,
"Right": 0,
"Bottom": 0,
"ReadOrder": 1,
"ZLevel": 0,
"States": {
"4294967295": {
"Id": 4294967295,
"Name": "",
"PassToChildren": false,
"IncorporationFlags": 30,
"Image": {
"File": 100682946,
"DrawMode": 3
},
"Cursor": null,
"Properties": {
"Values": {
"59": {
"Kind": 1,
"MasterPropertyId": 59,
"UnsignedValue": 0,
"IntegerValue": 0,
"FloatValue": 0,
"BoolValue": false,
"StringInfoValue": {
"Token": 0,
"StringId": 0,
"TableId": 0,
"Override": 0,
"English": 0,
"Comment": 0
},
"ColorValue": {
"Blue": 0,
"Green": 0,
"Red": 0,
"Alpha": 0
},
"VectorValue": {
"X": 0,
"Y": 0,
"Z": 0
},
"ArrayValue": [],
"StructValue": {}
}
}
}
}
},
"DefaultStateId": 0,
"FontDid": 0,
"HJustify": 1,
"VJustify": 1,
"FontColor": null,
"StateMedia": {
"": {
"Item1": 100682946,
"Item2": 3
}
},
"StateCursors": {},
"DefaultStateName": "",
"Children": []
}
]
}