use forge_foundation::ZoneType;
use super::EffectContext;
use crate::agent::types::GameEntity;
use crate::player::player_controller::PlayerController;
use crate::replacement::replacement_handler::{apply_replacements, ReplacementEvent};
use crate::replacement::ReplacementResult;
#[manabrew_engine_macros::spell_effect(AttachEffect)]
fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
let aura_id = match sa.source {
Some(s) => s,
None => return,
};
let chooser = sa
.chooser()
.and_then(|defined| {
crate::ability::ability_utils::resolve_defined_players_with_sa(
defined,
sa,
sa.activating_player,
ctx.game,
)
.into_iter()
.next()
})
.unwrap_or(sa.activating_player);
let mut candidates: Vec<GameEntity> = Vec::new();
if let Some(target_card) = sa.target_chosen.target_card {
candidates.push(GameEntity::Card(target_card));
}
if let Some(target_player) = sa.target_chosen.target_player {
candidates.push(GameEntity::Player(target_player));
}
if candidates.is_empty() {
if let Some(defined) = sa.defined() {
candidates.extend(
crate::ability::ability_utils::get_defined_cards(
ctx.game,
Some(aura_id),
defined,
Some(sa.activating_player),
)
.into_iter()
.map(GameEntity::Card),
);
candidates.extend(
crate::ability::ability_utils::resolve_defined_players_with_sa(
defined,
sa,
sa.activating_player,
ctx.game,
)
.into_iter()
.map(GameEntity::Player),
);
}
}
if candidates.is_empty() {
return;
}
let chosen = {
let agent = ctx.agents[chooser.index()].as_mut();
let mut controller = PlayerController::new(ctx.game, chooser, agent);
controller.snapshot_state(ctx.mana_pools);
controller.choose_single_entity_for_effect(&candidates)
};
let chosen = match chosen {
Some(chosen) => chosen,
None => return,
};
let target = match chosen {
GameEntity::Card(c) => c,
GameEntity::Player(_) => return,
};
if ctx.game.card(aura_id).zone != ZoneType::Battlefield
|| ctx.game.card(target).zone != ZoneType::Battlefield
{
return;
}
if crate::staticability::static_ability_cant_attach::cant_attach(
&ctx.game.cards,
ctx.game.card(aura_id),
ctx.game.card(target),
false,
) {
return;
}
let mut event = ReplacementEvent::Attached {
card: aura_id,
target,
};
let result = apply_replacements(ctx.game, &mut event);
if result == ReplacementResult::Skipped || result == ReplacementResult::Replaced {
return;
}
ctx.game.attach_to(aura_id, target);
ctx.trigger_handler.run_trigger(
crate::trigger::TriggerType::Attached,
crate::event::RunParams {
card: Some(aura_id),
..Default::default()
},
false,
);
}