Skip to main content

manabrew_engine/ability/effects/
heist_effect.rs

1//! Heist effect — exile cards from opponent's library, may cast them.
2//!
3//! Ported from Java's `HeistEffect.java`.
4//! Heist: Exile the top card of target opponent's library face-down.
5//! You may look at and cast that card for as long as it remains exiled.
6
7use forge_foundation::ZoneType;
8
9use super::{emit_zone_trigger, EffectContext};
10
11/// Struct form of this effect so it can participate in the
12/// `SpellAbilityEffect` trait hierarchy — mirrors Java's
13/// `HeistEffect` class extending `SpellAbilityEffect`.
14#[manabrew_engine_macros::spell_effect(HeistEffect)]
15fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
16    let controller = sa.activating_player;
17    let num = super::resolve_numeric_svar(ctx.game, sa, "Num", 1).max(0) as usize;
18
19    let target_player = sa
20        .target_chosen
21        .target_player
22        .unwrap_or_else(|| ctx.game.opponent_of(controller));
23
24    // Exile top N cards from target's library face-down
25    for _ in 0..num {
26        let lib = ctx
27            .game
28            .cards_in_zone(ZoneType::Library, target_player)
29            .to_vec();
30        let Some(&top) = lib.last() else { break };
31
32        let old_zone = ctx.game.card(top).zone;
33        ctx.game.card_mut(top).set_face_down(true);
34        ctx.move_card(top, ZoneType::Exile, target_player);
35
36        // Mark with exiled_by so controller can look at and cast it
37        if let Some(sid) = sa.source {
38            ctx.game.card_mut(top).set_exiled_by(Some(sid));
39        }
40
41        emit_zone_trigger(ctx.trigger_handler, top, old_zone, ZoneType::Exile);
42    }
43}