manabrew_engine/ability/effects/
zone_exchange_effect.rs1use forge_foundation::ZoneType;
8
9use super::EffectContext;
10use crate::ids::CardId;
11
12#[manabrew_engine_macros::spell_effect(ZoneExchangeEffect)]
16fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
17 let controller = sa.activating_player;
18
19 let zone1 = sa.ir.zone1.unwrap_or(ZoneType::Battlefield);
21 let zone2 = sa.ir.zone2.unwrap_or(ZoneType::Hand);
22
23 let object1 = if let Some(def) = sa.ir.object_text.as_deref() {
25 if def == "Self" {
26 sa.source
27 } else {
28 sa.source
29 .and_then(|sid| ctx.game.card(sid).remembered_cards.first().copied())
30 }
31 } else {
32 sa.source
33 };
34
35 let obj1 = match object1 {
36 Some(id) => id,
37 None => return,
38 };
39
40 if ctx.game.card(obj1).zone != zone1 {
42 return;
43 }
44 if ctx.game.card(obj1).owner != controller {
45 return;
46 }
47
48 let candidates: Vec<CardId> = ctx
50 .game
51 .cards
52 .iter()
53 .filter(|c| c.zone == zone2 && c.owner == controller)
54 .map(|c| c.id)
55 .collect();
56
57 if candidates.is_empty() {
58 return;
59 }
60
61 ctx.agents[controller.index()].snapshot_state(ctx.game, ctx.mana_pools);
63 let obj2 = ctx.agents[controller.index()]
64 .choose_single_card_for_zone_change(
65 ctx.game,
66 controller,
67 &candidates,
68 "Choose a card to exchange",
69 false,
70 )
71 .unwrap_or(candidates[0]);
72
73 if ctx.game.card(obj2).zone != zone2 {
75 return;
76 }
77
78 let old1 = ctx.game.card(obj1).zone;
80 let old2 = ctx.game.card(obj2).zone;
81
82 ctx.move_card(obj1, zone2, controller);
83 ctx.move_card(obj2, zone1, controller);
84
85 super::emit_zone_trigger(ctx.trigger_handler, obj1, old1, zone2);
86 super::emit_zone_trigger(ctx.trigger_handler, obj2, old2, zone1);
87}