Skip to main content

manabrew_engine/ability/effects/
counters_note_effect.rs

1//! CountersNote effect — note the number of counters on a permanent.
2//!
3//! Ported from Java's `CountersNoteEffect.java`.
4//! Store counter amounts for later use (e.g. "noted P1P1 counters").
5
6use super::EffectContext;
7use crate::card::CounterType;
8
9/// Note the number of counters of a specific type on a card.
10/// Mirrors Java's `CountersNoteEffect.noteCounters(Card, CounterType)`.
11///
12/// Stores the counter count in the source card's remembered_cmc list
13/// for later retrieval by effects that check "noted" counter amounts.
14pub fn note_counters(
15    game: &mut crate::game::GameState,
16    source_id: crate::ids::CardId,
17    target_id: crate::ids::CardId,
18    counter_type: &crate::card::CounterType,
19) {
20    let count = *game
21        .card(target_id)
22        .counters
23        .get(counter_type)
24        .unwrap_or(&0);
25    game.card_mut(source_id).add_remembered_cmc(count);
26}
27
28/// Load previously noted counter amounts back onto a card.
29/// Mirrors Java's `CountersNoteEffect.loadCounters(Card, CounterType)`.
30///
31/// Reads the noted counter count from the source card's remembered_cmc
32/// and adds that many counters of the specified type to the target.
33pub fn load_counters(
34    game: &mut crate::game::GameState,
35    source_id: crate::ids::CardId,
36    target_id: crate::ids::CardId,
37    counter_type: &crate::card::CounterType,
38) {
39    // Get the noted count (last remembered CMC value)
40    let noted_count = game
41        .card(source_id)
42        .remembered_cmc
43        .last()
44        .copied()
45        .unwrap_or(0);
46
47    if noted_count > 0 {
48        game.card_mut(target_id)
49            .add_counter(counter_type, noted_count);
50    }
51}
52
53/// Struct form of this effect so it can participate in the
54/// `SpellAbilityEffect` trait hierarchy — mirrors Java's
55/// `CountersNoteEffect` class extending `SpellAbilityEffect`.
56#[manabrew_engine_macros::spell_effect(CountersNoteEffect)]
57fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
58    let Some(source_id) = sa.source else { return };
59    let counter_type = sa.ir.counter_type.clone().unwrap_or(CounterType::P1P1);
60
61    let targets: Vec<crate::ids::CardId> = if sa.uses_targeting() {
62        sa.target_chosen.target_card.into_iter().collect()
63    } else {
64        sa.source.into_iter().collect()
65    };
66
67    for card_id in targets {
68        let count = *ctx
69            .game
70            .card(card_id)
71            .counters
72            .get(&counter_type)
73            .unwrap_or(&0);
74        // Store noted value in source's remembered_cmc (used by WithNotedCounters$)
75        ctx.game.card_mut(source_id).add_remembered_cmc(count);
76    }
77}