Commit Graph

941 Commits

Author SHA1 Message Date
troytt 4e461e1fdb feat(ui,items): implement 1.13c character equipment restrictions and red requirement display (#506) 2026-09-28 12:13:26 +00:00
troytt d4cd19d96c fix(frontend): load full 34-frame /ui/cursor.png atlas and render Loadingscreen.dc6 at 1.13c 256x256 centered size 2026-09-28 09:14:47 +00:00
troytt 99e23b9a53 fix(frontend): use act1/pal.pl2 and BIGMENU/radiobutton.dc6 for Battle.net Lobby per D2WinPalette.cpp & D2Multi.dll 2026-09-28 08:58:31 +00:00
troytt 298c6f6b39 fix(frontend): align button fonts (FontExocet10/FontRidiculous) and multiply engraving blend with D2Win.dll & D2Launch.dll 2026-09-28 08:28:56 +00:00
troytt a100885552 chore: remove standalone simulator pages (arena, loot, boss, skills) and related entry code 2026-09-28 08:09:37 +00:00
troytt 4914b4f770 Merge branch 'feat/bnet-flow'
# Conflicts:
#	src/scene/act-scene.ts
#	vite.config.ts
2026-09-28 07:42:22 +00:00
troytt af9a091356 feat(frontend): add bnet.html 7-stage Diablo II v1.13c pre-game & Battle.net flow into Act 1 Rogue Encampment 2026-09-28 07:39:13 +00:00
troytt 792578e566 test(ui): update vendor-panel-ui NPC menu header expectation to localized CHI name (Fixes #503) 2026-09-28 07:35:38 +00:00
troytt ef8a7ffff6 fix(i18n): resolve all Iteration 1 bilingual parity findings for Issue #503
- Prefer item.damageEn in ENG item tooltips and normalize 2H, versatile 1H/2H, and throwing weapon damage labels in localizeStarterTooltipLine and item-bridge.ts
- Fix starter set item tooltip regex ordering (+所有技能 without trailing $ and +生命补给 before +生命)
- Use getLocalizedNpcName for Town NPC stone menu headers in both ENG and CHI modes across getNpcMenuLayout, handleNpcMenuClick, and drawNpcMenu
- Add SUPERUNIQUE_TBL_ALIASES in monsterDisplayName for 7 SuperUniques whose SuperUniques.txt IDs differ from .tbl keys
- Export cleanChiItemName in ground-labels.ts and apply to CHI ground item labels and drop-to-ground status messages
- Update verify-issue-503-browser.ts LeftDockPanelKind loop + vendor/NPC coverage and expand issue-503-bilingual-parity.test.ts

Refs #503
2026-09-28 07:35:16 +00:00
troytt 6fa9c7784e feat(i18n): implement full Chinese (CHI) and English (ENG) bilingual versions (#503)
- Add src/i18n/lang.ts for URL/query/storage language detection, runtime state, and language switcher URL generation preserving query parameters
- Expand scripts/pack-canonical-tbl.ts and regenerate src/data/canonical-tbl-strings.ts with 3,721 ENG and 3,374 CHI 1.13c .tbl entries (UI, monsters, SuperUniques, levels, skills, items)
- Add completedEn speech strings for Act II Quest 2 and Act IV Quest 2 in src/data/canonical-quest-data.ts
- Add index.html bilingual entry portal, acts-zh.html (CHI), acts-en.html (ENG), and language switcher in acts.html; configure multi-page rollup inputs in vite.config.ts
- Localize all 15 UI/game modules (level-names-zh, character-sheet, control-bar, globes, ground-items, ground-labels, item-bridge, inventory, skill-tree-panel, hotkeys, npc-table, world-panels, monsters, hud-manager, act-scene) for authentic CHI and zero-CJK ENG modes
- Add tests/issue-503-bilingual-parity.test.ts and scripts/verify-issue-503-browser.ts

TAG=agy
CONV=5016e6fd-4af8-421f-ae4b-6d443a0a102a
2026-09-28 07:35:16 +00:00
troytt 44ec4124b9 fix(monsters): apply 1.13c MonUMod resistance bonuses in applyEliteModifiers/enrichMonsterStats and isolate hover from 36px click-assist 2026-09-28 07:00:16 +00:00
troytt 0be447fab3 fix(hud): enforce 1.13c Line 1 rank color prefix, MonUMod champion subtype IDs, and elite=all demotion
- Apply abilityColorPrefix (ÿc4 for Unique/Boss, ÿc3 for Champion, '' for Normal/Minion) across the entire Line 1 subtext in buildMonsterHoverSubtext per D2Client.dll 0x6fb719b0 / 0x6fb71a20 so <Race> (Demon/Undead) and race-only Champions/Bosses (DescStr == 'dummy') render in their rank color instead of white (ÿc0), and single-token overflow truncation preserves the rank color.
- Support numeric MonUMod.txt Champion subtype IDs ('16', '36'..'39' from .rdata:0x6fb86d64), case-insensitive modifier keys, and target.affixes fallback in resolveMonsterTitleAndColor, and forward descStr, subType, and affixes in monsterToTargetHudInfo.
- Demote already-elite packs in rebudgetMonsterPacks before re-promoting when elite === 'all' to prevent double-multiplying HP (9x/16x) and level (+4/+6).
- Call mouseController.syncMonsterTargetHud(camX, camY) before reading getActiveTargetMonster() in onRender so moving monsters/camera have zero 1-frame lag on the [1.25, 1.25, 1.25, 1.0] sprite highlight tint.
- Add Round 2 regression tests in tests/monster-target-bar.test.ts.

TAG=agy
CONV=4761a588-f887-4d60-a654-44297372fd6a
2026-09-28 06:19:49 +00:00
troytt 3a4cb77d06 fix(hud): resolve monster lifebar review findings, dummy DescStr filter, thief umod, and target lock 2026-09-28 05:04:38 +00:00
troytt b084aaba7f feat(hud): implement authentic 1.13c monster hover lifebar and 2-line subtext tooltip 2026-09-28 04:18:50 +00:00
troytt 2a93677e52 docs(readme): update README with latest 1.13c features, assets, pages, and controls 2026-09-28 01:49:31 +00:00
troytt 526d623f66 Merge branch 'feat/automap-113c'
# Conflicts:
#	public/ui/manifest.json
#	src/scene/act-scene.ts
#	src/ui/baked-ui-meta.ts
2026-09-28 01:33:06 +00:00
troytt a06777be07 fix(ui): remove non-authentic deposit/withdraw buttons over stash bottom keyhole area 2026-09-28 01:27:10 +00:00
troytt 14aa512e85 feat(automap): implement authentic Diablo II v1.13c isometric sprite Automap & Minimap 2026-09-28 01:27:10 +00:00
troytt b6fc2512d4 feat(drlg): generate Act I outdoor levels with the 1:1 D2MOO port (#455)
The eight Act I outdoor levels (Blood Moor 2, Cold Plains 3, Stony Field
4, Dark Wood 5, Black Marsh 6, Tamoe Highland 7, Burial Grounds 17, Moo
Moo Farm 39) are now generated by the function-by-function port of
D2MOO's D2Common DRLG in src/game/drlg, bit-exact against a native D2MOO
oracle. The legacy Act I generator (src/game/wilderness/*, the Blood Moor
branch and the Act I paths of wilderness.ts) is deleted; there is no
fallback. Acts 2-5 are unchanged.

Port (completes the kernel committed earlier):
- Tile-map stage: DRLGROOMTILE_AddRoomMapTiles with its tile-data,
  linked-tile and warp helpers, DRLGPRESET_AddPresetRoomMapTiles,
  DRLGOUTROOM_InitializeDrlgOutdoorRoom (drlg-outroom.ts), the
  DrlgDrlgLogic.cpp parts they reach (drlg-logic.ts), D2CMP shim updates.
- drlg-dump.ts: runAct1() driver API; schema 3 dumps with per-room tile
  lists. The port is now type-checked (tsconfig no longer excludes it).

Integration:
- drlg-map.ts (replaces drlg/adapter.ts): turns a generated level into
  the bake's DS1-shaped canvas with exact (style, sequence, type) per
  tile and per-cell DT1 masks, objects, seams from the DRLG level links,
  warps from their UNIT_TILE preset units; blank cells stay blocked.
- pack-act-assets: one D2 game seed per (act, variant), a DRLG bake job
  and index.json actLayouts; scripts/lib/drlg-mpq-source.ts feeds the
  port from the MPQs with the oracle's file list.
- act-variants.ts: WorldVariants picks one generated copy per act (and
  the Rogue Encampment DS1 that copy fixed); act-scene.ts and
  verify-world-walk both use it. act-scene no longer paints grass into
  the blank cells of DRLG scenes.
- world-graph: remove the invented Stony Field <-> Dark Wood seam
  (gAct1WildernessDrlgLink / gAct1MonasteryDrlgLink keep them apart;
  they meet only through the Underground Passage); world-placement
  anchors the second group at the Monastery Gate (3000, 1000).
- level-links: findBorderOpening takes an optional edge range.
- d2map: dt1MaskAllows extracted, behaviour unchanged.

Tools and tests:
- tools/d2moo-oracle: tile-map stage and schema 3; the 4 fixtures are
  regenerated (scripts/drlg-fixtures.ts).
- scripts/render-drlg-compare.ts (both dumps through the same adapter
  and renderer, fails unless the XOR is empty) and
  scripts/audit-levels-browser.ts (headless audit of every baked map).
- tests/drlg-act1-oracle.test.ts (all stages, all 4 fixtures) and
  tests/drlg-act1-invariants.test.ts; tests and stress scripts of the
  deleted generator are retired or now run on Acts 2-5 only.
- verify-world-walk: start in the town the runtime opens and floor the
  spawn sub-tile like the movement collision does.

Verification:
- drlg-diff --levels 2-7,17,39 --seeds 32: 32/32 identical at every
  stage; --trace-check 64/64, --isolated 32/32, difficulty 1 and 2 16/16.
- render-drlg-compare, 3 bake copies x 8 levels: 24/24 XOR empty.
- Full re-bake: 365 maps, 0 missing tiles. Browser audit: 355/365 maps,
  133/136 level ids clean (112/124/129: Act 5 minions without art, as
  before).
- verify:world-graph 37583 assertions; verify:world-walk 29/29;
  verify:entity-packs, typecheck clean. vitest 6369 passed; the 6
  failures (5 ground-item name formatting, 123-var3 waypoint) and the
  verify:packs / verify:generators failures also occur at bad6806.

Test pins updated, measured on the new bake: SceneEntrance 172 -> 166
and world-graph edges 286 -> 284 (the removed seam), seamless pairs
27 -> 26 and placement pairs 19 -> 18; full-spectrum floors / walls /
PNGs 1008898 / 237542 / 1390 (the old pins matched no bake of the
current code).

TAG=agy
CONV=a4f9163c-a011-4161-b169-7f361b1ed57e
2026-09-27 15:20:41 +00:00
troytt 230c20da67 fix(entities): bake the Hell Bovine (MonStats Code EC) art for the Moo Moo Farm
Commit 2e73d7b changed the Hell Bovine art token from CW to EC
(MonStats.txt hellbovine, Code EC) but never added EC to the act 1 list
of ACT_MONSTER_SPECS, so pack-entity-assets baked no ec-hth atlas and the
Moo Moo Farm's (level 39) Hell Bovines had no art.

- ACT_MONSTER_SPECS[1]: add { token: "EC", weapon: "hth" }.
- Re-baked entities: 70 monster atlases (was 69). entities/index.json is
  now sha256 675757cf...; the new ec-hth entry is its only change.
- Tests: pin 70 entities, 66 unique specs and the new index hash.

TAG=agy
CONV=a4f9163c-a011-4161-b169-7f361b1ed57e
2026-09-27 15:18:30 +00:00
troytt bad680600f feat(scene): replace G-key map transition with mouse-click warp & entrance interaction 2026-09-27 14:26:13 +00:00
troytt 1c738c5445 Merge branch 'fix/cube-transmute-btn' 2026-09-27 08:36:41 +00:00
troytt 3bf9a8c220 fix(ui): restore Horadric Cube Transmute and Close buttons per D2Client.dll 1.13c parity 2026-09-27 08:36:19 +00:00
troytt ffda82d650 Merge branch 'fix/vendor-item-bg-color' into main 2026-09-27 08:36:09 +00:00
troytt 598f8f2421 fix(ui): align vendor and gamble item background colors with D2 1.13c item usability rules 2026-09-27 08:35:32 +00:00
troytt 8c5ae5c623 fix(ui): 补齐物品栏金币按钮 (goldcoinbtn.dc6) 并对齐金币栏数值 2026-09-27 08:16:53 +00:00
troytt 855d610168 fix(ui): 点击商人面板买/卖/修理按钮后鼠标样式切换为原版 buysell.dc6 交易光标 (Fixes #491) 2026-09-27 07:47:31 +00:00
troytt 57c57c2662 Merge pull request 'fix(ui): restore authentic D2 v1.13c NPC dialog popup menu (Fixes #489)' (#495) from fix/issue-489-npc-menu-ui into main 2026-09-27 06:41:34 +00:00
troytt d998a0551b fix(ui): restore authentic D2 v1.13c NPC dialog popup menu (Fixes #489) 2026-09-27 06:41:10 +00:00
troytt 9c2e3ca81c fix(drop): prevent items and gold from dropping into player-unreachable locations (Fixes #492) 2026-09-27 06:09:02 +00:00
troytt d2358ede37 Merge pull request 'fix(ui): align Private Stash header and gold text inside TradeStash.dc6 recessed boxes (#493)' (#494) from fix/stash-text-align into main
Merge pull request 'fix(ui): align Private Stash header and gold text inside TradeStash.dc6 recessed boxes (#493)' (#494) from fix/stash-text-align into main
2026-09-27 05:55:32 +00:00
troytt 4d023e815f fix(ui): align Private Stash header and gold text inside TradeStash.dc6 recessed boxes (Fixes #493) 2026-09-27 05:54:58 +00:00
troytt f3c500978d fix(ui): 对齐技能树剩余技能点凹槽、移除底部冗余横幅并归位关闭按钮插槽 2026-09-27 05:50:42 +00:00
troytt e9c3b41768 feat(items): spawn magic/rare/set/unique drops unidentified and implement full 1.13c identification 2026-09-27 05:39:21 +00:00
troytt 7cc56ed967 Merge pull request 'fix(portal): 修正背包打开时右击回城书生成传送门遮挡、pointerEvents 穿透与城镇变体坐标同步 (#394)' (#490) from fix/issue-394-portal-visibility into main 2026-09-27 05:34:29 +00:00
troytt 5c19d92334 fix(portal): 修正背包打开时右击回城书生成传送门遮挡、pointerEvents 穿透与城镇变体坐标同步 (#394) 2026-09-27 05:32:13 +00:00
troytt e29d743f38 Merge pull request 'feat(portal): 实装回城之书/卷轴、1.13c 城镇传送门坐标与双向传送 (#394)' (#488) from feat/issue-394-town-portal into main 2026-09-26 15:11:58 +00:00
troytt 7295dc8b3e feat(portal): implement v1.13c Town Portal tome/scroll, DS1 town positions & two-way travel (#394)
- Resolve exact Diablo II v1.13c DS1 Type-2 Object #33 (Objects.txt ID 59) Town Portal sub-tiles across all 9 town presets (Acts 1-5) in src/game/portal.ts
- Implement TownPortalSlot.mouthInLevel(levelId) and enterFrom(levelId) per ObjMode.cpp:3245 (wilderness -> town keeps portal open; town -> wilderness closes portal)
- Add 20-charge quantity tracking for Tome of Town Portal (tbk) and Tome of Identify (ibk), right-click casting for tbk/tsc in inventory, and scroll-to-tome refill
- Bake authentic TP DCC sprite atlases (tptrlitophth, tphdlitophth, tptrlitonhth, tphdlitonhth) into public/overlays/town_portal_*
- Render Town Portal entity with OP/ON DCC animation, dynamic blue light (Light=19, RGB 64/110/255), overhead destination label, and proximity walk-to-interact in src/scene/act-scene.ts
- Add unit and parity tests in tests/town-portal.test.ts

Closes #394
2026-09-26 15:11:09 +00:00
troytt 43599963e4 fix(ui): separate left-click move/stack/identify-target from right-click use for tomes, scrolls, and cube (Fixes #487) 2026-09-26 14:17:57 +00:00
troytt cccc6ff527 chore(scripts): include anim, missiles, overlays, entities, and world-graph in publish-packs 2026-09-26 13:32:51 +00:00
troytt bdb3b4145a fix(ui): restore 1.13c buysell.dc6 vendor panel, tabs, and repair buttons 2026-09-26 11:45:37 +00:00
troytt 3b993cf04a feat(vendor): implement 1.13c vendor inventory generator, pricing engine & town NPC UI (Fixes #481, #482, #483, #484, #485, #486) 2026-09-26 05:49:03 +00:00
troytt b7ccc448b4 fix(items): strictly align item names & stat descriptions with 1.13c .tbl across inventory, stash, and ground (fixes #480) 2026-09-26 05:23:09 +00:00
troytt c09e237ff8 fix(drop): unify monster and inventory ground drops on 16x8 sub-tile lattice with bilingual metadata parity
1. Sub-Tile Scatter Spacing (D2Common.dll COLLISION_GetFreeCoordinatesImpl 0x6FD9D140):
   - Unify GameEngine.triggerMonsterDrop, GameEngine.dropItem, GameEngine.dropGold,
     and net-scene monster drops on findIsometricDropPosition (16x8 sub-tile diamond
     lattice, 16px orthogonal / 8px vertical spacing) instead of 80x40px macro cells.
   - Derive GroundItemEntity (cellX, cellY) from final scattered (finalX, finalY)
     via worldToCell rather than overwriting with stale origin cell coordinates.

2. Monster vs. Inventory Drop Metadata & Bilingual Name Parity:
   - Add formatBilingualGroundItemName in src/game/ground-items.ts using
     translateItemName / translateMagicName / translateRareName so raw monster-dropped
     Item objects receive identical '中文名 (English Name)' nameZh as UiInventoryItem.
   - Detect runes via isRuneCode in resolveItemQualityString so monster-dropped runes
     render with #ff9c18 orange labels matching inventory-dropped runes.
   - Preserve flippyFile, dropSound, and dropSfxFrame in itemToUiInventoryItem, fix
     socket count resolution so unsocketed items do not inherit base.gemsockets, and
     add embedded drop table fallback in resolveGroundItemMetadata.

3. Anti-Stacking for Sequential Player Inventory/Body Drops:
   - Simplify act-scene onDropItemToGround / onDropGoldToGround to delegate directly
     to engine.dropItem / engine.dropGold at (player.x, player.y) so every dropped
     item checks engine.groundItems.all and scatters to a unique sub-tile slot.

Fixes #479
2026-09-26 04:51:32 +00:00
troytt 9022579306 feat(drop): overhaul item drop engine for strict 1.13c assembly parity (Fixes #412, #413, #414, #415, #416, #417, #418, #419, #420, #421, #422, #423, #424, #425, #426, #427, #428)
- M1 (#412, #413, #414): Embed canonical DifficultyLevels.txt (RAW_DIFFICULTY_LEVELS), remove DEFAULT_DIFFICULTY_LEVEL_ODDS and synthetic rollDrop dead code, and enforce fail-fast monsterLevel/TC validation in GameEngine.
- M2 (#415, #416, #417, #418): Add 'boss' to MonsterRank (monsterType = 4), enforce Champion (+2) and Unique/Minion/SuperUnique (+3) mlvl modifiers, wire equipped Magic Find with 1.13c diminishing returns, and wire /players N NoDrop scaling.
- M3 (#419, #420, #421, #422): Spawn physical ground gold piles with 3-tier flpgld sprites and 10,000*level inventory capacity, gate drops on DT->DD death animation frame completion, trigger base item dropsound at dropsfxframe via AudioManager, and place drops via collision-grounded quadrant spiral search.
- M4 (#423, #424, #425, #427): Remove procedural colored rectangle fallbacks and verify 100% flippy DC6 coverage, apply #808080 gray ground labels for ethereal/socketed normal & superior items, align pickup bounds to 2-subtile collision reach with 2-pass auto-belt potion slotting, and synchronize multiplayer lockstep drops via monster dwInitSeed.
- M5 (#426, #428): Enforce 6-item drop cap per monster for Countess bonus rune TCs, wire Act Boss quest first-kill TreasureClass4 with save persistence, implement rollHellforgeDrop (1 rune + 4 gems), and complete full-spectrum statistical and 136-level verification.

Fixes #412
Fixes #413
Fixes #414
Fixes #415
Fixes #416
Fixes #417
Fixes #418
Fixes #419
Fixes #420
Fixes #421
Fixes #422
Fixes #423
Fixes #424
Fixes #425
Fixes #426
Fixes #427
Fixes #428
2026-09-25 22:37:17 +00:00
troytt 92966abdee feat(skills): complete 1.13c D2MOO parity for Assassin and Universal skills (#154-#374) 2026-09-25 22:13:38 +00:00
troytt d393a48043 feat(drop): embed MonStats and SuperUniques with 1.13c multi-diff TC parity (Fixes #410, #411)
- Pack and embed authentic 1.13c MonStats drop columns (734 kinds) with noRatio support
- Embed SuperUniques multi-difficulty TCs (66 unique bosses) and fail-fast loading
- Fix SuperUnique minion TC3 inheritance and minion monsterType identification
- Add adversarial drop parity audit and superunique minion test suites
- Update D2MOO oracle seed generator and Paladin skill tree parity
2026-09-25 13:44:35 +00:00
troytt 395f0b22bc feat(drlg): overhaul outdoor wilderness generator with strict D2MOO 1.13c parity (Fixes #455)
- Refactor entire wilderness generation pipeline under src/game/wilderness/
- Implement DRLGOUTPLACE dynamic level connection dimensions and orientation flags
- Align outer river double-column generation (x = nGridWidth - 2) replacing perimeter trees
- Implement authentic 4-pass secondary borders with 52 groups of DS1 substitution patterns
- Align 56x8 TownSTrans gate to river boundary and place all 5 canonical presets
- Replace dual road generators with single-pass orthogonal dirt path rasterizer
- Initialize 0x40002 base floor grass and apply LvlSub.txt SubType 6 clustered replacements
- Add D2MOO native mapgen parity fixtures and comprehensive stress & reachability test suites
2026-09-25 04:48:57 +00:00
troytt 16f2f5ef4a feat(skills): add Milestone M30 All 7 Classes Global Master Parity Gate suite 2026-09-25 04:01:20 +00:00
troytt a70ab93a61 test(skills): implement Assassin Milestone M29 Class Gate & End-to-End Suite (30/30 skills)
- Add adv-ass-e2e-gate.test.ts covering all 8 core cross-tree scenarios:
  1. Traps Tree Synergy Network & 5-Band Progression (LS +720%, DS corpse explosion, Blade weapon scaling 3/8 and 3/4).
  2. Martial Arts Charge-Up & Finisher Discharge Pipeline (multi-skill charges, single-tier Phoenix Strike, Dragon Talon multi-kicks, Dragon Claw dual strikes).
  3. Shadow Disciplines Buff Mechanics & Venom Bitrate Clamp (BoS vs Fade cancellation, Venom 10-frame clamp, CoS recast lockout).
  4. Minion & Summon Caps (5 Traps + 1 Shadow = 6 Max concurrent pets).
  5. NextDelay Collision Avoidance Across Trees (WoF 4f, Shock Web 25f, Dragon Flight 4f).
  6. Cross-Tree Hybrid Build Integration (Trapper / Kicksin / Shadow).
  7. Crowd Control & Status Effects (Mind Blast 4y stun/conversion, Psychic Hammer KB, CoS blind).
  8. Complete 30-Skill Assassin Tree Data Registry & Invariants (IDs 251..280 exist in D2DataRegistry, BATCH1_SKILLS length = 38).
- All 34 Assassin test files pass (166/166 tests passed).
- TypeScript Typecheck (tsc --noEmit) passes with 0 errors.
2026-09-25 03:52:03 +00:00