feedback5 WK: 自选编队 in the browser — the 干员调配 overlay's third tab 自选编队 (5阶 ×2, 6阶 ×2 slots; the slot picker lists the kitted picks of the tier with avatar, name, class, derived bonds and a 原型 / 已持有 tag; an owned pick chooses its skill and module — 集成战略 modules left out —, a prototype shows its locked skill; sp.pref.diy, export / import, 全部清空, synced as room.diy through the shared engine, welcome.diyKitted kept), the operator on shop / reward cards, own pieces (「自选」 tag, its model on bench and board), the detail card (pick's skill and module), placement and range previews, bond popups (own and a teammate's 自选 member), the result screen; new UI strings through t() with English; the e2e fast server's SP_START_LEVEL hook
Bonds of 自选 pieces checked everywhere membership is decided (the owner's reminder of 2026-10-05): the match's counts through the player's data view (煌 in 炎 and 维多利亚, one member per slot, 绝技 elites), the sim's bond effects through def.bonds (叙拉古 on deployment, 协防 ×1.2 / elite ×1.4), the client's strip, popups, cards and detail card. Golden unchanged. Tests: test/ui/diy-ui.test.js (15), test/match/diy-bonds.test.js (4), test/i18n.test.js pins screens/diy.js; test/ui/diy.e2e.test.js (SP_E2E=1, run once: pass).
This commit is contained in:
1 parent
e480b1cb26
commit
0def7babfd
31 files changed
+1637
-78
No files matched your search
@@ -1,12 +1,15 @@
|
||||
// public/js/screens/game/standInTags.js — 0.2.0 补位: the 「替补:X」 tag under the player's own prep pieces (hand,
|
||||
// 临时整备区, board) of a chess they do not own (m.private.standIns). The hand keeps the chess's own model (the card shows
|
||||
// the original operator); on the board the model is the stand-in's (render/app.js pieceInfo) — the tag says which
|
||||
// chess it is either way. Anchored to each piece's drawn body (view.pieceScreenRect, followed every frame like the
|
||||
// direction wheel follows its tile); never takes the pointer, so the pieces stay draggable.
|
||||
// chess it is either way. 0.2.0 自选编队: the 「自选」 tag under the player's own pieces of a DIY slot it filled
|
||||
// (m.private.diy) — the model is the operator's everywhere. Anchored to each piece's drawn body (view.pieceScreenRect,
|
||||
// followed every frame like the direction wheel follows its tile); never takes the pointer, so the pieces stay
|
||||
// draggable.
|
||||
|
||||
import { useEffect, useRef, useState } from '../../../vendor/hooks.module.js';
|
||||
import { html } from '../../ui/components.js';
|
||||
import { fieldsStandIn, standInOf, standInLabel } from '../../ui/gameLogic.js';
|
||||
import { fieldsStandIn, standInOf, standInLabel, ownDiyRecord } from '../../ui/gameLogic.js';
|
||||
import { t } from '../../../../shared/i18n.js';
|
||||
|
||||
const rawOf = (view) => (view && view.raw) || view || null;
|
||||
|
||||
@@ -30,9 +33,27 @@ export function standInPieces(priv, getChess, backups) {
|
||||
return out;
|
||||
}
|
||||
|
||||
/** @param {{ view: any, priv: any, getChess: (id: string) => any, backups: any }} props */
|
||||
export function StandInTags({ view, priv, getChess, backups }) {
|
||||
const items = standInPieces(priv, getChess, backups);
|
||||
/**
|
||||
* The player's own prep pieces of a DIY slot it filled (0.2.0 自选编队): [{ uid, label, name, area, diy: true }].
|
||||
* @param {any} priv m.private @param {(id: string) => any} getChess @param {{ chess: any, backups: any }} data
|
||||
*/
|
||||
export function diyPieces(priv, getChess, data) {
|
||||
const out = [];
|
||||
if (!priv || !priv.diy || typeof priv.diy !== 'object' || !Object.keys(priv.diy).length) return out;
|
||||
const add = (p, area) => {
|
||||
if (!p || p.kind !== 'chess' || !Number.isInteger(p.uid)) return;
|
||||
const rec = ownDiyRecord(getChess(p.id), priv, data);
|
||||
if (rec) out.push({ uid: p.uid, label: t('自选'), name: rec.name, area, diy: true });
|
||||
};
|
||||
for (const p of Array.isArray(priv.hand) ? priv.hand : []) add(p, 'hand');
|
||||
for (const p of Array.isArray(priv.temp) ? priv.temp : []) add(p, 'temp');
|
||||
for (const p of Array.isArray(priv.board) ? priv.board : []) add(p, 'board');
|
||||
return out;
|
||||
}
|
||||
|
||||
/** @param {{ view: any, priv: any, getChess: (id: string) => any, backups: any, diyData?: { chess: any, backups: any } | null }} props */
|
||||
export function StandInTags({ view, priv, getChess, backups, diyData = null }) {
|
||||
const items = [...standInPieces(priv, getChess, backups), ...(diyData ? diyPieces(priv, getChess, diyData) : [])];
|
||||
const [pos, setPos] = useState({});
|
||||
const last = useRef('');
|
||||
const key = items.map((it) => it.uid).join(',');
|
||||
@@ -64,7 +85,8 @@ export function StandInTags({ view, priv, getChess, backups }) {
|
||||
return html`<div class="sitags" aria-hidden="true" data-testid="standin-tags">
|
||||
${items.map((it) => {
|
||||
const p = pos[it.uid];
|
||||
return p ? html`<span key=${it.uid} class=${`sitag sitag--${it.area}`} data-uid=${it.uid} title=${`未持有:由 ${it.name} 上场`}
|
||||
return p ? html`<span key=${it.uid} class=${`sitag sitag--${it.area}${it.diy ? ' sitag--diy' : ''}`} data-uid=${it.uid} data-diy=${it.diy ? '1' : undefined}
|
||||
title=${it.diy ? t('自选编队:{name}', { name: it.name }) : `未持有:由 ${it.name} 上场`}
|
||||
style=${`left:${p.x.toFixed(1)}px;top:${p.y.toFixed(1)}px`}>${it.label}</span>` : null;
|
||||
})}
|
||||
</div>`;
|
||||
|
||||
Reference in new issue
Block a user