manabrew_engine/ability/effects/
tap_or_untap_effect.rs1use forge_foundation::ZoneType;
2
3use super::EffectContext;
4use crate::ability::ability_ir::DefinedRef;
5use crate::agent::BinaryChoiceKind;
6use crate::ids::CardId;
7
8#[manabrew_engine_macros::spell_effect(TapOrUntapEffect)]
15fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
16 let controller = sa.activating_player;
17 let source_name = sa
18 .source
19 .map(|cid| ctx.game.card(cid).card_name.clone())
20 .unwrap_or_else(|| "Ability".to_string());
21
22 let mut candidates: Vec<CardId> = Vec::new();
23 if let Some(target) = sa.target_chosen.target_card {
24 candidates.push(target);
25 } else if let Some(source) = sa.source {
26 if matches!(sa.defined_ref(), Some(DefinedRef::SelfCard)) {
27 candidates.push(source);
28 }
29 }
30
31 for card_id in candidates {
32 if ctx.game.card(card_id).zone != ZoneType::Battlefield {
33 continue;
34 }
35 let should_tap = if sa.ir.toggle {
36 !ctx.game.card(card_id).tapped
37 } else {
38 let prompt = format!("Tap or untap {}?", ctx.game.card(card_id).card_name);
39 ctx.agents[controller.index()].choose_binary(
40 controller,
41 &prompt,
42 BinaryChoiceKind::TapOrUntap,
43 None,
44 sa.source,
45 sa.api,
46 )
47 };
48
49 if should_tap {
50 if ctx.game.tap(card_id) {
51 ctx.trigger_handler.run_trigger(
52 crate::trigger::TriggerType::Taps,
53 crate::event::RunParams {
54 card: Some(card_id),
55 player: Some(controller),
56 ..Default::default()
57 },
58 false,
59 );
60 }
61 } else if ctx.game.untap(card_id) {
62 ctx.trigger_handler.run_trigger(
63 crate::trigger::TriggerType::Untaps,
64 crate::event::RunParams {
65 card: Some(card_id),
66 player: Some(controller),
67 ..Default::default()
68 },
69 false,
70 );
71 }
72 }
73}