manabrew_engine/ability/effects/
control_exchange_effect.rs1use forge_foundation::ZoneType;
7
8use super::EffectContext;
9use crate::ability::ability_ir::DefinedRef;
10use crate::ids::CardId;
11use crate::parsing::keys;
12
13#[manabrew_engine_macros::spell_effect(ControlExchangeEffect)]
17fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
18 let mut object1: Option<CardId> = None;
19 let mut object2: Option<CardId> = None;
20
21 if sa.uses_targeting() {
23 object1 = sa.target_chosen.target_card;
24 }
25
26 if let Some(defined) = sa.defined() {
28 if matches!(sa.defined_ref(), Some(DefinedRef::SelfCard)) {
29 object2 = sa.source;
30 } else if let Some(uid_str) = defined.strip_prefix("CardUID_") {
31 object2 = uid_str.parse::<u32>().ok().map(crate::ids::CardId);
32 }
33 } else if object1.is_some() {
34 object2 = sa.source;
37 }
38
39 let (Some(card1), Some(card2)) = (object1, object2) else {
40 return;
41 };
42
43 let c1 = ctx.game.card(card1);
45 let c2 = ctx.game.card(card2);
46 if c1.zone != ZoneType::Battlefield || c2.zone != ZoneType::Battlefield {
47 return;
48 }
49 if c1.phased_out || c2.phased_out {
50 return;
51 }
52
53 if sa.is_optional() {
55 let controller = sa.activating_player;
56 let name1 = c1.card_name.clone();
57 let name2 = c2.card_name.clone();
58 ctx.agents[controller.index()].snapshot_state(ctx.game, ctx.mana_pools);
59 let confirm = ctx.agents[controller.index()].confirm_action(
60 controller,
61 Some("ControlExchange"),
62 &format!("Exchange control of {} and {}?", name1, name2),
63 &[],
64 None,
65 None,
66 );
67 if !confirm {
68 return;
69 }
70 }
71
72 let player1 = ctx.game.card(card1).controller;
74 let player2 = ctx.game.card(card2).controller;
75
76 ctx.game.card_mut(card1).set_controller(player2);
77 ctx.game.card_mut(card2).set_controller(player1);
78
79 if sa.param_is_true(keys::REMEMBER_EXCHANGED) {
81 if let Some(sid) = sa.source {
82 ctx.game.card_mut(sid).add_remembered_card(card1);
83 ctx.game.card_mut(sid).add_remembered_card(card2);
84 }
85 }
86}