manabrew_engine/replacement/
replace_draw.rs1use crate::card::Card;
6use crate::game::GameState;
7use crate::ids::CardId;
8use forge_foundation::ZoneType;
9
10use super::replacement_effect::ReplacementEffect;
11use super::replacement_handler::ReplacementEvent;
12use super::replacement_result::ReplacementResult;
13use super::replacement_type::ReplacementType;
14use crate::card_trait_base::CardTrait;
15
16pub fn can_replace(
18 effect: &ReplacementEffect,
19 event: &ReplacementEvent,
20 game: &GameState,
21 source_card: &Card,
22) -> bool {
23 if effect.event != ReplacementType::Draw {
24 return false;
25 }
26 let player = match event {
27 ReplacementEvent::Draw { player, .. } => *player,
28 _ => return false,
29 };
30 if let Some(valid) = effect.ir.valid_player_selector.as_ref() {
31 if !effect.matches_compiled_valid_player(valid, player, source_card) {
32 return false;
33 }
34 }
35 if effect.ir.not_first_card_in_draw_step {
38 if let ReplacementEvent::Draw {
39 is_first_in_draw_step,
40 ..
41 } = event
42 {
43 if *is_first_in_draw_step {
44 return false;
45 }
46 }
47 }
48 if let Some(amount) = effect.ir.dredge_amount {
51 let lib_size = game.cards_in_zone(ZoneType::Library, player).len();
52 if lib_size < amount {
53 return false;
54 }
55 }
56 true
57}
58
59pub fn execute(
61 effect: &ReplacementEffect,
62 _event: &mut ReplacementEvent,
63 game: &mut GameState,
64 source_card_id: CardId,
65) -> ReplacementResult {
66 if effect.prevents() || effect.has_skip() {
67 return ReplacementResult::Skipped;
68 }
69 if let Some(replace) = effect.replace_with() {
71 if replace == "DrawTwo" || replace == "DrawExtra" {
72 if let ReplacementEvent::Draw { extra_draws, .. } = _event {
73 *extra_draws += 1;
74 return ReplacementResult::Updated;
75 }
76 }
77 }
78 if let Some(amount) = effect.ir.dredge_amount {
81 let player = match _event {
82 ReplacementEvent::Draw { player, .. } => *player,
83 _ => return ReplacementResult::Replaced,
84 };
85 let lib = game.cards_in_zone(ZoneType::Library, player);
87 let lib_len = lib.len();
88 let start = lib_len.saturating_sub(amount);
89 let mill_cards: Vec<crate::ids::CardId> = lib[start..].iter().rev().copied().collect();
90 for cid in mill_cards {
91 let owner = game.card(cid).owner;
92 game.move_card(cid, ZoneType::Graveyard, owner);
93 }
94 if game.card(source_card_id).zone == ZoneType::Graveyard {
96 game.move_card(source_card_id, ZoneType::Hand, player);
97 }
98 return ReplacementResult::Replaced;
99 }
100 ReplacementResult::Replaced
101}