feat(ui/controls): 实现完整 UI/HUD 系统、操作快捷键对齐与装备词条染色 (fixes #134, fixes #135, fixes #136, fixes #137, fixes #138, fixes #139, fixes #140)

- R1 (Issue #134): 离线烘焙预生成 UI 图集 (public/ui/) 与 embedded DropTables,彻底消除 2 秒纯色占位回退,实现零运行期 MPQ/DLL 依赖
- R2 (Issue #135): 修复地图缩放 (0.4x~8.0x) 及多 DPR 下 NPC 名称标签与模型顶部的投影对齐
- R3 (Issue #136): HUD 与全屏画布采用 1:1 纵横比等比缩放与居中,彻底修复宽屏下红蓝球被横向拉伸为椭圆的问题
- R4 (Issue #137): 传送点菜单 (Waypoint Menu) 支持点击无缝跨场景传送,随机选取地图变体并平稳降落在对应小站子网格
- R5 (Issue #138): 角色属性面板 (InvChar6) 文本与数字完美对准背景凹槽石框,加点按钮对齐
- R6 (Issue #139): 物品栏 5 级回退 DC6 图标渲染,消灭空白占位框;装备 Tooltip 等比缩放与视口翻折防遮挡
- R7 (Issue #140): 任务日志界面集成 1~5 幕全量 27 个任务图标 (a1q1..a5q6) 及 27 帧已完成印章,第 4 幕自动进行插槽钳制保护
- Controls Parity: 还原原版左键移动/NPC交互/小站/攻击,Shift 强制原地站立攻击,右键释放技能与被动/无技能移动回退,解除 A/W/S/1..4 快捷键与移动冲突
- Tooltips & Dyes: 基于 1.13c PL2 调色板 Table 104 (cgrn) 渲染翡翠绿军帽,战争召唤按 descpriority 完整呈现 11 行符文之语属性与三行正统标题
This commit is contained in:
troytt 2026-09-21 11:09:10 +00:00
parent ca55cd29d8
commit e2a74cc8f0
575 changed files with 94314 additions and 348 deletions

13
.gitignore vendored
View File

@ -23,11 +23,22 @@ samples/*
reference/
Diablo II*/
# 临时调试产物
# 临时调试产物与测试截图
.tmp/
scratch/
__pycache__/
.DS_Store
.agents/
tests/*.png
*audit*.png
public/*audit*.png
public/ui/*audit*.png
BRIEFING.md
ORIGINAL_REQUEST.md
PROJECT.md
TEST_INFRA.md
TEST_READY.md
# 覆盖率报告由 `npm run test:coverage` 生成,可随时重建
coverage/

View File

@ -18,16 +18,17 @@
h1 { font-size: 13px; margin: 0; color: #c8a15a; letter-spacing: .06em; }
a { color: #c8a15a; }
#hud { color: #9c8d78; }
#controls { left: 12px; bottom: 12px; padding: 8px 12px; display: flex; gap: 12px;
align-items: center; flex-wrap: wrap; max-width: calc(100vw - 24px); }
/* 状态与地图选择控件紧凑停靠在顶部,把屏幕底部完整让给暗黑2原版 800CtrlPnl7 控制栏与血蓝球 */
#controls { top: 4px; right: 12px; padding: 3px 8px; display: flex; gap: 8px;
align-items: center; flex-wrap: wrap; max-width: 72vw; font-size: 12px; z-index: 4; }
#controls label { color: #9c8d78; }
select { background: #1c1813; color: #e8dcc8; border: 1px solid #33291f;
border-radius: 4px; padding: 3px 6px; font: inherit; max-width: 28vw; }
border-radius: 4px; padding: 2px 5px; font: inherit; max-width: 22vw; }
optgroup { background: #1c1813; color: #c8a15a; }
option { background: #1c1813; }
/* 状态面板放在控件行上方:贴在右下角会压住"细分场景"那个下拉框 */
#status { right: 12px; bottom: 58px; padding: 6px 10px; max-width: 60vw; color: #9c8d78; }
#dialog { right: 12px; top: 36px; padding: 8px 12px; min-width: 240px; color: #e8dcc8; white-space: pre-wrap; font-size: 14px; background: rgba(30, 26, 21, .9); border-color: #c8a15a; }
#status { left: 12px; top: 34px; padding: 3px 8px; max-width: 55vw; color: #9c8d78; font-size: 11px; opacity: 0.85; pointer-events: none; z-index: 3; }
#dialog { right: 12px; top: 42px; padding: 8px 12px; min-width: 240px; color: #e8dcc8; white-space: pre-wrap; font-size: 14px; background: rgba(30, 26, 21, .9); border-color: #c8a15a; z-index: 5; }
#d2-hud-canvas { position: fixed; inset: 0; width: 100%; height: 100%; display: block; z-index: 6; pointer-events: none; image-rendering: pixelated; }
.hint { color: #6d5a34; }
</style>
</head>
@ -46,12 +47,13 @@
</select></label>
<label>场景 <select id="scene" disabled><option>正在读取场景列表…</option></select></label>
<label>细分场景 <select id="variant" disabled></select></label>
<span class="hint" style="margin:0">WASD / 方向键移动 · 滚轮或 +/− 缩放 · 三个下拉框都会换图并更新地址栏</span>
<span class="hint" style="margin:0">I背包 · A角色 · T技能 · Q任务 · V小站 · ~腰带 · R奔跑 · W换手</span>
</div>
<div id="status" class="overlay">正在加载地图…</div>
<div id="dialog" class="overlay" hidden></div>
<div id="labels" style="position: fixed; inset: 0; pointer-events: none;"></div>
<div id="labels" style="position: fixed; inset: 0; pointer-events: none; z-index: 2;"></div>
<canvas id="view" width="960" height="560"></canvas>
<canvas id="d2-hud-canvas" width="800" height="600"></canvas>
<script type="module" src="/src/scene/act-scene.ts"></script>
</body>
</html>

View File

@ -604,11 +604,12 @@
}
/* Card Quality Border Themes */
.d2-item-card.quality-unique { border-color: rgba(200, 161, 90, 0.5); background: linear-gradient(180deg, #161009 0%, #0a0704 100%); }
.d2-item-card.quality-set { border-color: rgba(0, 230, 0, 0.4); background: linear-gradient(180deg, #091609 0%, #040a04 100%); }
.d2-item-card.quality-rare { border-color: rgba(255, 255, 96, 0.4); background: linear-gradient(180deg, #161609 0%, #0a0a04 100%); }
.d2-item-card.quality-magic { border-color: rgba(72, 128, 255, 0.4); background: linear-gradient(180deg, #09101c 0%, #04070c 100%); }
.d2-item-card.quality-rune { border-color: rgba(255, 140, 0, 0.5); background: linear-gradient(180deg, #180f07 0%, #0a0603 100%); }
.d2-item-card.quality-unique, .d2-item-card.quality-暗金 { border-color: rgba(200, 161, 90, 0.5); background: linear-gradient(180deg, #161009 0%, #0a0704 100%); }
.d2-item-card.quality-set, .d2-item-card.quality-套装 { border-color: rgba(0, 230, 0, 0.4); background: linear-gradient(180deg, #091609 0%, #040a04 100%); }
.d2-item-card.quality-rare, .d2-item-card.quality-亮金 { border-color: rgba(255, 255, 96, 0.4); background: linear-gradient(180deg, #161609 0%, #0a0a04 100%); }
.d2-item-card.quality-magic, .d2-item-card.quality-魔法 { border-color: rgba(72, 128, 255, 0.4); background: linear-gradient(180deg, #09101c 0%, #04070c 100%); }
.d2-item-card.quality-rune, .d2-item-card.quality-符文 { border-color: rgba(255, 140, 0, 0.5); background: linear-gradient(180deg, #180f07 0%, #0a0603 100%); }
.d2-item-card.quality-gem, .d2-item-card.quality-宝石 { border-color: rgba(220, 220, 220, 0.4); background: linear-gradient(180deg, #141416 0%, #08080a 100%); }
/* Item Card Header */
.item-card-header {
@ -705,6 +706,21 @@
color: #ff8c00;
font-weight: 700;
}
.tooltip-stat-line.line-red {
color: #d03a3a;
font-weight: 700;
margin-top: 6px;
}
.tooltip-stat-line.line-instruction {
color: #e0d5c1;
margin-bottom: 6px;
}
.tooltip-stat-line.line-gray {
color: #999999;
}
.tooltip-stat-line.line-yellow {
color: #ffff00;
}
</style>
</head>
<body>

View File

@ -27,6 +27,7 @@
"verify:world-walk": "tsx scripts/verify-world-walk.ts",
"build:game": "vite build --base=/diablo2/ --outDir dist-game",
"pack:data": "tsx scripts/pack-act-assets.ts",
"pack:ui": "tsx scripts/pack-ui.ts",
"verify:packs": "tsx scripts/verify-packs.ts",
"verify:deploy": "tsx scripts/verify-deploy.ts",
"verify:listfile": "tsx scripts/verify-listfile.ts",

BIN
public/skills/bg_ama_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
public/skills/bg_ama_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
public/skills/bg_ama_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
public/skills/bg_ass_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
public/skills/bg_ass_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
public/skills/bg_ass_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
public/skills/bg_bar_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
public/skills/bg_bar_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
public/skills/bg_bar_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
public/skills/bg_dru_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
public/skills/bg_dru_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
public/skills/bg_dru_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
public/skills/bg_nec_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
public/skills/bg_nec_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
public/skills/bg_nec_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
public/skills/bg_pal_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
public/skills/bg_pal_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
public/skills/bg_pal_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
public/skills/bg_sor_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
public/skills/bg_sor_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
public/skills/bg_sor_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
public/skills/icon_10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
public/skills/icon_100.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
public/skills/icon_101.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_102.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
public/skills/icon_103.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
public/skills/icon_104.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_105.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_106.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_107.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_108.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
public/skills/icon_109.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
public/skills/icon_110.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
public/skills/icon_111.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
public/skills/icon_112.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_113.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
public/skills/icon_114.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
public/skills/icon_115.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
public/skills/icon_116.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
public/skills/icon_117.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
public/skills/icon_118.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
public/skills/icon_119.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
public/skills/icon_12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
public/skills/icon_120.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_121.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_122.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_123.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
public/skills/icon_124.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_125.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_126.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
public/skills/icon_127.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
public/skills/icon_128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
public/skills/icon_129.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_13.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
public/skills/icon_130.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_131.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/skills/icon_132.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
public/skills/icon_133.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Some files were not shown because too many files have changed in this diff Show More