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
2 changes: 1 addition & 1 deletion crates/engine/src/parser/oracle_effect/subject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2533,7 +2533,7 @@ pub(super) fn parse_subject_application(
is_optional: false,
});
}
// CR 303.4b + CR 702.5a + CR 701.17a (issues #5947, #5271): "enchanted
// CR 303.4b + CR 303.4m + CR 702.5a (issues #5947, #5271): "enchanted
// player" / "enchanted opponent" name the Aura's attached player host —
// `AttachedTo`, not a Typed EnchantedBy filter (which is object-only).
// The opponent qualifier constrains attachment when the Aura enters; its
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use engine::game::game_object::AttachTarget;
use engine::game::scenario::{GameScenario, P0, P1};
use engine::types::mana::ManaCost;
use engine::types::phase::Phase;

const OVERENCUMBERED_ORACLE: &str = "Enchant opponent\n\
When this Aura enters, enchanted opponent creates a Clue token, a Food token, and a Junk token.\n\
At the beginning of combat on enchanted opponent's turn, that player may pay {1} for each artifact they control. If they don't, creatures can't attack this combat.";

/// CR 111.2 + CR 303.4b + CR 608.2c: a player Aura's ETB resolves its
/// shared-verb token list for the enchanted opponent, not the Aura's controller.
#[test]
fn issue_5271_overencumbered_etb_gives_every_token_to_enchanted_opponent() {
let mut scenario = GameScenario::new();
scenario.at_phase(Phase::PreCombatMain);
let aura = {
let mut builder = scenario.add_creature_to_hand(P0, "Overencumbered", 0, 0);
builder
.as_enchantment()
.with_subtypes(vec!["Aura", "Curse"])
.with_mana_cost(ManaCost::zero())
.from_oracle_text_with_keywords(&["Enchant opponent"], OVERENCUMBERED_ORACLE);
builder.id()
};

let mut runner = scenario.build();
runner.cast(aura).target_player(P1).resolve();
assert_eq!(
runner.state().objects.get(&aura).unwrap().attached_to,
Some(AttachTarget::Player(P1)),
"the resolving Aura must attach to its chosen opponent before its ETB resolves"
);
runner.advance_until_stack_empty();

for token_name in ["Clue", "Food", "Junk"] {
let token = runner
.state()
.objects
.values()
.find(|object| object.name == token_name && object.is_token)
.unwrap_or_else(|| panic!("Overencumbered must create a {token_name} token"));
assert_eq!(
token.owner, P1,
"{token_name} must be owned by the enchanted opponent"
);
assert_eq!(
token.controller, P1,
"{token_name} must be controlled by the enchanted opponent"
);
}
}
1 change: 1 addition & 0 deletions crates/engine/tests/integration/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,7 @@ mod issue_5247_kinetic_ooze_conditional_multi_target;
mod issue_5252_additional_sacrifice_after_mana_abilities;
mod issue_5254_declaration_in_stone_clue_owner;
mod issue_5268_invincible_iron_man;
mod issue_5271_overencumbered_tokens;
mod issue_5274_call_the_spirit_dragons;
mod issue_5279_grave_sifter;
mod issue_5282_nissa_ultimate_emblem_search;
Expand Down
Loading