Playtest #6 follow-up (v2.5.1): leader HP review — 直接乘算, one debuff instance, 999 layer cap, 限伤; elite to the board; 假想敌:胄 kit
- co-op leaders died within seconds: leader HP is the official data (40 values pinned); bond / strategy / item / 机变 / 特质 "+X%" bonuses now add up (PRTS 直接乘算) instead of compounding; a same-named enemy debuff keeps one (strongest) instance per target (奥术 across a pair field); leader parts pass damage 1:1; fixed co-op pool (the user's call) - official limits read from the client: each bond stops at 999 layers (MAX_GARRISON_STACK); a leader hit of 300000+ in boss / hidden battles is cancelled (MAX_BATTLE_DAMAGE, 限伤) — shared/constants.js switches, research 11 - a merge that consumes a deployed copy puts the elite on that tile and facing (user-confirmed); gold target highlight, promotion effect - 假想敌:胄 per PRTS: one shell, shells within range, any drone death costs 2 % max HP, 剑/锤 sorties and 瘫痪 - DESIGN §20.10–§20.14; 2842 unit tests, all 28 browser suites green; Chrome = Node on boss fields
This commit is contained in:
1 parent
6464e4b46a
commit
620f88c0d8
81 files changed
+4194
-447
No files matched your search
@@ -458,7 +458,9 @@ export function priceTone(slot) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Owned copies of a base chess (normal pieces on board/hand/temp) — shop cards show merge progress.
|
||||
* Owned copies of a base chess (normal pieces on board/hand/temp) — shop cards show merge progress. An elite card
|
||||
* never merges (server PlayerState.completesChessMerge refuses isGolden), so it reports 0 copies: no pips, no 可晋升
|
||||
* tag and no mergeTarget tile.
|
||||
* @param {any} priv
|
||||
* @param {string} chessId
|
||||
* @param {(id:string)=>any} [getChess]
|
||||
@@ -468,12 +470,36 @@ export function mergeProgress(priv, chessId, getChess = () => null) {
|
||||
const c = getChess(chessId);
|
||||
const base = c?.baseId || chessId;
|
||||
const need = Number.isInteger(c?.upgradeNum) && c.upgradeNum > 0 ? c.upgradeNum : 3;
|
||||
if (c?.isGolden) return { copies: 0, need };
|
||||
let copies = 0;
|
||||
const pieces = [...(Array.isArray(priv?.board) ? priv.board : []), ...(Array.isArray(priv?.hand) ? priv.hand : []), ...(Array.isArray(priv?.temp) ? priv.temp : [])];
|
||||
for (const p of pieces) if (p?.kind === 'chess' && !p.golden && (p.id === base || getChess(p.id)?.baseId === base) && !String(p.id).endsWith('_b')) copies += 1;
|
||||
return { copies, need };
|
||||
}
|
||||
|
||||
/**
|
||||
* Where the elite appears when gaining one more normal copy of `chessId` completes a merge now (PRTS 卫戍协议/帮助
|
||||
* "若消耗已部署至作战区的干员,则发送至作战区对应位置"; mirror of server board.js mergeTile / PlayerState._mergeChess): the
|
||||
* board tile of the deployed copy that deploys first (row desc, then col asc) — `{ row, col, dir }` — or null (no
|
||||
* merge — an elite card never merges, see mergeProgress — or no copy is deployed: the elite goes to the hand). The
|
||||
* copies stand on legal tiles, and the elite is the same operator, so the tile needs no legality check here.
|
||||
* @param {any} priv
|
||||
* @param {string} chessId
|
||||
* @param {(id:string)=>any} [getChess]
|
||||
* @returns {{ row: number, col: number, dir: string } | null}
|
||||
*/
|
||||
export function mergeTarget(priv, chessId, getChess = () => null) {
|
||||
const { copies, need } = mergeProgress(priv, chessId, getChess);
|
||||
if (!(copies > 0 && copies + 1 >= need)) return null;
|
||||
const c = getChess(chessId);
|
||||
const base = c?.baseId || chessId;
|
||||
const board = (Array.isArray(priv?.board) ? priv.board : []).filter((p) => p?.kind === 'chess' && !p.golden && Number.isInteger(p.row) && Number.isInteger(p.col)
|
||||
&& !String(p.id).endsWith('_b') && (p.id === base || getChess(p.id)?.baseId === base));
|
||||
if (!board.length) return null;
|
||||
board.sort((a, b) => b.row - a.row || a.col - b.col);
|
||||
return { row: board[0].row, col: board[0].col, dir: board[0].dir || 'RIGHT' };
|
||||
}
|
||||
|
||||
/** Whether every hand slot is taken (the server refuses a purchase / reward that needs a slot: HAND_FULL). */
|
||||
export function handFull(priv) {
|
||||
const hand = Array.isArray(priv?.hand) ? priv.hand : [];
|
||||
|
||||
Reference in new issue
Block a user