1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use super::{resolve_defined_players, EffectContext};
/// `SP$ ChoosePlayer` — the activating player chooses a player.
/// Stores the result in `source.chosen_player` for subsequent effects.
///
/// Mirrors Java's `ChoosePlayerEffect.java`.
///
/// # Card script examples
/// ```text
/// A:SP$ ChoosePlayer | Defined$ You
/// ```
/// Struct form of this effect so it can participate in the
/// `SpellAbilityEffect` trait hierarchy — mirrors Java's
/// `ChoosePlayerEffect` class extending `SpellAbilityEffect`.
#[manabrew_engine_macros::spell_effect(ChoosePlayerEffect)]
fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
let controller = sa.activating_player;
let defined = sa.defined().unwrap_or("You");
let choosers = resolve_defined_players(defined, controller, ctx.game);
let valid_players: Vec<_> = if let Some(choices) = sa.ir.choices.as_deref() {
resolve_defined_players(choices, controller, ctx.game)
.into_iter()
.filter(|&pid| ctx.game.player(pid).is_alive())
.collect()
} else {
// Match Java getPlayersInTurnOrder() ordering while excluding players
// no longer in game.
ctx.game
.player_order
.iter()
.copied()
.filter(|&pid| ctx.game.player(pid).is_alive())
.collect()
};
for chooser in choosers {
if !ctx.game.player(chooser).is_alive() {
continue;
}
let chosen =
ctx.agents[chooser.index()].choose_target_player(chooser, &valid_players, None);
if let Some(chosen_pid) = chosen {
if let Some(source_id) = sa.source {
ctx.game.card_mut(source_id).set_chosen_player(
Some(chosen_pid),
Some(chooser),
!sa.ir.secretly,
);
}
}
}
}