feat(ui): port retail item appraisal reports
Follow ItemExamineUI's EoR dispatch and wording for item assessment instead of the generic projection. Resolve material and creature names through installed DAT maps, cover specialized item branches and item-XP curves, and narrow AP-110 to the remaining live/localized preview seams.
This commit is contained in:
parent
2c00d53db2
commit
d78d09cfbc
12 changed files with 1258 additions and 193 deletions
|
|
@ -517,6 +517,139 @@ ShowRemainingItemFields(profile):
|
|||
short and long descriptions
|
||||
```
|
||||
|
||||
### Exhaustive EoR item-report branches
|
||||
|
||||
The common projection above was re-audited against every helper called by
|
||||
`ItemExamineUI::SetAppraiseInfo @ 0x004B72B0`. The remaining item branches are
|
||||
not generic property labels; retail applies the following exact rules.
|
||||
|
||||
```text
|
||||
ShowTinkering:
|
||||
if NumTimesTinkered (171):
|
||||
"This item has been tinkered %d time[s]."
|
||||
if TinkerName (39): "Last tinkered by %s."
|
||||
if ImbuerName (40): "Imbued by %s."
|
||||
if Workmanship (105):
|
||||
if NumItemsInMaterial (170) is absent:
|
||||
"Workmanship: <adjective> (<integer workmanship>)"
|
||||
else:
|
||||
average = workmanship / NumItemsInMaterial
|
||||
"Workmanship: <adjective of rounded average> (<average, two decimals>)"
|
||||
blank line
|
||||
"Salvaged from %d items."
|
||||
|
||||
ShowSet:
|
||||
EquipmentSetId (265) selects the literal EoR set-name table.
|
||||
Unknown and explicitly unused entries produce no row.
|
||||
Known entries produce "Set: <name>".
|
||||
|
||||
ShowRatings:
|
||||
append only positive ratings, in this order:
|
||||
Dam, Dam Resist, Crit, Crit Dam, Crit Resist, Crit Dam Resist,
|
||||
Heal Boost, Nether Resist, Life Resist
|
||||
render as "Ratings: Dam 3, Crit 2" (there is no plus sign)
|
||||
positive Vitality (379) is a separate
|
||||
"This item adds %d Vitality."
|
||||
|
||||
ShowWeaponAndArmorData:
|
||||
only interpret WeaponProfile inside weapon/shield valid-location bits
|
||||
preserve retail Unknown sentinels for damage, speed, and range
|
||||
for ordinary clothing append:
|
||||
"Covers Head, Chest, Abdomen, Upper Arms, Lower Arms, Hands,
|
||||
Upper Legs, Lower Legs, Feet"
|
||||
selecting the names from ClothingPriority bits in that exact order
|
||||
|
||||
ShowShortMagic:
|
||||
list only ordinary spell ids (high bit clear)
|
||||
a failed appraisal prints "Spells: unknown."
|
||||
|
||||
ShowMagic:
|
||||
a failed appraisal also prints "Spells: unknown."
|
||||
ordinary spell rows are:
|
||||
"Spell Descriptions:\n~ <name>: <DAT description>"
|
||||
enchantment rows are:
|
||||
"Enchantments:\n~ <name>: <DAT description>"
|
||||
|
||||
ShowLevelLimits:
|
||||
min == max: "Restricted to characters of Level %d."
|
||||
min + max: "Restricted to characters of Levels %d to %d."
|
||||
min only: "Restricted to characters of Level %d or greater."
|
||||
max only: "Restricted to characters of Level %d or below."
|
||||
|
||||
ShowItemLevel:
|
||||
require ItemBaseXp (int64 5), ItemMaxLevel (319), and ItemXpStyle (320)
|
||||
currentLevel = ItemTotalXPToLevel(ItemTotalXp, baseXp, maxLevel, style)
|
||||
displayedLevel = min(currentLevel + 1, maxLevel)
|
||||
nextThreshold = ItemLevelToTotalXP(min(currentLevel + 1, maxLevel), ...)
|
||||
"Item Level: <displayedLevel> / <maxLevel>"
|
||||
"Item XP: <grouped total> / <grouped nextThreshold>"
|
||||
|
||||
ItemLevelToTotalXP(level, base, max, style):
|
||||
clamp level to [0, max]
|
||||
style 1: base * level
|
||||
style 2: base * (2^level - 1)
|
||||
style 3: base * level * (level + 1) / 2
|
||||
|
||||
ShowActivationRequirements:
|
||||
successful appraisals only
|
||||
append Arcane Lore, Allegiance Rank, Heritage, skill, primary-attribute,
|
||||
and secondary-attribute requirements to one "Activation requires " row
|
||||
in that order
|
||||
|
||||
ShowBoostValue / ShowHealKitValues:
|
||||
ordinary consumables render Health/Mana "... when used."
|
||||
Stamina is "... when consumed."
|
||||
healer and hooked-healer profiles instead interpret BoostValue as
|
||||
"Bonus to Healing Skill" and float 100 as "Restoration Bonus"
|
||||
|
||||
ShowRareInfo:
|
||||
RareUsesTimer (bool 108):
|
||||
"This rare item has a timer restriction of 3 minutes. You will not
|
||||
be able to use another rare item with a timer within 3 minutes of
|
||||
using this one."
|
||||
RareId (17): "Rare #%d"
|
||||
|
||||
ShowDescription:
|
||||
if lifespan, creation timestamp, and remaining lifespan are present:
|
||||
remaining < 0: "This item is in the act of disintegrating."
|
||||
otherwise: "This item expires in <years/days/hours/minutes/seconds>"
|
||||
LongDesc replaces ShortDesc when present; both are never printed
|
||||
GearPlatingName (52) replaces LongDesc before decoration
|
||||
AppraisalItemSkill (172) decorates that description:
|
||||
bit 1 prepends workmanship
|
||||
MaterialType (131) prepends the DAT material display name and removes
|
||||
its first occurrence from the authored description
|
||||
bit 4 appends ", set with <count> <pluralized material>"
|
||||
PortalBitmask (111) appends, in bit order:
|
||||
Player Killers may not use this portal.
|
||||
Lite Player Killers may not use this portal.
|
||||
Non-Player Killers may not use this portal.
|
||||
This portal cannot be recalled nor linked to.
|
||||
This portal cannot be summoned.
|
||||
```
|
||||
|
||||
The material name is not a locally invented table.
|
||||
`MaterialTypeEnumMapper::MaterialTypeToString @ 0x005CD500` performs
|
||||
`DBObj::GetByEnum(DBObjType=0x28, clientEnum=0x10000001, subEnum=1)`:
|
||||
the master map resolves the root `EnumIDMap`, sub-enum 1 resolves the material
|
||||
`DualEnumIDMap`, and its client name is read with underscores replaced by
|
||||
spaces. Creature/slayer
|
||||
names use `EnumMapper::GetString(0x10000005, value)`; heritage restrictions use
|
||||
`EnumMapper::GetString(0x10000002, value)` with retail's explicit
|
||||
Gharu'ndim/Umbraen/Olthoi spellings.
|
||||
|
||||
Additional named sources for these branches:
|
||||
|
||||
- `ItemExamineUI::Appraisal_ShowSet @ 0x004AE880`
|
||||
- `ItemExamineUI::Appraisal_ShowRatings @ 0x004AF080`
|
||||
- `ItemExamineUI::Appraisal_ShowTinkeringInfo @ 0x004B0E70`
|
||||
- `ItemExamineUI::Appraisal_ShowLevelLimitInfo @ 0x004B2920`
|
||||
- `ItemExamineUI::Appraisal_ShowItemLevelInfo @ 0x004B3C60`
|
||||
- `ItemExamineUI::Appraisal_ShowDescription @ 0x004B6990`
|
||||
- `ExperienceSystem::ItemLevelToTotalXP @ 0x005C8100`
|
||||
- `ExperienceSystem::ItemTotalXPToLevel @ 0x005C81B0`
|
||||
- `MaterialTypeEnumMapper::MaterialTypeToString @ 0x005CD500`
|
||||
|
||||
Sources:
|
||||
|
||||
- `ItemExamineUI::SetAppraiseInfo @ 0x004B72B0`
|
||||
|
|
@ -677,11 +810,13 @@ 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 and ratings, animated creature preview,
|
||||
viewport/list/text compositing, selection-follow, scrollbar ownership, and
|
||||
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.
|
||||
viewport/list/text compositing, selection-follow, scrollbar ownership, combat
|
||||
refresh, and the complete EoR item-report dispatch are in scope. Item rows now
|
||||
preserve retail's appraisal-only unknown values, hook/capacity/lock presence
|
||||
rules, exact paragraph boundaries, authored normal/beneficial/detrimental
|
||||
font-color selection, equipment-set/ratings/tinkering/weapon/armor/magic/XP/
|
||||
activation/healer/rare/description ordering, and installed-DAT material and
|
||||
creature names. Retail's item-object preview, live player-dependent effective
|
||||
shield/cooldown projections, localized augmentation-cost `StringInfo`,
|
||||
creature incomplete/high/low FontInfo selection, complete character detail,
|
||||
and PSR-only scribe-account/override behavior remain explicit AP-110 work.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue