Skip to main content

manabrew_engine/staticability/
static_ability_cant_draw.rs

1use forge_foundation::ZoneType;
2
3use crate::card::valid_filter;
4use crate::game::GameState;
5use crate::ids::PlayerId;
6use crate::parsing::CompiledSelector;
7use crate::staticability::StaticMode;
8
9pub fn can_draw_amount(game: &GameState, player: PlayerId, start_amount: i32) -> i32 {
10    if start_amount <= 0 {
11        return 0;
12    }
13    let mut amount = start_amount;
14    for card in game
15        .cards
16        .iter()
17        .filter(|c| c.zone == ZoneType::Battlefield)
18    {
19        for st_ab in card
20            .static_abilities
21            .iter()
22            .filter(|sa| sa.check_mode(&StaticMode::CantDraw))
23        {
24            let valid_player = st_ab.ir.valid_player.as_ref();
25            if !matches_valid_player(valid_player, player, card.controller) {
26                continue;
27            }
28            let limit = st_ab.ir.draw_limit.unwrap_or(0);
29            let drawn = game.player(player).drawn_this_turn;
30            amount = amount.min((limit - drawn).max(0));
31        }
32    }
33    amount
34}
35
36pub fn can_draw_this_amount(game: &GameState, player: PlayerId, amount: i32) -> bool {
37    can_draw_amount(game, player, amount) >= amount
38}
39
40pub fn apply_cant_draw_amount_ability(
41    draw_limit: Option<&str>,
42    valid_player: Option<&CompiledSelector>,
43    player: PlayerId,
44    source_controller: PlayerId,
45    drawn_this_turn: i32,
46    current_amount: i32,
47) -> i32 {
48    if !matches_valid_player(valid_player, player, source_controller) {
49        return current_amount;
50    }
51    let limit = draw_limit.and_then(|s| s.parse::<i32>().ok()).unwrap_or(0);
52    current_amount.min((limit - drawn_this_turn).max(0))
53}
54
55fn matches_valid_player(
56    valid: Option<&CompiledSelector>,
57    player: PlayerId,
58    source_controller: PlayerId,
59) -> bool {
60    valid_filter::matches_valid_player_selector_opt(valid, player, source_controller)
61}