use crate::parsing::keys;
use forge_foundation::{CardTypeLine, ColorSet, ManaCost, ZoneType};
use super::token_effect_base::{TokenEffectBase, TOKEN_EFFECT_BASE};
use super::{parse_counter_type, EffectContext};
use crate::card::card_zone_table::CardZoneTable;
use crate::card::Card;
use crate::ids::CardId;
use crate::spellability::SpellAbility;
use crate::staticability::parse_static_ability;
#[manabrew_engine_macros::spell_effect(AmassEffect)]
fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
let controller = sa.activating_player;
let amount = super::resolve_numeric_svar(ctx.game, sa, "Num", 1).max(0);
let amass_type = sa.ir.type_filter.as_deref().unwrap_or("Zombie");
let has_army = ctx.game.cards.iter().any(|c| {
c.zone == ZoneType::Battlefield
&& c.controller == controller
&& c.type_line
.subtypes
.iter()
.any(|s| s.eq_ignore_ascii_case("Army"))
});
if !has_army {
create_army_token(ctx, sa, controller, amass_type);
}
let armies: Vec<CardId> = ctx
.game
.cards
.iter()
.filter(|c| {
c.zone == ZoneType::Battlefield
&& c.controller == controller
&& c.type_line
.subtypes
.iter()
.any(|s| s.eq_ignore_ascii_case("Army"))
})
.map(|c| c.id)
.collect();
if armies.is_empty() {
return;
}
let target = if armies.len() == 1 {
armies[0]
} else {
ctx.agents[controller.index()].snapshot_state(ctx.game, ctx.mana_pools);
ctx.agents[controller.index()]
.choose_single_card_for_zone_change(
ctx.game,
controller,
&armies,
"Choose an Army",
false,
)
.unwrap_or(armies[0])
};
if sa.param_is_true(keys::REMEMBER_AMASS) {
if let Some(source_id) = sa.source {
ctx.game.card_mut(source_id).add_remembered_card(target);
}
}
let counter_type = parse_counter_type("P1P1");
ctx.add_counter(
target,
&counter_type,
amount,
sa,
crate::event::RunParams::default(),
);
let has_type = ctx
.game
.card(target)
.type_line
.subtypes
.iter()
.any(|s| s.eq_ignore_ascii_case(amass_type));
if !has_type {
add_type_effect(ctx, sa, controller, target, amass_type);
}
}
fn create_army_token(
ctx: &mut EffectContext,
_sa: &SpellAbility,
controller: crate::ids::PlayerId,
amass_type: &str,
) {
let army_script = format!("b_0_0_{}_army", amass_type.to_lowercase());
let mut token = TOKEN_EFFECT_BASE.require_token_template(ctx.token_templates, &army_script);
token.set_owner(controller);
token.set_controller(controller);
token.set_is_token(true);
token.set_s_var("TokenScript", army_script);
token.set_s_var("TokenSpawningAbility", _sa.ability_text.clone());
token.card_name = format!("{} Army Token", amass_type);
token.type_line = CardTypeLine::parse(&format!("Creature - {} Army", amass_type));
let token_table = TOKEN_EFFECT_BASE.make_token_table_internal(controller, token, 1);
let mut trigger_list = CardZoneTable::default();
let result =
TOKEN_EFFECT_BASE.make_token_table(ctx, token_table, false, &mut trigger_list, _sa);
if !result.created.is_empty() {
trigger_list.trigger_changes_zone_all(ctx.trigger_handler, ctx.game, Some(_sa));
}
}
fn add_type_effect(
ctx: &mut EffectContext,
sa: &SpellAbility,
controller: crate::ids::PlayerId,
target: CardId,
amass_type: &str,
) {
let mut effect = Card::new(
CardId(0),
"Amass Effect".to_string(),
controller,
CardTypeLine::parse("Effect"),
ManaCost::parse("0"),
ColorSet::COLORLESS,
None,
None,
vec![],
vec![],
);
effect.set_controller(controller);
effect.set_effect_source(sa.source);
effect.add_remembered_card(target);
effect.set_temp_effect_host(Some(target));
let static_text = format!(
"Mode$ Continuous | Affected$ Card.IsRemembered | EffectZone$ Command | AddType$ {}",
amass_type
);
if let Some(parsed) = parse_static_ability(&format!("S$ {}", static_text)) {
effect.add_static_ability(parsed);
}
let effect_id = ctx.game.create_card(effect);
ctx.move_card(effect_id, ZoneType::Command, controller);
}