manabrew_engine/ability/effects/
poison_effect.rs1use super::{resolve_defined_player, resolve_numeric_svar, EffectContext};
2use crate::ability::ability_ir::EffectIr;
3use crate::spellability::SpellAbility;
4
5#[manabrew_engine_macros::spell_effect(PoisonEffect)]
19fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
20 let amount = resolve_poison_amount(ctx, sa);
21 if amount == 0 {
22 return;
23 }
24
25 let controller = sa.activating_player;
26
27 if let Some(target_player) = sa.target_chosen.target_player {
29 if ctx.game.player(target_player).is_alive()
30 && !crate::staticability::static_ability_cant_put_counter::any_cant_put_counter_on_player(
31 &ctx.game.cards,
32 target_player,
33 &crate::card::CounterType::Poison,
34 ) {
35 if amount > 0 {
36 ctx.game.player_add_poison(target_player, amount);
37 } else {
38 ctx.game.player_remove_poison(target_player, -amount);
39 }
40 }
41 return;
42 }
43
44 let defined = sa.defined().unwrap_or("Opponent");
46
47 if defined == "Player" {
50 let alive: Vec<_> = ctx.game.alive_players().into_iter().collect();
51 for pid in alive {
52 if !crate::staticability::static_ability_cant_put_counter::any_cant_put_counter_on_player(
53 &ctx.game.cards,
54 pid,
55 &crate::card::CounterType::Poison,
56 ) {
57 if amount > 0 {
58 ctx.game.player_add_poison(pid, amount);
59 } else {
60 ctx.game.player_remove_poison(pid, -amount);
61 }
62 }
63 }
64 return;
65 }
66
67 if let Some(pid) = resolve_defined_player(defined, controller, ctx.game) {
69 if ctx.game.player(pid).is_alive()
70 && !crate::staticability::static_ability_cant_put_counter::any_cant_put_counter_on_player(
71 &ctx.game.cards,
72 pid,
73 &crate::card::CounterType::Poison,
74 ) {
75 if amount > 0 {
76 ctx.game.player_add_poison(pid, amount);
77 } else {
78 ctx.game.player_remove_poison(pid, -amount);
79 }
80 }
81 }
82}
83
84fn resolve_poison_amount(ctx: &EffectContext, sa: &SpellAbility) -> i32 {
85 if let Some(EffectIr::Poison(ir)) = &sa.ir.effect {
86 if let Some(amount) = &ir.amount {
87 let resolved = amount.resolve_for_spell_ability(ctx.game, sa, 1);
88 #[cfg(debug_assertions)]
89 debug_assert_eq!(
90 resolved,
91 resolve_numeric_svar(ctx.game, sa, "Num", 1),
92 "compiled Poison amount diverged from string params"
93 );
94 return resolved;
95 }
96 }
97
98 resolve_numeric_svar(ctx.game, sa, "Num", 1)
99}