diff --git a/src/ship/room.rs b/src/ship/room.rs new file mode 100644 index 0000000..982c0c1 --- /dev/null +++ b/src/ship/room.rs @@ -0,0 +1,148 @@ +use std::convert::{From, Into, TryFrom, TryInto}; + +#[derive(Debug)] +pub enum RoomCreationError { + InvalidMode, + InvalidEpisode(u8), + InvalidDifficulty(u8), + +} + +#[derive(Debug)] +pub enum Episode { + One, + Two, + Four, +} + +impl TryFrom for Episode { + type Error = RoomCreationError; + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(Episode::One), + 1 => Ok(Episode::Two), + 2 => 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)] +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, + name: [u16; 16], + 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: create_room.name, + password: create_room.password, + maps: [0; 0x20], + }) + } +}