feedback5 WK: 自选编队 on the server — room.diy { picks } (lenient: illegal picks dropped, only malformed input is BAD_MSG; stored per session / seat; a match takes the picks its seat had at the start, a change during a match is for the next one; welcome lists diyKitted), PlayerState.diy with the player's data view (a slotted DIY slot is its operator for every rule: bonds from its factions, no 特质, the pick's skill and module, the slot's tier / price / merge), a per-player stock per slotted piece (8 at tier 5, 5 at tier 6 [ASSUMED]; never in the shared pool; none when every bond of it is banned), DIY pieces in that player's shop rolls and reward offers once the 调度中心 reaches the slot's level, battleInput diy, m.private.diy / diyBanned, prep scouting and results name the operator, 信标 never sends a 自选 piece to a teammate [ASSUMED]
The owner's decisions of 2026-10-05 (picks, slots, shop per player, bans); research 0.2.0 §2. Golden unchanged (no scenario slots a DIY pick). Tests: test/match/diy-shop.test.js (9), test/lobby-diy.test.js (4).
This commit is contained in:
1 parent
742f478526
commit
4bee542e61
26 files changed
+1026
-105
No files matched your search
@@ -37,10 +37,12 @@ export class PlayerAcquire {
|
||||
*/
|
||||
acquireChess(chessId, { source = 'grant', toTemp = false, fromPool = true, silent = false } = {}) {
|
||||
const rec = this.gd.chess(chessId);
|
||||
if (!rec) return null;
|
||||
// a DIY slot is only ever this player's own 自选 piece: a slot it has not filled has no body (甄选干员) to gain
|
||||
if (!rec || (rec.isDiy && !rec.diyFor)) return null;
|
||||
const base = this.gd.baseIdOf(chessId);
|
||||
const need = rec.isGolden ? this.gd.goldenCopies : 1;
|
||||
const taken = fromPool ? this.m.pool.take(base, need) : 0;
|
||||
// the shared pool, or this player's stock of a slotted 自选 piece (player/diy.js poolOf)
|
||||
const taken = fromPool ? this.poolOf(base).take(base, need) : 0;
|
||||
const piece = this.newPiece('chess', chessId, { poolCopies: taken });
|
||||
this.round.gainedChess++;
|
||||
let owned = piece;
|
||||
@@ -121,7 +123,7 @@ export class PlayerAcquire {
|
||||
// equipment, which would be lost in temp — a summon stack removed there comes back at the next round start)
|
||||
if (where === 'board') this.grantTokensFor(elite);
|
||||
if (!where) {
|
||||
this.m.pool.give(baseId, copies);
|
||||
this.poolOf(baseId).give(baseId, copies);
|
||||
this.m.toast(this, 'warn', '整备区已满,晋升的精锐干员无法放入');
|
||||
this.m.log.warn?.(`[match ${this.m.roomCode}] ${this.playerId}: merge result dropped (hand+temp full)`);
|
||||
this.recompute();
|
||||
@@ -142,7 +144,7 @@ export class PlayerAcquire {
|
||||
if (!goldenId) return false;
|
||||
const base = this.gd.baseIdOf(piece.id);
|
||||
const extra = Math.max(0, this.gd.goldenCopies - (piece.poolCopies || 0));
|
||||
piece.poolCopies = (piece.poolCopies || 0) + this.m.pool.take(base, extra);
|
||||
piece.poolCopies = (piece.poolCopies || 0) + this.poolOf(base).take(base, extra);
|
||||
piece.id = goldenId;
|
||||
this.recompute();
|
||||
return true;
|
||||
@@ -205,6 +207,8 @@ export class PlayerAcquire {
|
||||
* copy-weighted roll from the shared pool excluding the ones already drawn; a tier left without another chess tops
|
||||
* up from the tier below (user playtest #6 item 19: the official promotion reward never offers one operator twice —
|
||||
* the user's first-hand report; the normal shop's slots may repeat). The offer reserves no copies (the pick takes one).
|
||||
* The player's slotted 自选 pieces join the draw like in its shop (player/diy.js diyRollEntries: once the 调度中心 is at
|
||||
* the slot's level) — the reward is a temporary refresh of the shop ("临时刷新3名…干员") [ASSUMED].
|
||||
*/
|
||||
pushRewardOffer(source = 'merge', { tier = null, ids = null, label = null } = {}) {
|
||||
const ro = this.gd.rewardOffer();
|
||||
@@ -216,7 +220,7 @@ export class PlayerAcquire {
|
||||
const fresh = (id) => !list.includes(id);
|
||||
for (let i = 0; i < ro.count; i++) {
|
||||
let id = null;
|
||||
for (let tt = t; tt >= 1 && !id; tt--) id = this.m.pool.roll(this.m.rngShop, { tier: tt, filter: fresh });
|
||||
for (let tt = t; tt >= 1 && !id; tt--) id = this.m.pool.roll(this.m.rngShop, { tier: tt, filter: fresh, extra: this.diyRollEntries() });
|
||||
if (id) list.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user