fix(chargen): Campaign CC gate round 1 Batch F — Skills page buckets, selection, info box, cost text, arrow states

R2-4/review F1-F2 (gmCGSkillsPage): row click (and arrow click, matching
retail's own post-Increase/DecreaseSkillLevel re-select) now selects a
skill, highlights its row name, and writes the info panes' title (name +
score) and a level-gated bonus line; the description/formula halves stay
unported (SkillBase._description/_formula unreachable from this page's
current data surface, documented on RefreshInfoBox). The listbox's own
authored scrollbar link is wired to its Scroll model (live-DAT-confirmed
at 0x100003F8, matching the "+1 from the listbox" hypothesis). Cost text
now matches SetSkillText @0x00480600 exactly: Untrained's down-cost and
Specialized's up-cost are literal "0", unconditional, where the port
previously rendered blank; the 999-blank gate applies to the up-cost
only, never to a down-cost. Arrow Ghosted/Enabled state (0x1000001a/
0x1000001b) is now gated per branch, including bUntrainable/
bUnspecializable re-derived as "this row's own effective cost is
nonzero" — no new data needed since the page already resolves that cost.

R2-4b (the four-bucket sorted model) is NOT implemented — its Useable-
vs-Unuseable-Untrained split reads SkillBase.MinLevel, confirmed present
in the installed dat (SkillTable_MinLevelDistribution_NeverExceedsTrained)
but not threaded through ChargenOptions/ChargenHeritageOptions/
CharacterCreationRuntimeBindings. AP-213 row records the exact channel a
future fix needs. Also live-DAT-pinned: Templates[0]'s header-caption
child (0x100002f6) resolves as a UiButton, not UiText, in the real dat —
the same UIElement_Button-is-DynamicCast(0xc)-compatible-with-Text quirk
already ported for GF-4b's slider labels.

App suite (live-DAT env) 5321/3 -> 5328/3 (+7, zero regressions).
Runtime 1735/0 unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-16 14:18:13 +02:00
parent 2ad805469d
commit 8c30aa18ee
5 changed files with 615 additions and 33 deletions

File diff suppressed because one or more lines are too long

View file

@ -107,6 +107,36 @@ by construction (`SetBackdrop` throws if called without a reserved slot,
and the entity-list-assembly helper `BuildDrawEntities` degrades to
exactly the main entity whenever no backdrop is configured/set).
**Batch F (Skills page completion — R2-4 + review F1/F2) is CODE-COMPLETE
2026-08-16, pending the user's visual gate.** Four of R2-4's five
sub-items are fixed; R2-4b (the four-bucket sorted model) is NOT — see the
AP-213 register row for the exact missing data channel this batch's
investigation pinned down (`SkillBase.MinLevel`, confirmed present in the
installed dat but not threaded through `ChargenOptions`/
`CharacterCreationRuntimeBindings`). **Fixed:** R2-4a (row selection — a
row click, or an arrow click matching retail's own post-Increase/
DecreaseSkillLevel re-select, highlights the row and writes the info
panes' TITLE — name + score — and a level-gated bonus line; the
description/formula halves stay unported for the SAME missing-data reason
as R2-4b, documented on `CharacterCreationSkillsPage.RefreshInfoBox`'s own
doc rather than a new register row since no file outside the page's own
scope was needed to identify it); R2-4c (the listbox's own authored
scrollbar link, live-DAT-CONFIRMED at `0x100003F8` — exactly this batch's
own "+1 from the listbox" hypothesis — wired to the listbox's `Scroll`
model, the ordinary page-level linkage every other `UiTemplateListBox`
owner uses); review F1 (the Untrained-down/Specialized-up literal `"0"`
cost text the prior port rendered blank, and the exact per-branch 999-blank
gate — up-cost only, never down-cost); review F2 (the
`pSkillUpButton`/`pSkillDownButton` Ghosted/Enabled state pair, gated on
credits and a re-derived `bUntrainable`/`bUnspecializable` — the row's own
effective cost being nonzero — using cost data the page already resolves,
no new channel needed). Fixture + one live-DAT test this round (no
graphical client launch); App suite live-DAT env went from 5321/3 to
5328/3 (+7, zero regressions — one pre-existing baseline flake, the
streaming "injected dungeon enqueue failure" test, is a known standalone-
pass-only flake unrelated to this batch and did not reproduce on the full
post-fix run), Runtime 1735/0 unchanged.
User ran the six-page chargen flow live (build `1.0.2-cc.e`, RDP session,
windowed). Screenshots: retail Heritage, acdream Heritage, retail
Profession. The user's side-by-side retail reports are AXIOMS