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:
sganggs committed 2026-10-06 00:13:31 +08:00
1 parent e480b1cb26
commit 0def7babfd
31 files changed
+1637 -78

No files matched your search

+8
View File
@@ -22,6 +22,8 @@
// eliminated spectator from the first round on (test/ui/watch-bonds.e2e.test.js, the Final Assault).
// SP_STAGE=<stageId>: every match is played on this stage instead of the drawn one (test/ui/feedback1-placement.e2e.test.js:
// 战场#08's pool).
// SP_START_LEVEL=<1..6>: the starter kit also puts every human's 调度中心 at this level (and rerolls its shop there, before
// SP_START_SHOP stocks its first slots) — test/ui/diy.e2e.test.js: a tier-5 自选 piece is sold from level 5.
// Not a test file (node --test runs it as a no-op module when NODE_TEST_CONTEXT is set).
import { startServer } from '../../server/index.js';
@@ -46,6 +48,7 @@ if (!process.env.NODE_TEST_CONTEXT) {
const autoPlace = process.env.SP_AUTO_PLACE === '1';
const eliminate = String(process.env.SP_ELIMINATE || '').split(',').map((x) => x.trim()).filter(Boolean).map(Number);
const forcedStage = String(process.env.SP_STAGE || '').trim();
const startLevel = Math.max(0, Math.min(6, Number(process.env.SP_START_LEVEL) || 0));
class FastMatch extends Match {
constructor(opts) {
@@ -152,6 +155,11 @@ if (!process.env.NODE_TEST_CONTEXT) {
if (slot < 0 || !this.gd.item(itemId)) continue;
try { ps.hand[slot] = ps.newPiece('item', itemId); } catch { /* best effort */ }
}
if (startLevel > 0) {
ps.shop.level = Math.min(startLevel, this.gd.maxShopLevel);
ps.shop.upgradePrice = this.gd.upgradeBase(ps.shop.level) ?? 0;
ps.rollShop({ keepFrozen: false });
}
kitShop.forEach((id, i) => {
if (i < ps.shop.slots.length && this.gd.chess(id)) ps.shop.slots[i] = { kind: 'chess', id, basePrice: this.gd.chessPrice(id), frozen: false, sold: false };
});