use serde::{Deserialize, Serialize};
use crate::ids::{CardId, PlayerId};
use crate::spellability::AlternativeCost;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum GameEntity {
Player(PlayerId),
Card(CardId),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct PlayOption {
pub card_id: CardId,
pub mode: PlayCardMode,
#[serde(default)]
pub alt_cost_index: u8,
}
impl PlayOption {
pub fn normal(card_id: CardId) -> Self {
Self {
card_id,
mode: PlayCardMode::Normal,
alt_cost_index: 0,
}
}
pub fn with_mode(card_id: CardId, mode: PlayCardMode) -> Self {
Self {
card_id,
mode,
alt_cost_index: 0,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum PlayCardMode {
Normal,
BackFaceLand,
RoomRightSplit,
Alternative(AlternativeCost),
StaticAlternative,
ForetellExile,
UnlockDoor,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum TargetChoice {
Player(PlayerId),
Card(CardId),
None,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MainPhaseAction {
Pass,
Play(PlayOption),
ActivateMana(CardId, Option<usize>, Option<u16>),
UntapMana(CardId),
ActivateAbility(CardId, usize),
}
#[derive(Debug, Clone)]
pub struct ActivatableAction {
pub card_id: CardId,
pub ability_index: usize,
pub description: String,
pub cost: Option<String>,
pub is_mana_ability: bool,
pub is_class_level_up: bool,
pub produced_mana: Option<String>,
pub produced_mana_amount: Option<i32>,
}
#[derive(Debug, Clone, Default)]
pub struct PriorityActionSpace {
pub playable: Vec<PlayOption>,
pub tappable_lands: Vec<CardId>,
pub untappable_lands: Vec<CardId>,
pub activatable: Vec<ActivatableAction>,
pub mana_abilities: Vec<ActivatableAction>,
}
impl PriorityActionSpace {
pub fn is_empty(&self) -> bool {
self.playable.is_empty()
&& self.tappable_lands.is_empty()
&& self.untappable_lands.is_empty()
&& self.activatable.is_empty()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CombatCostAction {
TapLand {
card_id: CardId,
mana_ability_index: Option<usize>,
express_choice: Option<u16>,
},
UntapLand(CardId),
Pay,
Decline,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ManaCostAction {
TapForMana {
card_id: CardId,
mana_ability_index: Option<usize>,
express_choice: Option<u16>,
},
Untap(CardId),
Pay {
auto: bool,
},
AttemptedAndFailed,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ManaAbilityOption {
pub card_id: CardId,
pub ability_index: usize,
pub description: String,
pub cost: Option<String>,
pub produced_mana: Option<String>,
pub produced_mana_amount: Option<i32>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinaryChoiceKind {
HeadsOrTails,
TapOrUntap,
PlayOrDraw,
OddsOrEvens,
UntapOrLeaveTapped,
LeftOrRight,
AddOrRemove,
IncreaseOrDecrease,
}
impl BinaryChoiceKind {
pub fn labels(self) -> (&'static str, &'static str) {
match self {
BinaryChoiceKind::HeadsOrTails => ("Heads", "Tails"),
BinaryChoiceKind::TapOrUntap => ("Tap", "Untap"),
BinaryChoiceKind::PlayOrDraw => ("Play", "Draw"),
BinaryChoiceKind::OddsOrEvens => ("Odds", "Evens"),
BinaryChoiceKind::UntapOrLeaveTapped => ("Untap", "Leave tapped"),
BinaryChoiceKind::LeftOrRight => ("Left", "Right"),
BinaryChoiceKind::AddOrRemove => ("Add", "Remove"),
BinaryChoiceKind::IncreaseOrDecrease => ("Increase", "Decrease"),
}
}
pub fn as_str(self) -> &'static str {
match self {
BinaryChoiceKind::HeadsOrTails => "HeadsOrTails",
BinaryChoiceKind::TapOrUntap => "TapOrUntap",
BinaryChoiceKind::PlayOrDraw => "PlayOrDraw",
BinaryChoiceKind::OddsOrEvens => "OddsOrEvens",
BinaryChoiceKind::UntapOrLeaveTapped => "UntapOrLeaveTapped",
BinaryChoiceKind::LeftOrRight => "LeftOrRight",
BinaryChoiceKind::AddOrRemove => "AddOrRemove",
BinaryChoiceKind::IncreaseOrDecrease => "IncreaseOrDecrease",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RollSwapChoice {
Power,
Toughness,
}