diablo2-web/arena.html

781 lines
29 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>d2web · 战斗数学与攻防测试竞技场(Issue #24 / M9)</title>
<style>
:root {
color-scheme: dark;
--bg-main: #0b0906;
--bg-panel: rgba(22, 18, 14, 0.92);
--border-color: #382d22;
--gold-primary: #c8a15a;
--gold-light: #e8dcc8;
--text-dim: #9c8d78;
--btn-bg: #221c15;
--btn-hover: #3a2f24;
}
* { box-sizing: border-box; }
html, body {
margin: 0;
padding: 0;
height: 100%;
background: var(--bg-main);
color: var(--gold-light);
font: 13px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
overflow: hidden;
}
/* 顶部导航 */
header {
height: 42px;
background: #14100c;
border-bottom: 1px solid var(--border-color);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 16px;
}
header h1 {
margin: 0;
font-size: 14px;
color: var(--gold-primary);
letter-spacing: 0.06em;
display: flex;
align-items: center;
gap: 8px;
}
header a {
color: var(--gold-primary);
text-decoration: none;
margin-left: 12px;
}
header a:hover { text-decoration: underline; }
/* 三栏主容器 */
#app-container {
display: grid;
grid-template-columns: 310px 1fr 310px;
height: calc(100vh - 42px);
overflow: hidden;
}
/* 侧边设定栏 */
.sidebar {
background: var(--bg-panel);
border-right: 1px solid var(--border-color);
display: flex;
flex-direction: column;
height: 100%;
overflow-y: auto;
}
.sidebar.right-sidebar {
border-right: none;
border-left: 1px solid var(--border-color);
}
.panel-header {
padding: 10px 14px;
background: #1a1510;
border-bottom: 1px solid var(--border-color);
color: var(--gold-primary);
font-weight: bold;
font-size: 13px;
display: flex;
align-items: center;
justify-content: space-between;
}
.panel-content {
padding: 12px 14px;
display: flex;
flex-direction: column;
gap: 10px;
overflow-y: auto;
}
/* 表单元素 */
.form-group {
display: flex;
flex-direction: column;
gap: 4px;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
}
.form-row-3 {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 6px;
}
label {
font-size: 11px;
color: var(--text-dim);
}
input, select {
background: #18140f;
border: 1px solid var(--border-color);
color: var(--gold-light);
padding: 4px 8px;
border-radius: 4px;
font: inherit;
font-size: 12px;
}
input[type="number"] {
font-variant-numeric: tabular-nums;
}
input:focus, select:focus {
outline: none;
border-color: var(--gold-primary);
}
.badge-section {
border-top: 1px dashed var(--border-color);
padding-top: 8px;
margin-top: 4px;
}
.section-title {
font-size: 11px;
color: var(--gold-primary);
margin-bottom: 6px;
font-weight: 600;
}
/* 中间主视口 */
#center-area {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
/* 画布容器 */
#viewport-wrapper {
position: relative;
flex: 1;
min-height: 280px;
background: #000;
overflow: hidden;
border-bottom: 1px solid var(--border-color);
}
#view {
width: 100%;
height: 100%;
display: block;
}
/* 操作控制栏 */
#action-bar {
background: #15110d;
padding: 8px 14px;
border-bottom: 1px solid var(--border-color);
display: flex;
gap: 8px;
flex-wrap: wrap;
align-items: center;
}
.btn {
background: var(--btn-bg);
border: 1px solid var(--border-color);
color: var(--gold-light);
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
font: inherit;
font-size: 12px;
display: inline-flex;
align-items: center;
gap: 6px;
transition: all 0.15s ease;
}
.btn:hover {
background: var(--btn-hover);
border-color: var(--gold-primary);
color: #fff;
}
.btn:active {
transform: translateY(1px);
}
.btn.primary {
background: #3d2b18;
border-color: #8c6a38;
color: #ffdfa9;
font-weight: bold;
}
.btn.primary:hover {
background: #543b20;
border-color: var(--gold-primary);
}
.btn.spell-fire { color: #ff8c5a; }
.btn.spell-cold { color: #72c2ff; }
.btn.spell-light { color: #ffe66d; }
.btn.spell-magic { color: #df9aff; }
.btn.danger { color: #ff6b6b; }
/* 公式日志分解面板 */
#log-panel {
height: 200px;
background: #0d0b08;
display: flex;
flex-direction: column;
overflow: hidden;
}
.log-header {
padding: 6px 12px;
background: #16120e;
border-bottom: 1px solid var(--border-color);
display: flex;
justify-content: space-between;
align-items: center;
font-size: 11px;
color: var(--text-dim);
}
#log-entries {
flex: 1;
overflow-y: auto;
padding: 8px 12px;
font-size: 12px;
line-height: 1.5;
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.log-item {
margin-bottom: 6px;
padding-bottom: 6px;
border-bottom: 1px solid #1f1913;
}
.log-item.hit { color: #c8e6c9; }
.log-item.miss { color: #78909c; }
.log-item.blocked { color: #90caf9; }
.log-item.crit { color: #ffe082; }
/* 状态与指示器 */
.tag {
display: inline-block;
padding: 1px 5px;
border-radius: 3px;
font-size: 10px;
font-weight: bold;
text-transform: uppercase;
}
.tag.immune { background: #b71c1c; color: #fff; }
.tag.res { background: #37474f; color: #cfd8dc; }
/* 快捷键提示 */
.key-pill {
display: inline-block;
background: #2b2319;
border: 1px solid #4a3c2c;
border-radius: 3px;
padding: 0 4px;
font-size: 10px;
color: var(--gold-primary);
}
</style>
</head>
<body>
<header>
<h1>
<span>⚔️</span>
<span>暗黑破坏神 2 · 真实战斗数学与攻防测试竞技场</span>
<span style="font-size: 11px; color: var(--text-dim); font-weight: normal;">(Issue #24 / M9)</span>
</h1>
<div>
<a href="/acts.html">🎮 返回战役漫步 (acts.html)</a>
</div>
</header>
<div id="app-container">
<!-- 左栏:角色属性设定 -->
<aside class="sidebar" id="player-sidebar">
<div class="panel-header">
<span>🧙 玩家角色数值 (Hero)</span>
<select id="char-preset" style="padding: 2px 4px; font-size: 11px;">
<option value="custom">-- 快捷预设模版 --</option>
<option value="novice">🔰 Lv1 新手物理角色</option>
<option value="zealot">⚔️ Lv45 圣骑士狂热狂徒</option>
<option value="sorc_fire">🔥 Lv75 纯火系法师</option>
<option value="sorc_orb">❄️ Lv80 冰风暴法师</option>
<option value="hell_slayer">👑 Lv90 地狱狂战杀手</option>
</select>
</div>
<div class="panel-content">
<div class="form-row">
<div class="form-group">
<label>职业 (Class)</label>
<select id="char-class">
<option value="Sorceress">女巫 (Sorceress)</option>
<option value="Barbarian">野蛮人 (Barbarian)</option>
<option value="Paladin">圣骑士 (Paladin)</option>
<option value="Amazon">亚马逊 (Amazon)</option>
<option value="Necromancer">死灵法师 (Necromancer)</option>
</select>
</div>
<div class="form-group">
<label>角色等级 (1–99)</label>
<input type="number" id="char-level" min="1" max="99" value="30" />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>生命值 (HP / Max)</label>
<input type="number" id="char-hp" min="1" max="9999" value="350" />
</div>
<div class="form-group">
<label>法力值 (Mana / Max)</label>
<input type="number" id="char-mana" min="0" max="9999" value="200" />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>攻击准确率 (AR / ToHit)</label>
<input type="number" id="char-ar" min="0" max="99999" value="1200" />
</div>
<div class="form-group">
<label>角色防御力 (DR / AC)</label>
<input type="number" id="char-dr" min="0" max="99999" value="650" />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>基础物理武器最小伤害</label>
<input type="number" id="char-dmg-min" min="1" max="9999" value="25" />
</div>
<div class="form-group">
<label>基础物理武器最大伤害</label>
<input type="number" id="char-dmg-max" min="1" max="9999" value="65" />
</div>
</div>
<div class="badge-section">
<div class="section-title">✨ 附加元素伤害 (Added Elemental Dmg)</div>
<div class="form-row">
<div class="form-group">
<label>🔥 火焰伤害 (Fire)</label>
<input type="number" id="char-fire" min="0" max="9999" value="15" />
</div>
<div class="form-group">
<label>❄️ 冰冷伤害 (Cold)</label>
<input type="number" id="char-cold" min="0" max="9999" value="10" />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>⚡ 闪电伤害 (Light)</label>
<input type="number" id="char-light" min="0" max="9999" value="25" />
</div>
<div class="form-group">
<label>☠️ 毒素伤害 (Poison)</label>
<input type="number" id="char-poison" min="0" max="9999" value="0" />
</div>
</div>
<div class="form-group">
<label>🔮 纯魔法伤害 (Magic)</label>
<input type="number" id="char-magic" min="0" max="9999" value="0" />
</div>
</div>
<div class="badge-section">
<div class="section-title">⚡ 暴击、压碎与撕裂 (CS / DS / CB / OW)</div>
<div class="form-row">
<div class="form-group">
<label>技能致命 CS % (Skill)</label>
<input type="number" id="char-cs" min="0" max="100" value="20" />
</div>
<div class="form-group">
<label>装备双倍 DS % (Item)</label>
<input type="number" id="char-ds" min="0" max="100" value="15" />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>压碎性打击 CB %</label>
<input type="number" id="char-cb" min="0" max="100" value="25" />
</div>
<div class="form-group">
<label>撕开伤口 OW % (8秒流血)</label>
<input type="number" id="char-ow" min="0" max="100" value="25" />
</div>
</div>
<div class="form-row" style="margin-top: 4px;">
<div class="form-group">
<label style="display:flex; align-items:center; gap:6px; cursor:pointer; color:#81c784; font-size:11px;">
<input type="checkbox" id="char-pmh" checked />
<span>阻止怪物自愈 (PMH: 80分锁血)</span>
</label>
</div>
<div class="form-group">
<label style="display:flex; align-items:center; gap:6px; cursor:pointer; color:var(--text-dim); font-size:11px;">
<input type="checkbox" id="char-is-merc" />
<span>雇佣兵出手 (PMH无效)</span>
</label>
</div>
</div>
</div>
<div class="badge-section">
<div class="section-title">⚡ 元素破免与光环诅咒 (1/5th Rule & -% Res)</div>
<div class="form-row">
<div class="form-group">
<label>审判光环 Conviction -%</label>
<input type="number" id="char-conviction" min="0" max="150" value="0" placeholder="如无限: 85" />
</div>
<div class="form-group">
<label>降低抗性 Lower Resist -%</label>
<input type="number" id="char-lower-res" min="0" max="100" value="0" placeholder="如诅咒: 60" />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>装备直减电抗 -% (Griffon)</label>
<input type="number" id="char-minus-light-res" min="0" max="100" value="0" />
</div>
<div class="form-group">
<label>装备直减火抗 -% (Facet)</label>
<input type="number" id="char-minus-fire-res" min="0" max="100" value="0" />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>装备直减冰抗 -%</label>
<input type="number" id="char-minus-cold-res" min="0" max="100" value="0" />
</div>
<div class="form-group">
<label>装备直减毒抗 -% (Death's Web)</label>
<input type="number" id="char-minus-poison-res" min="0" max="100" value="0" />
</div>
</div>
</div>
<div class="badge-section">
<div class="section-title">🛑 状态异常与控制 (Slow / HBT / HCMTF)</div>
<div class="form-row">
<div class="form-group">
<label>减速目标 Slows Target %</label>
<input type="number" id="char-slow" min="0" max="100" value="0" placeholder="如水魔: 75" />
</div>
<div class="form-group">
<label>致盲目标 HBT (微暗灵视 +X)</label>
<input type="number" id="char-hbt" min="0" max="20" value="0" placeholder="如+1致盲" />
</div>
</div>
<div class="form-group">
<label>击中使怪逃跑 HCMTF % (恐吓5秒)</label>
<input type="number" id="char-hcmtf" min="0" max="100" value="0" placeholder="如25%" />
</div>
</div>
<div class="badge-section">
<div class="section-title">🗡️ 悔恨纯伤与离体增伤 (Off-Weapon ED)</div>
<div class="form-row">
<div class="form-group">
<label>绝对基础纯伤害 (+Dmg 悔恨)</label>
<input type="number" id="char-flat-dmg" min="0" max="999" value="0" placeholder="如悔恨: 400" />
</div>
<div class="form-group">
<label>离体增伤 ED % (刚毅/狂热)</label>
<input type="number" id="char-off-weapon-ed" min="0" max="2000" value="0" placeholder="如刚毅: 300" />
</div>
</div>
<div class="form-group">
<label>属性点力敏增伤 % (Str/Dex Bonus)</label>
<input type="number" id="char-stat-bonus" min="0" max="1000" value="0" />
</div>
</div>
<div class="badge-section">
<div class="section-title">🎯 破防、吸取与控制 (ITD / Leech / Freeze)</div>
<div class="form-row">
<div class="form-group">
<label>偷取生命 LL %</label>
<input type="number" id="char-ll" min="0" max="100" value="10" />
</div>
<div class="form-group">
<label>偷取法力 ML %</label>
<input type="number" id="char-ml" min="0" max="100" value="5" />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>降低目标防御 % (-% Def)</label>
<input type="number" id="char-def-red" min="0" max="100" value="25" />
</div>
<div class="form-group">
<label>冻结目标 +X (Freezes)</label>
<input type="number" id="char-freeze" min="0" max="20" value="1" />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>击退几率 % (Knockback)</label>
<input type="number" id="char-knockback" min="0" max="100" value="25" />
</div>
<div class="form-group" style="justify-content: flex-end; padding-bottom: 2px;">
<label style="display:flex; align-items:center; gap:6px; cursor:pointer; color:var(--gold-primary); font-size:12px;">
<input type="checkbox" id="char-itd" />
<span>无视目标防御 (ITD)</span>
</label>
</div>
</div>
<div class="form-group">
<label>游戏难度 (Difficulty)</label>
<select id="game-difficulty">
<option value="normal">普通难度 (Normal: 100% 汲取)</option>
<option value="nightmare">噩梦难度 (Nightmare: 50% 汲取惩罚)</option>
<option value="hell">地狱难度 (Hell: 33% 汲取惩罚)</option>
</select>
</div>
</div>
<div class="badge-section">
<div class="section-title">🛡️ 防护与格挡 (Defense & Reductions)</div>
<div class="form-row-3">
<div class="form-group">
<label>格挡率 %</label>
<input type="number" id="char-block" min="0" max="75" value="45" />
</div>
<div class="form-group">
<label>物减 (Flat DR)</label>
<input type="number" id="char-flat-dr" min="0" max="999" value="2" />
</div>
<div class="form-group">
<label>魔减 (Flat MDR)</label>
<input type="number" id="char-flat-mdr" min="0" max="999" value="2" />
</div>
</div>
</div>
</div>
</aside>
<!-- 中间主视区 -->
<main id="center-area">
<!-- 画布视区 -->
<div id="viewport-wrapper">
<canvas id="view"></canvas>
</div>
<!-- 动作操作栏 -->
<div id="action-bar">
<button class="btn primary" id="btn-attack" title="快捷键: 1 或 空格">
<span>⚔️ 物理挥砍</span>
<span class="key-pill">1/Space</span>
</button>
<button class="btn spell-fire" id="btn-fire" title="快捷键: 2">
<span>🔥 火球法术</span>
<span class="key-pill">2</span>
</button>
<button class="btn spell-cold" id="btn-cold" title="快捷键: 3">
<span>❄️ 冰风暴</span>
<span class="key-pill">3</span>
</button>
<button class="btn spell-light" id="btn-light" title="快捷键: 4">
<span>⚡ 充能连电</span>
<span class="key-pill">4</span>
</button>
<button class="btn spell-magic" id="btn-magic" title="快捷键: 5">
<span>🔮 纯魔法矢</span>
<span class="key-pill">5</span>
</button>
<button class="btn" id="btn-monster-attack" title="测试怪物殴打玩家">
<span>👹 怪物攻击玩家</span>
</button>
<button class="btn" id="btn-auto-battle" title="快捷键: A">
<span id="auto-battle-label">🔄 开启自动对决</span>
<span class="key-pill">A</span>
</button>
<button class="btn danger" id="btn-reset" title="快捷键: R">
<span>🩺 满血重置</span>
<span class="key-pill">R</span>
</button>
</div>
<!-- 公式推导明细面板 -->
<div id="log-panel">
<div class="log-header">
<span>📐 实时战斗数学公式推导与日志 (Combat Math Provenance)</span>
<div>
<span id="stat-dps" style="margin-right: 12px; color: var(--gold-primary);">DPS: 0.0</span>
<button class="btn" id="btn-clear-log" style="padding: 2px 8px; font-size: 11px;">清空日志</button>
</div>
</div>
<div id="log-entries"></div>
</div>
</main>
<!-- 右栏:怪物属性设定 -->
<aside class="sidebar right-sidebar" id="monster-sidebar">
<div class="panel-header">
<span>👹 怪物对手设定 (Monster Target)</span>
<span id="monster-badge" class="tag" style="background:#423223; color:#f0c070;">NORMAL</span>
</div>
<div class="panel-content">
<div class="form-group">
<label>怪物原型种类 (Type)</label>
<select id="mon-type">
<option value="fallen1">沉沦魔 (Fallen) [恶魔]</option>
<option value="zombie1">僵尸 (Zombie) [不死,弱火]</option>
<option value="quillrat1">刺鼠 (Quill Rat) [动物]</option>
<option value="skeleton1">骷髅兵 (Skeleton) [不死,毒抗]</option>
<option value="corruptrogue1">黑暗猎手 (Dark Hunter) [恶魔]</option>
<option value="goatman1">羊头人 (Moon Clan) [动物]</option>
<option value="bloodraven">血鸟 (Blood Raven) [暗金Boss]</option>
<option value="andariel">安达利尔 (Andariel) [Act 1 Boss,弱火强毒]</option>
<option value="duriel">督瑞尔 (Duriel) [Act 2 Boss,强冷抗]</option>
<option value="mephisto">墨菲斯托 (Mephisto) [Act 3 Boss]</option>
<option value="diablo">暗黑破坏神 (Diablo) [Act 4 Boss]</option>
<option value="baal">巴尔 (Baal) [Act 5 Boss]</option>
<option value="dummy">测伤木桩 (Training Dummy) [全零抗/无敌]</option>
</select>
</div>
<div class="form-row">
<div class="form-group">
<label>怪物级别 (Tier)</label>
<select id="mon-tier">
<option value="normal">普通小怪 (Normal)</option>
<option value="boss">关底首领/暗金 (Boss/SuperUnique)</option>
<option value="player">对阵玩家 (Player PvP)</option>
</select>
</div>
<div class="form-group">
<label>目标姿态 (Posture)</label>
<select id="mon-posture">
<option value="stand">站立/攻击 (Standing)</option>
<option value="run">奔跑中 (Running: 防御=0/格挡1/3)</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>怪物体型 Size (击退几率)</label>
<select id="mon-size">
<option value="small">小型怪 Small (100% 击退几率)</option>
<option value="medium" selected>中型怪 Medium (50% 击退几率)</option>
<option value="large">大型怪 Large (25% 击退几率)</option>
</select>
</div>
<div class="form-group">
<label>自然回血速率 (RegenRate/4096)</label>
<input type="number" id="mon-regen" min="0" max="100" value="0" />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label style="display:flex; align-items:center; gap:6px; cursor:pointer; color:#ef5350; font-size:11px;">
<input type="checkbox" id="mon-is-uber" />
<span>超级火炬 Boss (Pandemonium Uber: 免疫PMH)</span>
</label>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>怪物等级 (Level 1–99)</label>
<input type="number" id="mon-level" min="1" max="99" value="28" />
</div>
<div class="form-group">
<label>格挡几率 % (Block)</label>
<input type="number" id="mon-block" min="0" max="75" value="0" />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>生命值 (HP / Max)</label>
<input type="number" id="mon-hp" min="1" max="999999" value="180" />
</div>
<div class="form-group">
<label>汲取效率 % (Drain Eff)</label>
<input type="number" id="mon-drain-eff" min="0" max="100" value="100" />
</div>
</div>
<div class="form-group">
<label>最大生命 (Max HP)</label>
<input type="number" id="mon-max-hp" min="1" max="999999" value="180" />
</div>
<div class="form-row">
<div class="form-group">
<label>防御力 (DR / AC)</label>
<input type="number" id="mon-dr" min="0" max="99999" value="480" />
</div>
<div class="form-group">
<label>命中等级 (AR / ToHit)</label>
<input type="number" id="mon-ar" min="0" max="99999" value="520" />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>怪物攻击最小伤害</label>
<input type="number" id="mon-dmg-min" min="1" max="9999" value="12" />
</div>
<div class="form-group">
<label>怪物攻击最大伤害</label>
<input type="number" id="mon-dmg-max" min="1" max="9999" value="28" />
</div>
</div>
<div class="badge-section">
<div class="section-title">🛡️ 各系元素抗性 (-100% ~ 150%, >=100% 即为免疫)</div>
<div class="form-row">
<div class="form-group">
<label>🛡️ 物理抗性 (Phys %)</label>
<input type="number" id="mon-res-phys" min="-100" max="200" value="0" />
</div>
<div class="form-group">
<label>🔥 火焰抗性 (Fire %)</label>
<input type="number" id="mon-res-fire" min="-100" max="200" value="0" />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>❄️ 冰冷抗性 (Cold %)</label>
<input type="number" id="mon-res-cold" min="-100" max="200" value="0" />
</div>
<div class="form-group">
<label>⚡ 闪电抗性 (Light %)</label>
<input type="number" id="mon-res-light" min="-100" max="200" value="0" />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>☠️ 毒素抗性 (Poison %)</label>
<input type="number" id="mon-res-poison" min="-100" max="200" value="0" />
</div>
<div class="form-group">
<label>🔮 魔法抗性 (Magic %)</label>
<input type="number" id="mon-res-magic" min="-100" max="200" value="0" />
</div>
</div>
</div>
<div class="badge-section">
<div class="section-title">📊 怪物减伤 (Damage Reduction)</div>
<div class="form-row">
<div class="form-group">
<label>物理减免 (Flat DR)</label>
<input type="number" id="mon-flat-dr" min="0" max="999" value="0" />
</div>
<div class="form-group">
<label>魔法减免 (Flat MDR)</label>
<input type="number" id="mon-flat-mdr" min="0" max="999" value="0" />
</div>
</div>
</div>
</div>
</aside>
</div>
<script type="module" src="/src/arena.ts"></script>
</body>
</html>