use forge_foundation::{CardTypeLine, ColorSet, ManaCost, ZoneType};
use super::EffectContext;
use crate::ability::ability_ir::DefinedRef;
use crate::card::Card;
use crate::ids::CardId;
use crate::staticability::parse_static_ability;
#[manabrew_engine_macros::spell_effect(AirbendEffect)]
fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
let parent_target = ctx.parent_target_card.or(sa.target_chosen.target_card);
let primary_def = sa.ir.defined.as_ref().and_then(|d| d.refs.first());
let targets: Vec<CardId> = match primary_def {
None => {
if let Some(target) = sa.target_chosen.target_card {
vec![target]
} else if let Some(source) = sa.source {
vec![source]
} else {
return;
}
}
Some(DefinedRef::SelfCard) => sa.source.into_iter().collect(),
Some(DefinedRef::Remembered) => sa
.source
.map(|sid| ctx.game.card(sid).remembered_cards.clone())
.unwrap_or_default(),
Some(DefinedRef::Targeted) => sa.target_chosen.target_card.into_iter().collect(),
Some(DefinedRef::Unsupported(raw)) if raw.starts_with("Valid ") => {
let filter = raw.strip_prefix("Valid ").unwrap_or("").trim();
let stripped: String = filter
.split('.')
.map(|seg| {
seg.split('+')
.filter(|term| !term.eq_ignore_ascii_case("NotDefinedTargeted"))
.collect::<Vec<_>>()
.join("+")
})
.filter(|seg| !seg.is_empty())
.collect::<Vec<_>>()
.join(".");
let mut out = Vec::new();
for &pid in &ctx.game.player_order {
for &cid in ctx.game.cards_in_zone(ZoneType::Battlefield, pid) {
if filter.contains("NotDefinedTargeted")
&& parent_target.is_some_and(|t| t == cid)
{
continue;
}
if super::matches_change_type(ctx.game.card(cid), &stripped, &[]) {
out.push(cid);
}
}
}
out
}
_ => sa.source.into_iter().collect(),
};
let host_id = sa.source;
let host_image = host_id.map(|id| ctx.game.card(id).card_name.clone());
let mut exiled_so_far: Vec<CardId> = Vec::new();
for card_id in targets {
if ctx.game.card(card_id).zone == ZoneType::None {
continue;
}
let old_zone = ctx.game.card(card_id).zone;
let owner = ctx.game.card(card_id).owner;
ctx.move_card(card_id, ZoneType::Exile, owner);
super::emit_zone_trigger(ctx.trigger_handler, card_id, old_zone, ZoneType::Exile);
if ctx.game.card(card_id).is_token {
continue;
}
if ctx.game.card(card_id).zone != ZoneType::Exile {
continue;
}
exiled_so_far.push(card_id);
let card_name_for_effect = ctx.game.card(card_id).card_name.clone();
let host_name = host_image.clone().unwrap_or_else(|| "Airbend".to_string());
let effect_name = format!("{} ({})", host_name, card_name_for_effect);
let mut effect = Card::new(
CardId(0),
effect_name,
owner,
CardTypeLine::parse("Effect"),
ManaCost::parse("0"),
ColorSet::COLORLESS,
None,
None,
vec![],
vec![],
);
effect.set_controller(owner);
effect.set_effect_source(host_id);
let static_text = "S$ Mode$ Continuous | MayPlay$ True | MayPlayAltManaCost$ 2 \
| EffectZone$ Command | Affected$ Card.IsRemembered+nonLand \
| AffectedZone$ Exile | Description$ You may cast the card.";
if let Some(static_ab) = parse_static_ability(static_text) {
effect.set_static_abilities(vec![static_ab]);
}
effect.add_remembered_cards(exiled_so_far.iter().copied());
effect.set_forget_on_moved_origin(Some(ZoneType::Exile));
let effect_id = ctx.game.create_card(effect);
ctx.move_card(effect_id, ZoneType::Command, owner);
}
}