Skip to main content

manabrew_engine/ability/effects/
damage_prevent_effect.rs

1//! DamagePrevent effect — prevent the next N damage to a target.
2//!
3//! Ported from Java's `DamagePreventEffect.java`.
4//! Prevent the next N damage that would be dealt to target creature/player.
5
6use forge_foundation::ZoneType;
7
8use super::EffectContext;
9use crate::card::card_util;
10
11/// End-of-turn revert for damage prevention. Mirrors the `GameCommand.run()` in Java
12/// `DamagePreventEffect` that resets damage prevention shields when the effect expires.
13///
14/// Resets the `damage_prevention` counter on a card to zero.
15pub fn run(game: &mut crate::game::GameState, card_id: crate::ids::CardId) {
16    if game.card(card_id).zone == ZoneType::Battlefield {
17        game.card_mut(card_id).damage_prevention = 0;
18    }
19}
20
21/// Struct form of this effect so it can participate in the
22/// `SpellAbilityEffect` trait hierarchy — mirrors Java's
23/// `DamagePreventEffect` class extending `SpellAbilityEffect`.
24#[manabrew_engine_macros::spell_effect(DamagePreventEffect)]
25fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
26    let amount = super::resolve_numeric_svar(ctx.game, sa, "Amount", 1).max(0);
27
28    // Target a player
29    if let Some(pid) = sa.target_chosen.target_player {
30        ctx.game.player_add_damage_prevention(pid, amount);
31        return;
32    }
33
34    // Target a creature
35    let mut targets = sa.target_chosen.target_card.into_iter().collect::<Vec<_>>();
36    targets.extend(card_util::get_radiance(ctx.game, sa).iter().copied());
37    targets.sort_unstable_by_key(|cid| cid.0);
38    targets.dedup();
39    if !targets.is_empty() {
40        for cid in targets {
41            if ctx.game.card(cid).zone == ZoneType::Battlefield {
42                ctx.game.card_mut(cid).damage_prevention += amount;
43            }
44        }
45        return;
46    }
47
48    // Self or defined
49    if let Some(def) = sa.defined() {
50        if def.eq_ignore_ascii_case("You") || def.eq_ignore_ascii_case("Self") {
51            let controller = sa.activating_player;
52            ctx.game.player_add_damage_prevention(controller, amount);
53        }
54    }
55}