- 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
35 lines
2.1 KiB
JavaScript
35 lines
2.1 KiB
JavaScript
// public/js/render/promote.js — which prep pieces were just promoted (精锐晋升), for the merge cue of render/app.js setPrep.
|
|
//
|
|
// A merge replaces the consumed normal copies by ONE new elite piece in the same m.private update: on the board tile of
|
|
// the consumed copy that deploys first when a copy was deployed (PRTS 卫戍协议/帮助 "若消耗已部署至作战区的干员,则发送至
|
|
// 作战区对应位置"; server board.js mergeTile), else in the hand / temp. So a promotion = a chess piece with a new uid that is
|
|
// an elite, while normal copies of the same operator (same baseId) vanished from the previous state. The cue then plays
|
|
// on the elite (fx.promote: gold pillar + rings, streaks from the vanished copies) instead of the plain deploy flash.
|
|
|
|
/**
|
|
* @param {Array<{ uid: number, area: string, piece: any }>} prev entries of the previous setPrep (render/app.js prepPieces)
|
|
* @param {Array<{ uid: number, area: string, piece: any }>} next entries of this setPrep
|
|
* @param {(id: string) => any} chessOf chess record lookup (`baseId`, `isGolden`)
|
|
* @returns {Map<number, Array<{ uid: number, area: string, piece: any }>>} new elite uid → the vanished copies (prev entries)
|
|
*/
|
|
export function promotionsOf(prev, next, chessOf) {
|
|
const out = new Map();
|
|
if (!Array.isArray(prev) || !prev.length || !Array.isArray(next)) return out;
|
|
const before = new Set(prev.map((e) => e.uid));
|
|
const now = new Set(next.map((e) => e.uid));
|
|
const baseOf = (id) => chessOf(id)?.baseId || id;
|
|
const isElite = (p) => !!(p?.golden || chessOf(p?.id)?.isGolden);
|
|
const gone = prev.filter((e) => e.piece?.kind === 'chess' && !now.has(e.uid) && !isElite(e.piece));
|
|
if (!gone.length) return out;
|
|
const used = new Set();
|
|
for (const e of next) {
|
|
if (e.piece?.kind !== 'chess' || before.has(e.uid) || !isElite(e.piece)) continue;
|
|
const base = baseOf(e.piece.id);
|
|
const copies = gone.filter((g) => !used.has(g.uid) && baseOf(g.piece.id) === base);
|
|
if (!copies.length) continue;
|
|
for (const g of copies) used.add(g.uid);
|
|
out.set(e.uid, copies);
|
|
}
|
|
return out;
|
|
}
|