manabrew_engine/ability/effects/
manifest_effect.rs1use forge_foundation::ZoneType;
10
11use super::manifest_base_effect::parse_manifest_params;
12use super::{emit_zone_trigger, EffectContext};
13use crate::ids::{CardId, PlayerId};
14use crate::spellability::SpellAbility;
15
16#[manabrew_engine_macros::spell_effect(ManifestEffect)]
20fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
21 let manifest_params = parse_manifest_params(ctx, sa);
22 let amount = manifest_params.amount;
23 let controller = sa.activating_player;
24
25 let players = if let Some(def) = sa.defined_player() {
27 crate::ability::ability_utils::resolve_defined_players_with_sa(
28 def, sa, controller, ctx.game,
29 )
30 } else {
31 vec![controller]
32 };
33
34 for pid in players {
35 manifest_for_player(ctx, sa, pid, amount);
36 }
37}
38
39fn manifest_for_player(
41 ctx: &mut EffectContext,
42 sa: &SpellAbility,
43 player: PlayerId,
44 amount: usize,
45) {
46 let defined = sa.defined().unwrap_or("TopOfLibrary");
47
48 let cards_to_manifest: Vec<CardId> = if defined == "TopOfLibrary" || defined.is_empty() {
50 let lib = ctx.game.cards_in_zone(ZoneType::Library, player).to_vec();
52 lib.into_iter().rev().take(amount).collect()
53 } else if let Some(zone) = sa.ir.choice_zone {
54 let zone_cards = ctx.game.cards_in_zone(zone, player).to_vec();
56 if zone_cards.is_empty() {
57 return;
58 }
59 ctx.agents[player.index()].snapshot_state(ctx.game, ctx.mana_pools);
61 ctx.agents[player.index()].choose_cards_for_zone_change(
62 ctx.game,
63 player,
64 &zone_cards,
65 amount.min(zone_cards.len()),
66 amount.min(zone_cards.len()),
67 "Choose cards to manifest",
68 )
69 } else {
70 sa.target_chosen.target_card.into_iter().collect()
72 };
73
74 for card_id in cards_to_manifest {
76 manifest_single_card(ctx, sa, card_id, player);
77 }
78}
79
80fn manifest_single_card(
82 ctx: &mut EffectContext,
83 sa: &SpellAbility,
84 card_id: CardId,
85 player: PlayerId,
86) {
87 let old_zone = ctx.game.card(card_id).zone;
88
89 ctx.game.card_mut(card_id).set_face_down(true);
91 ctx.game.card_mut(card_id).set_manifested(true);
92
93 ctx.game.card_mut(card_id).set_base_pt(Some(2), Some(2));
95
96 ctx.game.card_mut(card_id).set_controller(player);
98 ctx.move_card(card_id, ZoneType::Battlefield, player);
99
100 ctx.trigger_handler
101 .register_active_trigger(ctx.game, card_id);
102
103 if sa.ir.remember_manifested {
105 if let Some(source_id) = sa.source {
106 ctx.game.card_mut(source_id).add_remembered_card(card_id);
107 }
108 }
109
110 emit_zone_trigger(
111 ctx.trigger_handler,
112 card_id,
113 old_zone,
114 ZoneType::Battlefield,
115 );
116}