fix: 将涤火杰西卡的盾牌放置限制在相邻四格
This commit is contained in:
1 parent
1db8e51023
commit
85062bab67
11 files changed
+209
-22
No files matched your search
+4
-1
@@ -1207,5 +1207,8 @@
|
||||
"请等待所有玩家连接后再发起投票": "Wait for all players to connect before starting a vote.",
|
||||
"同意重刷": "Agree to reroll",
|
||||
"拒绝重刷": "Reject reroll",
|
||||
"取消投票": "Cancel vote"
|
||||
"取消投票": "Cancel vote",
|
||||
"只能部署在召唤者相邻四格": "Can only be deployed on the four tiles adjacent to the summoner",
|
||||
"{names}只能部署在召唤者相邻四格,已退回整备区": "{names} can only be deployed on the four tiles adjacent to the summoner and returned to the Bench",
|
||||
"{names}只能部署在召唤者相邻四格,整备区已满,下回合返还": "{names} can only be deployed on the four tiles adjacent to the summoner; the Bench is full, so they come back next round"
|
||||
}
|
||||
+4
-1
@@ -1213,5 +1213,8 @@
|
||||
"请等待所有玩家连接后再发起投票": "全プレイヤーの接続を待ってから投票を開始してください。",
|
||||
"同意重刷": "再抽選に同意",
|
||||
"拒绝重刷": "再抽選を拒否",
|
||||
"取消投票": "投票を取り消す"
|
||||
"取消投票": "投票を取り消す",
|
||||
"只能部署在召唤者相邻四格": "召喚者に隣接する上下左右の4マスにのみ配置可能",
|
||||
"{names}只能部署在召唤者相邻四格,已退回整备区": "{names}は召喚者に隣接する上下左右の4マスにのみ配置可能なため、ベンチに戻りました",
|
||||
"{names}只能部署在召唤者相邻四格,整备区已满,下回合返还": "{names}は召喚者に隣接する上下左右の4マスにのみ配置可能です。ベンチが満員のため、次のラウンドに返却されます"
|
||||
}
|
||||
+4
-1
@@ -1209,5 +1209,8 @@
|
||||
"请等待所有玩家连接后再发起投票": "모든 플레이어가 접속한 후 투표를 시작하세요.",
|
||||
"同意重刷": "다시 추첨에 동의",
|
||||
"拒绝重刷": "다시 추첨 거부",
|
||||
"取消投票": "투표 취소"
|
||||
"取消投票": "투표 취소",
|
||||
"只能部署在召唤者相邻四格": "소환자와 상하좌우로 인접한 4칸에만 배치할 수 있습니다",
|
||||
"{names}只能部署在召唤者相邻四格,已退回整备区": "{names}은(는) 소환자와 상하좌우로 인접한 4칸에만 배치할 수 있어 정비 구역으로 돌아갔습니다",
|
||||
"{names}只能部署在召唤者相邻四格,整备区已满,下回合返还": "{names}은(는) 소환자와 상하좌우로 인접한 4칸에만 배치할 수 있습니다. 정비 구역이 가득 차 다음 라운드에 반환됩니다"
|
||||
}
|
||||
@@ -1211,5 +1211,8 @@
|
||||
"请等待所有玩家连接后再发起投票": "請等待所有玩家連線後再發起投票",
|
||||
"同意重刷": "同意重刷",
|
||||
"拒绝重刷": "拒絕重刷",
|
||||
"取消投票": "取消投票"
|
||||
"取消投票": "取消投票",
|
||||
"只能部署在召唤者相邻四格": "只能部署在召喚者相鄰四格",
|
||||
"{names}只能部署在召唤者相邻四格,已退回整备区": "{names}只能部署在召喚者相鄰四格,已退回整備區",
|
||||
"{names}只能部署在召唤者相邻四格,整备区已满,下回合返还": "{names}只能部署在召喚者相鄰四格,整備區已滿,下回合返還"
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
import { GEO } from '../../../../shared/constants.js';
|
||||
import { attackRangeGrid } from '../../../../shared/loadoutRecord.js';
|
||||
import { meleeOnHighGround } from '../../../../shared/highGround.js';
|
||||
import { summonPlacementGrid } from '../../../../shared/summonPlacement.js';
|
||||
import { pieceDir, rangeTiles } from '../facing.js';
|
||||
import { isObj, tileKey } from './shared.js';
|
||||
import { boardTileOf, fieldTile } from './camera.js';
|
||||
@@ -250,15 +251,18 @@ export function tileAllows(ctx, piece, row, col) {
|
||||
/**
|
||||
* Board tiles ('r,c') where a summon whose text reads "只能部署在召唤者攻击范围内" may stand (tokens.json `ownerRange`:
|
||||
* 伺夜's 狼群, 缪尔赛思's 流形 — the tactical point; player report #9 after 0.1.0): its owner's attack range (the
|
||||
* loadout's grid, shared/loadoutRecord.js attackRangeGrid, rotated by the owner's facing around its tile). Null when
|
||||
* loadout's grid, shared/loadoutRecord.js attackRangeGrid, rotated by the owner's facing around its tile).
|
||||
* Jessica's shield uses the four-adjacent-tile grid instead, independent of facing/skill/module. Null when
|
||||
* the piece is not range-bound or its owner is not on the board. `owner` ({ row, col, piece }) replaces the owner's
|
||||
* current position (a summon swapped with its own owner). Mirror of server/match/PlayerState.js summonRange.
|
||||
* @param {ReturnType<typeof placementContext>} ctx
|
||||
* @returns {Set<string> | null}
|
||||
*/
|
||||
export function summonRange(ctx, piece, owner = null) {
|
||||
if (!isObj(piece) || piece.kind !== 'token' || ctx?.getToken?.(piece.id)?.ownerRange !== true) return null;
|
||||
return ownerRangeOf(ctx, piece, owner);
|
||||
if (!isObj(piece) || piece.kind !== 'token') return null;
|
||||
const grid = summonPlacementGrid(piece.id);
|
||||
if (!grid && ctx?.getToken?.(piece.id)?.ownerRange !== true) return null;
|
||||
return ownerRangeOf(ctx, piece, owner, grid);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,14 +277,14 @@ export function summonExcluded(ctx, piece, owner = null) {
|
||||
return ownerRangeOf(ctx, piece, owner);
|
||||
}
|
||||
|
||||
/** The attack-range tiles of a summon piece's owner on the board (summonRange / summonExcluded), or null. */
|
||||
function ownerRangeOf(ctx, piece, owner = null) {
|
||||
/** The attack or fixed placement range of a summon piece's owner on the board, or null. */
|
||||
function ownerRangeOf(ctx, piece, owner = null, placementGrid = null) {
|
||||
let at = owner;
|
||||
if (!at) for (const e of ctx.boardAt.values()) if (e.piece.uid === piece.ownerUid && e.piece.kind === 'chess') { at = e; break; }
|
||||
const rec = at && ctx.getChess(at.piece.id);
|
||||
if (!rec) return null;
|
||||
let grid = null;
|
||||
try { grid = attackRangeGrid(deployedRecord(rec, ctx.priv, ctx.getChess, ctx.backups) || rec); } catch { /* the data grid */ }
|
||||
try { grid = placementGrid || attackRangeGrid(deployedRecord(rec, ctx.priv, ctx.getChess, ctx.backups) || rec); } catch { /* the data grid */ }
|
||||
return new Set(rangeTiles(grid || rec.rangeGrid, at.row, at.col, pieceDir(at.piece)).map(([r, c]) => tileKey(r, c)));
|
||||
}
|
||||
|
||||
@@ -367,7 +371,7 @@ export function canPlace(ctx, uid, target) {
|
||||
// dropped onto its own owner (the two swap); an outside-bound one (战术锚点) outside it
|
||||
const ownerSwap = src.area === 'board' && occ && occ.piece.uid === piece.ownerUid ? { row: src.row, col: src.col, piece: occ.piece } : null;
|
||||
const range = summonRange(ctx, piece, ownerSwap);
|
||||
if (range && !range.has(tileKey(row, col))) return no('BAD_TILE', t('只能部署在召唤者攻击范围内'));
|
||||
if (range && !range.has(tileKey(row, col))) return no('BAD_TILE', summonPlacementGrid(piece.id) ? t('只能部署在召唤者相邻四格') : t('只能部署在召唤者攻击范围内'));
|
||||
const out = summonExcluded(ctx, piece, ownerSwap);
|
||||
if (out && out.has(tileKey(row, col))) return no('BAD_TILE', t('只能部署在召唤者攻击范围外'));
|
||||
if (src.area === 'board') {
|
||||
|
||||
Reference in new issue
Block a user