manabrew_engine/ability/effects/
two_piles_effect.rs1use forge_foundation::ZoneType;
2
3use super::{emit_zone_trigger, resolve_numeric_svar, EffectContext};
4use crate::ids::CardId;
5use crate::parsing::keys;
6
7#[manabrew_engine_macros::spell_effect(TwoPilesEffect)]
23fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
24 let controller = sa.activating_player;
25 let num_cards = resolve_numeric_svar(ctx.game, sa, keys::NUM_CARDS, 5).max(0) as usize;
26
27 let zone1 = sa.ir.zone1.unwrap_or(ZoneType::Hand);
28 let zone2 = sa.ir.zone2.unwrap_or(ZoneType::Graveyard);
29
30 let lib = ctx
32 .game
33 .cards_in_zone(ZoneType::Library, controller)
34 .to_vec();
35 if lib.is_empty() {
36 return;
37 }
38
39 let count = num_cards.min(lib.len());
40 let revealed: Vec<CardId> = lib[lib.len() - count..].to_vec();
42
43 if revealed.is_empty() {
44 return;
45 }
46
47 let min_pile1 = if count > 1 { 1 } else { 0 };
50 let max_pile1 = if count > 1 { count - 1 } else { count };
51
52 let pile1: Vec<CardId> = ctx.agents[controller.index()]
53 .choose_cards_for_effect(controller, &revealed, min_pile1, max_pile1);
54 let pile2: Vec<CardId> = revealed
55 .iter()
56 .filter(|c| !pile1.contains(c))
57 .copied()
58 .collect();
59
60 let opponent = ctx.game.opponent_of(controller);
62 let pile1_names: Vec<String> = pile1
63 .iter()
64 .map(|&cid| ctx.game.card(cid).card_name.clone())
65 .collect();
66 let pile2_names: Vec<String> = pile2
67 .iter()
68 .map(|&cid| ctx.game.card(cid).card_name.clone())
69 .collect();
70
71 let prompt = format!(
72 "Choose a pile: Pile 1 ({}) or Pile 2 ({})?",
73 pile1_names.join(", "),
74 pile2_names.join(", "),
75 );
76 let choose_pile1 =
77 ctx.agents[opponent.index()].choose_optional_trigger(opponent, &prompt, sa.source, sa.api);
78
79 let (chosen_pile, unchosen_pile) = if choose_pile1 {
80 (pile1, pile2)
81 } else {
82 (pile2, pile1)
83 };
84
85 for cid in chosen_pile {
87 if ctx.game.card(cid).zone == ZoneType::Library {
88 ctx.move_card(cid, zone1, controller);
89 emit_zone_trigger(ctx.trigger_handler, cid, ZoneType::Library, zone1);
90 }
91 }
92
93 for cid in unchosen_pile {
95 if ctx.game.card(cid).zone == ZoneType::Library {
96 ctx.move_card(cid, zone2, controller);
97 emit_zone_trigger(ctx.trigger_handler, cid, ZoneType::Library, zone2);
98 }
99 }
100}