use bevy::prelude::*; use thiserror::Error; use crate::{ fighter::FighterId, match_loading::{MatchConfig, MatchPlayer, MatchRules}, stage::manifest::StageId, }; pub struct MenuMatchPlayerSlot { pub slot: usize, pub fighter: Option, } #[derive(Resource, Default)] pub struct MenuMatchConfig { pub stage: Option, pub players: Vec, } #[derive(Error, Debug, Reflect)] pub enum MenuMatchConfigErrors { #[error("Fighter slot {0} was invalid!")] PlayerSlotInvalid(usize), #[error("Invalid configuration: Slot {0} doesn't have a fighter selected")] FighterNotSelectedForSlot(usize), #[error("Invalid configuration: No stage selected")] StageNotSelected, } impl MenuMatchConfig { pub fn set_player_fighter( &mut self, player_slot: usize, fighter_id: Option, ) -> Result<(), MenuMatchConfigErrors> { let slot = self .players .get_mut(player_slot) .ok_or(MenuMatchConfigErrors::PlayerSlotInvalid(player_slot))?; slot.fighter = fighter_id; Ok(()) } pub fn get_player_fighter( &self, player_slot: usize, ) -> Result, MenuMatchConfigErrors> { let slot = self .players .get(player_slot) .ok_or(MenuMatchConfigErrors::PlayerSlotInvalid(player_slot))?; Ok(slot.fighter) } pub fn all_players_ready(&self) -> bool { let has_unselected_fighter = self .players .iter() .any(|player_slot| player_slot.fighter.is_none()); !has_unselected_fighter } pub fn to_match_config(&self) -> Result { let mut match_players = vec![]; let stage = self.stage.ok_or(MenuMatchConfigErrors::StageNotSelected)?; for player in self.players.iter() { let fighter_id = player .fighter .ok_or(MenuMatchConfigErrors::FighterNotSelectedForSlot( player.slot, ))?; match_players.push(MatchPlayer { fighter: fighter_id, handle: player.slot, }); } Ok(MatchConfig { players: match_players, stage, rules: MatchRules::default(), }) } } #[cfg(test)] mod tests { use super::*; #[test] fn menu_config_uses_default_match_rules() { let menu = MenuMatchConfig { stage: Some(StageId::TestStage), players: vec![MenuMatchPlayerSlot { slot: 0, fighter: Some(FighterId::TestFighter), }], }; assert_eq!(menu.to_match_config().unwrap().rules, MatchRules::default()); } }