Skip to main content

manabrew_engine/replacement/
replace_pay_life.rs

1//! Replacement logic for `Event$ PayLife`.
2//!
3//! Mirrors Java `ReplacePayLife.java` in `forge/game/replacement/`.
4
5use crate::card::Card;
6use crate::game::GameState;
7use crate::ids::CardId;
8use crate::parsing::compare::compare_expr;
9
10use super::replacement_effect::ReplacementEffect;
11use super::replacement_handler::{
12    execute_replace_with_numeric_update, resolve_replace_value, ReplacementEvent,
13};
14use super::replacement_result::ReplacementResult;
15use super::replacement_type::ReplacementType;
16use crate::card_trait_base::CardTrait;
17
18/// Mirrors Java `ReplacePayLife.canReplace()`.
19pub fn can_replace(
20    effect: &ReplacementEffect,
21    event: &ReplacementEvent,
22    _game: &GameState,
23    source_card: &Card,
24) -> bool {
25    if effect.event != ReplacementType::PayLife {
26        return false;
27    }
28    let (player, amount) = match event {
29        ReplacementEvent::PayLife { player, amount } => (*player, *amount),
30        _ => return false,
31    };
32    if let Some(valid) = effect.ir.valid_player_selector.as_ref() {
33        if !effect.matches_compiled_valid_player(valid, player, source_card) {
34            return false;
35        }
36    }
37    if let Some(amount_cmp) = effect.ir.amount_text.as_deref() {
38        let threshold = amount_cmp.get(2..).unwrap_or("");
39        let rhs = resolve_replace_value(threshold, _game, source_card.id, event)
40            .or_else(|| threshold.parse::<i32>().ok())
41            .unwrap_or(0);
42        let cmp = format!("{}{}", amount_cmp.get(..2).unwrap_or("GE"), rhs);
43        if !compare_expr(amount, &cmp) {
44            return false;
45        }
46    }
47    true
48}
49
50/// Mirrors Java `ReplacementHandler.executeReplacement()` for PayLife.
51pub fn execute(
52    effect: &ReplacementEffect,
53    event: &mut ReplacementEvent,
54    _game: &GameState,
55    _source_card_id: CardId,
56) -> ReplacementResult {
57    match event {
58        ReplacementEvent::PayLife { .. } => {}
59        _ => return ReplacementResult::NotReplaced,
60    }
61    if effect.prevents() {
62        if let ReplacementEvent::PayLife { amount, .. } = event {
63            *amount = 0;
64        }
65        return ReplacementResult::Prevented;
66    }
67    if let Some(result) =
68        execute_replace_with_numeric_update(effect, event, _game, _source_card_id, "Amount")
69    {
70        return result;
71    }
72    ReplacementResult::Replaced
73}