Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions HANDOFF.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ BS10(121枚)・BS11(91枚)・BS12(91枚)・BS13(97枚)は全枚

## 2. 未決(答えが出たら手順書へ1行移して、ここから消す)

**「【X】を持つ」を印刷だけで見ている kind が残っている**:規則は「効果で得たものも含む」に確定(2026-09-25、ACTION_VOCABULARY)。`effectGrant` だけ揃えた。`effectDef.ts` で `keywordFilter` に「静的に持つ」と注記のある kind(fieldEvent の召喚・costMod・手札付与など)と `triggers.ts` の `hasKeyword(cardId…)` を洗い、挙動が変わるカードを一覧にしてから揃える。



Expand Down
24 changes: 16 additions & 8 deletions data/cards/BS08.json
Original file line number Diff line number Diff line change
Expand Up @@ -4547,16 +4547,24 @@
"kind": "magic",
"timing": "flash",
"action": {
"type": "grantEffectToTargetThisTurn",
"trigger": "onBattleWin",
"battleRole": "attacker",
"type": "timedEffect",
"content": [
{
"type": "grantTrigger",
"trigger": "onBattleWin",
"action": {
"type": "lifeCrush",
"count": 1,
"countCounter": "selfSymbols"
},
"battleRole": "attacker"
}
],
"duration": "turn",
"side": "own",
"count": 1,
"filter": {
"nameContains": "ヴルム"
},
"action": {
"type": "lifeCrush",
"count": 1,
"countCounter": "selfSymbols"
}
}
}
Expand Down
14 changes: 8 additions & 6 deletions data/cards/BS14.json
Original file line number Diff line number Diff line change
Expand Up @@ -1848,15 +1848,17 @@
},
{
"id": "BS14-032-e3",
"kind": "step",
"step": "attack",
"turn": "own",
"kind": "effectGrant",
"levels": [
2
],
"action": {
"type": "grantEffectToAllByKeywordThisTurn",
"keyword": "bofu",
"target": "ownAll",
"keywordFilter": "bofu",
"phaseTurn": {
"phase": "attack",
"turn": "own"
},
"granted": {
"trigger": "onBattleLose",
"action": {
"type": "returnBofuExhaustedToHand"
Expand Down
20 changes: 14 additions & 6 deletions data/cards/BS15.json
Original file line number Diff line number Diff line change
Expand Up @@ -5117,12 +5117,20 @@
"kind": "magic",
"timing": "flash",
"action": {
"type": "grantEffectToTargetThisTurn",
"trigger": "onLifeDealt",
"action": {
"type": "voidCoreToReserve",
"count": 1
}
"type": "timedEffect",
"content": [
{
"type": "grantTrigger",
"trigger": "onLifeDealt",
"action": {
"type": "voidCoreToReserve",
"count": 1
}
}
],
"duration": "turn",
"side": "own",
"count": 1
}
}
]
Expand Down
22 changes: 15 additions & 7 deletions data/cards/BS16-red.json
Original file line number Diff line number Diff line change
Expand Up @@ -839,17 +839,25 @@
"kind": "magic",
"timing": "flash",
"action": {
"type": "grantEffectToTargetThisTurn",
"trigger": "onBattleWin",
"type": "timedEffect",
"content": [
{
"type": "grantTrigger",
"trigger": "onBattleWin",
"action": {
"type": "lifeCrush",
"count": 1,
"countCounter": "selfSymbols"
}
}
],
"duration": "turn",
"side": "own",
"count": 1,
"filter": {
"family": [
"覇皇"
]
},
"action": {
"type": "lifeCrush",
"count": 1,
"countCounter": "selfSymbols"
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions docs/design/ACTION_VOCABULARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@
- 「このターンの間、可能ならば必ずアタックする」は `timedEffect` の内容 `{ type: "mustAttack" }`(期間 `turn`)。1体は個体の印 `mustAttackThisTurn`(既に印がある個体は候補にしない)、「すべて」は `timedRule` で後から出たスピリットにも効く。判定は `shared/rules.ts` の `mustAttackThisTurn`。「好きなだけ指定」(BS12-079)だけ旧 `forceAttackThisTurn` に残す(2026-09-25)
- 「このターンの間、〜の効果は発揮されない」は `timedEffect` の内容 `{ type: "suppressTrigger"; trigger }`(期間 `turn`)。1体は個体の `suppressedTriggersThisTurn`、`all: true` は陣営ごとの `state.triggerSuppressionThisTurn`(陣営は `side`、絞り込みは未対応)。判定は `triggers.ts` の `isTriggerSuppressed`(2026-09-25)
- 「このターンの間、疲労状態でもブロックできる」は `timedEffect` の内容 `{ type: "canBlockWhileRested" }`(期間 `turn`・`side: "own"`)。1体は自分のスピリットから選んで個体の印 `canBlockWhileRestedThisTurn`、`all: true` は `timedRule`。判定は `shared/rules.ts` の `canBlockWhileRestedThisTurn`(2026-09-25)
- 「このターンの間、自分のスピリットに“誘発効果”を与える」は `timedEffect` の内容 `{ type: "grantTrigger"; trigger; action; battleRole? }`(期間 `turn`・`side: "own"`)。1体は自分のスピリットから選んで個体の `tempGrantedTriggers`(`triggers.ts` の `fireTrigger` が静的な効果と合わせて読む)。「すべてに与える」はステップの見出しを期間とする継続効果 `effectGrant`(`phaseTurn`)で書き、`timedEffect` の `all` は未対応(2026-09-25)
- 「【X】を持つ」には、効果で得たキーワードも含める(印刷されたものに限らない。2026-09-25 ユーザー確認)。判定は `spiritHasKeyword`。`effectGrant` の `keywordFilter` はこれに揃えた
- 破壊された後に誘発する効果(『バトル時』破壊されたとき等)は、場を離れた直前の状態を見る。`effectGrant` は誘発している個体自身も発生源に含める(ヤツノカンゾウ自身が負けたときも付与が効く。2026-09-25)
- `timedEffect` の `all: true` は個体を選ばず `turnConstraints` に `timedRule`(内容・陣営・解決済みの `filter`)を積み、宣言のたびに `shared/rules.ts` の `cantActByTimedRule` が `matchesTarget` で照合する。陣営は `side`(相手=既定/`own`/`both`)。いまは期間 `turn` だけ(2026-09-24)
- 「このターンの間、〜のスピリットすべては〜できない」は、効果の解決後に場に出たスピリットや、後から条件に合うようになったスピリットにも効く(判定のたびに条件を照合する全体ルール。2026-09-24 ユーザー確認)。「〜1体を指定し」は解決時に選んだ個体にだけ効く
- 「この効果で消滅したスピリット1体につき」(BS10-X02)は、直前の結果を数える形(`if` の `last`/カウンタ)で読む
Expand Down
2 changes: 1 addition & 1 deletion docs/design/REFACTOR_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ R1 と R2 は挙動を変えずに効くので最初にやる。R6 と R7 は着
| 3 | M1 `pay` | 18種・延べ44枚 | `pay { cost, then }` と「完全に解決できる」の判定 | **12種は移行済み(09-24)**。残りは量が支払いの結果で決まる6種と、アクションに組み込まれた `costXxx` 31種・54枚(移すときに数どおりの規則へ揃える) |
| 4 | M2 `if`・`forEach`・マジックの使用 | 18+2+3種 | `if { cond: last/state/event }`、`forEach`、`マジックの使用 { from, コスト }` | 接続詞ごとの読み(下記) |
| 5 | M5 オープン | 17種・延べ36枚 | `オープン { from, 枚数, 選ぶ, 行き先, 残り }` | |
| 6 | M8 期間つき継続効果(既存の内容あり) | 51種・延べ95枚 | 器「継続効果を期間つきで置く」+期間の値。内容は既存の継続効果の語彙をそのまま使う | **器 `timedEffect` を作り、「アタック/ブロックできない」を個体に付ける3種(4か所)を移行済み(09-24)**。全体ルール型(`all: true`・`side`)と `banActByCostThisTurn`・`restrictActionsToColorThisTurn`(5か所)も移行済み。「すべてをBP+」(`bpBuffAll` 11か所)も内容 `bp` で移行済み。1体を指定する `bpBuff` も150か所移行済み(オプション付き7か所は旧 `bpBuff` に残す)。`selfBuff`(82か所)も `target: "self"` で移行済み。『アタック時』『ブロック時』の BP+ も「バトルの間」にそろえた(86か所)。見出しの BP+ 4枚はオーラへ移した。キーワードを与える(`grantKeyword`・`grantKeywordAll`)も移行済み。Lv を「として扱う」の1体指定2種(9か所)も移行済み。「すべて」2種も全体ルールで移行済み(後から出たスピリットにも効く)。色を与える(`grantColorThisTurn`・`grantColorChoice`)も移行済み(系統・色の貸与は器に入れない)。プレイヤーに掛かる制約8種(10か所)も `playerRule` で移行済み。「ブロックされない」3種(5か所)も移行済み(ゲッコ・グライダーとムーンボウクロークは残し)。バトル中の印(`lockFlash`・`disableOpponentBurstThisBattle`、9か所)も移行済み。シンボル・コスト(4種・4か所)と効果の付け替え(4種・4か所)も移行済み。比較基準・勝敗反転(4種・6か所)も `compareBy`・`invertBattleWinner` で移行済み。強制アタック(`forceAttackThisTurn` 7か所)も `mustAttack` で移行済み(「好きなだけ指定」の1枚は残し)。トリガー抑止(2種・2か所)も `suppressTrigger` で移行済み。疲労状態でもブロック(2か所)も `canBlockWhileRested` で移行済み。次は §A の残り(「として扱う」・効果の借用など、内容を新設するもの) |
| 6 | M8 期間つき継続効果(既存の内容あり) | 51種・延べ95枚 | 器「継続効果を期間つきで置く」+期間の値。内容は既存の継続効果の語彙をそのまま使う | **器 `timedEffect` を作り、「アタック/ブロックできない」を個体に付ける3種(4か所)を移行済み(09-24)**。全体ルール型(`all: true`・`side`)と `banActByCostThisTurn`・`restrictActionsToColorThisTurn`(5か所)も移行済み。「すべてをBP+」(`bpBuffAll` 11か所)も内容 `bp` で移行済み。1体を指定する `bpBuff` も150か所移行済み(オプション付き7か所は旧 `bpBuff` に残す)。`selfBuff`(82か所)も `target: "self"` で移行済み。『アタック時』『ブロック時』の BP+ も「バトルの間」にそろえた(86か所)。見出しの BP+ 4枚はオーラへ移した。キーワードを与える(`grantKeyword`・`grantKeywordAll`)も移行済み。Lv を「として扱う」の1体指定2種(9か所)も移行済み。「すべて」2種も全体ルールで移行済み(後から出たスピリットにも効く)。色を与える(`grantColorThisTurn`・`grantColorChoice`)も移行済み(系統・色の貸与は器に入れない)。プレイヤーに掛かる制約8種(10か所)も `playerRule` で移行済み。「ブロックされない」3種(5か所)も移行済み(ゲッコ・グライダーとムーンボウクロークは残し)。バトル中の印(`lockFlash`・`disableOpponentBurstThisBattle`、9か所)も移行済み。シンボル・コスト(4種・4か所)と効果の付け替え(4種・4か所)も移行済み。比較基準・勝敗反転(4種・6か所)も `compareBy`・`invertBattleWinner` で移行済み。強制アタック(`forceAttackThisTurn` 7か所)も `mustAttack` で移行済み(「好きなだけ指定」の1枚は残し)。トリガー抑止(2種・2か所)も `suppressTrigger` で移行済み。疲労状態でもブロック(2か所)も `canBlockWhileRested` で移行済み。誘発効果の付与(2種・4か所)も移行済み(1体の3か所は `grantTrigger`、「すべて」のヤツノカンゾウは見出しを期間とする `effectGrant`+`phaseTurn`)。次は §A の残り(「として扱う」・効果の借用など、内容を新設するもの) |
| 7 | M8 期間つき継続効果(内容を新設) | 37種・延べ136枚 | 新しい内容(効果の付け替え・比較基準・ブロックの追加コスト・シンボル・「として扱う」) | 内容ごとに分けて複数 PR にする |

1〜2 は確認なしで進められる。3・4 は着手前に下の確認を取る。
Expand Down
11 changes: 7 additions & 4 deletions scripts/smoke/part144.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// TargetFilter.hasTrigger/fieldEvent.excludePhase/FieldEvent"ownTensho"+discardOpponent.cardTypeFilter/
// fieldEvent.condition"targetMaxBp"/battleWon.firstAttackOfTurn+destroyByBpBudget.budgetFromSelfBp/
// reviveOnDestroy.cost.ownLifeOneToVoid/summonFromHandFree.keywordFilter+skipTensho/
// destroyAll.drawPerDestroyed/grantEffectToTargetThisTurn+lifeCrush.countCounter/
// destroyAll.drawPerDestroyed/timedEffect の grantTrigger+lifeCrush.countCounter/
// destroyDownToOwnCount+magic condition"ownSpiritCountAtLeast"/revealAndSummonAllByFamily/
// destroy の countCounter(EffectCounter { ownFamily })
import {
Expand Down Expand Up @@ -427,10 +427,13 @@ console.log("=== BS08ドラゴンスクランブル:lendSelfThisTurn+destroy
assert(s.players.p1.hand.length === handBefore + 1, "破壊した数ぶんデッキから1枚ドローする")
}

console.log("=== BS08メテオストーム:grantEffectToTargetThisTurn+lifeCrush.countCounter ===")
console.log("=== BS08メテオストーム:timedEffect の grantTrigger+lifeCrush.countCounter ===")
{
const meteor = findByEffect((e) => e["kind"] === "magic" && (e["action"] as Record<string, unknown> | undefined)?.["type"] === "grantEffectToTargetThisTurn")
const entry = entryOf(meteor, (e) => (e["action"] as Record<string, unknown> | undefined)?.["type"] === "grantEffectToTargetThisTurn")
const isMeteor = (e: Record<string, unknown>) =>
e["kind"] === "magic" && JSON.stringify(e["action"] ?? null).includes('"grantTrigger"') && JSON.stringify(e["action"]).includes('"nameContains"')
const meteor = findByEffect(isMeteor)
assert(meteor.cardId === "BS08-068" && meteor.name === "メテオストーム", "名前で絞る付与はメテオストーム")
const entry = entryOf(meteor, isMeteor)
const grantAction = (entry["action"] as Record<string, unknown>)
const nameFilter = String(((grantAction["filter"]) as Record<string, unknown>)["nameContains"])
const targetCard = CARDS.find((c) => c.type === "spirit" && c.name.includes(nameFilter))!
Expand Down
5 changes: 5 additions & 0 deletions scripts/smoke/part196.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ console.log("=== パート196:effectGrant で付与された効果が、付与
directed: false,
}
refreshLevelAsOverrides(s)
// 「【暴風】で疲労させた相手を戻す」付与(ヤツノカンゾウ)は、付与先の【暴風】で疲労させた記録が要る
const grantedType = (granted?.["action"] as Record<string, unknown> | undefined)?.["type"]
if (grantedType === "returnBofuExhaustedToHand" && foeInst) {
s.bofuExhaustedThisBattle = [{ pid: "p2", instanceId: foeInst, bofuSourceInstanceId: target.instanceId }]
}

// 付与前:同じ誘発を撃っても何も起きない
// 役割(アタッカー/ブロッカー)は常に渡す。
Expand Down
2 changes: 1 addition & 1 deletion scripts/smoke/part315.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// smoke パート315(BS14 緑バッチ20枚:BS14-023〜033/069/079〜081/099〜102/X03)
// 新設した器: kind:"burst" の granted.condition.targetMaxBp(effectGrant onBattleEnd用)/
// action:"grantEffectToAllByKeywordThisTurn"/action:"returnBofuExhaustedToHand"(bofuSourceInstanceId限定)/
// timedEffect の grantTrigger(all)/action:"returnBofuExhaustedToHand"(bofuSourceInstanceId限定)/
// action:"revealTopSummonFreeOrReturnToDeck"/action:"sequence"/action:"bpBuff.costReturnSelfToHand"/
// action:"grantCanBlockWhileRestedThisTurn.singleTarget"/action:"summonBurstCardFreeIfCoresAtLeast"/
// AuraCounter "opponentSpirits"/step.condition.ownTrashOnlyColor
Expand Down
Loading
Loading