feedback1 integrate: WP live skill range on the card; 烛煌 S3 target + 1.7 splash; 信仰搅拌机 S3 ignores 攻击距离
This commit is contained in:
commit
313db2f55f
18 files changed
+917
-53
No files matched your search
@@ -129,6 +129,7 @@
|
||||
.rgrid i { width: var(--rg); height: var(--rg); border: 1px solid rgba(255, 255, 255, .06); }
|
||||
.rgrid i.on { background: rgba(246, 163, 41, .25); border-color: var(--amber); }
|
||||
.rgrid i.self { background: var(--mint-500); border-color: var(--mint-400); }
|
||||
.rgrid-all { font-size: .16rem; font-weight: 700; color: var(--amber); padding: .02rem .06rem; border: 1px solid var(--amber); background: rgba(246, 163, 41, .25); }
|
||||
.dsec { display: flex; flex-direction: column; gap: .08rem; }
|
||||
.dsec__title { display: flex; align-items: baseline; gap: .1rem; font-size: .17rem; font-weight: 700; color: var(--mint-400); padding-bottom: .04rem; border-bottom: 1px solid var(--line); }
|
||||
.dtext { font-size: .15rem; line-height: 1.65; color: var(--text-md); }
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
// battleRunner.stats() → { ticks, stepMs, avgTickMs, maxFrameMs, catchups, errors, battles }
|
||||
// battleRunner.unitStats(unitId, fieldId?) → the live stats of a unit of the battle on screen (shared/protocol.js
|
||||
// unitStatsEntry: current HP, effective max HP / ATK / DEF / RES / interval / block / move
|
||||
// speed next to its base) | null — the detail card reads it a few times a second (user
|
||||
// playtest #4 item 7). Read-only: it takes the stats the sim computed last (`unit._s`) and
|
||||
// never makes the unit recompute them, so looking never changes the battle's floats.
|
||||
// speed next to its base; an ally also its live attack range `range` — unit.liveRangeGrid,
|
||||
// facing RIGHT, never a kit's target-selection grid) | null — the detail card reads it a few
|
||||
// times a second (user playtest #4 item 7; the range mini-map, community report E1 after
|
||||
// 0.1.0). Read-only: it takes the stats the sim computed last (`unit._s`) and the range grid it
|
||||
// keeps, and never makes the unit recompute them, so looking never changes the battle's floats.
|
||||
// battleRunner.unitIdOf(uid, ownerId, fieldId?) → the id of an own board piece's unit in that battle | null
|
||||
// battleRunner.ownerOps(ownerId, fieldId?) → [{ kind: 'op', ownerId, defId, items? }] that player's operators in the
|
||||
// battle on screen with their equipment (a teammate's bond popup: the members in play, DESIGN
|
||||
|
||||
@@ -21,7 +21,10 @@
|
||||
// getter re-read 4× a second: current HP, max HP, ATK, DEF, RES, attack interval, block), in prep the stats the own
|
||||
// board's units start their next battle with (m.unitStats: equipment, bonds / layers, 特质, band and 机变 effects). Each
|
||||
// value is coloured against the unit's base like the official card — green when it helps (higher, or a shorter attack
|
||||
// interval) with the difference beside it, red when it hurts — and a 实时 / 开战时 tag says which it is.
|
||||
// interval) with the difference beside it, red when it hurts — and a 实时 / 开战时 tag says which it is. The 攻击范围
|
||||
// mini-map follows the live entry's `range` too (cardRangeGrid: the grid the unit attacks with now — a running skill's
|
||||
// range such as 烛煌 S3's 4-11, rangeExtend included; community report E1 after 0.1.0, it used to stay the base grid);
|
||||
// a grid larger than the box (RANGE_FIT) draws smaller cells (rangeGridStyle), a whole-field one reads 全场.
|
||||
|
||||
import { html, Icon, TierChip, MicroLabel, Button, confirmDialog, useTicker } from './components.js';
|
||||
import { Img, RichText, UnitThumb, BondGlyph, GIcon } from './gameComponents.js';
|
||||
@@ -42,8 +45,40 @@ const EVENT_ICON = { IN_BATTLE: 's_icon_battle', SERVER_GAIN: 's_icon_bond', SER
|
||||
const RANK = { NORMAL: '普通', ELITE: '精英', BOSS: '领袖' };
|
||||
const DMG = { phys: '物理', arts: '法术', heal: '治疗', true: '真实', none: '无' };
|
||||
|
||||
/** A range grid of at least this many tiles covers the field (纯烬艾雅法拉 S3 "攻击范围扩大至整个战场"): named, not drawn. */
|
||||
export const FIELD_WIDE_CELLS = 400;
|
||||
/**
|
||||
* Columns × rows of the mini-map's own cells (.14rem, 2px apart) the card's range box holds without growing: the widest
|
||||
* record attack range (灰毫's 6 columns) and the tallest live one (银灰 S3's 7 rows). A larger grid — a live skill range
|
||||
* such as 远牙 S3's line to the field's edge (21 tiles) — draws smaller cells, edge to edge, in that space, so the box keeps
|
||||
* its size and the stats beside it stay readable.
|
||||
*/
|
||||
export const RANGE_FIT = Object.freeze({ cols: 6, rows: 7 });
|
||||
|
||||
/** Inline style of the mini-map (rangeGridBox `box`): its columns, and smaller cells when the grid exceeds RANGE_FIT. */
|
||||
export function rangeGridStyle(box) {
|
||||
const cols = `grid-template-columns:repeat(${box.cols}, var(--rg))`;
|
||||
if (box.cols <= RANGE_FIT.cols && box.rows <= RANGE_FIT.rows) return cols;
|
||||
const fit = (n, k) => `calc((${k} * .14rem + ${(k - 1) * 2}px) / ${n})`;
|
||||
return `${cols};gap:0;--rg:max(1px, min(.14rem, ${fit(box.cols, RANGE_FIT.cols)}, ${fit(box.rows, RANGE_FIT.rows)}))`;
|
||||
}
|
||||
|
||||
/**
|
||||
* The grid the card's 攻击范围 shows: the live entry's `range` (shared/protocol.js unitStatsEntry — what the unit attacks
|
||||
* with now: a running skill's range, rangeExtend included), else the loadout record's attack range at deployment
|
||||
* (shared/loadoutRecord.js attackRangeGrid: an elite's module grid, a passive range skill, the 特性's 攻击距离 — the same
|
||||
* tiles as the board overlay and the deploy wheel), else the record's own.
|
||||
* @param {any} live unitStatsEntry (+ src) or null @param {any} rec loadout-resolved record @param {any} chess
|
||||
* @returns {number[][]|null}
|
||||
*/
|
||||
export function cardRangeGrid(live, rec, chess) {
|
||||
if (live && Array.isArray(live.range) && live.range.length) return live.range;
|
||||
return attackRangeGrid(rec) || chess?.rangeGrid || null;
|
||||
}
|
||||
|
||||
/** Mini range map. */
|
||||
export function RangeGrid({ grid, class: cls }) {
|
||||
if (Array.isArray(grid) && grid.length >= FIELD_WIDE_CELLS) return html`<span class=${cx('rgrid-all', cls)} aria-label="攻击范围">全场</span>`;
|
||||
const box = rangeGridBox(grid);
|
||||
if (!box.cells.size) return html`<span class="t-dim">—</span>`;
|
||||
const cells = [];
|
||||
@@ -53,7 +88,7 @@ export function RangeGrid({ grid, class: cls }) {
|
||||
cells.push(html`<i key=${`${r},${c}`} class=${cx(box.cells.has(tileKey(r, c)) && 'on', self && 'self')}></i>`);
|
||||
}
|
||||
}
|
||||
return html`<div class=${cx('rgrid', cls)} style=${`grid-template-columns:repeat(${box.cols}, var(--rg))`} aria-label="攻击范围">${cells}</div>`;
|
||||
return html`<div class=${cx('rgrid', cls)} style=${rangeGridStyle(box)} aria-label="攻击范围">${cells}</div>`;
|
||||
}
|
||||
|
||||
function Stat({ k, v, sub, tone = null, title }) {
|
||||
@@ -293,7 +328,7 @@ export function ChessDetail({ chess, piece, unit, snapHp, editable, onSell, bond
|
||||
<${Stat} k="部署费用" v=${s.cost ?? '—'} />
|
||||
<${Stat} k="再部署" v=${s.respawnTime != null ? `${s.respawnTime}s` : '—'} />
|
||||
</div>
|
||||
<div class="drange"><span class="dstat__k">攻击范围</span><${RangeGrid} grid=${attackRangeGrid(fr) || c.rangeGrid} /></div>
|
||||
<div class="drange"><span class="dstat__k">攻击范围</span><${RangeGrid} grid=${cardRangeGrid(live, fr, c)} /></div>
|
||||
</div>`;
|
||||
blocks.skill = sk ? html`<${Section} key="skill" title="技能" micro="SKILL" class="dsec--skill">
|
||||
<div class="dskill" data-skill=${sk.skillId || ''}>
|
||||
|
||||
@@ -132,9 +132,11 @@ const isObj = (v) => !!v && typeof v === 'object';
|
||||
export const pieceDir = (piece) => normDir(isObj(piece) ? piece.dir : null);
|
||||
|
||||
/**
|
||||
* Range grid previewed by the wheel / on a selected unit: the operator's own grid (heal range for medics — the data
|
||||
* grid is the one the unit uses; an elite's equipped "攻击范围扩大" module grid, DESIGN §16 — `chessRecord` resolves
|
||||
* the player's loadout), a summon's grid, an Art's grid (画卷 `1-1`). Null when there is nothing to show.
|
||||
* Range grid previewed by the wheel / on a selected unit: the operator's range at deployment (heal range for medics —
|
||||
* the data grid is the one the unit uses; an elite's equipped "攻击范围扩大" module grid, DESIGN §16, a selected
|
||||
* "被动效果:攻击范围扩大" skill, a module's 攻击距离 — shared/loadoutRecord.js attackRangeGrid, the prep card's range;
|
||||
* `chessRecord` resolves the player's loadout), a summon's grid, an Art's grid (画卷 `1-1`). Null when there is nothing
|
||||
* to show.
|
||||
* @param {{ getChess:(id:string)=>any, getToken:(id:string)=>any, getItem:(id:string)=>any, chessRecord?:(rec:any)=>any }} lookups
|
||||
*/
|
||||
export function previewGrid(lookups, piece) {
|
||||
|
||||
Reference in new issue
Block a user