Skip to main content

manabrew_engine/ability/effects/
advance_crank_effect.rs

1//! AdvanceCrank — advance a crank counter (Unfinity).
2//! Ported from Java's AdvanceCrankEffect: advances the player's CRANK!
3//! counter to the next sprocket and cranks contraptions on that sprocket.
4
5use forge_foundation::ZoneType;
6
7use super::EffectContext;
8use crate::event::RunParams;
9use crate::ids::CardId;
10use crate::trigger::TriggerType;
11
12/// Struct form of this effect so it can participate in the
13/// `SpellAbilityEffect` trait hierarchy — mirrors Java's
14/// `AdvanceCrankEffect` class extending `SpellAbilityEffect`.
15#[manabrew_engine_macros::spell_effect(AdvanceCrankEffect)]
16fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
17    let players = if let Some(def) = sa.defined() {
18        super::resolve_defined_players(def, sa.activating_player, ctx.game)
19    } else {
20        vec![sa.activating_player]
21    };
22
23    for player_id in players {
24        if ctx.game.player(player_id).has_lost {
25            continue;
26        }
27        // Advance crank counter — track via player svar-like approach
28        // using a card in command zone or player counter
29        // Find all contraptions on battlefield for this player and trigger them
30        let contraptions: Vec<CardId> = ctx
31            .game
32            .cards
33            .iter()
34            .filter(|c| {
35                c.zone == ZoneType::Battlefield
36                    && c.controller == player_id
37                    && c.type_line
38                        .subtypes
39                        .iter()
40                        .any(|s| s.eq_ignore_ascii_case("Contraption"))
41            })
42            .map(|c| c.id)
43            .collect();
44
45        for card_id in contraptions {
46            ctx.trigger_handler.run_trigger(
47                TriggerType::CrankAdvanced,
48                RunParams {
49                    card: Some(card_id),
50                    player: Some(player_id),
51                    ..Default::default()
52                },
53                false,
54            );
55        }
56    }
57}