Skip to main content

manabrew_engine/ability/effects/
subgame_effect.rs

1//! Subgame — play a subgame (Shahrazad).
2//! Ported from Java's SubgameEffect: creates a full sub-game with each player's
3//! library, plays it to completion, then returns cards and applies results.
4//! This is an enormously complex operation — we implement the core structure
5//! but the actual sub-game execution requires the full game loop.
6
7use super::EffectContext;
8
9/// Struct form of this effect so it can participate in the
10/// `SpellAbilityEffect` trait hierarchy — mirrors Java's
11/// `SubgameEffect` class extending `SpellAbilityEffect`.
12#[manabrew_engine_macros::spell_effect(SubgameEffect)]
13fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
14    // Subgame is one of the most complex effects in Magic.
15    // Full implementation requires creating a new GameState, transferring
16    // all library cards, running a complete game, then returning cards.
17    // For now, we simulate the outcome: each player loses half their life
18    // (matching Shahrazad's typical outcome for the loser).
19    let player_ids: Vec<_> = ctx.game.players.iter().map(|p| p.id).collect();
20
21    // The losing player of the subgame loses half their life (rounded up)
22    // Randomly determine winner for now (proper implementation needs full game loop)
23    let loser_idx = ctx.rng.next_int(player_ids.len() as i32) as usize % player_ids.len();
24
25    for (i, &pid) in player_ids.iter().enumerate() {
26        if i == loser_idx {
27            let life = ctx.game.player(pid).life;
28            let loss = (life + 1) / 2; // round up
29            ctx.game.player_lose_life(pid, loss);
30        }
31    }
32
33    // Remember winners/losers if requested
34    if let Some(source) = sa.source {
35        if let Some(remember) = sa.ir.remember_players_text.as_deref() {
36            for (i, &pid) in player_ids.iter().enumerate() {
37                let is_winner = i != loser_idx;
38                if (remember == "Win" && is_winner) || (remember == "NotWin" && !is_winner) {
39                    ctx.game
40                        .card_mut(source)
41                        .set_s_var(format!("RememberedPlayer{}", pid.0), "True");
42                }
43            }
44        }
45    }
46}