fix(ui): restore authentic 1.13c mercenary hire stone dialog and packet protocol (#558) #561

Merged
troytt merged 1 commits from fix/issue-558-mercenary-hire-ui into main 2026-10-02 10:41:26 +00:00
Owner

Summary

Closes #558.
Restores authentic Diablo II v1.13c mercenary hire stone dialog, scrollable list control, confirmation warning dialog, and packet protocol per decompiled binary ground truth (D2Client.dll, D2Common.dll, D2Game.dll, Hireling.txt, textslid.dc6).

Resolves the broken placeholder and overflowing cards reported in:
https://screenshot-v2.corp.google.com/2qe6rvuna5ci8


Changes Implemented

  1. Authentic 490x350 Stone Dialog & textslid.dc6 Scrollable List (D2Client.dll 0x6faf9440 & 0x6fb17d00):

    • Replaced fake 320x432 left dock panel with centered 490x350 stone dialog at x = (screenWidth - 490) / 2 = 155, y = screenHeight / 2 - 195 = 105 with carved boxpieces.dc6 frame.
    • Extracted data/global/ui/menu/textslid.dc6 (17 frames of 12x13) to public/assets/ui/textslid.png and public/ui/textslid.png, integrated into pack-ui.ts, pack-ui-assets.ts, and baked-ui-meta.ts.
    • Title line at y = 126 formatted in font16 white: String 0x0d24 (ItemDesc1s: "Your Gold: %d Hire which Mercenary?" / "你的金錢: %d 雇用那個傭兵? ") displaying player available gold (playerGold + stashGold).
    • Scrollable candidate list at x = 155, y = 140, w = 490, h = 280 displaying up to 7 candidates at a time (34px 2-line pitch per candidate: Line 1 with name, lvl, hp, def, cost; Line 2 with HireDesc ability string).
    • Up/down scroll buttons and proportional slider thumb (textslid.dc6 frames 8, 9, 13, 14, 15, 16) activated when candidates > 7, supporting mouse clicks, dragging, and mouse wheel.
    • Bottom Cancel option at y = 420: String 0x0d48 (Back: "cancel" / "取消"), which closes the hire dialog and re-opens the originating NPC menu (D2Client.dll 0x6faf9090).
    • Suppressed npcMenu rendering and re-opening while the hire stone dialog is active.
  2. 64-bit LCG Stat Derivation (D2Common.dll Ordinals 10988 0x6fd7c9e0 & 10458 0x6fd7ccc0):

    • Implemented src/common/units/hireling-table.ts containing all 120 compiled records of hireling.bin.
    • Act index mapping per D2Common_10988 from mercenary name ID (0 Rogue, 1 Desert Mercenary, 2 Iron Wolf, 4 Barbarian).
    • Candidate stat, level, hire cost, and ability resolution per D2Common_10458 64-bit LCG (seedLo = dwSeed >>> 0, seedHi = 666, multiplier 0x6AC690C5).
    • Exported all 167 mercenary names (merc01..merc34, merca201..merca241, MercX101..MercX167) and ability descriptions (strhirespecial1..10, PalMerc*) in both English and Chinese into canonical-tbl-strings.ts.
  3. Replace Mercenary Confirmation Dialog (D2Client.dll 0x6faf7500):

    • If the player currently has an active living or dead mercenary, clicking a candidate prompts the centered 300x160 stone confirmation dialog with String 0x0d18 (VerifyTransaction9: "This Mercenary will replace your current one." / "這個傭兵會換掉前一位。"), Yes (0x0d10), and No (0x0d11).
    • Clicking Yes confirms the transaction and dispatches 0x36 MercHire.
  4. C2S 0x36 MercHire Protocol Fix (D2Game.dll 0x6fcdd5e0 / 0x6fcdd490):

    • Fixed hireMerc to send wMercName (nameId) instead of seed as the second u32 parameter in 0x36 MercHire (9B), satisfying authoritative D2GS candidate validation.
  5. Testing & Parity Verification:

    • Added unit test suite tests/common/hireling-table.test.ts verifying act resolution, localized names, ability descriptions, and LCG stat calculations.
    • Added unit test suite tests/client/hire-dialog.test.ts verifying 490x350 stone dialog rendering, scrolling, hit testing, confirmation dialog, and cancel re-opening NPC menu.
    • All 254 relevant tests across 10 test suites passed cleanly with 0 regressions.
## Summary Closes #558. Restores authentic Diablo II v1.13c mercenary hire stone dialog, scrollable list control, confirmation warning dialog, and packet protocol per decompiled binary ground truth (`D2Client.dll`, `D2Common.dll`, `D2Game.dll`, `Hireling.txt`, `textslid.dc6`). Resolves the broken placeholder and overflowing cards reported in: https://screenshot-v2.corp.google.com/2qe6rvuna5ci8 --- ## Changes Implemented 1. **Authentic 490x350 Stone Dialog & `textslid.dc6` Scrollable List (`D2Client.dll` `0x6faf9440` & `0x6fb17d00`)**: - Replaced fake 320x432 left dock panel with centered `490x350` stone dialog at `x = (screenWidth - 490) / 2 = 155, y = screenHeight / 2 - 195 = 105` with carved `boxpieces.dc6` frame. - Extracted `data/global/ui/menu/textslid.dc6` (17 frames of `12x13`) to `public/assets/ui/textslid.png` and `public/ui/textslid.png`, integrated into `pack-ui.ts`, `pack-ui-assets.ts`, and `baked-ui-meta.ts`. - Title line at `y = 126` formatted in `font16` white: String `0x0d24` (`ItemDesc1s`: `"Your Gold: %d Hire which Mercenary?"` / `"你的金錢: %d 雇用那個傭兵? "`) displaying player available gold (`playerGold + stashGold`). - Scrollable candidate list at `x = 155, y = 140, w = 490, h = 280` displaying up to 7 candidates at a time (`34px` 2-line pitch per candidate: Line 1 with name, lvl, hp, def, cost; Line 2 with `HireDesc` ability string). - Up/down scroll buttons and proportional slider thumb (`textslid.dc6` frames 8, 9, 13, 14, 15, 16) activated when candidates > 7, supporting mouse clicks, dragging, and mouse wheel. - Bottom Cancel option at `y = 420`: String `0x0d48` (`Back`: `"cancel"` / `"取消"`), which closes the hire dialog and re-opens the originating NPC menu (`D2Client.dll` `0x6faf9090`). - Suppressed `npcMenu` rendering and re-opening while the hire stone dialog is active. 2. **64-bit LCG Stat Derivation (`D2Common.dll` Ordinals 10988 `0x6fd7c9e0` & 10458 `0x6fd7ccc0`)**: - Implemented `src/common/units/hireling-table.ts` containing all 120 compiled records of `hireling.bin`. - Act index mapping per `D2Common_10988` from mercenary name ID (`0` Rogue, `1` Desert Mercenary, `2` Iron Wolf, `4` Barbarian). - Candidate stat, level, hire cost, and ability resolution per `D2Common_10458` 64-bit LCG (`seedLo = dwSeed >>> 0`, `seedHi = 666`, multiplier `0x6AC690C5`). - Exported all 167 mercenary names (`merc01`..`merc34`, `merca201`..`merca241`, `MercX101`..`MercX167`) and ability descriptions (`strhirespecial1..10`, `PalMerc*`) in both English and Chinese into `canonical-tbl-strings.ts`. 3. **Replace Mercenary Confirmation Dialog (`D2Client.dll` `0x6faf7500`)**: - If the player currently has an active living or dead mercenary, clicking a candidate prompts the centered `300x160` stone confirmation dialog with String `0x0d18` (`VerifyTransaction9`: `"This Mercenary will replace your current one."` / `"這個傭兵會換掉前一位。"`), `Yes` (`0x0d10`), and `No` (`0x0d11`). - Clicking `Yes` confirms the transaction and dispatches `0x36 MercHire`. 4. **C2S `0x36` MercHire Protocol Fix (`D2Game.dll` `0x6fcdd5e0` / `0x6fcdd490`)**: - Fixed `hireMerc` to send `wMercName` (`nameId`) instead of `seed` as the second `u32` parameter in `0x36 MercHire` (9B), satisfying authoritative D2GS candidate validation. 5. **Testing & Parity Verification**: - Added unit test suite `tests/common/hireling-table.test.ts` verifying act resolution, localized names, ability descriptions, and LCG stat calculations. - Added unit test suite `tests/client/hire-dialog.test.ts` verifying 490x350 stone dialog rendering, scrolling, hit testing, confirmation dialog, and cancel re-opening NPC menu. - All 254 relevant tests across 10 test suites passed cleanly with 0 regressions.
troytt added 1 commit 2026-10-02 10:41:12 +00:00
710ea7a856 fix(ui): restore authentic 1.13c mercenary hire stone dialog and packet protocol
- Closes #558
- Ground truth parity with Diablo II v1.13c:
  * Replace 320x432 left dock panel placeholder with authentic centered 490x350 carved stone dialog (D2Client.dll 0x6faf9440 + dialog.cpp 0x6fb53e40)
  * Implement scrollable candidate list control (0x6fb17f20 / 0x6fb17d00) with authentic textslid.dc6 vertical scrollbar
  * Eliminate vertical overflow past HUD and prevent collision with NPC interaction menu
  * Implement D2Common.dll ordinal 10988 (0x6fd7c9e0) act resolution and ordinal 10458 (0x6fd7ccc0) 64-bit LCG candidate stat, level, cost, and ability evaluation
  * Fix C2S 0x36 MercHire (9B) to send wMercName (nameId) instead of dwSeed per D2Game.dll 0x6fcdd5e0
  * Implement 300x160 stone confirmation warning dialog (0x6faf7500) when replacing an active/dead mercenary
  * Add unit tests for 1.13c Hireling.txt table and candidate dialog interaction
troytt merged commit 7873ffc227 into main 2026-10-02 10:41:26 +00:00
Sign in to join this conversation.
No reviewers
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: troytt/diablo2-web#561
No description provided.