diff --git a/public/css/screens/game-panels.css b/public/css/screens/game-panels.css index 4589b71f..1cda7adb 100644 --- a/public/css/screens/game-panels.css +++ b/public/css/screens/game-panels.css @@ -298,6 +298,9 @@ .bpop__ban .icon { width: .14rem; height: .14rem; } /* a member through 变形同构体 (the item pairing, not the operator's own bond): a gold 同构 tag on the portrait */ .bpop__iso { position: absolute; top: .02rem; right: .08rem; padding: 0 .04rem; font-size: .11rem; line-height: 1.45; font-weight: 700; color: #141414; background: var(--gold-2); } +/* a 自选 pick all of whose bonds are off this match (m.private.diyBanned): its 「自选」 tag moves down to the portrait's + bottom corner (the 替补 mark's place), clear of the red ✕ and the tier chip */ +.bpop__member.is-banned .bpop__diy { top: .42rem; } .dbonds--top .dbond.is-granted { border-style: dashed; } .dbond__iso { font-size: .11rem; font-weight: 700; color: var(--gold-2); } /* a count that holds 调和's +1 (the server's bond entry `harmony`, DESIGN §21.26): 在场 n(含调和 +1) and the 调和 row that diff --git a/public/js/screens/game.js b/public/js/screens/game.js index 35f6d399..b72d54c9 100644 --- a/public/js/screens/game.js +++ b/public/js/screens/game.js @@ -1389,7 +1389,7 @@ function MatchScreen() { ${bondPop ? html`<${BondPopup} bondId=${bondPop.bondId} entry=${bondPop.entry} priv=${bondPop.priv} banned=${pub?.bannedChess || []} owner=${bondPop.name} off=${offBonds.has(bondPop.bondId)} place=${bpPlace} over=${!!resolved && bpPlace === dSide} - onClose=${() => setBondOpen(null)} onMember=${(id, items, standInFor) => setDetail({ kind: 'chess', id, owner: bondPop.ownerId, items: items || null, standInFor: standInFor || null })} />` : null} + onClose=${() => setBondOpen(null)} onMember=${(id, items, standInFor, diy) => setDetail({ kind: 'chess', id, owner: bondPop.ownerId, items: items || null, standInFor: standInFor || null, diy: diy || null })} />` : null} ${resolved ? html`<${DetailPanel} detail=${resolved} snapHp=${snapHp} onClose=${() => { setDetail(null); setSel(null); }} bonds=${detailBonds} offBonds=${offBonds} loadout=${detailLoadout} side=${dSide} shopOpen=${shopOpen} live=${liveStats} voice=${combat} diff --git a/public/js/ui/bondStrip.js b/public/js/ui/bondStrip.js index 17068757..b656f4f4 100644 --- a/public/js/ui/bondStrip.js +++ b/public/js/ui/bondStrip.js @@ -21,6 +21,11 @@ // 0.2.0 补位: a member the player fields as its stand-in (the own m.private.standIns; a teammate's unit that says so — // UnitInfo `standInFor`) is drawn as the stand-in — avatar, name, a small 「替补」 mark on the thumbnail — and its row // opens the stand-in's card (gameLogic memberStandIn; the owner's recall of the official mode, 2026-10-06). +// 0.2.1 自选编队 (the owner's report of 2026-10-07): each 自选 pick of the player (m.private.diy) is a row of every bond its +// operator carries — the operator's name and portrait with the 「自选」 tag, dimmed until owned (not bought, or not in the +// shop yet), ✕ when all its bonds are off this match (m.private.diyBanned) — and opens the operator's card; a watched +// teammate's 自选 pieces on the field are rows too (their picks are not sent), opening THEIR operator's card (the unit's +// pick goes with onMember: never the empty 甄选干员 slot's card). import { html, BondDisc, Icon, MicroLabel, Tooltip } from './components.js'; import { RichText, UnitThumb, BondGlyph, GIcon } from './gameComponents.js'; @@ -86,12 +91,13 @@ export function BondStrip({ bonds, layersDisabled = false, onOpen, openId = null /** * Bond detail popup. * @param {{ bondId: string, entry?: any, priv?: any, banned?: string[], onClose: Function, - * onMember?: (chessId:string, items?:string[]|null, standInFor?:string|null)=>void, + * onMember?: (chessId:string, items?:string[]|null, standInFor?:string|null, diy?:any)=>void, * place?: 'left'|'beside'|'besideR'|'right'|null, over?: boolean, beside?: 'left'|'right'|null, owner?: string|null, off?: boolean }} props — * `place`: where it opens (gameLogic bondPopupPlace; `beside: 'left'` = the older spelling of 'beside'); `over`: above the * detail card; `owner`: the watched teammate's name (`entry` / `priv` are then theirs: ui/watchBonds.js); `onMember` * gets a 变形同构体 row's item ids too (its card shows the pair and the granted chip), null for a plain member, and a - * stand-in row's `standInFor` (0.2.0 补位: a teammate's card then shows the stand-in too); `off`: the + * stand-in row's `standInFor` (0.2.0 补位: a teammate's card then shows the stand-in too), and a teammate's 自选 row's + * pick (`diy`, its unit's: the card composes their operator; the own rows' card reads m.private.diy); `off`: the * mode never activates this bond (gameLogic modeOffBonds — 标准's 10 inactive bonds): 本局禁用 instead of 未激活, with a * note, no 在场 count and no 当前效果 block (its numbers would promise an effect the mode never gives; the bond text stays). * `entry.harmony` (the server's bond views: the +1 调和 added to `count`): 在场 n(含调和 +1) and the 调和 row @@ -166,8 +172,8 @@ export function BondPopup({ bondId, entry, priv, banned = [], onClose, onMember, const name = si ? si.name : mb.name; const items = mb.granted && Array.isArray(mb.items) ? mb.items : null; return html`