Skip to main content

manabrew_engine/replacement/
replace_token.rs

1//! Replacement logic for `Event$ CreateToken`.
2//!
3//! Mirrors Java `ReplaceToken.java` in `forge/game/replacement/`.
4
5use crate::card::Card;
6use crate::game::GameState;
7use crate::ids::CardId;
8
9use super::replacement_effect::ReplacementEffect;
10use super::replacement_handler::{execute_replace_with_numeric_update, ReplacementEvent};
11use super::replacement_result::ReplacementResult;
12use super::replacement_type::ReplacementType;
13use crate::card_trait_base::CardTrait;
14
15/// Apply the token amount filter based on the effect's `ReplaceWith$` param.
16///
17/// - `"AddOneMoreToken"` → base_amount + 1
18/// - `"DoubleTokens"` → base_amount * 2
19/// - anything else → base_amount unchanged
20///
21/// Mirrors Java `ReplaceToken.filterAmount()`.
22pub fn filter_amount(effect: &ReplacementEffect, base_amount: i32) -> i32 {
23    match effect.replace_with() {
24        Some(s) if s == "AddOneMoreToken" || s == "AddOneMoreTokens" => base_amount + 1,
25        Some("DoubleTokens") => base_amount * 2,
26        _ => base_amount,
27    }
28}
29
30/// Mirrors Java `ReplaceToken.canReplace()`.
31pub fn can_replace(
32    effect: &ReplacementEffect,
33    event: &ReplacementEvent,
34    _game: &GameState,
35    source_card: &Card,
36) -> bool {
37    if effect.event != ReplacementType::CreateToken {
38        return false;
39    }
40    let (player, is_effect) = match event {
41        ReplacementEvent::CreateToken {
42            player, is_effect, ..
43        } => (*player, *is_effect),
44        _ => return false,
45    };
46    // EffectOnly$ True: only apply to tokens created by effects, not game rules
47    if effect.ir.effect_only && !is_effect {
48        return false;
49    }
50    if let Some(valid) = effect.ir.valid_player_selector.as_ref() {
51        if !effect.matches_compiled_valid_player(valid, player, source_card) {
52            return false;
53        }
54    }
55    true
56}
57
58/// Mirrors Java `ReplacementHandler.executeReplacement()` for CreateToken.
59pub fn execute(
60    effect: &ReplacementEffect,
61    event: &mut ReplacementEvent,
62    _game: &GameState,
63    _source_card_id: CardId,
64) -> ReplacementResult {
65    match event {
66        ReplacementEvent::CreateToken { .. } => {}
67        _ => return ReplacementResult::NotReplaced,
68    }
69    if let Some(result) =
70        execute_replace_with_numeric_update(effect, event, _game, _source_card_id, "TokenNum")
71    {
72        return result;
73    }
74    ReplacementResult::Replaced
75}