Files
ark-stronghold-protocol/public/js/ui/gameLogic/draft.js
T
sganggs eb04f5dfa4 feedback5 R5: split the in-match UI logic into modules
public/js/ui/gameLogic.js becomes a re-export barrel. The bodies move verbatim into public/js/ui/gameLogic/*.js (shared, phases, camera, watch, bonds, shop, placement, draft, enemies, format, shortcuts, settings, result, loadout, panel). The barrel re-exports the same 96 names in the same order. isObj and int gain export on shared.js so sibling modules can import them; they stay off the barrel. No importer changes.
2026-10-05 17:06:45 +08:00

76 lines
3.7 KiB
JavaScript

// ui/gameLogic/draft.js — 机变 and band-draft normalisation. Re-exported from ../gameLogic.js.
import { isObj } from './shared.js';
// ---- 机变 / band draft normalisation ----------------------------------------------------------------------
/**
* Normalise m.public.draft ({order, turn, picks, skips?}) — tolerant of index/playerId turns and
* object/array picks.
* @param {any} draft
* @param {any[]} [players]
* @returns {{ order: string[], turnPid: string|null, picks: Map<string,string>, skipsLeft: Map<string, number>, done: boolean }}
*/
export function normalizeDraft(draft, players = []) {
const ids = (Array.isArray(players) ? players : []).filter(isObj).map((p) => p.playerId);
const order = Array.isArray(draft?.order) && draft.order.length ? draft.order.filter((x) => typeof x === 'string') : ids;
let turnPid = null;
if (typeof draft?.turn === 'string') turnPid = draft.turn;
else if (Number.isInteger(draft?.turn) && draft.turn >= 0 && draft.turn < order.length) turnPid = order[draft.turn];
const picks = new Map();
const src = draft?.picks;
if (Array.isArray(src)) {
src.forEach((v, i) => {
if (typeof v === 'string' && order[i]) picks.set(order[i], v);
else if (isObj(v) && typeof v.playerId === 'string' && typeof v.bandId === 'string') picks.set(v.playerId, v.bandId);
});
} else if (isObj(src)) {
for (const [k, v] of Object.entries(src)) if (typeof v === 'string' && v) picks.set(k, v);
}
const skipsLeft = new Map();
const sk = draft?.skipsLeft ?? draft?.skips;
if (isObj(sk)) for (const [k, v] of Object.entries(sk)) if (Number.isFinite(v)) skipsLeft.set(k, v);
const done = order.length > 0 && order.every((pid) => picks.has(pid));
return { order, turnPid, picks, skipsLeft, done };
}
/**
* Normalise m.public.sp ({family, cards, turn, picks, order?}).
* Cards: string ids or objects; picks: {playerId: cardIdx} | [{playerId, idx}] | card.takenBy.
* @param {any} sp
* @param {any[]} [players]
*/
export function normalizeSp(sp, players = []) {
if (!isObj(sp)) return null;
const ids = (Array.isArray(players) ? players : []).filter(isObj).map((p) => p.playerId);
const order = Array.isArray(sp.order) && sp.order.length ? sp.order.filter((x) => typeof x === 'string') : ids;
const cards = (Array.isArray(sp.cards) ? sp.cards : []).slice(0, 6).map((c, idx) => {
const card = typeof c === 'string' ? { id: c } : isObj(c) ? { ...c } : {};
return { ...card, idx, takenBy: typeof card.takenBy === 'string' ? card.takenBy : null };
});
const takenBy = new Map(); // idx → playerId
const pickOf = new Map(); // playerId → idx
const src = sp.picks;
const add = (pid, idx) => {
if (typeof pid !== 'string' || !Number.isInteger(idx) || idx < 0 || idx >= cards.length) return;
takenBy.set(idx, pid);
pickOf.set(pid, idx);
};
if (Array.isArray(src)) src.forEach((v, i) => { if (isObj(v)) add(v.playerId, v.idx); else if (Number.isInteger(v) && order[i]) add(order[i], v); });
else if (isObj(src)) for (const [k, v] of Object.entries(src)) add(k, v);
if (isObj(sp.taken)) for (const [k, v] of Object.entries(sp.taken)) add(v, Number(k));
for (const c of cards) if (c.takenBy) add(c.takenBy, c.idx);
for (const c of cards) c.takenBy = takenBy.get(c.idx) ?? null;
let turnPid = null;
if (typeof sp.turn === 'string') turnPid = sp.turn;
else if (Number.isInteger(sp.turn) && sp.turn >= 0 && sp.turn < order.length) turnPid = order[sp.turn];
return {
family: typeof sp.family === 'string' ? sp.family : null,
name: typeof sp.name === 'string' && sp.name ? sp.name : null,
desc: typeof sp.desc === 'string' && sp.desc ? sp.desc : null,
untimed: !!sp.untimed,
cards, order, turnPid, pickOf, takenBy, pickedCount: pickOf.size,
};
}