feedback7: merge fb7-loadout — per-operator 潜能 (1–6) and 练度 (未精英化 / 精英1 / 精英2 / 精英2 Lv.60) set in 干员调配, defaults 潜能 6 and 精英2 Lv.60 (the owner's decision of 2026-10-08); PR #301 ported as one aligned list; #398 the skill frame, #400 REA-Y's heal text
- Conflicts (the branch started at ae22335c): the four i18n packs (union of keys), game.js DetailPanel props (ops + the
voices' voice=true), detailPanel.js resolveDetail (cultOpts + the voices' tap), match/views.js (both helpers),
docs/PLAYING.md and design/network.md merged line by line against the base. test/match/bosshp.test.js's ATK formula
now includes the unit's 练度 multiplier (cultMul).
- Grok review: MERGE AFTER FIXES — the note and the module card at the set potential fixed on the branch.
- Golden: every owned operator ×1.1 ATK / DEF / max HP by default — roster 49, bonds 46, fields 22, matches 18, diy 134
(stand-in battles and prototype picks unchanged). Broad node --test 5666 (0 fail after the bosshp formula; 2 skipped);
lint 0 errors; typecheck; i18n strict clean (1152 msgids).
This commit is contained in:
commit
0ced21d321
82 files changed
+9156
-6840
No files matched your search
@@ -9,6 +9,7 @@ import { normDir, mirrorDir } from '../dir.js';
|
||||
import { SkillRuntime } from '../skills.js';
|
||||
import { resolveProfile } from '../professions.js';
|
||||
import { normalizeToken } from '../simdata.js';
|
||||
import { isPotential, isCultivate } from '../../../shared/potential.js';
|
||||
import { setupUnitKit } from '../content/index.js';
|
||||
import { installTraitAttackSpeed } from '../content/traitMods.js';
|
||||
import { clone } from './util.js';
|
||||
@@ -145,10 +146,12 @@ export class BattlePlayers {
|
||||
// the unit's own loadout (DESIGN §16): an entry without loadout fields is the DEFAULT — never another player's
|
||||
// choice for the same chess id in a multi-player field (the per-battle data view maps id-only lookups); `standIn:
|
||||
// true` fields the chess as its 补位 stand-in (simdata getStandIn: the stand-in's body, the chess's identity); `diy`
|
||||
// fills a 自选 slot with its pick (simdata getDiy: the slot's identity, the operator's body, skill and module)
|
||||
// fills a 自选 slot with its pick (simdata getDiy: the slot's identity, the operator's body, skill and module);
|
||||
// `potential` (潜能 1–6, 0.2.2) composes the def at it (never a stand-in's)
|
||||
const lo = { skillIndex: inp.skillIndex ?? null, moduleId: inp.moduleId ?? null };
|
||||
if (inp.standIn === true) lo.standIn = true;
|
||||
if (inp.diy && typeof inp.diy === 'object') lo.diy = inp.diy;
|
||||
if (inp.standIn !== true && isPotential(inp.potential)) lo.potential = inp.potential;
|
||||
const def = this.data.getChess(inp.chessId, lo);
|
||||
if (!def) { this.log(`unknown chess ${inp.chessId}${lo.diy ? ' (illegal 自选 pick)' : ''}`); return null; }
|
||||
// a DIY slot has no body of its own (甄选干员): it fights only as a 自选 piece (its `diy` pick)
|
||||
@@ -156,6 +159,12 @@ export class BattlePlayers {
|
||||
const u = this._makeAlly(ps, def, 'op', r, c, { uid: inp.uid, dir });
|
||||
u.items = [...(inp.items ?? [])];
|
||||
u.carry = inp.carryState ?? null;
|
||||
// 练度 (自持有, 0.2.2): the owned operator's ×ATK / ×DEF / ×max HP (units.js Πmul) — never a 补位 stand-in's nor a
|
||||
// prototype 自选 pick's (another character than the one the player owns)
|
||||
if (isCultivate(inp.cultivate) && !def.standInFor && !def.raw?.diyProto) {
|
||||
const mul = typeof this.data.cultivateMul === 'function' ? this.data.cultivateMul(inp.cultivate) : null;
|
||||
if (mul) { u.cultivate = inp.cultivate; u.cultMul = Object.freeze({ ...mul }); u.markDirty(); }
|
||||
}
|
||||
return u;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user