Skip to main content

manabrew_engine/ability/effects/
reveal_effect.rs

1use forge_foundation::ZoneType;
2
3use super::{resolve_defined_player, resolve_numeric_svar, EffectContext};
4use crate::agent::GameLogEvent;
5use crate::parsing::keys;
6
7/// Mirrors Java's `RevealEffect.java`.
8///
9/// `SP$ Reveal | Defined$ You | NumCards$ N`
10/// The target player reveals cards from their hand.
11/// In the engine, reveal is informational — we notify all agents.
12/// Struct form of this effect so it can participate in the
13/// `SpellAbilityEffect` trait hierarchy — mirrors Java's
14/// `RevealEffect` class extending `SpellAbilityEffect`.
15#[manabrew_engine_macros::spell_effect(RevealEffect)]
16fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
17    let num = resolve_numeric_svar(ctx.game, sa, keys::NUM_CARDS, 1).max(0) as usize;
18
19    let target = sa
20        .target_chosen
21        .target_player
22        .or_else(|| {
23            sa.defined()
24                .and_then(|defined| resolve_defined_player(defined, sa.activating_player, ctx.game))
25        })
26        .unwrap_or(sa.activating_player);
27
28    let hand = ctx.game.cards_in_zone(ZoneType::Hand, target).to_vec();
29    if hand.is_empty() {
30        return;
31    }
32
33    let count = num.min(hand.len());
34    let revealed = &hand[hand.len() - count..];
35
36    // Notify all agents of the revealed cards.
37    for agent in ctx.agents.iter_mut() {
38        for &id in revealed {
39            let name = ctx.game.card(id).card_name.clone();
40            agent.notify(crate::agent::notification::GameNotification::Event(
41                GameLogEvent::rule(format!("Revealed: {}", name)).with_card(id),
42            ));
43        }
44    }
45
46    // Mirrors `game.getAction().reveal(revealed, p, ...)` in
47    // RevealEffect.java:81-85 — broadcast a modal of the revealed cards to
48    // every player so all parties can see what was revealed.
49    let source_name = sa.source.map(|cid| ctx.game.card(cid).card_name.clone());
50    let revealed_vec = revealed.to_vec();
51    for agent in ctx.agents.iter_mut() {
52        agent.reveal_cards(
53            ctx.game,
54            target,
55            &revealed_vec,
56            ZoneType::Hand,
57            target,
58            source_name.as_deref(),
59        );
60    }
61}