feedback2 WF: 钩索师 and 推击手 (歌蕾蒂娅, 崖心, 见行者) may stand on a 高台 — chess.json placement 'all' from the branch trait 可以放置于远程位; server, client highlights; bots keep them on the ground as blockers
This commit is contained in:
1 parent
2a03467897
commit
9d15538865
9 files changed
+272
-15
No files matched your search
+3
-2
@@ -51,7 +51,7 @@ import { getData } from '../server/data.js';
|
||||
import { buildNormalWave, buildBossWave } from '../server/match/waves.js';
|
||||
import { arrange } from '../server/match/bot.js';
|
||||
import { computeBonds } from '../server/match/bondsMeta.js';
|
||||
import { positionClass } from '../server/match/board.js';
|
||||
import { basePositionClass } from '../server/match/board.js';
|
||||
import { pairPlayers, bossPoolHp, SharedBossPool } from '../server/match/finalAssault.js';
|
||||
import { planUnite, uniteBattleOpts, uniteSurvivors } from '../server/match/unite.js';
|
||||
import { createRng, deriveSeed } from '../server/sim/rng.js';
|
||||
@@ -92,7 +92,8 @@ const frac = (x, rng) => Math.max(0, Math.floor(x + rng()));
|
||||
|
||||
// ---- chess helpers ----------------------------------------------------------------------------------------------
|
||||
const isHealer = (c) => !!c && (c.dmgType === 'heal' || c.attackKind === 'heal');
|
||||
const isBlocker = (c) => !!c && positionClass(c) === 'melee' && (c.stats?.blockCnt ?? 1) > 0 && c.attackKind !== 'none' && !isHealer(c);
|
||||
// the record's own position (bot.js isBlocker): a 钩索师 / 推击手 (placement 'all', DESIGN §22.6) still blocks
|
||||
const isBlocker = (c) => !!c && basePositionClass(c) === 'melee' && (c.stats?.blockCnt ?? 1) > 0 && c.attackKind !== 'none' && !isHealer(c);
|
||||
const hitsFly = (c) => !!c && !!c.canHitFly && !isHealer(c) && c.attackKind !== 'none';
|
||||
const isDealer = (c) => !!c && !isHealer(c) && c.attackKind !== 'none';
|
||||
|
||||
|
||||
@@ -724,6 +724,21 @@ function hasE2Art(ctx, charId, kind) {
|
||||
return (ctx.charTable[charId]?.phases?.length || 0) >= 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* The branch-trait line that lets a MELEE operator stand on the ranged (高台) tiles too: 钩索师 "技能可以使敌人产生位移\n
|
||||
* 可以放置于远程位" and 推击手 "同时攻击阻挡的所有敌人\n可以放置于远程位" (character_table description; PRTS 新人入门:
|
||||
* both branches "可部署在高台和地面"). Chess records get `placement: 'all'` (server/match/board.js positionClass); the
|
||||
* position stays MELEE for the battle. Only the no-module trait counts: the Y-module 教官's "可以额外部署在远程位" is a
|
||||
* module talent (buildable_type), a 部署效果 the mode switches off in the prep placement (PRTS 卫戍协议/帮助 §战斗部署
|
||||
* "携带Y模组的教官仍无法部署至高台位"). DESIGN §22.6.
|
||||
*/
|
||||
const PLACE_ON_RANGED_RE = /可以放置于远程位/;
|
||||
|
||||
/** The branch trait text of a character at (phase, level), without module parts (traitRecord's template). */
|
||||
function branchTraitText(char, phase, level) {
|
||||
return bestCandidate(char.trait?.candidates, phase, level)?.overrideDescripton || char.description || '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Build data/chess.json: every chess (normal + golden) of the season, keyed by chessId, with its loadout
|
||||
* choices (DESIGN §16: `skills[]`; golden `modules[]` + `statsBase`/`traitBase`/`talentsBase`).
|
||||
@@ -788,6 +803,8 @@ function buildChess(ctx) {
|
||||
rec.subProfessionName = uniequip.subProfDict?.[char.subProfessionId]?.subProfessionName || null;
|
||||
rec.position = char.position;
|
||||
rec.nationId = char.nationId || null;
|
||||
// 可以放置于远程位 (钩索师, 推击手): the prep placement also allows the ranged tiles (DESIGN §22.6)
|
||||
if (PLACE_ON_RANGED_RE.test(branchTraitText(char, phase, level))) rec.placement = 'all';
|
||||
|
||||
// Module (only active on golden chess: equipLevel > 0).
|
||||
const modId = shop.defaultUniEquipId || null;
|
||||
@@ -3090,6 +3107,8 @@ function validateAll(f) {
|
||||
// DESIGN §16 loadout choices
|
||||
if (!Array.isArray(c.skills) || c.skills.filter((s) => s.isDefault).length !== 1 || c.skills.find((s) => s.isDefault)?.skillId !== c.skill?.skillId) err(`chess ${c.chessId}: skills[] without exactly one default = skill`);
|
||||
if (c.modules && (c.modules.filter((m) => m.isDefault).length !== (c.module?.active ? 1 : 0) || !c.statsBase || !c.traitBase || !c.talentsBase)) err(`chess ${c.chessId}: inconsistent module choices`);
|
||||
// DESIGN §22.6: only a MELEE operator is widened to every deployable tile
|
||||
if (c.placement !== undefined && (c.placement !== 'all' || c.position !== 'MELEE')) err(`chess ${c.chessId}: placement ${c.placement} on position ${c.position}`);
|
||||
}
|
||||
// the deliberate trigger deviations (DESIGN §21.29) still override an official TAKE_DAMAGE row, on the normal chess
|
||||
// and its elite alike
|
||||
|
||||
Reference in new issue
Block a user