Playtest #6 fixes: summons placed by hand, boss pool stall, bounties, 联防 leak counter, distinct offers, 机变 card text, phone buy tap, skill triggers, blocking, push force, 孤立, enemies, element bar
- #1 #2 skill / device summons (赫默's drone, 巫恋's doll, 凯瑟琳's devices) are hand cards placed by the player; placed summons deploy once at battle start, then a skill summon re-appears at its tile on each cast (the user's call) - #3 叙拉古 隐匿 ends on time (32 + 0.4 × layers s); 忍冬 S3 迷彩 lasts until her next cast (official), kept apart from 隐匿 - #4 multi-round bounty cards last two battles (the user's call; MULTI_ROUND_BOUNTY_BATTLES), blue / red card text - #5 the shared boss pool's float dust (≈3.6e-12 HP) stalled Final Assault leaders at 0 %; < 1 HP now clears the pool, and the team LP reaching 0 first is a defeat (PRTS) - #6 #10 机变 cards show their official effect text; an invisible 详情 button no longer swallows the confirming tap on phones - #7 live ×N counter of a leaker's enemies still on the 联防 field (LP loss stays capped at 10) - #8 #15 #16 skill triggers per 技能策略: skill-range triggers, injured-ally heals (古米, 塞雷娅), tank take-damage triggers with a 3 s cooldown; 新约能天使 S2 shields the highest-aggro operator in range - #9 official per-enemy model scales (威龙) - #11 element bar under the unit's HP bar (white = 元素值 left, element-coloured refill after a burst), floor rounding - #12 枯朽战车 kit per PRTS; every ranged enemy reaches its target's 0.25 collider - #13 恐惧 wander (萨科塔之翼 at half HP, operator fears make enemies flee) with re-planning after pushes - #14 push / pull distance by 力度 − 重量 (PRTS table); #17 every blocker attacks what it blocks; ASPD floor 20 - #18 炎佑 is 孤立: no heals or ally buffs - #19 every free pick-one chess offer (promotion reward, 信标, 寻呼模块) shows different operators - DESIGN §20 and the normative lines, SIM / META / DATA / PLAYING updated; 2747 unit tests and all 27 browser suites green; dev recordings regenerated
This commit is contained in:
1 parent
e6628f0cfe
commit
6464e4b46a
138 files changed
+7946
-1379
No files matched your search
@@ -37,9 +37,10 @@
|
||||
// shows the paused overlay (继续作战 / 放弃模拟) and freezes the HUD clocks. Boss rounds: the top bar shows the level's
|
||||
// 120 s countdown and the red DOT overtime warning (m.public.overtimeAt).
|
||||
// User playtest #3: the own LP drops live while the own battle's enemies enter the blue gate (item 2: the runner's
|
||||
// state().leaks → ui/hud.js liveLp → top bar + own team row; teammates' rows from m.public players[].pendingLp); while
|
||||
// the temp overflow row (临时整备区) holds pieces it is framed and labelled on the board (ui/underframe.js
|
||||
// TempRowNotice) and 准备就绪 / Space say why they are refused (item 3).
|
||||
// state().leaks → ui/hud.js liveLp → top bar + own team row; teammates' rows from m.public players[].pendingLp; in 联防 a
|
||||
// leaker's enemies still standing — runner state().uniteLeft / m.public players[].uniteLeft, the ×N tag — user
|
||||
// playtest #6 item 7); while the temp overflow row (临时整备区) holds pieces it is framed and labelled on the board
|
||||
// (ui/underframe.js TempRowNotice) and 准备就绪 / Space say why they are refused (item 3).
|
||||
// User playtest #4: the detail card shows live stats (item 7) — in battle the local sim's unit (battle/runner.js
|
||||
// unitStats), in prep an own board unit's start-of-battle stats (g.unitStats → m.unitStats); 机变 cards take two taps
|
||||
// (item 2, ui/choiceOverlay.js).
|
||||
@@ -49,7 +50,7 @@ import { PHASE, GEO } from '../../../shared/constants.js';
|
||||
import { html, Spinner, PhaseBanner, Icon, Button, MicroLabel, confirmDialog, useTicker } from '../ui/components.js';
|
||||
import { useGameData, GIcon } from '../ui/gameComponents.js';
|
||||
import { useFieldView } from '../ui/fieldHost.js';
|
||||
import { TopBar, liveLp, ownLeaks, tempInfo, tempReadyReason } from '../ui/hud.js';
|
||||
import { TopBar, liveLp, ownLeaks, uniteRemaining, tempInfo, tempReadyReason } from '../ui/hud.js';
|
||||
import { BondStrip, BondPopup } from '../ui/bondStrip.js';
|
||||
import { TeamPanel } from '../ui/teamPanel.js';
|
||||
import { ShopBar } from '../ui/shopBar.js';
|
||||
@@ -217,12 +218,18 @@ function MatchScreen() {
|
||||
// or display replica) and the server's m.public players[].pendingLp, whichever is further (both only grow during a
|
||||
// round; a display replica stands still while the player watches a teammate's field, the server's count then moves
|
||||
// on) — cost min(lpCapPerRound, n) at settlement; shown at once until the settled m.private lands (ui/hud.js liveLp
|
||||
// keeps the base between renders)
|
||||
// keeps the base between renders); 联防 (user playtest #6 item 7): a leaker's enemies still standing on the 联防 field —
|
||||
// the local replica's count while it runs, else m.public players[].uniteLeft (ui/hud.js uniteRemaining) — replace it;
|
||||
// the teammates' rows take the same local counts (`uniteLocal`, ui/teamPanel.js rowLp)
|
||||
const lpBaseRef = useRef(null);
|
||||
const localLeaks = battleState && battleState.leaks ? battleState.leaks[ownFieldId(myId)] : undefined;
|
||||
const uniteLocal = phase === PHASE.UNITE && battleState && battleState.uniteLeft ? battleState.uniteLeft : null;
|
||||
const leaker = phase === PHASE.UNITE && Array.isArray(pub?.unite?.leakers) && pub.unite.leakers.includes(myId);
|
||||
const localLeft = leaker && uniteLocal ? (uniteLocal[myId] ?? 0) : undefined;
|
||||
const liveLpNow = liveLp(lpBaseRef.current, {
|
||||
phase, round: pub?.round, lp: priv?.lp, statsLeaks: priv?.stats?.leaks, alive,
|
||||
leaks: ownLeaks(localLeaks, meP?.pendingLp), cap: gd.config?.lpCapPerRound,
|
||||
uniteLeft: leaker ? uniteRemaining(localLeft, meP?.uniteLeft) : null,
|
||||
});
|
||||
lpBaseRef.current = liveLpNow.base;
|
||||
|
||||
@@ -807,11 +814,14 @@ function MatchScreen() {
|
||||
// accepted: the piece stays on the tile until m.private shows it there (or a short grace passes)
|
||||
setTimeout(() => { if (heldRef.current.has(f.uid)) releaseHold(f.uid); }, 1500);
|
||||
}, [view, releaseHold]);
|
||||
// m.private caught up with a committed placement → stop holding it
|
||||
// m.private caught up with a committed placement → stop holding it; a summon stack of several copies (凯瑟琳's 2
|
||||
// devices, user playtest #6) stays in the hand and one copy — another piece — lands on the tile: release it too
|
||||
useEffect(() => {
|
||||
const splitLanded = (e, h) => e.piece.kind === 'token' && [...placeCtx.pieces.values()].some((x) => x.area === 'board' && x.piece.kind === 'token'
|
||||
&& x.piece.id === e.piece.id && x.piece.uid !== e.piece.uid && x.row === h.row && x.col === h.col);
|
||||
for (const [uid, h] of [...heldRef.current]) {
|
||||
const e = placeCtx.pieces.get(uid);
|
||||
if (!e || (e.area === 'board' && e.row === h.row && e.col === h.col)) releaseHold(uid);
|
||||
if (!e || (e.area === 'board' && e.row === h.row && e.col === h.col) || (e.area !== 'board' && splitLanded(e, h))) releaseHold(uid);
|
||||
}
|
||||
}, [placeCtx]);
|
||||
// the wheel closes when editing stops (ready, phase end, observing) or its piece is gone (merged, sold)
|
||||
@@ -1038,8 +1048,8 @@ function MatchScreen() {
|
||||
onOpen=${(id) => { setBondOpen((b) => (b === id ? null : id)); audio.sfx('click', { volume: 0.4 }); }} />
|
||||
</div>
|
||||
|
||||
<${TeamPanel} pub=${pub} myId=${myId} watching=${watchingNow} bubbles=${bubbles} onWatch=${watchPlayer}
|
||||
self=${Number.isFinite(priv?.lp) ? { lp: priv.lp, pending: liveLpNow.pending, unite: liveLpNow.unite } : null}
|
||||
<${TeamPanel} pub=${pub} myId=${myId} watching=${watchingNow} bubbles=${bubbles} onWatch=${watchPlayer} cap=${gd.config?.lpCapPerRound ?? 10} uniteLocal=${uniteLocal}
|
||||
self=${Number.isFinite(priv?.lp) ? { lp: priv.lp, pending: liveLpNow.pending, unite: liveLpNow.unite, left: liveLpNow.left } : null}
|
||||
observe=${cc ? { canObserve: (p) => observeTarget(p, pub, myId, { observing: watchingOther, ownDone: localDone }), observing: watchingOther, onBack: backHome } : null} />
|
||||
|
||||
<div class="gm__effects"><${EffectsList} effects=${priv?.effects} /></div>
|
||||
|
||||
Reference in new issue
Block a user