manabrew_engine/ability/effects/
token_effect.rs1use super::token_effect_base::{TokenCreateResult, TokenEffectBase, TOKEN_EFFECT_BASE};
2use super::EffectContext;
3use crate::card::card_zone_table::CardZoneTable;
4use crate::ids::PlayerId;
5use crate::spellability::SpellAbility;
6
7#[manabrew_engine_macros::spell_effect(TokenEffect)]
11fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
12 let amount: usize = sa
15 .ir
16 .token_amount
17 .as_deref()
18 .map(|raw| super::resolve_numeric_value(ctx.game, sa, raw, 1))
19 .unwrap_or(1)
20 .max(0) as usize;
21
22 let token_owners = resolve_token_owners(ctx, sa);
23 if token_owners.is_empty() {
24 return;
25 }
26
27 let mut trigger_list = CardZoneTable::default();
28 let scripts = TOKEN_EFFECT_BASE.token_scripts(sa);
29 let result = if scripts.is_empty() {
30 let mut all_created = TokenCreateResult::default();
31 for owner in token_owners {
32 let template = TOKEN_EFFECT_BASE.build_inline_token(sa, owner);
33 let token_table = TOKEN_EFFECT_BASE.make_token_table_internal(owner, template, amount);
34 let created =
35 TOKEN_EFFECT_BASE.make_token_table(ctx, token_table, false, &mut trigger_list, sa);
36 all_created.created.extend(created.created);
37 all_created.combat_changed |= created.combat_changed;
38 }
39 all_created
40 } else {
41 TOKEN_EFFECT_BASE.make_token_table_from_scripts(
42 ctx,
43 &token_owners,
44 &scripts,
45 amount,
46 false,
47 &mut trigger_list,
48 sa,
49 )
50 };
51
52 if !result.created.is_empty() {
53 trigger_list.trigger_changes_zone_all(ctx.trigger_handler, ctx.game, Some(sa));
54 }
55}
56
57fn resolve_token_owners(ctx: &EffectContext, sa: &SpellAbility) -> Vec<PlayerId> {
58 if let Some(defined) = sa.token_owner() {
63 return crate::ability::ability_utils::resolve_defined_players_with_sa(
64 defined,
65 sa,
66 sa.activating_player,
67 ctx.game,
68 );
69 }
70 vec![sa.activating_player]
71}