Play liveChoose your opponent
Join
main
68 lines · 2.9 KB Raw Permalink History
1// Choosing a general, as 无名杀's 选将 dialog: the candidates as portrait cards with faction, HP and skills; pick one,
2// then 确定. The move is the upstream's own (OverlaysLayer): 系统规则 · 选将 with the general's name.
3import { useState } from 'react';
4import { getCharacterMeta } from '../../../src/engine/data/character-meta';
5import { getSkillDescription } from '../../../src/engine/skills/lifecycle';
6import { displaySkillName } from '../../../src/client/utils/skillDisplay';
7import type { ActionMsg } from '../../../src/client/types';
8import { portrait, FACTION_KEY } from './art';
9import { Hp, Timer } from './Seat';
10
11interface Props {
12 candidates: Array<{ name: string; skills: string[] }>;
13 target: number;
14 mine: boolean;
15 deadline: number | null;
16 totalMs: number;
17 onAction: (a: ActionMsg) => void;
18}
19
20export function CharSelect({ candidates, target, mine, deadline, totalMs, onAction }: Props) {
21 const [pick, setPick] = useState<string | null>(null);
22 const [sent, setSent] = useState(false);
23 if (sent || !mine) return <div className="nm-dialog-wait">等待其他角色选择武将…</div>;
24 return (
25 <div className="nm-dialog-mask">
26 <div className="nm-dialog choose">
27 <div className="nm-dialog-title">请选择武将</div>
28 <div className="nm-choose-row">
29 {candidates.map((c) => {
30 const meta = getCharacterMeta(c.name);
31 const fac = meta?.faction ?? '群';
32 const img = portrait(c.name);
33 return (
34 <button key={c.name} className={`nm-choose ${FACTION_KEY[fac] ?? 'qun'}${pick === c.name ? ' selected' : ''}`} onClick={() => setPick(c.name)} onDoubleClick={() => setPick(c.name)}>
35 <div className="nm-avatar" style={img ? { backgroundImage: `url(${img})` } : undefined} />
36 <div className="nm-frame" />
37 <div className={`nm-faction ${FACTION_KEY[fac] ?? 'qun'}`}>{fac}</div>
38 <div className={`nm-name${c.name.length > 4 ? ' long' : ''}`}>{c.name}</div>
39 {meta && <Hp hp={meta.maxHealth} max={meta.maxHealth} />}
40 <div className="nm-choose-skills">
41 {c.skills.map((s) => (
42 <span key={s} title={getSkillDescription(s) ?? ''}>
43 {displaySkillName(s)}
44 </span>
45 ))}
46 </div>
47 </button>
48 );
49 })}
50 </div>
51 <Timer deadline={deadline} totalMs={totalMs} />
52 <div className="nm-control in-dialog">
53 <button
54 className="nm-btn ok"
55 disabled={!pick}
56 onClick={() => {
57 if (!pick) return;
58 setSent(true);
59 onAction({ skillId: '系统规则', actionType: '选将', ownerId: target, params: { character: pick } });
60 }}
61 >
62 确定
63 </button>
64 </div>
65 </div>
66 </div>
67 );
68}