fix(ui): match retail item appraisal semantics

Preserve PublicWeenieDesc hook identity from CreateObject through the item model so hook appraisals suppress sentinel capacities exactly. Use appraisal-only Value and Burden presence, retain AddItemInfo paragraph and authored font-color selection, and port retail lock, page, enchantment, and spell-block formatting.

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-23 18:04:19 +02:00
parent bc47bc4917
commit d3c5e06fdd
21 changed files with 982 additions and 145 deletions

View file

@ -23,6 +23,16 @@ retained examination window.
- `Attribute2ndInfoRegion::Update @ 0x004F1E80`
- `AppraisalSystem::InqCreatureDisplayName @ 0x005B59E0`
- `ItemExamineUI::SetAppraiseInfo @ 0x004B72B0`
- `ItemExamineUI::AddItemInfo @ 0x004AC050/0x004ADCA0`
- `ItemExamineUI::Appraisal_ShowValueInfo @ 0x004ADEA0`
- `ItemExamineUI::Appraisal_ShowBurdenInfo @ 0x004AE180`
- `ItemExamineUI::Appraisal_ShowCapacity @ 0x004B2680`
- `ItemExamineUI::Appraisal_ShowLockAppraiseInfo @ 0x004B2790`
- `AppraisalProfile::HasHookedItem @ 0x00525C70`
- `AppraisalProfile::InqIntEnchantmentMod @ 0x005B2C10`
- `AppraisalProfile::InqFloatEnchantmentMod @ 0x005B2C70`
- `AppraisalSystem::LockpickSuccessPercentToString @ 0x005B4600`
- `ACCWeenieObject::IsHook @ 0x0058C660`
- `ItemExamineUI::HandleInscriptionGainingFocus @ 0x004AC0E0`
- `ItemExamineUI::HandleInscriptionMousePresses @ 0x004AC230`
- `ItemExamineUI::SetInscriptionEditableState @ 0x004AC720`
@ -333,6 +343,57 @@ The individual branches are not a generic property dump. They project the
wire profile into retail prose:
```text
AddItemInfo(text, fontColorIndex, sameParagraph):
if the report already contains text:
append sameParagraph ? "\n" : "\n\n"
append text with font-list index 0 and the requested color-list index
ShowValueAndBurden(profile):
if profile contains int 19:
append "Value: <grouped value>"
else:
append "Value: ???"
if profile contains int 5:
append "Burden: <grouped burden>"
else:
append "Burden: Unknown"
IsHook(object):
return PublicWeenieDesc.HookType != 0
and PublicWeenieDesc.HookItemTypes != TYPE_UNDEF
ShowCapacity(object, profile):
if object is not a hook or profile does not contain a HookProfile:
append authored item/container capacity as a new paragraph
if profile contains PageCount (175) and PageUsed (174):
append "<used> of <count> pages full." as a new paragraph
# A hook with a HookProfile describes its mounted item. Its sentinel
# 255/255 PublicWeenieDesc capacities are not player-facing capacity.
ShowLock(object, profile):
if object is a hook:
return
if Locked bool is absent:
append nonzero LockpickResistance as
"Bonus to Lockpick Skill: <signed value>"
return
append "Unlocked" and return when Locked is false
append "Locked"
if LockpickResistance is absent:
append "You can't tell how hard the lock is to pick."
else if LockpickSuccessPercent is present:
map it through LockpickSuccessPercentToString
append "The lock looks <grade> to pick (Resistance <value>)."
FontColor(profileBitfield, lowBit):
if lowBit is absent:
return normal color index 0
if the corresponding bit 16 positions higher is present:
return beneficial color index 1
return detrimental color index 2
ShowWeaponAndArmor(validLocations, profile):
ammoType = live PublicWeenieDesc ammo type
if object is a hook:
@ -470,6 +531,10 @@ The main text and inscription areas use their authored scrollbars. A newly
selected object resets those scroll positions to the top; a refresh of the
same object preserves the user's position.
LayoutDesc `0x2100006B` element `0x1000013C` authors the item report's
font-color list as white, green, and red. Those are the concrete colors selected
by the `AddItemInfo` indices above; they are not hard-coded by appraisal logic.
## Window behavior
The LayoutDesc root already contains retail's complete floaty window chrome,
@ -603,7 +668,10 @@ The request lifetime, exact packet flags, independent floaty window,
inscription permission/edit/write transaction, subview choice, authored outer
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
combat refresh are in scope. Common item report rows now preserve retail's
appraisal-only unknown values, hook/capacity/lock presence rules, exact
paragraph boundaries, and authored normal/beneficial/detrimental font-color
selection. Retail's item-object preview, exhaustive specialized
`ItemExamineUI` detail branches, creature incomplete/high/low FontInfo
selection, and PSR-only scribe-account/override behavior remain explicit
AP-110 work.