/*
* This file is part of laurelin_client
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
* See LICENSE for licensing information.
*/
use bevy::prelude::*;
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::api::game::{Action, Command, Game};
mod parser;
#[derive(Deserialize, Serialize, Clone, PartialEq)]
pub struct CardAction {
pub command: Command,
/// if false, targets the next player
pub target_self: bool,
}
#[derive(Deserialize, Serialize, Clone, PartialEq)]
pub struct Card {
pub name: String,
/// short details shown on the card, e.g. Draw 2
pub short_details: Vec<String>,
/// longer explanations of features of the card
pub long_details: Vec<String>,
pub cost: usize,
/// if set, use this?
//vp_cost: Option<u32>,
pub actions: Vec<CardAction>,
/// trash after play?
pub to_be_trashed: bool,
}
/// a supply pile holds an amount of some card
#[derive(Clone)]
pub struct SupplyPile {
/// the card type that the supply pile holds
pub card: Card,
/// the amount of cards currently in the pile
pub amount: usize,
}
#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq)]
pub enum PlayerState {
/// e.g. not their turn
Idle,
/// play phase, playing cards
PlayPhase,
/// buy phase, buying cards
BuyPhase,
}
#[derive(Clone)]
pub struct PlayerStatus {
pub turn_n: usize,
pub display_name: String,
pub state: PlayerState,
pub plays: usize,
pub buys: usize,
pub currency: usize,
pub vp: usize,
pub hand: Vec<Card>,
pub deck: Vec<Card>,
pub discard: Vec<Card>,
}
/// constructed from a vector of [`Action`]s
#[derive(Clone, Reflect, FromReflect)]
pub struct GameStatus {
/// log entries, filled in one at a time when parsing actions
pub log: Vec<LogEntry>,
/// a modifiable Actions Vector, will be modified when parsing actions,
/// used for showing the log
#[reflect(ignore)]
pub actions: Vec<Action>,
#[reflect(ignore)]
pub supply_piles: Vec<SupplyPile>,
/// player ids mapped to statuses
#[reflect(ignore)]
pub players: HashMap<String, PlayerStatus>,
}
impl GameStatus {
pub fn new(game: &Game) -> Self {
match parser::parse(game) {
Ok(res) => res,
Err(_) => panic!("parsing actions failed"),
}
}
}
#[derive(Clone, Reflect, FromReflect)]
pub struct LogEntry {
pub sections: Vec<LogSection>,
}
impl LogEntry {
pub fn from_sections(sections: impl IntoIterator<Item = LogSection>) -> Self {
Self {
sections: sections.into_iter().collect(),
}
}
}
#[derive(Clone, Reflect, FromReflect)]
pub enum LogSection {
Normal(String),
Bold(String),
}
impl LogSection {
pub fn normal(value: &str) -> LogSection {
LogSection::Normal(value.to_string())
}
pub fn bold(value: &str) -> LogSection {
LogSection::Bold(value.to_string())
}
}