feedback5 WE: the 整备区 rules of PRTS 卫戍协议/帮助 §手牌区 (GitHub #82, second part) — a full regular hand refuses every purchase and reward pick, also one whose copy would complete a merge at once ("当常规手牌区全满无空位时,玩家将无法执行使手牌溢出的操作" — "例如招募/购入等通常情况下会增加手牌的操作"; BWIKI 盟约 says the same with no exception; the reporter checked it in the official game), and a free regular slot pulls the 临时整备区 in at once ("常规手牌区出现空位时自动移入"): PlayerState._fillHandFromTemp runs in every recompute, the temp row right to left (the order it fills, [ASSUMED]) into the hand's free slots right to left — after a sale, a deployment from the hand, a merge that consumed hand copies, an item equipped / destroyed / used, a summon stack removed with its owner. invariants.js: temp holds pieces only while the hand is full. The client's refusal path follows (gameLogic.shopBlockReason: 整备区已满 on every card — a one-line change in a file the R5 split moves). Bots: a full hand never tries a purchase, an affordable third copy of a held pair sheds the weakest hand single first (never one of this prep), resolveTemp decides temp right to left. Tests: test/match/feedback5-hand.test.js; merge / hardening / playtest6-elite-to-board / economy / prep-bench / uiFixes updated to the rule. Docs: META §1 Hand, DESIGN §6, PLAYING §3, research 00-INDEX / 01 (the old "a merge-completing purchase is allowed" corrected). Golden: 3 match scenarios moved (coop2-NORMAL-3, solo-HARD-9-boosted, coop2-ABYSS-10-boosted — bot seats that reached a full hand: the merge-completing purchase refused or a single shed first, temp pieces moving in by themselves); every battle digest unchanged
This commit is contained in:
1 parent
b1ec04b58c
commit
db1b44bb71
22 files changed
+356
-101
No files matched your search
@@ -731,15 +731,16 @@ export function mergeTarget(priv, chessId, getChess = () => null) {
|
||||
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). */
|
||||
/** Whether every hand slot is taken (the server refuses every purchase / reward pick then: HAND_FULL, GitHub #82). */
|
||||
export function handFull(priv) {
|
||||
const hand = Array.isArray(priv?.hand) ? priv.hand : [];
|
||||
return hand.length >= GEO.HAND_SIZE && hand.every((p) => p != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Would gaining one more `slot` (shop / reward card: { kind: 'chess'|'item', id }) complete a merge right away, so it
|
||||
* needs no hand slot? Mirror of server PlayerState completesChessMerge / completesItemMerge.
|
||||
* Would gaining one more `slot` (shop / reward card: { kind: 'chess'|'item', id }) complete a merge right away? Mirror
|
||||
* of server PlayerState completesChessMerge / completesItemMerge. (A full hand refuses such a purchase all the same:
|
||||
* PRTS 卫戍协议/帮助 §手牌区, GitHub #82.)
|
||||
* @param {any} priv
|
||||
* @param {{kind?:string, id:string}} slot
|
||||
* @param {{ getChess?:(id:string)=>any, getItem?:(id:string)=>any, itemMergeCount?: number }} [o]
|
||||
@@ -795,10 +796,10 @@ export function offerHeader(offer) {
|
||||
/**
|
||||
* Why a shop action is unavailable (null when available).
|
||||
* @param {'buy'|'reward'|'refresh'|'freeze'|'levelUp'|'ready'} kind
|
||||
* @param {{ priv:any, editable:boolean, slot?:any, getChess?:(id:string)=>any, getItem?:(id:string)=>any }} ctx
|
||||
* @param {{ priv:any, editable:boolean, slot?:any }} ctx
|
||||
* @returns {string|null} Chinese reason
|
||||
*/
|
||||
export function shopBlockReason(kind, { priv, editable, slot, getChess, getItem } = {}) {
|
||||
export function shopBlockReason(kind, { priv, editable, slot } = {}) {
|
||||
if (!priv) return '尚未就绪';
|
||||
if (priv.alive === false) return '你已被淘汰';
|
||||
if (kind === 'ready') return priv.canReady === false ? '临时整备区不为空,请先处理溢出的资源' : null;
|
||||
@@ -811,7 +812,8 @@ export function shopBlockReason(kind, { priv, editable, slot, getChess, getItem
|
||||
if (kind === 'buy' || kind === 'reward') {
|
||||
if (!isObj(slot) || slot.sold) return kind === 'reward' ? '已选择' : '已售出';
|
||||
if ((Number(slot.price) || 0) > funds) return '资金不足';
|
||||
if (handFull(priv) && !completesMerge(priv, slot, { getChess, getItem })) return '整备区已满';
|
||||
// a full hand refuses every purchase / pick, a merge-completing one too (PRTS 卫戍协议/帮助 §手牌区, GitHub #82)
|
||||
if (handFull(priv)) return '整备区已满';
|
||||
return null;
|
||||
}
|
||||
if (kind === 'refresh') return (Number(shop.refreshPrice) || 0) > funds ? '资金不足' : null;
|
||||
|
||||
@@ -37,7 +37,7 @@ function PriceHex({ slot, free, poor = false }) {
|
||||
title=${poor ? '资金不足' : tone === 'discount' ? `折扣价(原价 ${slot.basePrice})` : tone === 'premium' ? `加价(原价 ${slot.basePrice})` : '价格'} />`;
|
||||
}
|
||||
|
||||
/** Data lookups for shopBlockReason (full-hand purchases that complete a merge stay allowed). */
|
||||
/** Data lookups (merge progress / target, the loadout; shopBlockReason ignores them — a full hand refuses every purchase). */
|
||||
const LOOKUPS = { getChess: (id) => data.lookup('chess', id), getItem: (id) => data.lookup('items', id) };
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user