feat(ui): complete retail creature appraisal details

Port the separate creature rating list, layer the animated preview between authored row chrome and text, and follow selection while the examination floaty is visible. Preserve the remaining item-preview and font-state gaps in AP-110.

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-23 14:04:19 +02:00
parent 7eaa68a5f4
commit d96ea2de98
11 changed files with 578 additions and 61 deletions

View file

@ -191,16 +191,27 @@ on time pulse:
send another Event_Appraise(currentAppraisalId)
```
When the examination window's selection-follow option is active, a selection
change appraises the new selected GUID; clearing selection hides the window.
That optional retail preference remains outside this slice.
`gmExaminationUI::gmExaminationUI @ 0x004AB2B0` initializes
`m_examineNewlySelectedItem` to one. Selection-follow is therefore retail's
default examination behavior, not an optional preference:
```text
on SelectionChanged:
if examination window is not visible:
return
if selected object id != 0:
ClientUISystem.ExamineObject(selected id)
else:
hide examination window
```
## Creature presentation
`BasicCreatureExamineUI` binds viewport `0x10000148`, list box `0x10000149`,
level value `0x1000014C`, and creature display name `0x1000014E`. Its stat
rows are instances of LayoutDesc `0x2100006B` template `0x10000166`, whose
label and value fields are `0x1000012A` and `0x1000012B`.
`BasicCreatureExamineUI` binds viewport `0x10000148`, base-stat list box
`0x10000149`, miscellaneous-rating list box `0x10000335`, level value
`0x1000014C`, and creature display name `0x1000014E`. Its rows are instances
of LayoutDesc `0x2100006B` template `0x10000166`, whose label and value fields
are `0x1000012A` and `0x1000012B`.
```text
on creature appraisal:
@ -222,6 +233,27 @@ on creature appraisal:
Health current secondary 2 / maximum secondary 1, show percent
Stamina current secondary 4 / maximum secondary 3
Mana current secondary 6 / maximum secondary 5
clear miscellaneous list
damageRating = int property 0x133
damageResistRating = int property 0x134
critRating = int property 0x139
critDamageRating = int property 0x13A
critResistRating = int property 0x13B
critDamageResist = int property 0x13C
healingBoostRating = int property 0x143
dotResistRating = int property 0x15E
lifeResistRating = int property 0x15F
if any displayed rating group is nonzero:
append blank row
if damageRating or critRating or critDamageRating is positive:
append "Dmg/CritDmg" = "Rating: damageRating/critDamageRating"
if damageResistRating or critResistRating or critDamageResist is positive:
append "Dmg/CritDmg" = "Resist: damageResistRating/critDamageResist"
if dotResistRating or lifeResistRating is positive:
append "DoT/Life:" = "Resist: dotResistRating/lifeResistRating"
append blank row
```
Successful primary values are decimal integers. Successful Health is
@ -230,6 +262,18 @@ assessment, Health still shows the percentage when both values are known,
while every other row is `???`. The profile highlight/color bitfields select
one of retail's four authored FontInfo entries (normal, beneficial,
detrimental, or incomplete); exact FontInfo-list binding remains AP-110.
The 2013 client reads HealingBoost but does not append it to this creature
rating list. CritRating and CritResistRating determine whether their paired
row exists, while the displayed right-hand value is CritDamageRating or
CritDamageResistRating exactly as retail formats it.
The authored viewport and list overlap. Retail draws the creature between the
row chrome and the row text. The modern retained RTT seam reproduces that
ordering with two synchronized copies of the same DAT row template: media-only
chrome below the viewport and media-free label/value descendants above it.
Both copies share one pixel scroll model. The 292-pixel authored row is inset
four pixels within the 300-pixel list surface, giving the text a balanced
left/right margin without changing template geometry.
The animated preview is a private `CreatureMode`, not the live world object:
@ -412,9 +456,9 @@ implements the same behavior.
The request lifetime, exact packet flags, independent floaty window,
inscription permission/edit/write transaction, subview choice, authored outer
layout, ordered creature stats, animated creature preview, scrollbar
ownership, and combat refresh are in scope. Retail's item-object preview,
exhaustive specialized `ItemExamineUI` detail branches, creature
extra-rating regions, exact appraisal FontInfo-list selection,
selection-follow preference, and PSR-only scribe-account/override behavior
remain explicit AP-110 work.
layout, ordered creature stats and ratings, animated creature preview,
viewport/list/text compositing, selection-follow, scrollbar ownership, and
combat refresh are in scope. Retail's item-object preview, exhaustive
specialized `ItemExamineUI` detail branches, exact appraisal FontInfo-list
selection, and PSR-only scribe-account/override behavior remain explicit
AP-110 work.