use std::convert::{From, Into, TryFrom, TryInto}; #[derive(Debug)] pub enum RoomCreationError { InvalidMode, InvalidEpisode(u8), InvalidDifficulty(u8), } #[derive(Debug, Copy, Clone)] pub enum Episode { One, Two, Four, } impl TryFrom for Episode { type Error = RoomCreationError; fn try_from(value: u8) -> Result { match value { 1 => Ok(Episode::One), 2 => Ok(Episode::Two), 3 => Ok(Episode::Four), _ => Err(RoomCreationError::InvalidEpisode(value)) } } } impl Into for Episode { fn into(self) -> u8 { match self { Episode::One => 1, Episode::Two => 2, Episode::Four => 3, } } } #[derive(Debug, Copy, Clone)] pub enum Difficulty { Normal, Hard, VeryHard, Ultimate, } impl TryFrom for Difficulty { type Error = RoomCreationError; fn try_from(value: u8) -> Result { match value { 0 => Ok(Difficulty::Normal), 1 => Ok(Difficulty::Hard), 2 => Ok(Difficulty::VeryHard), 3 => Ok(Difficulty::Ultimate), _ => Err(RoomCreationError::InvalidDifficulty(value)) } } } impl Into for Difficulty { fn into(self) -> u8 { match self { Difficulty::Normal => 0, Difficulty::Hard => 1, Difficulty::VeryHard => 2, Difficulty::Ultimate => 3, } } } #[derive(Debug)] pub enum RoomMode { Single { episode: Episode, difficulty: Difficulty, }, Multi { episode: Episode, difficulty: Difficulty, }, Challenge { episode: Episode, }, Battle { episode: Episode, difficulty: Difficulty, } } #[derive(Debug)] pub struct RoomState { mode: RoomMode, pub name: String, password: [u16; 16], pub maps: [u32; 0x20], // drop_table // items on ground // enemy info } impl RoomState { /*fn new(mode: RoomMode) -> Room { Room { mode: mode, } }*/ pub fn from_create_room(create_room: &libpso::packet::ship::CreateRoom) -> Result { if [create_room.battle, create_room.challenge, create_room.single_player].iter().sum::() > 1 { return Err(RoomCreationError::InvalidMode) } let room_mode = if create_room.battle == 1 { RoomMode::Battle { episode: create_room.episode.try_into()?, difficulty: create_room.difficulty.try_into()?, } } else if create_room.challenge == 1 { RoomMode::Challenge { episode: create_room.episode.try_into()?, } } else if create_room.single_player == 1 { RoomMode::Single { episode: create_room.episode.try_into()?, difficulty: create_room.difficulty.try_into()?, } } else { // normal multimode RoomMode::Multi { episode: create_room.episode.try_into()?, difficulty: create_room.difficulty.try_into()?, } }; Ok(RoomState { mode: room_mode, name: String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).into(), password: create_room.password, maps: [0; 0x20], }) } }