Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
c881eae
feat(engine): add storied and recruit
matthewevans Aug 7, 2026
35fbffc
fix(engine): complete storied and recruit condition matches
matthewevans Aug 7, 2026
488cc4b
fix(engine): restore recruit frame invariants
matthewevans Aug 7, 2026
c407edd
fix(engine): dereference boxed discard frames
matthewevans Aug 7, 2026
f580c99
fix(engine): box suspended resolution stack
matthewevans Aug 7, 2026
264d40a
fix(engine): keep enduring story state out of line
matthewevans Aug 7, 2026
ec1fce0
fix(client): localize enduring story badge
matthewevans Aug 7, 2026
2eae5f9
fix(engine): satisfy resolution frame lints
matthewevans Aug 7, 2026
656d219
fix(engine): update discard provenance fixtures
matthewevans Aug 7, 2026
17a5e04
test(engine): update designation predicate coverage
matthewevans Aug 7, 2026
21a0a8d
fix(engine): preserve discard frame stack boundaries
matthewevans Aug 7, 2026
7e770ff
fix(engine): retain adjacent recruit handoff
matthewevans Aug 7, 2026
1a72277
test(engine): silence discard fixture warning
matthewevans Aug 7, 2026
6a5bd7f
test(engine): refresh state and resolution inventories
matthewevans Aug 7, 2026
6858a04
fix(engine): address recruit and storied review findings
matthewevans Aug 7, 2026
140a4e6
fix(engine): retire prevented discard frames safely
matthewevans Aug 7, 2026
09790c2
fix(test): defer unreleased Bards Company fixture
matthewevans Aug 7, 2026
b13f9a5
fix(test): restore CR733 authority matrix schema
matthewevans Aug 7, 2026
ace0d41
test(engine): classify enduring story authority
matthewevans Aug 7, 2026
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
2 changes: 2 additions & 0 deletions client/src/adapter/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2426,6 +2426,7 @@ export type GameEvent =
| { type: "StackPushed"; data: { object_id: ObjectId } }
| { type: "StackResolved"; data: { object_id: ObjectId } }
| { type: "Discarded"; data: { player_id: PlayerId; object_id: ObjectId } }
| { type: "EnduringStoryGained"; data: { player_id: PlayerId } }
| { type: "DamageCleared"; data: { object_id: ObjectId } }
| { type: "GameOver"; data: { winner: PlayerId | null } }
| { type: "DamageDealt"; data: { source_id: ObjectId; target: TargetRef; amount: number; is_combat: boolean; excess?: number } }
Expand Down Expand Up @@ -3115,6 +3116,7 @@ export interface GameState {
initiative?: PlayerId | null;
monarch?: PlayerId | null;
city_blessing?: PlayerId[];
enduring_story?: PlayerId[];
ring_level?: Record<string, number>;
ring_bearer?: Record<string, ObjectId | null>;
commander_damage?: CommanderDamageEntry[];
Expand Down
2 changes: 2 additions & 0 deletions client/src/components/board/OpponentSeatHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
ConditionBadge,
CounterBadge,
DungeonBadge,
EnduringStoryBadge,
InitiativeBadge,
MonarchBadge,
PendingSpellBadge,
Expand Down Expand Up @@ -188,6 +189,7 @@ export function OpponentSeatHeader({ playerId, compact = false, onKickPlayer }:
{designations.isMonarch ? <MonarchBadge /> : null}
{designations.hasInitiative ? <InitiativeBadge /> : null}
{designations.hasCityBlessing ? <CityBlessingBadge /> : null}
{designations.hasEnduringStory ? <EnduringStoryBadge /> : null}
{designations.activeDungeon ? (
<DungeonBadge
dungeonName={designations.activeDungeon}
Expand Down
15 changes: 15 additions & 0 deletions client/src/components/hud/HudBadges.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@ export function CityBlessingBadge() {
);
}

export function EnduringStoryBadge() {
const { t } = useTranslation("game");
return (
<BadgeTip text={t("badges.enduringStoryTooltip")}>
<span
role="img"
aria-label={t("badges.enduringStory")}
className="relative inline-flex h-6 min-w-6 shrink-0 items-center justify-center overflow-hidden rounded-full px-1 text-[12px] leading-none ring-1 bg-indigo-500 ring-indigo-200/80 shadow-[0_0_14px_rgba(99,102,241,0.55)]"
>
<span aria-hidden className="relative drop-shadow-[0_1px_1px_rgba(0,0,0,0.45)]">📖</span>
</span>
</BadgeTip>
);
}

interface DungeonBadgeProps {
dungeonName: DungeonId;
roomIndex: number;
Expand Down
4 changes: 3 additions & 1 deletion client/src/components/hud/OpponentHud.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { getOpponentIds, isOneOnOne, resolveFocusedOpponent } from "../../viewmo
import { LifeTotal } from "../controls/LifeTotal.tsx";
import { ManaPoolSummary } from "./ManaPoolSummary.tsx";
import { ScoreBadge } from "../draft/ScoreBadge.tsx";
import { CityBlessingBadge, CounterBadge, DungeonBadge, InitiativeBadge, MonarchBadge, StatusBadge, UnboundedBadge } from "./HudBadges.tsx";
import { CityBlessingBadge, CounterBadge, DungeonBadge, EnduringStoryBadge, InitiativeBadge, MonarchBadge, StatusBadge, UnboundedBadge } from "./HudBadges.tsx";
import { AurasHoverPreview } from "./AurasHoverPreview.tsx";
import { AvatarHoverPreview } from "./AvatarHoverPreview.tsx";
import { BattlefieldPeekPopover } from "./BattlefieldPeekPopover.tsx";
Expand Down Expand Up @@ -305,6 +305,7 @@ export function OpponentHud({
{opponentDesignations.isMonarch ? <MonarchBadge /> : null}
{opponentDesignations.hasInitiative ? <InitiativeBadge /> : null}
{opponentDesignations.hasCityBlessing ? <CityBlessingBadge /> : null}
{opponentDesignations.hasEnduringStory ? <EnduringStoryBadge /> : null}
{opponentDesignations.activeDungeon ? (
<DungeonBadge dungeonName={opponentDesignations.activeDungeon} roomIndex={opponentDesignations.currentRoom} />
) : null}
Expand Down Expand Up @@ -761,6 +762,7 @@ function OpponentTab({
{designations.isMonarch ? <MonarchBadge /> : null}
{designations.hasInitiative ? <InitiativeBadge /> : null}
{designations.hasCityBlessing ? <CityBlessingBadge /> : null}
{designations.hasEnduringStory ? <EnduringStoryBadge /> : null}
{designations.activeDungeon ? (
<DungeonBadge dungeonName={designations.activeDungeon} roomIndex={designations.currentRoom} />
) : null}
Expand Down
3 changes: 2 additions & 1 deletion client/src/components/hud/PlayerHud.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { UndoButton } from "../board/UndoButton.tsx";
import { LifeTotal } from "../controls/LifeTotal.tsx";
import { ManaPoolSummary } from "./ManaPoolSummary.tsx";
import { PhaseIndicatorLeft, PhaseIndicatorRight } from "../controls/PhaseStopBar.tsx";
import { CityBlessingBadge, ConditionBadge, CounterBadge, DungeonBadge, InitiativeBadge, MonarchBadge, PendingSpellBadge, RingBenefitsBadge, StatusBadge, UnboundedBadge } from "./HudBadges.tsx";
import { CityBlessingBadge, ConditionBadge, CounterBadge, DungeonBadge, EnduringStoryBadge, InitiativeBadge, MonarchBadge, PendingSpellBadge, RingBenefitsBadge, StatusBadge, UnboundedBadge } from "./HudBadges.tsx";
import { EnchantmentsBadge } from "./EnchantmentsBadge.tsx";
import { HudPlate } from "./HudPlate.tsx";
import { NextUpBadge } from "./NextUpBadge.tsx";
Expand Down Expand Up @@ -106,6 +106,7 @@ export function PlayerHud() {
{designations.isMonarch ? <MonarchBadge /> : null}
{designations.hasInitiative ? <InitiativeBadge /> : null}
{designations.hasCityBlessing ? <CityBlessingBadge /> : null}
{designations.hasEnduringStory ? <EnduringStoryBadge /> : null}
{designations.activeDungeon ? (
<DungeonBadge dungeonName={designations.activeDungeon} roomIndex={designations.currentRoom} />
) : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ describe("OpponentHud designations (single-opponent path)", () => {
expect(screen.getByLabelText("City's Blessing")).toBeInTheDocument();
});

it("renders the enduring story badge for the opponent", () => {
act(() => {
useGameStore.setState({ gameState: createTwoPlayerState({ enduring_story: [1] }) });
});
render(<OpponentHud />);
expect(screen.getByLabelText("Enduring Story")).toBeInTheDocument();
});

it("renders the ring counter at the opponent's level", () => {
act(() => {
useGameStore.setState({ gameState: createTwoPlayerState({ ring_level: { "1": 4 } }) });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@ describe("PlayerHud designations", () => {
});
});

describe("Enduring Story", () => {
it("renders only for the designated local player", () => {
act(() => {
useGameStore.setState({ gameState: buildGameState({ enduring_story: [0] }) });
});
render(<PlayerHud />);
expect(screen.getByLabelText("Enduring Story")).toBeInTheDocument();
});
});

describe("Ring level", () => {
it("renders the ring counter at level 3 for the local player", () => {
act(() => {
Expand Down
10 changes: 10 additions & 0 deletions client/src/hooks/usePlayerDesignations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface PlayerDesignations {
isMonarch: boolean;
hasInitiative: boolean;
hasCityBlessing: boolean;
hasEnduringStory: boolean;
ringLevel: number;
ringBearerId: ObjectId | null;
ringBearerName: string | null;
Expand Down Expand Up @@ -61,6 +62,7 @@ const EMPTY: PlayerDesignations = {
isMonarch: false,
hasInitiative: false,
hasCityBlessing: false,
hasEnduringStory: false,
ringLevel: 0,
ringBearerId: null,
ringBearerName: null,
Expand Down Expand Up @@ -97,6 +99,7 @@ export function usePlayerDesignations(playerId: PlayerId): PlayerDesignations {
const isMonarch = gs.monarch != null && gs.monarch === playerId;
const hasInitiative = gs.initiative != null && gs.initiative === playerId;
const hasCityBlessing = gs.city_blessing?.includes(playerId) ?? false;
const hasEnduringStory = gs.enduring_story?.includes(playerId) ?? false;
const ringLevel = gs.ring_level?.[playerKey(playerId)] ?? 0;
const ringBearerId = gs.ring_bearer?.[playerKey(playerId)] ?? null;
const ringBearerName = ringBearerId != null ? (gs.objects[String(ringBearerId)]?.name ?? null) : null;
Expand Down Expand Up @@ -124,6 +127,7 @@ export function usePlayerDesignations(playerId: PlayerId): PlayerDesignations {
isMonarch
|| hasInitiative
|| hasCityBlessing
|| hasEnduringStory
|| activeDungeon != null
|| ringLevel > 0
|| energy > 0
Expand All @@ -136,6 +140,7 @@ export function usePlayerDesignations(playerId: PlayerId): PlayerDesignations {
isMonarch,
hasInitiative,
hasCityBlessing,
hasEnduringStory,
ringLevel,
ringBearerId,
ringBearerName,
Expand All @@ -151,3 +156,8 @@ export function usePlayerDesignations(playerId: PlayerId): PlayerDesignations {
};
}, [gameState, playerId]);
}

/** Engine-projected player designation; this hook deliberately performs only membership lookup. */
export function useHasEnduringStory(playerId: PlayerId): boolean {
return useGameStore((state) => state.gameState?.enduring_story?.includes(playerId) ?? false);
}
2 changes: 2 additions & 0 deletions client/src/i18n/locales/de/game.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,8 @@
"initiativeTooltip": "Hat die Initiative — wagt sich zu Beginn der Versorgung in die Unterstadt vor",
"cityBlessing": "Segen der Stadt",
"cityBlessingTooltip": "Segen der Stadt — kontrolliert zehn oder mehr bleibende Karten (Aufstieg)",
"enduringStory": "Bleibende Geschichte",
"enduringStoryTooltip": "Bleibende Geschichte — erhalten, wenn du eine Storied bleibende Karte und drei oder mehr Artefakte, legendäre bleibende Karten und/oder Sagen kontrollierst; bleibt für den Rest der Partie bestehen",
"dungeonAriaLabel": "Wagt sich in {{name}} vor, Raum {{room}}",
"dungeonTooltip": "Wagt sich in {{name}} vor — Raum {{room}}",
"poisonAriaLabel_one": "{{count}} Giftmarke",
Expand Down
2 changes: 2 additions & 0 deletions client/src/i18n/locales/en/game.json
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,8 @@
"initiativeTooltip": "Has the Initiative — ventures into Undercity at start of upkeep",
"cityBlessing": "City's Blessing",
"cityBlessingTooltip": "City's Blessing — controls ten or more permanents (Ascend)",
"enduringStory": "Enduring Story",
"enduringStoryTooltip": "Enduring Story — gained by controlling a Storied permanent and three or more artifacts, legendary permanents, and/or Sagas; lasts for the rest of the game",
"dungeonAriaLabel": "Venturing in {{name}}, room {{room}}",
"dungeonTooltip": "Venturing in {{name}} — room {{room}}",
"poisonAriaLabel_one": "{{count}} poison counter",
Expand Down
2 changes: 2 additions & 0 deletions client/src/i18n/locales/es/game.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,8 @@
"initiativeTooltip": "Tiene la Iniciativa — se aventura en la Ciudad Baja al inicio del mantenimiento",
"cityBlessing": "Bendición de la ciudad",
"cityBlessingTooltip": "Bendición de la ciudad — controla diez o más permanentes (Ascender)",
"enduringStory": "Historia perdurable",
"enduringStoryTooltip": "Historia perdurable — se obtiene al controlar un permanente con Storied y tres o más artefactos, permanentes legendarios y/o sagas; dura el resto del juego",
"dungeonAriaLabel": "Aventurándose en {{name}}, sala {{room}}",
"dungeonTooltip": "Aventurándose en {{name}} — sala {{room}}",
"poisonAriaLabel_one": "{{count}} contador de veneno",
Expand Down
2 changes: 2 additions & 0 deletions client/src/i18n/locales/fr/game.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,8 @@
"initiativeTooltip": "Détient l'Initiative — s'aventure dans la Ville souterraine au début de l'entretien",
"cityBlessing": "Bénédiction de la cité",
"cityBlessingTooltip": "Bénédiction de la cité — contrôle dix permanents ou plus (Ascension)",
"enduringStory": "Histoire durable",
"enduringStoryTooltip": "Histoire durable — obtenue en contrôlant un permanent avec Storied et au moins trois artefacts, permanents légendaires et/ou sagas ; dure pour le reste de la partie",
"dungeonAriaLabel": "Aventure dans {{name}}, salle {{room}}",
"dungeonTooltip": "Aventure dans {{name}} — salle {{room}}",
"poisonAriaLabel_one": "{{count}} marqueur poison",
Expand Down
2 changes: 2 additions & 0 deletions client/src/i18n/locales/it/game.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,8 @@
"initiativeTooltip": "Ha l'Iniziativa — si avventura nella Città Bassa all'inizio del mantenimento",
"cityBlessing": "Benedizione della Città",
"cityBlessingTooltip": "Benedizione della Città — controlla dieci o più permanenti (Ascendere)",
"enduringStory": "Storia duratura",
"enduringStoryTooltip": "Storia duratura — ottenuta controllando un permanente con Storied e tre o più artefatti, permanenti leggendari e/o saghe; dura per il resto della partita",
"dungeonAriaLabel": "Avventura in {{name}}, stanza {{room}}",
"dungeonTooltip": "Avventura in {{name}} — stanza {{room}}",
"poisonAriaLabel_one": "{{count}} segnalino veleno",
Expand Down
2 changes: 2 additions & 0 deletions client/src/i18n/locales/pl/game.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,8 @@
"initiativeTooltip": "Ma Inicjatywę — wyprawia się do Podmiasta na początku utrzymania",
"cityBlessing": "Błogosławieństwo miasta",
"cityBlessingTooltip": "Błogosławieństwo miasta — kontroluje dziesięć lub więcej trwałych (Ascend)",
"enduringStory": "Trwała historia",
"enduringStoryTooltip": "Trwała historia — zdobyta za kontrolowanie permanenta ze Storied i co najmniej trzech artefaktów, legendarnych permanentów i/lub Sag; trwa do końca gry",
"dungeonAriaLabel": "Wyprawa w {{name}}, pokój {{room}}",
"dungeonTooltip": "Wyprawa w {{name}} — pokój {{room}}",
"poisonAriaLabel_one": "{{count}} znacznik trucizny",
Expand Down
2 changes: 2 additions & 0 deletions client/src/i18n/locales/pt/game.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,8 @@
"initiativeTooltip": "Tem a Iniciativa — aventura-se na Subcidade no início da manutenção",
"cityBlessing": "Bênção da Cidade",
"cityBlessingTooltip": "Bênção da Cidade — controla dez ou mais permanentes (Ascender)",
"enduringStory": "História duradoura",
"enduringStoryTooltip": "História duradoura — obtida ao controlar um permanente com Storied e três ou mais artefatos, permanentes lendários e/ou sagas; dura pelo resto do jogo",
"dungeonAriaLabel": "Aventurando-se em {{name}}, sala {{room}}",
"dungeonTooltip": "Aventurando-se em {{name}} — sala {{room}}",
"poisonAriaLabel_one": "{{count}} marcador de veneno",
Expand Down
1 change: 1 addition & 0 deletions crates/engine/src/ai_support/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -996,6 +996,7 @@ fn condition_reads_only_memo_safe_state(c: &ParsedCondition) -> bool {
| ParsedCondition::CardsLeftYourGraveyardThisTurnAtLeast { .. }
| ParsedCondition::PlayerCountAtLeast { .. }
| ParsedCondition::HasCityBlessing
| ParsedCondition::HasEnduringStory
// CR 903.3 / CR 903.3d: a controller-scoped battlefield scan for a commander
// (via `game::commander`), like the other `YouControl*` predicates — reads no
// combat/damage/pending-cast history, so it is memo-safe.
Expand Down
8 changes: 8 additions & 0 deletions crates/engine/src/game/ability_rw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1861,6 +1861,7 @@ fn legacy_trigger_condition(x: &TriggerCondition) -> bool {
| TriggerCondition::IsInitiative
| TriggerCondition::NoMonarch
| TriggerCondition::HasCityBlessing
| TriggerCondition::HasEnduringStory
| TriggerCondition::CompletedDungeon { .. }
| TriggerCondition::TributeNotPaid
| TriggerCondition::CastDuringPhase { .. }
Expand All @@ -1879,6 +1880,7 @@ fn legacy_ability_condition(x: &AbilityCondition) -> bool {
}
AbilityCondition::PreviousEffectAmount { rhs, .. } => legacy_quantity_expr(rhs),
AbilityCondition::ScopedPlayerMatches { filter } => legacy_player_filter(filter),
AbilityCondition::DiscardedCardMatchesFilter { filter } => legacy_target_filter(filter),
AbilityCondition::ConditionInstead { inner }
| AbilityCondition::Not { condition: inner } => legacy_ability_condition(inner),
AbilityCondition::And { conditions } | AbilityCondition::Or { conditions } => {
Expand Down Expand Up @@ -1923,6 +1925,7 @@ fn legacy_ability_condition(x: &AbilityCondition) -> bool {
| AbilityCondition::CompletedDungeon { .. }
| AbilityCondition::IsInitiative
| AbilityCondition::HasCityBlessing
| AbilityCondition::HasEnduringStory
| AbilityCondition::IsRingBearer
| AbilityCondition::TargetHasKeywordInstead { .. }
| AbilityCondition::HasObjectTarget
Expand Down Expand Up @@ -1984,6 +1987,7 @@ fn legacy_static_condition(x: &StaticCondition) -> bool {
| StaticCondition::IsInitiative
| StaticCondition::NoMonarch
| StaticCondition::HasCityBlessing
| StaticCondition::HasEnduringStory
| StaticCondition::CompletedADungeon
| StaticCondition::Unrecognized { .. }
| StaticCondition::DuringYourTurn
Expand Down Expand Up @@ -6093,6 +6097,7 @@ fn rw_ability_condition(x: &AbilityCondition) -> RwProfile {
// feed — the read is the write's own reveal output). So `conservative()`
// (which the coarse fallback assigned) falsely conflicts.
AbilityCondition::RevealedHasCardType { .. } => RwProfile::empty(),
AbilityCondition::DiscardedCardMatchesFilter { .. } => RwProfile::empty(),
AbilityCondition::SourceEnteredThisTurn
| AbilityCondition::AdditionalCostPaid { .. }
| AbilityCondition::CastVariantPaid { .. }
Expand Down Expand Up @@ -6126,6 +6131,7 @@ fn rw_ability_condition(x: &AbilityCondition) -> RwProfile {
| AbilityCondition::CompletedDungeon { .. }
| AbilityCondition::IsInitiative
| AbilityCondition::HasCityBlessing
| AbilityCondition::HasEnduringStory
| AbilityCondition::IsRingBearer
| AbilityCondition::TargetHasKeywordInstead { .. }
| AbilityCondition::HasObjectTarget
Expand Down Expand Up @@ -6243,6 +6249,7 @@ fn rw_trigger_condition(x: &TriggerCondition) -> RwProfile {
| TriggerCondition::IsInitiative
| TriggerCondition::NoMonarch
| TriggerCondition::HasCityBlessing
| TriggerCondition::HasEnduringStory
| TriggerCondition::CompletedDungeon { .. }
| TriggerCondition::TributeNotPaid
| TriggerCondition::CastDuringPhase { .. }
Expand Down Expand Up @@ -6331,6 +6338,7 @@ fn rw_static_condition(x: &StaticCondition) -> RwProfile {
| StaticCondition::IsInitiative
| StaticCondition::NoMonarch
| StaticCondition::HasCityBlessing
| StaticCondition::HasEnduringStory
| StaticCondition::CompletedADungeon
| StaticCondition::Unrecognized { .. }
| StaticCondition::DuringYourTurn
Expand Down
8 changes: 8 additions & 0 deletions crates/engine/src/game/ability_scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2645,6 +2645,10 @@ fn scan_ability_condition(x: &AbilityCondition, mode: ScanMode) -> Axes {
AbilityCondition::CompletedDungeon { .. } => Axes::NONE,
AbilityCondition::IsInitiative => Axes::NONE,
AbilityCondition::HasCityBlessing => Axes::NONE,
AbilityCondition::HasEnduringStory => Axes::NONE,
AbilityCondition::DiscardedCardMatchesFilter { filter } => {
scan_target_filter(filter, FilterReadContext::SnapshotOrEvent, mode)
}
AbilityCondition::IsRingBearer => Axes::NONE,
AbilityCondition::TargetHasKeywordInstead { keyword: _ } => Axes::NONE,
// `subject_slot: _` is a target-slot INDEX selector (CR 608.2c): `Some(n)`
Expand Down Expand Up @@ -3265,6 +3269,7 @@ fn scan_trigger_condition(x: &TriggerCondition, mode: ScanMode) -> Axes {
projected: true,
},
TriggerCondition::HasCityBlessing => Axes::NONE,
TriggerCondition::HasEnduringStory => Axes::NONE,
TriggerCondition::CompletedDungeon { specific: _ } => Axes::NONE,
TriggerCondition::SourceIsTapped => Axes::NONE,
TriggerCondition::SourceIsTransformed => Axes::NONE,
Expand Down Expand Up @@ -3552,6 +3557,7 @@ fn scan_static_condition(x: &StaticCondition, mode: ScanMode) -> Axes {
StaticCondition::IsInitiative => Axes::NONE,
StaticCondition::NoMonarch => Axes::NONE,
StaticCondition::HasCityBlessing => Axes::NONE,
StaticCondition::HasEnduringStory => Axes::NONE,
StaticCondition::CompletedADungeon => Axes::NONE,
StaticCondition::WasStartingPlayer { controller, .. } => {
let mut acc = Axes::NONE;
Expand Down Expand Up @@ -4564,6 +4570,7 @@ pub(crate) fn keyword_cost_reads_growing_class(kw: &Keyword) -> bool {
| Keyword::Exploit
| Keyword::Explore
| Keyword::Ascend
| Keyword::Storied
| Keyword::StartYourEngines
| Keyword::Dredge(_)
| Keyword::Modular(_)
Expand Down Expand Up @@ -4829,6 +4836,7 @@ fn scan_keyword(kw: &Keyword, mode: ScanMode) -> Axes {
| Keyword::Exploit
| Keyword::Explore
| Keyword::Ascend
| Keyword::Storied
| Keyword::StartYourEngines
| Keyword::Dredge(_)
| Keyword::Modular(_)
Expand Down
Loading
Loading