use std::path::{Path, PathBuf};
use bevy::prelude::*;
use de_types::player::{Player, PlayerRange};
use tinyvec::{array_vec, ArrayVec};
#[derive(Resource)]
pub struct GameConfig {
map_path: PathBuf,
multiplayer: bool,
locals: LocalPlayers,
}
impl GameConfig {
pub fn new<P: Into<PathBuf>>(map_path: P, multiplayer: bool, locals: LocalPlayers) -> Self {
Self {
map_path: map_path.into(),
multiplayer,
locals,
}
}
pub fn map_path(&self) -> &Path {
self.map_path.as_path()
}
pub fn multiplayer(&self) -> bool {
self.multiplayer
}
pub fn locals(&self) -> &LocalPlayers {
&self.locals
}
}
pub struct LocalPlayers {
playable: Player,
locals: ArrayVec<[Player; Player::MAX_PLAYERS]>,
}
impl LocalPlayers {
pub fn from_max_player(playable: Player, max_player: Player) -> Self {
Self::from_range(playable, PlayerRange::up_to(max_player))
}
pub fn from_range(playable: Player, locals: PlayerRange) -> Self {
Self::new(playable, locals.collect())
}
pub fn from_single(playable: Player) -> Self {
Self::new(playable, array_vec!(_ => playable))
}
pub fn new(playable: Player, locals: ArrayVec<[Player; Player::MAX_PLAYERS]>) -> Self {
assert!((*locals).contains(&playable));
Self { playable, locals }
}
pub fn playable(&self) -> Player {
self.playable
}
pub fn locals(&self) -> &[Player] {
self.locals.as_slice()
}
pub fn is_playable(&self, player: Player) -> bool {
self.playable == player
}
pub fn is_local(&self, player: Player) -> bool {
self.locals.contains(&player)
}
}
pub fn is_multiplayer(config: Option<Res<GameConfig>>) -> bool {
match config {
Some(config) => config.multiplayer(),
None => false,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_game_config() {
let config = GameConfig::new(
"/some/path",
false,
LocalPlayers::from_max_player(Player::Player1, Player::Player4),
);
assert_eq!(config.map_path().to_string_lossy(), "/some/path");
}
}