feedback1b WG: 奥术 re-measured; bonds the mode never activates read 本局禁用
Player report after 0.1.0: "奥术盟约不生效". Measured on a real 险境 battle (Match._normalOpts) and the same battle from its BattleSpec (browser path): the bond works - member arts hits debuff the target x(1.2 + 0.01*L) for 3 s, later arts hits land multiplied, the 3-member tier gives x1.4 below 50 % HP, in-battle layer gains apply live, browser = server. What a player sees instead: 标准模拟 switches 奥术 off (official inactiveBondIdList, with 9 other bonds) while 深靛 洛洛 阿罗玛 夕 圣聆初雪 stay in the pool through their other bond; their cards showed 奥术 like any bond and the detail chip read "0/2 未激活" with three deployed. Shop / reward cards, the detail card's bond chips and the bond popup now mark such a bond 本局禁用 (gameLogic modeOffBonds over config.modes[modeId].inactiveBondIds). The PRTS 盟约记录 奥术 note (one instance per unit and target) is documented next to the one-effective-instance rule it fits (SIM.md, bond header).
This commit is contained in:
1 parent
7f134737ce
commit
b4fa21a0a6
11 files changed
+295
-39
No files matched your search
+16
-10
@@ -1,5 +1,6 @@
|
||||
// Bottom shop bar (research 06 §11.2 / D3): LEVEL card (upgrade price hex, 升级), 3–5 operator cards
|
||||
// (tier chip, price hex with discount/markup colours, portrait, bonds, class, frozen overlay, sold state,
|
||||
// (tier chip, price hex with discount/markup colours, portrait, bonds — a bond the mode never activates struck through,
|
||||
// 本局禁用 — class, frozen overlay, sold state,
|
||||
// merge progress), the item card, the funds card with ✕ 收起; above it 剩余可放置角色, 冻结/解冻 and 刷新.
|
||||
// Buying and upgrading take two taps (research 09 §5 / §6.5, official `EventOnFirstClick` → `EventOnConfirm` /
|
||||
// `EventOnUpgrade`): the first tap selects a card — it lifts and enlarges, its detail opens and it shows 确认购买
|
||||
@@ -19,7 +20,7 @@
|
||||
import { useEffect, useState } from '../../vendor/hooks.module.js';
|
||||
import { html, Icon, HexBadge, TierChip, Tooltip, MicroLabel } from './components.js';
|
||||
import { Img, BondGlyph, CoinGlyph, GIcon, RichText } from './gameComponents.js';
|
||||
import { priceTone, mergeProgress, mergeTarget, shopBlockReason, chessLoadout } from './gameLogic.js';
|
||||
import { priceTone, mergeProgress, mergeTarget, shopBlockReason, chessLoadout, briefingBondTip } from './gameLogic.js';
|
||||
import { chessPortraitUrl, itemIconUrl, profIconUrl, uiUrl, skillIconUrl, skillRecordIconUrl, moduleTypeIconUrl } from './assetUrls.js';
|
||||
import { data } from '../data.js';
|
||||
|
||||
@@ -58,7 +59,7 @@ function ArmedTag({ reason, free }) {
|
||||
* @param {{ slot:any, idx:number, priv:any, frozen?:boolean, reason?:string|null, free?:boolean, armed?:boolean,
|
||||
* onTap?:(idx:number)=>void, onBuy:Function, onDetail:Function }} props
|
||||
*/
|
||||
export function ChessCard({ slot, idx, priv, frozen = false, reason = null, free = false, armed = false, onTap = null, onBuy, onDetail }) {
|
||||
export function ChessCard({ slot, idx, priv, frozen = false, reason = null, free = false, armed = false, onTap = null, onBuy, onDetail, offBonds = null }) {
|
||||
const c = data.lookup('chess', slot.id);
|
||||
const m = data.get('assets');
|
||||
const tier = c?.tier ?? 1;
|
||||
@@ -86,7 +87,11 @@ export function ChessCard({ slot, idx, priv, frozen = false, reason = null, free
|
||||
${lo?.skill ? html`<${SkillBadge} chess=${c} lo=${lo} />` : null}
|
||||
<span class="scard__name">${c?.name || slot.id}</span>
|
||||
<span class="scard__bonds">
|
||||
${bonds.slice(0, 3).map((b) => html`<span key=${b} class="scard__bond"><${BondGlyph} bondId=${b} /><span>${data.lookup('bonds', b)?.name || b}</span></span>`)}
|
||||
${bonds.slice(0, 3).map((b) => {
|
||||
const name = data.lookup('bonds', b)?.name || b;
|
||||
const off = !!(offBonds && offBonds.has(b)); // a bond this mode never activates (gameLogic modeOffBonds)
|
||||
return html`<span key=${b} class=${cx('scard__bond', off && 'is-off')} title=${off ? briefingBondTip(name, 'off') : undefined}><${BondGlyph} bondId=${b} /><span>${name}</span></span>`;
|
||||
})}
|
||||
</span>
|
||||
<span class="scard__class">
|
||||
<${Img} src=${profIconUrl(m, c?.profession)} class="scard__prof" />
|
||||
@@ -213,7 +218,7 @@ export function useTwoTap({ editable, keys }) {
|
||||
* Promotion reward (research 00 §3): after a merge the operator cards of the bar are replaced by 3 free operators of
|
||||
* tier min(level+1, 6); pick 1 (g.reward idx) or put it off (稍后选择 → the normal shop + a reminder pill).
|
||||
*/
|
||||
function RewardCards({ offer, priv, editable, onPick, onDetail, onLater, armed, onTap }) {
|
||||
function RewardCards({ offer, priv, editable, onPick, onDetail, onLater, armed, onTap, offBonds = null }) {
|
||||
return html`<div class="shopbar__reward" role="group" aria-label="晋升奖励">
|
||||
<div class="rwtag">
|
||||
<${Icon} name="crown" class="rwtag__icon" />
|
||||
@@ -224,7 +229,7 @@ function RewardCards({ offer, priv, editable, onPick, onDetail, onLater, armed,
|
||||
</div>
|
||||
<div class="shopbar__rwcards">
|
||||
${offer.slots.map((s, i) => (s && !s.sold
|
||||
? html`<${ChessCard} key=${`rw${i}:${s.id}`} slot=${{ ...s, price: 0 }} idx=${i} priv=${priv} free=${true}
|
||||
? html`<${ChessCard} key=${`rw${i}:${s.id}`} slot=${{ ...s, price: 0 }} idx=${i} priv=${priv} free=${true} offBonds=${offBonds}
|
||||
armed=${armed === armKey('r', i, s)} onTap=${(idx) => onTap('r', idx, s, 'chess', shopBlockReason('reward', { priv, editable, slot: s, ...LOOKUPS }), onPick)}
|
||||
reason=${shopBlockReason('reward', { priv, editable, slot: s, ...LOOKUPS })} onBuy=${onPick} onDetail=${onDetail} />`
|
||||
: html`<div key=${`rw${i}`} class="scard scard--sold"><span class="scard__soldtxt"><span>已选择</span></span></div>`))}
|
||||
@@ -237,10 +242,11 @@ function RewardCards({ offer, priv, editable, onPick, onDetail, onLater, armed,
|
||||
* @param {{ priv:any, editable:boolean, collapsed:boolean, onCollapse:(c:boolean)=>void,
|
||||
* onBuy:(i:number)=>void, onLevel:Function, onRefresh:Function, onFreeze:Function, onDetail:(id:string, kind?:string, hint?:string|null)=>void,
|
||||
* onDetailClose?: () => void, onRefuse?: (reason: string) => void, barRef:any,
|
||||
* reward?: any, onReward?: (idx:number)=>void, onRewardLater?: Function }} props
|
||||
* reward?: any, onReward?: (idx:number)=>void, onRewardLater?: Function, offBonds?: Set<string>|null }} props — offBonds:
|
||||
* the bonds this mode never activates (gameLogic modeOffBonds), struck through on the operator cards
|
||||
*/
|
||||
export function ShopBar({ priv, editable, collapsed, onCollapse, onBuy, onLevel, onRefresh, onFreeze, onDetail, onDetailClose, onRefuse, barRef,
|
||||
reward = null, onReward, onRewardLater, onArm = null }) {
|
||||
reward = null, onReward, onRewardLater, onArm = null, offBonds = null }) {
|
||||
const shop = priv?.shop || {};
|
||||
const slots = Array.isArray(shop.slots) ? shop.slots : [];
|
||||
const chessSlots = slots.map((s, i) => ({ s, i })).filter(({ s }) => !s || s.kind !== 'item');
|
||||
@@ -308,12 +314,12 @@ export function ShopBar({ priv, editable, collapsed, onCollapse, onBuy, onLevel,
|
||||
<div class="shopbar__row">
|
||||
<${LevelCard} shop=${shop} reason=${lvReason} armed=${armed === 'lv'} onTap=${tapLevel} />
|
||||
${showReward ? html`<${RewardCards} offer=${reward} priv=${priv} editable=${editable} onPick=${onReward} onDetail=${onDetail} onLater=${onRewardLater}
|
||||
armed=${armed} onTap=${tapCard} />`
|
||||
armed=${armed} onTap=${tapCard} offBonds=${offBonds} />`
|
||||
: html`<div class="shopbar__cards">
|
||||
${chessSlots.map(({ s, i }) => {
|
||||
if (!s || s.sold) return html`<${SoldCard} key=${`s${i}`} />`;
|
||||
const reason = shopBlockReason('buy', { priv, editable, slot: s, ...LOOKUPS });
|
||||
return html`<${ChessCard} key=${`c${i}:${s.id}`} slot=${s} idx=${i} priv=${priv} frozen=${frozen} onBuy=${onBuy} onDetail=${onDetail}
|
||||
return html`<${ChessCard} key=${`c${i}:${s.id}`} slot=${s} idx=${i} priv=${priv} frozen=${frozen} onBuy=${onBuy} onDetail=${onDetail} offBonds=${offBonds}
|
||||
reason=${reason} armed=${armed === armKey('c', i, s)} onTap=${editable ? (idx) => tapCard('c', idx, s, 'chess', reason, onBuy) : null} />`;
|
||||
})}
|
||||
</div>`}
|
||||
|
||||
Reference in new issue
Block a user