use manabrew_engine::game::GameState;
use manabrew_engine::ids::{CardId, PlayerId};
use manabrew_protocol::prompts::scry::ScryDestination;
use crate::game_view_dto::{card_to_dto, CardDto};
use crate::ids_codec::{card_id_str, parse_card_id};
use crate::prompt::*;
use super::{PromptAgent, Responder};
fn library_dtos(game: &GameState, cards: &[CardId]) -> Vec<CardDto> {
cards.iter().map(|&id| card_to_dto(game, id)).collect()
}
fn send_scry<T: Responder>(
agent: &mut PromptAgent<T>,
game: &GameState,
source: Option<CardId>,
cards: &[CardId],
title: &str,
description: &str,
zones: Vec<ScryDestination>,
) -> Vec<Vec<CardId>> {
agent.send_prompt(
PromptInput::Scry(ScryInput {
presentation: PromptPresentation {
title: title.to_string(),
description: Some(description.to_string()),
text: None,
targets: Vec::new(),
},
cards: library_dtos(game, cards),
zones,
}),
source,
);
match agent.recv_action() {
PromptOutput::Scry(ScryOutput::ScryDecision { zone_card_ids }) => zone_card_ids
.into_iter()
.map(|zone| zone.iter().filter_map(|id| parse_card_id(id)).collect())
.collect(),
_ => vec![cards.to_vec(), vec![]],
}
}
pub(super) fn choose_scry<T: Responder>(
agent: &mut PromptAgent<T>,
game: &GameState,
_player: PlayerId,
source: Option<CardId>,
cards: &[CardId],
) -> Vec<Vec<CardId>> {
send_scry(
agent,
game,
source,
cards,
"Scry",
"Put any number on the bottom; the rest on top in any order.",
vec![ScryDestination::LibraryTop, ScryDestination::LibraryBottom],
)
}
pub(super) fn choose_surveil<T: Responder>(
agent: &mut PromptAgent<T>,
game: &GameState,
_player: PlayerId,
source: Option<CardId>,
cards: &[CardId],
) -> Vec<Vec<CardId>> {
send_scry(
agent,
game,
source,
cards,
"Surveil",
"Put any number into your graveyard; the rest on top in any order.",
vec![ScryDestination::LibraryTop, ScryDestination::Graveyard],
)
}
pub(super) fn choose_dig<T: Responder>(
agent: &mut PromptAgent<T>,
game: &GameState,
_player: PlayerId,
valid: &[CardId],
max: usize,
optional: bool,
) -> Vec<CardId> {
let cards = library_dtos(game, valid);
let min = if optional { 0 } else { max.min(1) };
agent.send_prompt(
PromptInput::ChooseCards(manabrew_protocol::prompts::choose_cards::ChooseCardsInput {
presentation: PromptPresentation {
title: "Dig".to_string(),
description: Some("Choose cards to put into your hand.".to_string()),
text: None,
targets: Vec::new(),
},
cards,
min,
max,
}),
None,
);
match agent.recv_action() {
PromptOutput::ChooseCards(ChooseCardsOutput::ChooseCardsDecision { chosen_card_ids }) => {
chosen_card_ids
.iter()
.filter_map(|id| parse_card_id(id))
.collect()
}
_ => valid.iter().copied().take(max).collect(),
}
}
pub(super) fn choose_reorder_library<T: Responder>(
agent: &mut PromptAgent<T>,
game: &GameState,
_player: PlayerId,
cards: &[CardId],
) -> Vec<CardId> {
let items = cards
.iter()
.map(|&id| ReorderItem {
id: card_id_str(id),
card: card_to_dto(game, id),
oracle: None,
})
.collect();
agent.send_prompt(
PromptInput::Reorder(manabrew_protocol::prompts::reorder::ReorderInput {
presentation: PromptPresentation {
title: "Reorder".to_string(),
description: Some("Arrange these cards on top of your library.".to_string()),
text: None,
targets: Vec::new(),
},
items,
}),
None,
);
match agent.recv_action() {
PromptOutput::Reorder(ReorderOutput::ReorderDecision { ordered_ids }) => {
let parsed: Vec<CardId> = ordered_ids
.iter()
.filter_map(|s| parse_card_id(s))
.collect();
if parsed.len() == cards.len() && cards.iter().all(|id| parsed.contains(id)) {
parsed
} else {
cards.to_vec()
}
}
_ => cards.to_vec(),
}
}