feat(web): 适配阵营技能树系统

- 添加技能树 CSS 样式(紧凑布局、状态指示)
- 添加技能树 HTML 结构
- 实现 renderSkills 渲染函数
- 显示技能解锁状态、名称、cost

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
empty
2025-12-30 13:31:18 +08:00
parent 3f75eb26c4
commit 4664796d0b

View File

@@ -125,6 +125,22 @@
/* 剧情事件提示 */
#story-event { background: #3b0764; border: 1px solid #a78bfa; border-radius: 8px; padding: 12px; margin-bottom: 16px; display: none; font-size: 14px; }
/* 技能树 */
.skill-trees { margin-top: 16px; padding-top: 12px; border-top: 1px solid #3f3f46; }
.skill-trees-title { font-size: 11px; color: #71717a; text-transform: uppercase; margin-bottom: 8px; letter-spacing: 0.05em; }
.skill-trees-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.skill-tree { background: #27272a; border-radius: 6px; padding: 10px; }
.skill-tree-header { font-size: 11px; font-weight: 600; margin-bottom: 8px; display: flex; align-items: center; gap: 4px; }
.skill-tree-header.opt { color: #86efac; }
.skill-tree-header.fear { color: #fca5a5; }
.skill-item { display: flex; align-items: center; gap: 6px; padding: 6px 8px; margin-bottom: 4px; border-radius: 4px; font-size: 11px; background: #1a1a2e; }
.skill-item:last-child { margin-bottom: 0; }
.skill-item.unlocked { border-left: 2px solid #22c55e; }
.skill-item.locked { border-left: 2px solid #3f3f46; opacity: 0.7; }
.skill-icon { font-size: 12px; }
.skill-name { flex: 1; color: #e4e4e7; }
.skill-cost { font-size: 10px; color: #71717a; background: #3f3f46; padding: 2px 6px; border-radius: 3px; }
</style>
</head>
<body>
@@ -193,6 +209,8 @@
<div class="faction-power" id="faction-power"></div>
<!-- 剧情线 -->
<div class="story-arcs" id="story-arcs"></div>
<!-- 技能树 -->
<div class="skill-trees" id="skill-trees"></div>
</div>
<div class="card">
<div class="card-title">居民</div>
@@ -252,6 +270,19 @@
const weatherMap = { sunny: '☀️', rainy: '🌧️' };
const actionHistory = [];
// 渲染技能列表
function renderSkills(skills, names) {
return Object.entries(skills).map(([id, s]) => {
const cls = s.unlocked ? 'unlocked' : 'locked';
const icon = s.unlocked ? '✅' : '🔒';
return `<div class="skill-item ${cls}">
<span class="skill-icon">${icon}</span>
<span class="skill-name">${names[id] || id}</span>
<span class="skill-cost">${s.cost}</span>
</div>`;
}).join('');
}
function updateUI(data) {
const { world_state, actions, global_event, triggered_faction_event, story_event } = data;
@@ -355,6 +386,28 @@
}).join('');
}
// ⑦ 技能树
if (world_state.faction_skills) {
const skillsEl = document.getElementById('skill-trees');
const fs = world_state.faction_skills;
const skillNames = {
festival_boost: '节日增幅', unity: '团结一心',
panic_spread: '恐慌蔓延', control: '压制控制'
};
skillsEl.innerHTML = `
<div class="skill-trees-title">技能树</div>
<div class="skill-trees-grid">
<div class="skill-tree">
<div class="skill-tree-header opt">🌟 乐观派</div>
${renderSkills(fs.optimists.skills, skillNames)}
</div>
<div class="skill-tree">
<div class="skill-tree-header fear">💀 恐惧派</div>
${renderSkills(fs.fearful.skills, skillNames)}
</div>
</div>`;
}
// 角色
const agentsEl = document.getElementById('agents');
agentsEl.innerHTML = '';