fix(ui): restore modern spell formula presentation
Resolve spell-examination component cells through their DAT icon DIDs, project scarab and prismatic-taper formulas when ACE disables component enforcement, and version authored window geometry so stale examination sizes reset once without losing user layout behavior. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
3e31b0ac70
commit
d4ce64f56b
22 changed files with 307 additions and 41 deletions
|
|
@ -717,6 +717,17 @@ public sealed class AppraisalUiControllerTests
|
|||
new SpellComponentDescriptor(101u, "Malar Herb", 1u, 0x06000011u),
|
||||
Owned: false),
|
||||
};
|
||||
var componentTemplate = new SpellExamineComponentTemplateFactory(
|
||||
new ElementInfo
|
||||
{
|
||||
Id = SpellExamineComponentTemplateFactory.TemplateId,
|
||||
Type = 3,
|
||||
Width = 20,
|
||||
Height = 20,
|
||||
},
|
||||
NoTexture,
|
||||
defaultFont: null);
|
||||
var resolvedComponentIcons = new List<uint>();
|
||||
int shown = 0;
|
||||
using AppraisalUiController controller = Bind(
|
||||
layout,
|
||||
|
|
@ -730,8 +741,14 @@ public sealed class AppraisalUiControllerTests
|
|||
selection: selection,
|
||||
spellbook: spellbook,
|
||||
resolveSpellIcon: id => id + 1_000u,
|
||||
resolveComponentIcon: did =>
|
||||
{
|
||||
resolvedComponentIcons.Add(did);
|
||||
return did + 2_000u;
|
||||
},
|
||||
spellComponents: _ => components,
|
||||
magicSkill: _ => 200u)!;
|
||||
magicSkill: _ => 200u,
|
||||
spellComponentTemplates: componentTemplate)!;
|
||||
|
||||
Assert.True(interaction.ExamineSelectedOrEnterMode(ObjectId));
|
||||
Assert.Equal(1, interaction.BusyCount);
|
||||
|
|
@ -784,6 +801,17 @@ public sealed class AppraisalUiControllerTests
|
|||
UiTextureElement icon = Assert.Single(
|
||||
iconHost.Children.OfType<UiTextureElement>());
|
||||
Assert.Equal(metadata.SpellId + 1_000u, icon.Texture);
|
||||
Assert.Equal(
|
||||
new uint[] { 0x06000010u, 0x06000011u },
|
||||
resolvedComponentIcons);
|
||||
UiElement formula = layout.FindElement(
|
||||
AppraisalUiController.SpellFormulaListId)!;
|
||||
Assert.Equal(
|
||||
new uint[] { 0x06000010u + 2_000u, 0x06000011u + 2_000u },
|
||||
formula.Children
|
||||
.SelectMany(cell => cell.Children)
|
||||
.OfType<UiTextureElement>()
|
||||
.Select(texture => texture.Texture));
|
||||
}
|
||||
|
||||
private static AppraisalUiController? Bind(
|
||||
|
|
|
|||
|
|
@ -94,6 +94,87 @@ public sealed class RetailWindowLayoutPersistenceTests : IDisposable
|
|||
Assert.True(state.Restored.Maximized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Restore_OlderAuthoredGeometryRevision_ResetsOnlySavedExtent()
|
||||
{
|
||||
var store = new SettingsStore(PathName);
|
||||
store.SaveWindowLayout(
|
||||
"Alice",
|
||||
"800x600",
|
||||
WindowNames.Examination,
|
||||
new UiWindowLayout(
|
||||
44f,
|
||||
55f,
|
||||
310f,
|
||||
545f,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
AuthoredGeometryRevision: 0));
|
||||
|
||||
var root = new UiRoot { Width = 800, Height = 600 };
|
||||
RetailWindowHandle handle = Mount(
|
||||
root,
|
||||
WindowNames.Examination,
|
||||
authoredGeometryRevision: 1,
|
||||
width: 310f,
|
||||
height: 400f);
|
||||
using var persistence = new RetailWindowLayoutPersistence(
|
||||
root.WindowManager,
|
||||
store,
|
||||
() => "Alice",
|
||||
() => (800, 600));
|
||||
|
||||
persistence.RestoreAll();
|
||||
|
||||
Assert.Equal((44f, 55f), (handle.Left, handle.Top));
|
||||
Assert.Equal((310f, 400f), (handle.Width, handle.Height));
|
||||
UiWindowLayout migrated = Assert.IsType<UiWindowLayout>(
|
||||
store.LoadWindowLayout(
|
||||
"Alice",
|
||||
"800x600",
|
||||
WindowNames.Examination,
|
||||
default));
|
||||
Assert.Equal(1, migrated.AuthoredGeometryRevision);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RestoreNamed_OlderRevisionUsesMountedAuthoredExtent_NotCurrentSize()
|
||||
{
|
||||
var store = new SettingsStore(PathName);
|
||||
store.SaveNamedWindowLayout(
|
||||
"legacy",
|
||||
WindowNames.Examination,
|
||||
new UiWindowLayout(
|
||||
44f,
|
||||
55f,
|
||||
310f,
|
||||
545f,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
AuthoredGeometryRevision: 0));
|
||||
|
||||
var root = new UiRoot { Width = 800, Height = 600 };
|
||||
RetailWindowHandle handle = Mount(
|
||||
root,
|
||||
WindowNames.Examination,
|
||||
authoredGeometryRevision: 1,
|
||||
width: 310f,
|
||||
height: 400f);
|
||||
handle.ResizeTo(500f, 300f);
|
||||
using var persistence = new RetailWindowLayoutPersistence(
|
||||
root.WindowManager,
|
||||
store,
|
||||
() => "Alice",
|
||||
() => (800, 600));
|
||||
|
||||
persistence.RestoreNamed("legacy");
|
||||
|
||||
Assert.Equal((44f, 55f), (handle.Left, handle.Top));
|
||||
Assert.Equal((310f, 400f), (handle.Width, handle.Height));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DefaultPreLoginKey_NeverOverwritesCharacterLayouts()
|
||||
{
|
||||
|
|
@ -169,14 +250,17 @@ public sealed class RetailWindowLayoutPersistenceTests : IDisposable
|
|||
private static RetailWindowHandle Mount(
|
||||
UiRoot root,
|
||||
string name,
|
||||
IRetainedWindowStateController? state = null)
|
||||
IRetainedWindowStateController? state = null,
|
||||
int authoredGeometryRevision = 0,
|
||||
float width = 200f,
|
||||
float height = 100f)
|
||||
{
|
||||
var frame = new UiPanel
|
||||
{
|
||||
Left = 10f,
|
||||
Top = 20f,
|
||||
Width = 200f,
|
||||
Height = 100f,
|
||||
Width = width,
|
||||
Height = height,
|
||||
MinWidth = 100f,
|
||||
MinHeight = 80f,
|
||||
MaxWidth = 600f,
|
||||
|
|
@ -185,7 +269,11 @@ public sealed class RetailWindowLayoutPersistenceTests : IDisposable
|
|||
Resizable = true,
|
||||
};
|
||||
root.AddChild(frame);
|
||||
return root.RegisterWindow(name, frame, stateController: state);
|
||||
return root.RegisterWindow(
|
||||
name,
|
||||
frame,
|
||||
stateController: state,
|
||||
authoredGeometryRevision: authoredGeometryRevision);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue