Skip to main content

manabrew_engine/ability/effects/
cloak_effect.rs

1//! Cloak effect — like Manifest but with Ward {2}.
2//!
3//! Ported from Java's `CloakEffect.java`.
4//! Cloak: Put card face-down as 2/2 creature with ward {2}.
5
6use forge_foundation::ZoneType;
7
8use super::manifest_base_effect::parse_manifest_params;
9use super::{emit_zone_trigger, EffectContext};
10use crate::ids::{CardId, PlayerId};
11use crate::parsing::keys;
12use crate::spellability::SpellAbility;
13
14/// Struct form of this effect so it can participate in the
15/// `SpellAbilityEffect` trait hierarchy — mirrors Java's
16/// `CloakEffect` class extending `SpellAbilityEffect`.
17#[manabrew_engine_macros::spell_effect(CloakEffect)]
18fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
19    let manifest_params = parse_manifest_params(ctx, sa);
20    let amount = manifest_params.amount;
21    let controller = sa.activating_player;
22
23    let players = if let Some(def) = sa.defined_player() {
24        super::resolve_defined_players(def, controller, ctx.game)
25    } else {
26        vec![controller]
27    };
28
29    for pid in players {
30        cloak_for_player(ctx, sa, pid, amount);
31    }
32}
33
34fn cloak_for_player(ctx: &mut EffectContext, sa: &SpellAbility, player: PlayerId, amount: usize) {
35    // Default: top N cards of library
36    let lib = ctx.game.cards_in_zone(ZoneType::Library, player).to_vec();
37    let cards: Vec<CardId> = lib.into_iter().rev().take(amount).collect();
38
39    for card_id in cards {
40        let old_zone = ctx.game.card(card_id).zone;
41
42        ctx.game.card_mut(card_id).set_face_down(true);
43        ctx.game.card_mut(card_id).set_cloaked(true);
44        ctx.game.card_mut(card_id).set_base_pt(Some(2), Some(2));
45        // Ward {2} while cloaked
46        ctx.game.card_mut(card_id).add_pump_keyword("Ward:2");
47        ctx.game.card_mut(card_id).set_controller(player);
48
49        if sa.is_tapped() {
50            ctx.game.tap(card_id);
51        }
52
53        ctx.move_card(card_id, ZoneType::Battlefield, player);
54        ctx.trigger_handler
55            .register_active_trigger(ctx.game, card_id);
56
57        if sa.param_is_true(keys::REMEMBER_CLOAKED) {
58            if let Some(sid) = sa.source {
59                ctx.game.card_mut(sid).add_remembered_card(card_id);
60            }
61        }
62
63        emit_zone_trigger(
64            ctx.trigger_handler,
65            card_id,
66            old_zone,
67            ZoneType::Battlefield,
68        );
69    }
70}