@sophiacyl/dsh-plugin-waves 0.0.0-stage → 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DSH-GO-VERIFICATION.md +57 -0
- package/ICON.png +0 -0
- package/LICENSE +674 -0
- package/README.md +251 -2
- package/cordis.patch.yml +8 -0
- package/install.ps1 +0 -0
- package/install.sh +209 -0
- package/lib/client.js +1511 -0
- package/lib/host/aliashint.js +70 -0
- package/lib/host/attachments.js +25 -0
- package/lib/host/command.js +34 -0
- package/lib/host/consts.js +16 -0
- package/lib/host/dataguide.js +35 -0
- package/lib/host/imagebridge.js +41 -0
- package/lib/host/native-result.js +91 -0
- package/lib/host/native.js +191 -0
- package/lib/host/proxy.js +59 -0
- package/lib/host/results.js +67 -0
- package/lib/host/service.js +263 -0
- package/lib/host/tool.js +185 -0
- package/lib/host/troubleshoot.js +31 -0
- package/lib/host/worldbook.js +80 -0
- package/lib/index.js +74 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +136 -4
- package/service/ICON.png +0 -0
- package/service/ai/AI_DATA.md +221 -0
- package/service/knowledge/additional/manual.jsonl +5 -0
- package/service/knowledge/wiki/baike.jsonl +1231 -0
- package/service/knowledge/wiki/chengjiu.jsonl +36 -0
- package/service/knowledge/wiki/gonglve.jsonl +383 -0
- package/service/knowledge/wiki/huodong.jsonl +427 -0
- package/service/knowledge/wiki/renwu.jsonl +412 -0
- package/service/knowledge/wiki/tujian.jsonl +2889 -0
- package/service/knowledge/wiki/zixun.jsonl +47 -0
- package/service/plugins/__init__.py +0 -0
- package/service/pyproject.toml +40 -0
- package/service/rover/__init__.py +0 -0
- package/service/rover/ai_core/__init__.py +0 -0
- package/service/rover/ai_core/models.py +50 -0
- package/service/rover/ai_core/rag/__init__.py +5 -0
- package/service/rover/ai_core/rag/knowledge.py +23 -0
- package/service/rover/ai_core/register.py +86 -0
- package/service/rover/ai_core/resource.py +6 -0
- package/service/rover/ai_core/skills/__init__.py +0 -0
- package/service/rover/ai_core/skills/operations.py +8 -0
- package/service/rover/api.py +720 -0
- package/service/rover/api_render.py +161 -0
- package/service/rover/app_life.py +154 -0
- package/service/rover/aps.py +47 -0
- package/service/rover/avatar.py +85 -0
- package/service/rover/bot.py +133 -0
- package/service/rover/builtin.py +152 -0
- package/service/rover/cards/__init__.py +26 -0
- package/service/rover/cards/_shared.py +129 -0
- package/service/rover/cards/char_list.py +258 -0
- package/service/rover/cards/char_panel.py +1353 -0
- package/service/rover/cards/echo_list.py +206 -0
- package/service/rover/cards/matrix_roles.py +25 -0
- package/service/rover/cards/rank_boards.py +714 -0
- package/service/rover/cards/rank_total.py +664 -0
- package/service/rover/compat.py +215 -0
- package/service/rover/config.py +163 -0
- package/service/rover/custom_panel.py +220 -0
- package/service/rover/data_store.py +31 -0
- package/service/rover/gss.py +19 -0
- package/service/rover/handler.py +191 -0
- package/service/rover/help/__init__.py +0 -0
- package/service/rover/help/draw_new_plugin_help.py +332 -0
- package/service/rover/help/model.py +16 -0
- package/service/rover/help/utils.py +7 -0
- package/service/rover/hooks.py +420 -0
- package/service/rover/html_actions.py +236 -0
- package/service/rover/i18n.py +19 -0
- package/service/rover/knowledge.py +235 -0
- package/service/rover/logger.py +102 -0
- package/service/rover/main.py +33 -0
- package/service/rover/media.py +222 -0
- package/service/rover/message_models.py +23 -0
- package/service/rover/models.py +92 -0
- package/service/rover/native_media.py +64 -0
- package/service/rover/ocr.py +79 -0
- package/service/rover/pool.py +43 -0
- package/service/rover/restart.py +36 -0
- package/service/rover/segment.py +143 -0
- package/service/rover/server.py +131 -0
- package/service/rover/status/__init__.py +0 -0
- package/service/rover/status/models.py +10 -0
- package/service/rover/status/plugin_status.py +17 -0
- package/service/rover/subscribe.py +148 -0
- package/service/rover/sv.py +403 -0
- package/service/rover/templates/char_list.html +182 -0
- package/service/rover/templates/char_panel.html +465 -0
- package/service/rover/templates/echo_list.html +221 -0
- package/service/rover/templates/rank_all_total.html +193 -0
- package/service/rover/templates/rank_board.html +107 -0
- package/service/rover/templates/rank_level_total.html +57 -0
- package/service/rover/templates/rank_matrix_total.html +66 -0
- package/service/rover/templates/rank_phantom_total.html +180 -0
- package/service/rover/templates/rank_slash_total.html +38 -0
- package/service/rover/trigger.py +98 -0
- package/service/rover/utils/__init__.py +0 -0
- package/service/rover/utils/boardcast/__init__.py +0 -0
- package/service/rover/utils/boardcast/models.py +15 -0
- package/service/rover/utils/cookie_manager/__init__.py +0 -0
- package/service/rover/utils/cookie_manager/qrlogin.py +24 -0
- package/service/rover/utils/database/__init__.py +0 -0
- package/service/rover/utils/database/base_models.py +1771 -0
- package/service/rover/utils/database/models.py +80 -0
- package/service/rover/utils/database/startup.py +60 -0
- package/service/rover/utils/default_bg/bg.jpg +0 -0
- package/service/rover/utils/download_resource/__init__.py +0 -0
- package/service/rover/utils/download_resource/download_core.py +164 -0
- package/service/rover/utils/download_resource/download_file.py +46 -0
- package/service/rover/utils/fonts/__init__.py +0 -0
- package/service/rover/utils/fonts/fonts.py +33 -0
- package/service/rover/utils/image/__init__.py +0 -0
- package/service/rover/utils/image/convert.py +51 -0
- package/service/rover/utils/image/image_tools.py +30 -0
- package/service/rover/utils/image/utils.py +70 -0
- package/service/rover/utils/plugins_config/__init__.py +0 -0
- package/service/rover/utils/plugins_config/gs_config.py +506 -0
- package/service/rover/utils/plugins_config/models.py +182 -0
- package/service/rover/web_app.py +3 -0
- package/service/rover/webconsole/__init__.py +0 -0
- package/service/rover/webconsole/mount_app.py +26 -0
- package/service/tools/migrate.py +351 -0
- package/service/tools/regression.py +87 -0
- package/service/tools/smoke.py +63 -0
- package/service/tools/update_plugins.py +212 -0
- package/service/tools/verify_actions.py +104 -0
- package/service/tools/verify_card.py +82 -0
- package/service/tools/wwdata.py +665 -0
- package/tests/compat.test.js +181 -0
- package/tests/imagebridge.test.js +58 -0
- package/tests/media.test.js +68 -0
- package/tests/native.test.js +127 -0
- package/tests/runtime.test.js +69 -0
- package/tests/service.test.js +48 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>鸣潮声骸仓库</title>
|
|
6
|
+
<style>
|
|
7
|
+
@import url('{{ font_css_url }}');
|
|
8
|
+
|
|
9
|
+
* { box-sizing: border-box; }
|
|
10
|
+
|
|
11
|
+
body {
|
|
12
|
+
margin: 0; padding: 0;
|
|
13
|
+
background-color: #0f1115;
|
|
14
|
+
font-family: 'Source Han Sans CN', 'Noto Sans CJK JP', sans-serif;
|
|
15
|
+
width: 1600px;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.container {
|
|
19
|
+
position: relative;
|
|
20
|
+
width: 1600px; padding: 40px;
|
|
21
|
+
display: flex; flex-direction: column; align-items: center; gap: 35px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.bg-layer {
|
|
25
|
+
position: absolute; top: 0; left: 0; right: 0; bottom: 0;
|
|
26
|
+
z-index: 0; pointer-events: none;
|
|
27
|
+
}
|
|
28
|
+
.bg-layer::after {
|
|
29
|
+
content: ""; position: absolute;
|
|
30
|
+
top: 0; left: 0; width: 100%; height: 100%;
|
|
31
|
+
background-color: rgba(0, 0, 0, 0.2); z-index: 1;
|
|
32
|
+
}
|
|
33
|
+
.bg-image { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
34
|
+
|
|
35
|
+
.user-card {
|
|
36
|
+
position: relative; z-index: 1; width: 100%;
|
|
37
|
+
background:
|
|
38
|
+
radial-gradient(circle at 100% 0%, rgba(212, 177, 99, 0.15) 0%, transparent 40%),
|
|
39
|
+
linear-gradient(180deg, rgba(30, 34, 42, 0.9) 0%, rgba(15, 17, 21, 0.95) 100%);
|
|
40
|
+
border-radius: 16px; padding: 25px 40px;
|
|
41
|
+
display: flex; align-items: center;
|
|
42
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
43
|
+
border-top: 1px solid rgba(255, 255, 255, 0.2);
|
|
44
|
+
box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.5);
|
|
45
|
+
}
|
|
46
|
+
.user-card::before {
|
|
47
|
+
content: ""; position: absolute;
|
|
48
|
+
top: 0; left: 0; width: 100%; height: 100%;
|
|
49
|
+
background-image:
|
|
50
|
+
linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px),
|
|
51
|
+
linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
|
|
52
|
+
background-size: 30px 30px;
|
|
53
|
+
mask-image: linear-gradient(to bottom, black, transparent 80%);
|
|
54
|
+
pointer-events: none; border-radius: 16px;
|
|
55
|
+
}
|
|
56
|
+
.deco-text {
|
|
57
|
+
position: absolute; top: 20px; right: 30px;
|
|
58
|
+
font-family: 'Oswald', sans-serif; font-size: 14px;
|
|
59
|
+
letter-spacing: 4px; color: rgba(255, 255, 255, 0.1);
|
|
60
|
+
font-weight: bold; pointer-events: none;
|
|
61
|
+
}
|
|
62
|
+
.avatar-container {
|
|
63
|
+
width: 100px; height: 100px; flex-shrink: 0;
|
|
64
|
+
margin-right: 30px; position: relative;
|
|
65
|
+
border-radius: 50%; border: 3px solid #2a2e35;
|
|
66
|
+
background-color: #222;
|
|
67
|
+
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5);
|
|
68
|
+
}
|
|
69
|
+
.avatar-ring {
|
|
70
|
+
position: absolute; top: -6px; left: -6px; right: -6px; bottom: -6px;
|
|
71
|
+
border-radius: 50%; border: 1px solid rgba(255, 255, 255, 0.05);
|
|
72
|
+
border-left: 2px solid #d4b163; transform: rotate(-45deg);
|
|
73
|
+
box-shadow: -2px 2px 10px rgba(212, 177, 99, 0.2);
|
|
74
|
+
pointer-events: none; z-index: 0;
|
|
75
|
+
}
|
|
76
|
+
.avatar { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 50%; position: relative; z-index: 1; }
|
|
77
|
+
.user-info { flex: 1; display: flex; flex-direction: column; justify-content: center; z-index: 2; }
|
|
78
|
+
.user-row-1 {
|
|
79
|
+
display: flex; align-items: baseline; margin-bottom: 10px;
|
|
80
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
|
81
|
+
padding-bottom: 8px; position: relative;
|
|
82
|
+
}
|
|
83
|
+
.user-row-1::after {
|
|
84
|
+
content: ""; position: absolute; bottom: -1px; left: 0;
|
|
85
|
+
width: 40px; height: 2px; background: #d4b163; box-shadow: 0 0 8px #d4b163;
|
|
86
|
+
}
|
|
87
|
+
.user-name { font-size: 42px; font-weight: 800; color: #fff; margin-right: 20px; text-shadow: 0 4px 10px rgba(0, 0, 0, 0.5); }
|
|
88
|
+
.user-uid {
|
|
89
|
+
font-family: 'JetBrains Mono', monospace; font-size: 20px; color: #d4b163;
|
|
90
|
+
background: rgba(0, 0, 0, 0.4); padding: 4px 12px; border-radius: 6px;
|
|
91
|
+
border: 1px solid rgba(212, 177, 99, 0.2); letter-spacing: 1.5px; font-weight: bold;
|
|
92
|
+
}
|
|
93
|
+
.page-badge {
|
|
94
|
+
margin-left: auto; font-family: 'Oswald', sans-serif; font-size: 22px; font-weight: bold;
|
|
95
|
+
color: #d8d8d8; background: rgba(212, 177, 99, 0.15);
|
|
96
|
+
border: 1px solid rgba(212, 177, 99, 0.3); border-radius: 6px; padding: 4px 12px;
|
|
97
|
+
}
|
|
98
|
+
.user-stats { display: flex; gap: 40px; }
|
|
99
|
+
.stat-item { display: flex; flex-direction: column; }
|
|
100
|
+
.stat-value {
|
|
101
|
+
font-family: 'Oswald', sans-serif; font-size: 30px; font-weight: 700; line-height: 1.1;
|
|
102
|
+
background: linear-gradient(180deg, #fff 50%, #d4b163 100%);
|
|
103
|
+
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
|
104
|
+
}
|
|
105
|
+
.stat-label { font-size: 12px; color: #6d717a; font-weight: bold; letter-spacing: 1px; margin-top: 2px; }
|
|
106
|
+
|
|
107
|
+
/* 卡格按 PIL 版坐标绝对定位, 行间 30px 交叠让角色头像压住上一行 */
|
|
108
|
+
.echo-grid { position: relative; z-index: 1; width: {{ grid_w }}px; height: {{ grid_h }}px; }
|
|
109
|
+
.echo-grid .echo-card { position: absolute; width: {{ card_w }}px; height: {{ card_h }}px; overflow: hidden; }
|
|
110
|
+
.echo-card i { display: block; background-size: 100% 100%; background-repeat: no-repeat; }
|
|
111
|
+
.card-bg, .card-title { position: absolute; left: 0; top: 50px; width: 350px; }
|
|
112
|
+
.card-bg { height: 550px; background-image: url('{{ sh_bg_url }}'); }
|
|
113
|
+
.card-title { height: 150px; }
|
|
114
|
+
|
|
115
|
+
.role-avatar { position: absolute; left: 230px; top: 10px; width: 180px; height: 180px; }
|
|
116
|
+
|
|
117
|
+
.phantom-icon { position: absolute; left: 20px; top: 70px; width: 100px; height: 100px; }
|
|
118
|
+
.phantom-icon .icon { width: 100%; height: 100%; }
|
|
119
|
+
.phantom-icon .fetter { position: absolute; top: 0; }
|
|
120
|
+
|
|
121
|
+
.phantom-name {
|
|
122
|
+
position: absolute; left: 130px; top: 90px; transform: translateY(-50%);
|
|
123
|
+
font-size: 28px; font-weight: bold; color: rgb(234, 183, 4);
|
|
124
|
+
white-space: nowrap; text-shadow: 0 2px 6px rgba(0, 0, 0, 0.6);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.pill {
|
|
128
|
+
position: absolute; top: 108px; height: 30px; border-radius: 8px;
|
|
129
|
+
display: flex; align-items: center; font-size: 24px; color: #fff;
|
|
130
|
+
}
|
|
131
|
+
.pill.level { left: 128px; width: 84px; padding-left: 8px; background: rgba(0, 0, 0, 0.8); }
|
|
132
|
+
.pill.score { left: 228px; width: 92px; padding-left: 5px; background: rgba(186, 55, 42, 0.8); }
|
|
133
|
+
|
|
134
|
+
.cost { position: absolute; left: 128px; top: 140px; display: flex; }
|
|
135
|
+
.cost i { width: 30px; height: 30px; background-image: url('{{ promote_url }}'); }
|
|
136
|
+
|
|
137
|
+
.props {
|
|
138
|
+
position: absolute; left: 15px; top: {{ prop_top }}px; width: 335px;
|
|
139
|
+
display: flex; flex-direction: column; gap: {{ prop_gap }}px;
|
|
140
|
+
}
|
|
141
|
+
.prop { height: 40px; display: flex; align-items: center; }
|
|
142
|
+
.prop i { width: 40px; height: 40px; }
|
|
143
|
+
.prop-name { margin-left: 5px; font-size: 24px; white-space: nowrap; }
|
|
144
|
+
.prop-value { margin-left: auto; padding-right: 7px; font-size: 24px; }
|
|
145
|
+
|
|
146
|
+
.footer { position: relative; z-index: 1; text-align: center; width: 100%; opacity: 0.6; }
|
|
147
|
+
.footer img { max-width: 100%; }
|
|
148
|
+
</style>
|
|
149
|
+
<style>
|
|
150
|
+
{% for url in assets %}.a{{ loop.index0 }} { background-image: url('{{ url }}'); }
|
|
151
|
+
{% endfor %}
|
|
152
|
+
</style>
|
|
153
|
+
</head>
|
|
154
|
+
<body>
|
|
155
|
+
<div class="container">
|
|
156
|
+
<div class="bg-layer">
|
|
157
|
+
<img src="{{ bg_url }}" class="bg-image">
|
|
158
|
+
</div>
|
|
159
|
+
|
|
160
|
+
<div class="user-card">
|
|
161
|
+
<div class="deco-text">ECHO STORAGE</div>
|
|
162
|
+
<div class="avatar-container">
|
|
163
|
+
<div class="avatar-ring"></div>
|
|
164
|
+
<img src="{{ avatar_url }}" class="avatar">
|
|
165
|
+
</div>
|
|
166
|
+
<div class="user-info">
|
|
167
|
+
<div class="user-row-1">
|
|
168
|
+
<div class="user-name">{{ user_name }}</div>
|
|
169
|
+
<div class="user-uid">特征码 {{ user_id }}</div>
|
|
170
|
+
{% if page_text %}<div class="page-badge">{{ page_text }}</div>{% endif %}
|
|
171
|
+
</div>
|
|
172
|
+
<div class="user-stats">
|
|
173
|
+
{% if show_stats %}
|
|
174
|
+
<div class="stat-item">
|
|
175
|
+
<div class="stat-value">Lv.{{ level }}</div>
|
|
176
|
+
<div class="stat-label">账号等级</div>
|
|
177
|
+
</div>
|
|
178
|
+
<div class="stat-item">
|
|
179
|
+
<div class="stat-value">Lv.{{ world_level }}</div>
|
|
180
|
+
<div class="stat-label">世界等级</div>
|
|
181
|
+
</div>
|
|
182
|
+
{% endif %}
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
<div class="echo-grid">
|
|
188
|
+
{% for echo in echoes %}
|
|
189
|
+
<div class="echo-card" style="left: {{ echo.left }}px; top: {{ echo.top }}px;"{% if echo.command %} data-ww-cmd="{{ echo.command }}"{% endif %}>
|
|
190
|
+
<i class="card-bg"></i>
|
|
191
|
+
<i class="card-title {{ echo.title_class }}"></i>
|
|
192
|
+
<i class="role-avatar {{ echo.role_class }}"></i>
|
|
193
|
+
<div class="phantom-icon">
|
|
194
|
+
<i class="icon {{ echo.icon_class }}"></i>
|
|
195
|
+
<i class="fetter {{ echo.fetter_class }}" style="left: {{ echo.fetter_left }}%; width: {{ echo.fetter_size }}%; height: {{ echo.fetter_size }}%;"></i>
|
|
196
|
+
</div>
|
|
197
|
+
<div class="phantom-name">{{ echo.name }}</div>
|
|
198
|
+
<div class="pill level">Lv.{{ echo.level }}</div>
|
|
199
|
+
<div class="pill score">{{ echo.score }}分</div>
|
|
200
|
+
<div class="cost">
|
|
201
|
+
{% for _ in range(echo.cost) %}<i></i>{% endfor %}
|
|
202
|
+
</div>
|
|
203
|
+
<div class="props">
|
|
204
|
+
{% for prop in echo.props %}
|
|
205
|
+
<div class="prop">
|
|
206
|
+
<i class="{{ prop.icon_class }}"></i>
|
|
207
|
+
<div class="prop-name" style="color: {{ prop.name_color }};">{{ prop.name }}</div>
|
|
208
|
+
<div class="prop-value" style="color: {{ prop.value_color }};">{{ prop.value }}</div>
|
|
209
|
+
</div>
|
|
210
|
+
{% endfor %}
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
{% endfor %}
|
|
214
|
+
</div>
|
|
215
|
+
|
|
216
|
+
{% if footer_url %}
|
|
217
|
+
<div class="footer"><img src="{{ footer_url }}"></div>
|
|
218
|
+
{% endif %}
|
|
219
|
+
</div>
|
|
220
|
+
</body>
|
|
221
|
+
</html>
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>{{ header.title_name }}</title>
|
|
6
|
+
<style>
|
|
7
|
+
@import url('{{ font_css_url }}');
|
|
8
|
+
|
|
9
|
+
* { box-sizing: border-box; }
|
|
10
|
+
body { margin: 0; background: #0f1115; }
|
|
11
|
+
|
|
12
|
+
.container {
|
|
13
|
+
position: relative;
|
|
14
|
+
width: {{ card_w }}px;
|
|
15
|
+
padding-bottom: 40px;
|
|
16
|
+
background-image: url('{{ bg }}');
|
|
17
|
+
background-size: cover;
|
|
18
|
+
background-position: center;
|
|
19
|
+
font-family: 'Source Han Sans CN', 'Noto Sans CJK JP', 'Noto Sans CJK KR', sans-serif;
|
|
20
|
+
font-weight: 700;
|
|
21
|
+
color: #fff;
|
|
22
|
+
overflow: hidden;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* 文本按 PIL 锚点定位: lm 左中 / mm 中中 / rm 右中 */
|
|
26
|
+
.t { position: absolute; white-space: nowrap; line-height: 1; transform: translateY(-50%); }
|
|
27
|
+
.t.mm { transform: translate(-50%, -50%); }
|
|
28
|
+
|
|
29
|
+
/* ---------------- 头部: 标题底图 + 立绘, 底部渐隐 ---------------- */
|
|
30
|
+
.header { position: relative; width: 100%; height: {{ header_h }}px; }
|
|
31
|
+
.header .art {
|
|
32
|
+
position: absolute; inset: 0; overflow: hidden;
|
|
33
|
+
-webkit-mask-image: {{ header.mask }}; mask-image: {{ header.mask }};
|
|
34
|
+
}
|
|
35
|
+
.header .art img { position: absolute; }
|
|
36
|
+
.header .title-bg { left: {{ header.title_dx }}px; top: 0; width: 1050px; height: 500px; }
|
|
37
|
+
.header .logo { left: 50px; top: 65px; width: 200px; height: 80px; }
|
|
38
|
+
.header .time { left: 170px; top: 205px; font-size: 20px; color: {{ grey }}; }
|
|
39
|
+
.header .title { left: 240px; top: 265px; font-size: 30px; color: #000; }
|
|
40
|
+
.header .ver {
|
|
41
|
+
position: absolute; top: 255px; width: 100px; height: 30px;
|
|
42
|
+
border-radius: 6px; background: rgba(0, 79, 152, .9);
|
|
43
|
+
font-size: 24px; line-height: 30px; text-align: center;
|
|
44
|
+
}
|
|
45
|
+
.header .stat-v { top: 335px; font-size: 44px; }
|
|
46
|
+
.header .stat-l { top: 375px; font-size: 20px; color: {{ gold }}; }
|
|
47
|
+
|
|
48
|
+
/* ---------------- 上榜条件 ---------------- */
|
|
49
|
+
.cond { position: relative; width: 100%; height: {{ cond.height }}px; }
|
|
50
|
+
.cond .panel {
|
|
51
|
+
position: absolute; left: 20px; top: 20px;
|
|
52
|
+
width: {{ card_w - 40 }}px; height: {{ cond.height - 35 }}px;
|
|
53
|
+
border-radius: 8px; background: rgba(36, 36, 41, .9);
|
|
54
|
+
}
|
|
55
|
+
.cond .accent {
|
|
56
|
+
position: absolute; left: 20px; top: 20px;
|
|
57
|
+
width: {{ card_w - 40 }}px; height: 7px; background: rgb(203, 161, 95);
|
|
58
|
+
}
|
|
59
|
+
.cond .label { left: 40px; top: 60px; font-size: 28px; color: {{ grey }}; }
|
|
60
|
+
.cond .line { left: 185px; font-size: 20px; color: {{ gold }}; }
|
|
61
|
+
.cond .right { right: {{ card_w - 1260 }}px; font-size: 20px; color: {{ gold }}; }
|
|
62
|
+
.cond .notes { right: {{ card_w - 1260 }}px; top: {{ cond.height - 30 }}px; font-size: 16px; color: {{ gold }}; }
|
|
63
|
+
|
|
64
|
+
/* ---------------- 排行行 ---------------- */
|
|
65
|
+
.row {
|
|
66
|
+
position: relative; width: {{ card_w }}px; height: {{ row_h }}px;
|
|
67
|
+
background-image: url('{{ bar }}'); background-size: 100% 100%;
|
|
68
|
+
overflow: hidden;
|
|
69
|
+
}
|
|
70
|
+
.row .glow { position: absolute; left: 120px; right: 70px; top: 6px; bottom: 6px; border-radius: 14px; }
|
|
71
|
+
.row.t1 .glow { background: linear-gradient(90deg, rgba(255, 196, 60, .18), rgba(255, 196, 60, 0) 42%); }
|
|
72
|
+
.row.t2 .glow { background: linear-gradient(90deg, rgba(208, 216, 226, .16), rgba(208, 216, 226, 0) 42%); }
|
|
73
|
+
.row.t3 .glow { background: linear-gradient(90deg, rgba(214, 150, 92, .16), rgba(214, 150, 92, 0) 42%); }
|
|
74
|
+
|
|
75
|
+
.row .medal { position: absolute; left: 37px; top: 27px; width: 55px; height: 55px; }
|
|
76
|
+
.row .box {
|
|
77
|
+
position: absolute; top: 30px; height: 50px; border-radius: 8px;
|
|
78
|
+
background: rgba(54, 54, 54, .9); font-size: 34px; line-height: 50px; text-align: center;
|
|
79
|
+
}
|
|
80
|
+
.row .avatar { position: absolute; left: 100px; top: 0; width: 180px; height: 180px; }
|
|
81
|
+
.row .chain, .row .level {
|
|
82
|
+
position: absolute; top: 30px; height: 20px; border-radius: 6px;
|
|
83
|
+
font-size: 18px; line-height: 20px; padding-left: 5px; overflow: hidden;
|
|
84
|
+
}
|
|
85
|
+
.row .chain { left: 190px; width: 46px; }
|
|
86
|
+
.row .level { left: 240px; width: 60px; background: rgba(54, 54, 54, .9); }
|
|
87
|
+
.row .attr { position: absolute; left: 300px; top: 20px; width: 40px; height: 40px; }
|
|
88
|
+
.row .uid { left: 350px; top: 40px; font-size: 20px; }
|
|
89
|
+
.row .name {
|
|
90
|
+
left: 210px; top: 75px; font-size: 20px;
|
|
91
|
+
max-width: 130px; overflow: hidden; text-overflow: ellipsis;
|
|
92
|
+
}
|
|
93
|
+
.row .badge { position: absolute; left: 346px; top: 60px; width: 208px; height: 39px; }
|
|
94
|
+
.row .badge .plate { position: absolute; left: 4px; top: 5px; width: 201px; height: 31px; border-radius: 6px; background: rgba(54, 54, 54, .6); }
|
|
95
|
+
.row .badge .bg { position: absolute; left: 104px; top: 19px; transform: translate(-50%, -50%); }
|
|
96
|
+
.row .badge .txt { position: absolute; left: 104px; top: 20px; transform: translate(-50%, -50%); font-size: 18px; white-space: nowrap; }
|
|
97
|
+
.row .emblem { position: absolute; left: 545px; top: 2px; width: 110px; height: 110px; }
|
|
98
|
+
.row .score-v { left: 707px; top: 45px; font-size: 34px; }
|
|
99
|
+
.row .score-l { left: 707px; top: 75px; font-size: 16px; color: {{ gold }}; }
|
|
100
|
+
.row .sonata { position: absolute; left: 790px; top: 15px; width: 50px; height: 50px; }
|
|
101
|
+
.row .sonata-l { left: 815px; top: 75px; }
|
|
102
|
+
/* 武器块按原版 600x300 画布排版, 整体缩到 260x130 */
|
|
103
|
+
.row .weapon { position: absolute; left: 850px; top: 25px; width: 600px; height: 300px; transform: scale(.43333); transform-origin: top left; }
|
|
104
|
+
.row .weapon .icon { position: absolute; left: 45px; top: 0; width: 140px; height: 140px; }
|
|
105
|
+
.row .weapon .wname { left: 200px; top: 30px; font-size: 40px; color: {{ gold }}; max-width: 390px; overflow: hidden; text-overflow: ellipsis; }
|
|
106
|
+
.row .weapon .wlv { left: 203px; top: 75px; font-size: 30px; }
|
|
107
|
+
.row .weapon .reson { position: absolute; left: 205px; top: 105px; width: 65px; height: 30px; border-radius: 7px; }
|
|
108
|
+
.row .weapon .reson span { position: absolute; left: 15px; top: 15px; transform: translateY(-50%); font-size: 24px; }
|
|
109
|
+
.row .dmg-v { left: 1140px; top: 45px; font-size: 34px; color: {{ gold }}; }
|
|
110
|
+
.row .dmg-l { left: 1140px; top: 75px; font-size: 16px; }
|
|
111
|
+
.hot { position: absolute; border-radius: 10px; }
|
|
112
|
+
|
|
113
|
+
.icon-img { background-size: 100% 100%; background-repeat: no-repeat; }
|
|
114
|
+
{% for a in assets %}.{{ a.cls }} { background-image: url('{{ a.uri }}'); }
|
|
115
|
+
{% endfor %}
|
|
116
|
+
</style>
|
|
117
|
+
</head>
|
|
118
|
+
<body>
|
|
119
|
+
<div class="container">
|
|
120
|
+
<div class="header">
|
|
121
|
+
<div class="art">
|
|
122
|
+
<img class="title-bg" src="{{ header.title_bg }}">
|
|
123
|
+
<img class="logo" src="{{ header.logo }}">
|
|
124
|
+
<div class="t time">{{ header.time }}</div>
|
|
125
|
+
<div class="t title">{{ header.title_name }}</div>
|
|
126
|
+
<div class="ver" style="left: {{ header.version_x }}px">{{ header.version }}</div>
|
|
127
|
+
{% for s in header.stats %}
|
|
128
|
+
<div class="t mm stat-v" style="left: {{ s.x }}px">{{ s.value }}</div>
|
|
129
|
+
<div class="t mm stat-l" style="left: {{ s.x }}px">{{ s.label }}</div>
|
|
130
|
+
{% endfor %}
|
|
131
|
+
{% if header.pile %}
|
|
132
|
+
<img class="pile" src="{{ header.pile.uri }}"
|
|
133
|
+
style="left: {{ header.pile.x }}px; top: {{ header.pile.y }}px; width: {{ header.pile.w }}px; height: {{ header.pile.h }}px">
|
|
134
|
+
{% endif %}
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div class="cond">
|
|
139
|
+
<div class="panel"></div>
|
|
140
|
+
<div class="accent"></div>
|
|
141
|
+
<div class="t label">上榜条件</div>
|
|
142
|
+
<div class="t line" style="top: 50px">{{ cond.line1 }}</div>
|
|
143
|
+
<div class="t line" style="top: 85px">{{ cond.line2 }}</div>
|
|
144
|
+
{% if cond.modal %}<div class="t line" style="top: 120px">{{ cond.modal }}</div>{% endif %}
|
|
145
|
+
{% if cond.modal_current %}<div class="t right" style="top: 120px">{{ cond.modal_current }}</div>{% endif %}
|
|
146
|
+
<div class="t notes">{{ cond.notes }}</div>
|
|
147
|
+
</div>
|
|
148
|
+
|
|
149
|
+
{% for row in rows %}
|
|
150
|
+
<div class="row{% if row.rank <= 3 %} t{{ row.rank }}{% endif %}"{% if row.cmd %} data-ww-cmd="{{ row.cmd }}"{% endif %}>
|
|
151
|
+
<div class="glow"></div>
|
|
152
|
+
{% if row.medal %}
|
|
153
|
+
<div class="medal icon-img {{ row.medal }}"></div>
|
|
154
|
+
{% else %}
|
|
155
|
+
<div class="box" style="left: {{ row.box.left }}px; width: {{ row.box.w }}px">{{ row.box.text }}</div>
|
|
156
|
+
{% endif %}
|
|
157
|
+
<img class="avatar" src="{{ row.avatar }}">
|
|
158
|
+
<div class="chain" style="background: {{ row.chain_color }}">{{ row.chain }}</div>
|
|
159
|
+
<div class="level">{{ row.level }}</div>
|
|
160
|
+
<div class="attr icon-img {{ row.attribute }}"></div>
|
|
161
|
+
<div class="t uid" style="color: {{ row.uid_color }}">{{ row.uid }}</div>
|
|
162
|
+
<div class="t name">{{ row.name }}</div>
|
|
163
|
+
{% if row.badge %}
|
|
164
|
+
<div class="badge">
|
|
165
|
+
{% if row.badge.cls %}
|
|
166
|
+
<div class="bg icon-img {{ row.badge.cls }}" style="width: {{ row.badge.w }}px; height: {{ row.badge.h }}px"></div>
|
|
167
|
+
{% else %}<div class="plate"></div>{% endif %}
|
|
168
|
+
<div class="txt">{{ row.badge.name }}</div>
|
|
169
|
+
</div>
|
|
170
|
+
{% endif %}
|
|
171
|
+
{% if row.score %}
|
|
172
|
+
<div class="emblem icon-img {{ row.score.cls }}"></div>
|
|
173
|
+
<div class="t mm score-v">{{ row.score.value }}</div>
|
|
174
|
+
<div class="t mm score-l">{{ row.score.label }}</div>
|
|
175
|
+
{% endif %}
|
|
176
|
+
{% if row.sonata %}<div class="sonata icon-img {{ row.sonata }}"></div>{% endif %}
|
|
177
|
+
<div class="t mm sonata-l" style="font-size: {{ row.sonata_size }}px">{{ row.sonata_label }}</div>
|
|
178
|
+
<div class="weapon">
|
|
179
|
+
<div class="icon icon-img {{ row.weapon.cls }}"></div>
|
|
180
|
+
<div class="t wname">{{ row.weapon.name }}</div>
|
|
181
|
+
<div class="t wlv">{{ row.weapon.level }}</div>
|
|
182
|
+
<div class="reson" style="background: {{ row.weapon.reson_color }}"><span>{{ row.weapon.reson }}</span></div>
|
|
183
|
+
</div>
|
|
184
|
+
<div class="t mm dmg-v">{{ row.damage }}</div>
|
|
185
|
+
<div class="t mm dmg-l">{{ row.damage_name }}</div>
|
|
186
|
+
<div class="hot" style="left: 545px; top: 2px; width: 215px; height: 106px" data-ww-cmd="{{ cmd_score }}"></div>
|
|
187
|
+
<div class="hot" style="left: 775px; top: 12px; width: 72px; height: 86px" data-ww-cmd="{{ cmd_phantom }}"></div>
|
|
188
|
+
<div class="hot" style="left: 1060px; top: 25px; width: 160px; height: 66px" data-ww-cmd="{{ cmd_damage }}"></div>
|
|
189
|
+
</div>
|
|
190
|
+
{% endfor %}
|
|
191
|
+
</div>
|
|
192
|
+
</body>
|
|
193
|
+
</html>
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>{{ header.title }}</title>
|
|
6
|
+
<style>
|
|
7
|
+
@import url('{{ font_css_url }}');
|
|
8
|
+
|
|
9
|
+
* { box-sizing: border-box; }
|
|
10
|
+
body { margin: 0; background: #0f1115; }
|
|
11
|
+
|
|
12
|
+
.container {
|
|
13
|
+
position: relative;
|
|
14
|
+
width: {{ card_w }}px;
|
|
15
|
+
padding-bottom: 40px;
|
|
16
|
+
background-image: url('{{ bg }}');
|
|
17
|
+
background-size: cover;
|
|
18
|
+
background-position: center;
|
|
19
|
+
font-family: 'Source Han Sans CN', 'Noto Sans CJK JP', 'Noto Sans CJK KR', sans-serif;
|
|
20
|
+
font-weight: 700;
|
|
21
|
+
color: #fff;
|
|
22
|
+
overflow: hidden;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* 文本按 PIL 锚点定位: lm 左中 / mm 中中 / rm 右中 */
|
|
26
|
+
.t { position: absolute; white-space: nowrap; line-height: 1; transform: translateY(-50%); }
|
|
27
|
+
.t.mm { transform: translate(-50%, -50%); }
|
|
28
|
+
.t.rm { transform: translate(-100%, -50%); }
|
|
29
|
+
|
|
30
|
+
/* ---------------- 头部: 标题底图 + 图标, 底部渐隐 ---------------- */
|
|
31
|
+
.header { position: relative; width: 100%; height: 510px; }
|
|
32
|
+
.header .art {
|
|
33
|
+
position: absolute; left: 0; top: 0; width: {{ card_w }}px; height: 500px; overflow: hidden;
|
|
34
|
+
-webkit-mask-image: {{ header.mask }}; mask-image: {{ header.mask }};
|
|
35
|
+
}
|
|
36
|
+
.header .bg { position: absolute; left: 0; top: 0; width: {{ card_w }}px; height: 500px; }
|
|
37
|
+
.header .icon { position: absolute; left: 60px; top: 240px; width: 128px; height: 128px; }
|
|
38
|
+
.header .title { left: 220px; top: 290px; font-size: 58px; }
|
|
39
|
+
.header .subs {
|
|
40
|
+
position: absolute; left: 225px; top: 360px; transform: translateY(-50%);
|
|
41
|
+
display: flex; gap: 16px; font-size: 20px; color: {{ grey }}; white-space: nowrap;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* ---------------- 排行行: 底板 110 高, 行距 120 ---------------- */
|
|
45
|
+
.row {
|
|
46
|
+
position: relative; width: {{ card_w }}px; height: 110px; margin-bottom: 10px;
|
|
47
|
+
background: url('{{ bar }}') no-repeat left top; background-size: {{ card_w }}px 110px;
|
|
48
|
+
overflow: hidden;
|
|
49
|
+
}
|
|
50
|
+
.row .medal { left: 37px; top: 27px; width: 55px; height: 55px; }
|
|
51
|
+
.row .box {
|
|
52
|
+
position: absolute; top: 30px; height: 50px; border-radius: 8px;
|
|
53
|
+
background: rgba(54, 54, 54, .9); font-size: 34px; line-height: 50px; text-align: center;
|
|
54
|
+
}
|
|
55
|
+
.row .avatar { position: absolute; left: 100px; top: 0; width: 180px; height: 180px; }
|
|
56
|
+
.row .name { left: 210px; top: 75px; }
|
|
57
|
+
.row .uid { top: 40px; font-size: 20px; }
|
|
58
|
+
|
|
59
|
+
/* bot 主人徽章: 底图以 208x39 中心为锚点, 名字压在中间 */
|
|
60
|
+
.badge { position: absolute; width: 208px; height: 39px; }
|
|
61
|
+
.badge .plate { position: absolute; left: 4px; top: 5px; width: 201px; height: 31px; border-radius: 6px; background: rgba(54, 54, 54, .6); }
|
|
62
|
+
.badge .bg { left: 104px; top: 19px; transform: translate(-50%, -50%); }
|
|
63
|
+
.badge .txt { position: absolute; left: 104px; top: 20px; transform: translate(-50%, -50%); font-size: 18px; white-space: nowrap; }
|
|
64
|
+
|
|
65
|
+
.icon-img { position: absolute; background-size: 100% 100%; background-repeat: no-repeat; }
|
|
66
|
+
{% block style %}{% endblock %}
|
|
67
|
+
{% for a in assets %}.{{ a.cls }} { background-image: url('{{ a.uri }}'); }
|
|
68
|
+
{% endfor %}
|
|
69
|
+
</style>
|
|
70
|
+
</head>
|
|
71
|
+
<body>
|
|
72
|
+
<div class="container">
|
|
73
|
+
<div class="header">
|
|
74
|
+
<div class="art">
|
|
75
|
+
<img class="bg" src="{{ header.art }}">
|
|
76
|
+
<img class="icon" src="{{ header.icon }}">
|
|
77
|
+
<div class="t title">{{ header.title }}</div>
|
|
78
|
+
<div class="subs">{% for s in header.subs %}<span>{{ s }}</span>{% endfor %}</div>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
{% block board %}{% endblock %}
|
|
83
|
+
|
|
84
|
+
{% for row in rows %}
|
|
85
|
+
<div class="row">
|
|
86
|
+
{% if row.medal %}
|
|
87
|
+
<div class="medal icon-img {{ row.medal }}"></div>
|
|
88
|
+
{% else %}
|
|
89
|
+
<div class="box" style="left: {{ row.box.left }}px; width: {{ row.box.w }}px">{{ row.box.text }}</div>
|
|
90
|
+
{% endif %}
|
|
91
|
+
<img class="avatar" src="{{ row.avatar }}">
|
|
92
|
+
<div class="t name" style="font-size: {{ row.name_size }}px">{{ row.name }}</div>
|
|
93
|
+
<div class="t uid" style="left: {{ row.uid_x }}px; color: {{ row.uid_color }}">{{ row.uid }}</div>
|
|
94
|
+
{% if row.badge %}
|
|
95
|
+
<div class="badge" style="left: {{ row.badge.x }}px; top: {{ row.badge.y }}px">
|
|
96
|
+
{% if row.badge.cls %}
|
|
97
|
+
<div class="bg icon-img {{ row.badge.cls }}" style="width: {{ row.badge.w }}px; height: {{ row.badge.h }}px"></div>
|
|
98
|
+
{% else %}<div class="plate"></div>{% endif %}
|
|
99
|
+
<div class="txt">{{ row.badge.name }}</div>
|
|
100
|
+
</div>
|
|
101
|
+
{% endif %}
|
|
102
|
+
{% block row scoped %}{% endblock %}
|
|
103
|
+
</div>
|
|
104
|
+
{% endfor %}
|
|
105
|
+
</div>
|
|
106
|
+
</body>
|
|
107
|
+
</html>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{% extends "rank_board.html" %}
|
|
2
|
+
|
|
3
|
+
{% block style %}
|
|
4
|
+
/* ---------------- 排行说明 ---------------- */
|
|
5
|
+
.cond { position: relative; width: 100%; height: 130px; }
|
|
6
|
+
.cond .panel {
|
|
7
|
+
position: absolute; left: 20px; top: 20px; width: {{ card_w - 60 }}px; height: 90px;
|
|
8
|
+
border-radius: 8px; background: rgba(36, 36, 41, .9);
|
|
9
|
+
}
|
|
10
|
+
.cond .accent { position: absolute; left: 20px; top: 20px; width: {{ card_w - 60 }}px; height: 7px; background: rgb(203, 161, 95); }
|
|
11
|
+
.cond .label { left: 40px; top: 60px; font-size: 28px; color: {{ grey }}; }
|
|
12
|
+
.cond .line { left: 185px; font-size: 20px; color: {{ gold }}; }
|
|
13
|
+
.cond .notes { left: 1260px; top: 100px; font-size: 16px; color: {{ gold }}; }
|
|
14
|
+
|
|
15
|
+
/* ---------------- 行内: 角色数 / 前十角色 / 最高分 / 总分 ---------------- */
|
|
16
|
+
.row .count-l { left: 210px; top: 45px; font-size: 18px; }
|
|
17
|
+
.row .count-v { left: 280px; top: 45px; font-size: 20px; color: {{ red }}; }
|
|
18
|
+
/* 挂了命令的格子会被交互桥改成 position:relative, 这里按更高优先级钉回绝对定位 */
|
|
19
|
+
.row .ch {
|
|
20
|
+
position: absolute; top: 35px; width: 40px; height: 40px;
|
|
21
|
+
-webkit-mask-image: {{ char_mask }}; mask-image: {{ char_mask }};
|
|
22
|
+
}
|
|
23
|
+
.row .cs {
|
|
24
|
+
position: absolute; top: 77px; width: 40px; transform: translateY(-50%);
|
|
25
|
+
text-align: center; font-size: 12px; color: {{ gold }};
|
|
26
|
+
}
|
|
27
|
+
.row .best-v { left: 1080px; top: 45px; font-size: 30px; color: lightgreen; }
|
|
28
|
+
.row .best-l { left: 1080px; top: 75px; font-size: 16px; }
|
|
29
|
+
.row .total-v { left: 1180px; top: 45px; font-size: 34px; }
|
|
30
|
+
.row .total-l { left: 1180px; top: 75px; font-size: 16px; }
|
|
31
|
+
{% endblock %}
|
|
32
|
+
|
|
33
|
+
{% block board %}
|
|
34
|
+
<div class="cond">
|
|
35
|
+
<div class="panel"></div>
|
|
36
|
+
<div class="accent"></div>
|
|
37
|
+
<div class="t label">排行说明</div>
|
|
38
|
+
<div class="t line" style="top: 50px">{{ cond.line1 }}</div>
|
|
39
|
+
<div class="t line" style="top: 85px">{{ cond.line2 }}</div>
|
|
40
|
+
<div class="t rm notes">{{ cond.notes }}</div>
|
|
41
|
+
</div>
|
|
42
|
+
{% endblock %}
|
|
43
|
+
|
|
44
|
+
{% block row %}
|
|
45
|
+
<div class="t count-l">角色数:</div>
|
|
46
|
+
<div class="t count-v">{{ row.count }}</div>
|
|
47
|
+
{% for c in row.chars %}
|
|
48
|
+
<div class="ch icon-img {{ c.cls }}" style="left: {{ c.x }}px"{% if c.cmd %} data-ww-cmd="{{ c.cmd }}"{% endif %}></div>
|
|
49
|
+
<div class="cs" style="left: {{ c.x }}px">{{ c.score }}</div>
|
|
50
|
+
{% endfor %}
|
|
51
|
+
{% if row.best %}
|
|
52
|
+
<div class="t mm best-v">{{ row.best }}</div>
|
|
53
|
+
<div class="t mm best-l">最高分</div>
|
|
54
|
+
{% endif %}
|
|
55
|
+
<div class="t mm total-v">{{ row.total }}</div>
|
|
56
|
+
<div class="t mm total-l">总分</div>
|
|
57
|
+
{% endblock %}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{% extends "rank_board.html" %}
|
|
2
|
+
|
|
3
|
+
{% block style %}
|
|
4
|
+
/* ---------------- 行内: 队伍块 / 总分 ---------------- */
|
|
5
|
+
.row .gold { position: absolute; left: 210px; top: 40px; display: flex; align-items: center; gap: 4px; transform: translateY(-50%); }
|
|
6
|
+
.row .gold .l { font-size: 12px; }
|
|
7
|
+
.row .gold .v { font-size: 18px; color: {{ red }}; }
|
|
8
|
+
.row .team-count { left: 454px; top: 40px; font-size: 20px; color: {{ grey }}; }
|
|
9
|
+
.row .score { top: 55px; font-size: 44px; }
|
|
10
|
+
|
|
11
|
+
/* 挂了命令的格子会被交互桥改成 position:relative, 这里按更高优先级钉回绝对定位 */
|
|
12
|
+
.row .ch { position: absolute; top: {{ char_y }}px; width: {{ char_size }}px; height: {{ char_size }}px; }
|
|
13
|
+
.row .ch .pic { position: absolute; inset: 0; background-size: 100% 100%; }
|
|
14
|
+
.row .ch .pic.round { border-radius: 50%; }
|
|
15
|
+
.row .ch .chain { position: absolute; right: 0; bottom: 0; width: {{ chain_size }}px; height: {{ chain_size }}px; }
|
|
16
|
+
.row .ch .chain span { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size: 12px; }
|
|
17
|
+
|
|
18
|
+
/* 队伍不足 3 人时的占位格 */
|
|
19
|
+
.row .hole {
|
|
20
|
+
position: absolute; top: {{ char_y }}px; width: {{ char_size }}px; height: {{ char_size }}px;
|
|
21
|
+
background: rgba(60, 60, 60, .5); border: 1px solid rgba(120, 120, 120, .78);
|
|
22
|
+
}
|
|
23
|
+
.row .hole span { position: absolute; left: 50%; transform: translate(-50%, -50%); font-size: 12px; color: {{ grey }}; }
|
|
24
|
+
|
|
25
|
+
.row .buff { top: {{ buff_y }}px; width: {{ buff_size }}px; height: {{ buff_size }}px; }
|
|
26
|
+
.row .buff .plate { position: absolute; inset: 0; border-radius: 5px; background: rgba(0, 0, 0, .8); }
|
|
27
|
+
.row .buff .pic { position: absolute; inset: 0; background-size: 100% 100%; }
|
|
28
|
+
.row .team-score { top: 80px; font-size: 18px; }
|
|
29
|
+
|
|
30
|
+
/* 满分档的水晶炫彩 */
|
|
31
|
+
.crystal { background-image: {{ crystal }}; -webkit-background-clip: text; background-clip: text; color: transparent; }
|
|
32
|
+
{% endblock %}
|
|
33
|
+
|
|
34
|
+
{% block row %}
|
|
35
|
+
{% if single_team %}
|
|
36
|
+
<div class="gold"><span class="l">上场队伍角色金数:</span><span class="v">{{ row.gold }}</span></div>
|
|
37
|
+
{% elif row.team_count %}
|
|
38
|
+
<div class="t mm team-count">{{ row.team_count }}</div>
|
|
39
|
+
{% endif %}
|
|
40
|
+
<div class="t mm score{% if not row.score_color %} crystal{% endif %}"
|
|
41
|
+
style="left: {{ row.score_x }}px{% if row.score_color %}; color: {{ row.score_color }}{% endif %}">{{ row.score }}</div>
|
|
42
|
+
{% for team in row.teams %}
|
|
43
|
+
{% for c in team.chars %}
|
|
44
|
+
<div class="ch icon-img" style="left: {{ c.x }}px"{% if c.cmd %} data-ww-cmd="{{ c.cmd }}"{% endif %}>
|
|
45
|
+
<div class="pic {{ c.cls }}{% if c.round %} round{% endif %}"></div>
|
|
46
|
+
{% if c.chain != -1 %}<div class="chain" style="background: {{ c.chain_color }}"><span>{{ c.chain }}</span></div>{% endif %}
|
|
47
|
+
</div>
|
|
48
|
+
{% endfor %}
|
|
49
|
+
{% for x in team.holes %}
|
|
50
|
+
<div class="hole" style="left: {{ x }}px">
|
|
51
|
+
<span style="top: {{ hole_first_y }}px">模版</span>
|
|
52
|
+
<span style="top: {{ hole_second_y }}px">角色</span>
|
|
53
|
+
</div>
|
|
54
|
+
{% endfor %}
|
|
55
|
+
{% if team.buff %}
|
|
56
|
+
<div class="buff icon-img" style="left: {{ team.buff_x }}px">
|
|
57
|
+
<div class="plate"></div>
|
|
58
|
+
<div class="pic {{ team.buff }}"></div>
|
|
59
|
+
</div>
|
|
60
|
+
{% endif %}
|
|
61
|
+
{% if not single_team %}
|
|
62
|
+
<div class="t mm team-score{% if not team.score_color %} crystal{% endif %}"
|
|
63
|
+
style="left: {{ team.score_x }}px{% if team.score_color %}; color: {{ team.score_color }}{% endif %}">{{ team.score }}</div>
|
|
64
|
+
{% endif %}
|
|
65
|
+
{% endfor %}
|
|
66
|
+
{% endblock %}
|