/*
* 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::reflect::{FromReflect, Reflect};
use serde::{Deserialize, Serialize};
use serde_repr::Deserialize_repr;
use crate::{
game_status::{Card, PlayerState, CardAction},
seed_gen,
};
use super::user::User;
mod forming;
pub use forming::*;
mod my_games;
pub use my_games::*;
mod join;
pub use join::*;
mod create;
pub use create::*;
mod create_action;
pub use create_action::*;
mod details;
pub use details::*;
mod end;
pub use end::*;
#[derive(Deserialize, Serialize, Clone, PartialEq)]
pub enum Command {
InitSupplyPile {
card: Card,
amount: usize,
},
/// take a card from pile N
TakeFromPile {
index: usize,
for_cost: usize,
},
/// play card from hand index N
PlayCard {
index: usize,
},
/// draw N amount of cards from deck
Draw {
amount: usize,
},
/// discard card from hand in slot N
Discard {
index: usize,
},
/// end the invokers turn, and invoke StartTurn for the target
EndTurn {},
/// start the targets turn
StartTurn {},
/// change player state to another
ChangePlayerState {
state: PlayerState,
},
RollForAdvanced {
amount: usize,
sides: usize,
pairs: Vec<(usize, CardAction)>,
},
GiveCurrency {
amount: usize,
},
RollForCurrency {
amount: usize,
sides: usize,
},
GivePlays {
amount: usize,
},
RollForPlays {
amount: usize,
sides: usize,
},
GiveBuys {
amount: usize,
},
GiveVP {
amount: usize,
},
RemoveVP {
amount: usize,
},
/// mark a card in the targets deck to be trashed on play.
/// if index in None, a random card will be chosen
MarkCardInDeckToBeTrashed {
index: Option<usize>,
},
}
#[derive(Deserialize, Serialize, Clone, PartialEq)]
pub struct Action {
pub id: String,
pub created_at: chrono::DateTime<chrono::Utc>,
pub updated_at: chrono::DateTime<chrono::Utc>,
pub game_id: String,
pub invoker: String,
pub target: String,
pub command: Command,
/// it's actually u64, but we handle it as a string to make psql happy
pub seed: String,
}
impl Action {
pub fn new(
game_id: &str,
invoker: &str,
target: &str,
command: &Command,
seed: Option<u64>,
) -> Self {
let seed = if seed.is_none() {
seed_gen!()
} else {
seed.unwrap()
};
Self {
id: "".to_string(),
created_at: chrono::Utc::now(),
updated_at: chrono::Utc::now(),
game_id: game_id.to_string(),
invoker: invoker.to_string(),
target: target.to_string(),
command: command.clone(),
seed: seed.to_string(),
}
}
}
#[derive(Debug, Deserialize_repr, Clone, PartialEq, Reflect, FromReflect)]
#[repr(u8)]
pub enum GameState {
Forming = 0,
InProgress = 1,
Finished = 2,
Cancelled = 3,
}
#[derive(Deserialize, Clone, Reflect, FromReflect)]
pub struct Game {
pub id: String,
#[reflect(ignore)]
pub created_at: chrono::DateTime<chrono::Utc>,
#[reflect(ignore)]
pub updated_at: chrono::DateTime<chrono::Utc>,
#[reflect(ignore)]
pub ended_at: chrono::DateTime<chrono::Utc>,
pub host_id: String,
pub host: Option<User>,
pub guest_id: String,
pub guest: Option<User>,
pub state: GameState,
pub turn: u8,
#[reflect(ignore)]
pub actions: Option<Vec<Action>>,
}