use std::collections::HashMap;
use super::EffectContext;
use crate::event::RunParams;
use crate::ids::PlayerId;
use crate::parsing::keys;
use crate::trigger::TriggerType;
#[manabrew_engine_macros::spell_effect(VoteEffect)]
fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
let controller = sa.activating_player;
let mut voters: Vec<PlayerId> = if let Some(def) = sa.defined_player() {
super::resolve_defined_players(def, controller, ctx.game)
} else {
ctx.game.player_order.clone()
};
if let Some(pos) = voters.iter().position(|&p| p == controller) {
voters.rotate_left(pos);
}
let choices: Vec<String> = if let Some(choices_str) = sa.ir.choices.as_deref() {
choices_str
.split(',')
.map(|s| s.trim().to_string())
.collect()
} else if let Some(msg) = sa.ir.vote_message_text.as_deref() {
msg.split(" or ").map(|s| s.trim().to_string()).collect()
} else {
return;
};
if choices.is_empty() {
return;
}
let mut vote_counts: HashMap<String, Vec<PlayerId>> = HashMap::new();
for choice in &choices {
vote_counts.insert(choice.clone(), Vec::new());
}
for &voter in &voters {
if ctx.game.player(voter).has_lost {
continue;
}
ctx.agents[voter.index()].snapshot_state(ctx.game, ctx.mana_pools);
let chosen = ctx.agents[voter.index()].confirm_action(
voter,
Some("Vote"),
&format!("Vote: {}", choices.join(" or ")),
&choices,
sa.source,
sa.api,
);
let choice_idx = if chosen { 0 } else { 1.min(choices.len() - 1) };
let chosen_str = &choices[choice_idx];
if let Some(voters_list) = vote_counts.get_mut(chosen_str) {
voters_list.push(voter);
}
}
let max_votes = vote_counts.values().map(|v| v.len()).max().unwrap_or(0);
let winners: Vec<String> = vote_counts
.iter()
.filter(|(_, v)| v.len() == max_votes)
.map(|(k, _)| k.clone())
.collect();
let all_votes = vote_counts
.iter()
.map(|(choice, voters)| (choice.clone(), voters.clone()))
.collect();
ctx.trigger_handler.run_trigger(
TriggerType::Vote,
RunParams {
all_votes: Some(all_votes),
..Default::default()
},
false,
);
if sa.param_is_true(keys::STORE_VOTE_NUM) {
if let Some(source_id) = sa.source {
for (choice, voters_list) in &vote_counts {
let svar_name = format!("VoteNum{choice}");
let svar_val = format!("Number${}", voters_list.len());
ctx.game.card_mut(source_id).set_s_var(svar_name, svar_val);
}
}
}
if sa.param_is_true(keys::REMEMBER_VOTED_OBJECTS) {
if let Some(source_id) = sa.source {
for winner in &winners {
if let Some(idx) = choices.iter().position(|c| c == winner) {
ctx.game.card_mut(source_id).add_remembered_cmc(idx as i32);
}
}
}
}
}