feat: add achievements center, match summary, and configurable multiplayer runtime

This commit is contained in:
leeexin committed 2026-03-08 18:28:43 +08:00
1 parent 22b90c4a6d
commit 36bb2d1730
21 files changed
+1407 -9

No files matched your search

+47
View File
@@ -0,0 +1,47 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>成就中心 - Echo Tavern</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}" />
</head>
<body class="achievements-page"
data-user='{{ user | tojson | safe if user else "null" }}'
data-theme="{{ user.theme if user else 'dopamine' }}"
data-profile-username="{{ profile_username }}">
<header class="lobby-topbar">
<div class="brand-block">
<h1>成就中心</h1>
<p id="achievements-subtitle">加载中...</p>
</div>
<div class="top-actions">
{% if user %}
<a class="link-btn" href="{{ url_for('user_profile_page', username=user.username) }}">我的主页</a>
<a class="link-btn" href="{{ url_for('user_achievements_page', username=user.username) }}">我的成就</a>
{% endif %}
<a class="link-btn" href="{{ url_for('rooms_page') }}">联机大厅</a>
<a class="link-btn" href="{{ url_for('leaderboard_page') }}">玩家排行</a>
<a class="link-btn" href="{{ url_for('index') }}">返回大厅</a>
</div>
</header>
<main class="plaza-grid achievements-grid">
<section class="card">
<h2>官方成就</h2>
<p id="official-summary" class="helper-text">加载中...</p>
<div id="official-achievements" class="achievement-rows"></div>
</section>
<section class="card">
<h2>故事卡成就</h2>
<p id="card-summary" class="helper-text">加载中...</p>
<div id="card-achievements" class="achievement-rows"></div>
</section>
</main>
<section id="status" class="status-banner"></section>
<script src="{{ url_for('static', filename='js/theme.js') }}"></script>
<script src="{{ url_for('static', filename='js/invite_notify.js') }}"></script>
<script src="{{ url_for('static', filename='js/achievements.js') }}"></script>
</body>
</html>
+24
View File
@@ -157,6 +157,30 @@
这是“高自由扩展区”。可写战斗、技能、资源、法术、阵营等结构,AI 会读取并在叙述中遵循。
</p>
<h2>玩法控制</h2>
<label for="card-interaction-mode">玩家互动模式</label>
<select id="card-interaction-mode">
<option value="hybrid">混合(可合作也可分头)</option>
<option value="cooperative">强协作(强调团队协同)</option>
<option value="split">分头行动(允许明显分线)</option>
</select>
<p class="json-help">会传给 AI 作为主持约束,决定对玩家行动关系的叙述倾向。</p>
<label class="toggle-row" for="card-sync-all-replies">
<input id="card-sync-all-replies" type="checkbox" />
<span>同步所有玩家 AI 私聊回复(全员收到同一轮简报)</span>
</label>
<label class="toggle-row" for="card-allow-player-death">
<input id="card-allow-player-death" type="checkbox" />
<span>允许玩家失败/死亡状态</span>
</label>
<label class="toggle-row" for="card-allow-revive">
<input id="card-allow-revive" type="checkbox" />
<span>允许复活(需 AI 在状态更新中触发)</span>
</label>
<h2>内容包</h2>
<label for="card-genre-tags">题材标签(逗号分隔)</label>
<input id="card-genre-tags" maxlength="540" placeholder="例如:科幻, 战斗, 合作, 生存" />
+2
View File
@@ -20,6 +20,8 @@
{% if user.role == 'admin' %}
<a class="link-btn" href="{{ url_for('admin_page') }}">管理后台</a>
{% endif %}
<a class="link-btn" href="{{ url_for('user_profile_page', username=user.username) }}">我的主页</a>
<a class="link-btn" href="{{ url_for('user_achievements_page', username=user.username) }}">我的成就</a>
<a class="link-btn" href="{{ url_for('rooms_page') }}">联机大厅</a>
<a class="link-btn" href="{{ url_for('leaderboard_page') }}">玩家排行</a>
<a class="link-btn" href="{{ url_for('plaza_page') }}">游戏卡广场</a>
+4
View File
@@ -13,6 +13,10 @@
<p>按胜场、参与局数和总回合综合排序,点击用户名可查看个人主页。</p>
</div>
<div class="top-actions">
{% if user %}
<a class="link-btn" href="{{ url_for('user_profile_page', username=user.username) }}">我的主页</a>
<a class="link-btn" href="{{ url_for('user_achievements_page', username=user.username) }}">我的成就</a>
{% endif %}
<a class="link-btn" href="{{ url_for('rooms_page') }}">联机大厅</a>
<a class="link-btn" href="{{ url_for('index') }}">返回大厅</a>
</div>
+4
View File
@@ -16,6 +16,10 @@
{% if user and user.role == 'admin' %}
<a class="link-btn" href="{{ url_for('admin_page') }}">管理后台</a>
{% endif %}
{% if user %}
<a class="link-btn" href="{{ url_for('user_profile_page', username=user.username) }}">我的主页</a>
<a class="link-btn" href="{{ url_for('user_achievements_page', username=user.username) }}">我的成就</a>
{% endif %}
<a class="link-btn" href="{{ url_for('leaderboard_page') }}">玩家排行</a>
<a class="link-btn" href="{{ url_for('rooms_page') }}">联机大厅</a>
{% if user %}
+5
View File
@@ -19,6 +19,10 @@
<p>房间码 <strong id="room-code">{{ room_id }}</strong> · 玩家 <strong>{{ player_name }}</strong></p>
</div>
<div class="header-actions">
{% if user %}
<a class="link-btn" href="{{ url_for('user_profile_page', username=user.username) }}">我的主页</a>
<a class="link-btn" href="{{ url_for('user_achievements_page', username=user.username) }}">我的成就</a>
{% endif %}
<a class="link-btn back-home-link" href="/">返回主页</a>
<button id="invite-btn" class="secondary-btn" type="button">邀请链接</button>
<button id="public-btn" class="secondary-btn" type="button">公开房间</button>
@@ -118,6 +122,7 @@
<div class="ending-card">
<h2 id="ending-title">本局结束</h2>
<p id="ending-summary">结局已触发。</p>
<a id="ending-summary-link" class="link-btn" href="#">查看总结页</a>
<a class="link-btn" href="/">返回大厅</a>
</div>
</section>
+48
View File
@@ -0,0 +1,48 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>对局总结 - Echo Tavern</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}" />
</head>
<body class="room-summary-page"
data-room-id="{{ room_id }}"
data-user='{{ user | tojson | safe if user else "null" }}'
data-theme="{{ user.theme if user else 'dopamine' }}">
<header class="lobby-topbar">
<div class="brand-block">
<h1>对局总结</h1>
<p id="summary-subtitle">加载中...</p>
</div>
<div class="top-actions">
{% if user %}
<a class="link-btn" href="{{ url_for('user_profile_page', username=user.username) }}">我的主页</a>
<a class="link-btn" href="{{ url_for('user_achievements_page', username=user.username) }}">我的成就</a>
{% endif %}
<a class="link-btn" id="summary-back-room" href="{{ url_for('room_page', room_id=room_id) }}">返回房间</a>
<a class="link-btn" href="{{ url_for('rooms_page') }}">联机大厅</a>
<a class="link-btn" href="{{ url_for('index') }}">返回大厅</a>
</div>
</header>
<main class="plaza-grid room-summary-grid">
<section class="card">
<h2>本局概况</h2>
<div id="summary-overview" class="status-grid"></div>
<h2 style="margin-top: 1rem;">MVP</h2>
<div id="summary-mvp" class="profile-hero"></div>
</section>
<section class="card">
<h2>玩家状态</h2>
<ul id="summary-players" class="compact-list"></ul>
</section>
</main>
<section id="status" class="status-banner"></section>
<script src="{{ url_for('static', filename='js/theme.js') }}"></script>
<script src="{{ url_for('static', filename='js/invite_notify.js') }}"></script>
<script src="{{ url_for('static', filename='js/room_summary.js') }}"></script>
</body>
</html>
+4
View File
@@ -13,6 +13,10 @@
<p>查看公开房间、输入房间码加入、快速重连你参与过的对局。</p>
</div>
<div class="top-actions">
{% if user %}
<a class="link-btn" href="{{ url_for('user_profile_page', username=user.username) }}">我的主页</a>
<a class="link-btn" href="{{ url_for('user_achievements_page', username=user.username) }}">我的成就</a>
{% endif %}
<a class="link-btn" href="{{ url_for('leaderboard_page') }}">玩家排行</a>
<a class="link-btn" href="{{ url_for('plaza_page') }}">游戏卡广场</a>
<a class="link-btn" href="{{ url_for('index') }}">返回主页</a>
+5
View File
@@ -16,6 +16,10 @@
<p id="profile-subtitle">加载中...</p>
</div>
<div class="top-actions">
{% if user %}
<a class="link-btn" href="{{ url_for('user_profile_page', username=user.username) }}">我的主页</a>
<a class="link-btn" href="{{ url_for('user_achievements_page', username=user.username) }}">我的成就</a>
{% endif %}
<a class="link-btn" href="{{ url_for('rooms_page') }}">联机大厅</a>
<a class="link-btn" href="{{ url_for('leaderboard_page') }}">返回排行</a>
<a class="link-btn" href="{{ url_for('index') }}">返回大厅</a>
@@ -29,6 +33,7 @@
<div id="profile-meta" class="status-grid" style="margin-top: 0.8rem;"></div>
<h2 style="margin-top: 1rem;">成就展柜</h2>
<p id="achievement-summary" class="helper-text">加载中...</p>
<a id="achievement-detail-link" class="link-btn" href="#" style="margin-top: 0.6rem;">查看完整成就页</a>
<ul id="achievements-list" class="compact-list"></ul>
</section>