Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion crates/engine/src/analysis/ability_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,7 @@ fn effect_projection(effect: &Effect) -> Projection {
| Effect::ExploreAll { .. }
| Effect::Tribute { .. }
| Effect::TimeTravel
| Effect::BecomeMonarch
| Effect::BecomeMonarch { .. }
| Effect::NoOp
| Effect::Populate
| Effect::Clash
Expand Down
30 changes: 24 additions & 6 deletions crates/engine/src/game/ability_rw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1862,7 +1862,10 @@ fn legacy_trigger_condition(x: &TriggerCondition) -> bool {
| TriggerCondition::AttackedThisTurn
| TriggerCondition::FirstCombatPhaseOfTurn
| TriggerCondition::HasMaxSpeed
| TriggerCondition::IsMonarch
// CR 725.1: no `legacy_player_scope` classifier exists, and both scopes
// the parser can emit (`Controller`, `ScopedPlayer`) have non-legacy
// `ControllerRef` analogues, so the monarch subject axis stays here.
| TriggerCondition::IsMonarch { .. }
| TriggerCondition::IsInitiative
| TriggerCondition::NoMonarch
| TriggerCondition::HasCityBlessing
Expand Down Expand Up @@ -1998,7 +2001,9 @@ fn legacy_static_condition(x: &StaticCondition) -> bool {
| StaticCondition::DayNightIs { .. }
| StaticCondition::CastVariantPaid { .. }
| StaticCondition::ClassLevelGE { .. }
| StaticCondition::IsMonarch
// CR 725.1: no `legacy_player_scope` classifier exists; see the
// `legacy_trigger_condition` sibling arm for the same reasoning.
| StaticCondition::IsMonarch { .. }
| StaticCondition::IsInitiative
| StaticCondition::NoMonarch
| StaticCondition::HasCityBlessing
Expand Down Expand Up @@ -2901,6 +2906,8 @@ fn legacy_effect(x: &Effect) -> bool {
| Effect::ReassembleContraptionOnSprocket { target, .. }
| Effect::ApplySticker { target, .. }
| Effect::RememberCard { target }
// CR 725.1 + CR 115.1: "target opponent becomes the monarch".
| Effect::BecomeMonarch { target }
| Effect::GrantCastingPermission { target, .. }
| Effect::AddTargetReplacement { target, .. }
| Effect::DiscardCard { target, .. }
Expand Down Expand Up @@ -3440,7 +3447,6 @@ fn legacy_effect(x: &Effect) -> bool {
| Effect::Investigate
| Effect::Tribute { .. }
| Effect::TimeTravel
| Effect::BecomeMonarch
| Effect::NoOp
| Effect::Proliferate
| Effect::Populate
Expand Down Expand Up @@ -5614,12 +5620,19 @@ fn rw_effect(
min: _,
max: _,
}
| Effect::BecomeMonarch
| Effect::RingTemptsYou
| Effect::TimeTravel
| Effect::Planeswalk
| Effect::VentureIntoDungeon
| Effect::SolveCase => (ext_write(StateKind::Other), None),
// CR 725.1 + CR 725.3: the designation write, plus the chosen-target
// write axis — "target opponent becomes the monarch" writes to a player
// named by a CR 115.1 target slot, exactly like `Effect::ExtraTurn`.
Effect::BecomeMonarch { target } => {
let mut p = ext_write(StateKind::Other);
flag_legacy_write_target(&mut p, target);
(p, None)
}
Effect::ForceAttack {
target,
required_defender: _,
Expand Down Expand Up @@ -6373,6 +6386,10 @@ fn rw_ability_condition(x: &AbilityCondition) -> RwProfile {

fn rw_trigger_condition(x: &TriggerCondition) -> RwProfile {
match x {
// CR 725.1: the monarch designation itself is global state with no
// member/event binding; the read profile is entirely determined by the
// subject scope, classified through the shared `PlayerScope` walker.
TriggerCondition::IsMonarch { player } => rw_player_scope(player),
TriggerCondition::GainedLife { minimum: _ }
| TriggerCondition::LostLife
| TriggerCondition::LostLifeLastTurn => reads_player_of(StateKind::JournalLife),
Expand Down Expand Up @@ -6473,7 +6490,6 @@ fn rw_trigger_condition(x: &TriggerCondition) -> RwProfile {
| TriggerCondition::AttackedThisTurn
| TriggerCondition::FirstCombatPhaseOfTurn
| TriggerCondition::HasMaxSpeed
| TriggerCondition::IsMonarch
| TriggerCondition::IsInitiative
| TriggerCondition::NoMonarch
| TriggerCondition::HasCityBlessing
Expand All @@ -6495,6 +6511,9 @@ fn rw_trigger_condition(x: &TriggerCondition) -> RwProfile {

fn rw_static_condition(x: &StaticCondition) -> RwProfile {
match x {
// CR 725.1: see the `rw_trigger_condition` sibling — the read profile is
// entirely determined by the monarch subject scope.
StaticCondition::IsMonarch { player } => rw_player_scope(player),
StaticCondition::DevotionGE { .. }
| StaticCondition::SharesColorWithMostCommonColorAmongPermanents => reads_zone_membership(),
StaticCondition::IsPresent { filter } => match filter {
Expand Down Expand Up @@ -6574,7 +6593,6 @@ fn rw_static_condition(x: &StaticCondition) -> RwProfile {
| StaticCondition::DayNightIs { .. }
| StaticCondition::CastVariantPaid { .. }
| StaticCondition::ClassLevelGE { .. }
| StaticCondition::IsMonarch
| StaticCondition::IsInitiative
| StaticCondition::NoMonarch
| StaticCondition::HasCityBlessing
Expand Down
21 changes: 15 additions & 6 deletions crates/engine/src/game/ability_scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,10 @@ fn scan_effect(x: &Effect, mode: ScanMode) -> Axes {
Effect::Investigate => Axes::NONE,
Effect::Tribute { count: _ } => Axes::NONE,
Effect::TimeTravel => Axes::NONE,
Effect::BecomeMonarch => Axes::NONE,
// CR 725.1 + CR 115.1: the designation subject is a target filter,
// walked through the same single authority every other targeted effect
// uses.
Effect::BecomeMonarch { target } => scan_target_filter(target, target_ctx, mode),
Effect::NoOp => Axes::NONE,
// Captured at activation time; no resolution-time dynamic read.
Effect::NoteManaSpent => Axes::NONE,
Expand Down Expand Up @@ -3355,7 +3358,11 @@ fn scan_trigger_condition(x: &TriggerCondition, mode: ScanMode) -> Axes {
acc
}
TriggerCondition::HasMaxSpeed => Axes::NONE,
TriggerCondition::IsMonarch => Axes::NONE,
// CR 725.1: the monarch predicate itself reads no axis; its subject
// scope is classified per-axis by the shared `PlayerScope` classifier,
// mirroring `WasStartingPlayer { controller }`'s delegation to
// `scan_controller_ref`.
TriggerCondition::IsMonarch { player } => scan_player_scope(player),
TriggerCondition::IsInitiative => Axes::NONE,
TriggerCondition::NoMonarch => Axes::NONE,
TriggerCondition::WasStartingPlayer { controller, .. } => {
Expand Down Expand Up @@ -3659,7 +3666,9 @@ fn scan_static_condition(x: &StaticCondition, mode: ScanMode) -> Axes {
StaticCondition::SourceIsAttacking => Axes::NONE,
StaticCondition::SourceIsBlocking => Axes::NONE,
StaticCondition::SourceIsBlocked => Axes::NONE,
StaticCondition::IsMonarch => Axes::NONE,
// CR 725.1: see the `TriggerCondition::IsMonarch` arm above — the
// subject scope is classified through the shared `PlayerScope` walker.
StaticCondition::IsMonarch { player } => scan_player_scope(player),
StaticCondition::IsInitiative => Axes::NONE,
StaticCondition::NoMonarch => Axes::NONE,
StaticCondition::HasCityBlessing => Axes::NONE,
Expand Down Expand Up @@ -5505,7 +5514,7 @@ fn effect_target_ctx(e: &Effect, mode: ScanMode) -> FilterReadContext {
| Effect::Investigate
| Effect::Tribute { .. }
| Effect::TimeTravel
| Effect::BecomeMonarch
| Effect::BecomeMonarch { .. }
| Effect::NoOp
| Effect::NoteManaSpent
| Effect::Proliferate
Expand Down Expand Up @@ -5913,7 +5922,7 @@ fn effect_census_role(e: &Effect) -> CensusRole {
| Effect::Investigate
| Effect::Tribute { .. }
| Effect::TimeTravel
| Effect::BecomeMonarch
| Effect::BecomeMonarch { .. }
| Effect::NoOp
| Effect::NoteManaSpent
| Effect::Proliferate
Expand Down Expand Up @@ -6150,7 +6159,7 @@ pub(crate) fn effect_is_randomness_bearing(e: &Effect) -> bool {
| Effect::Investigate
| Effect::Tribute { .. }
| Effect::TimeTravel
| Effect::BecomeMonarch
| Effect::BecomeMonarch { .. }
| Effect::NoOp
| Effect::NoteManaSpent
| Effect::Proliferate
Expand Down
Loading
Loading