2020-01-02 20:33:37 -08:00
|
|
|
use std::convert::{From, Into, TryFrom, TryInto};
|
|
|
|
|
2020-02-20 23:03:51 -08:00
|
|
|
use crate::ship::map::Maps;
|
|
|
|
|
2020-01-02 20:33:37 -08:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum RoomCreationError {
|
|
|
|
InvalidMode,
|
|
|
|
InvalidEpisode(u8),
|
|
|
|
InvalidDifficulty(u8),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-03-14 10:44:27 -07:00
|
|
|
#[derive(Debug, Copy, Clone, derive_more::Display)]
|
2020-01-02 20:33:37 -08:00
|
|
|
pub enum Episode {
|
2020-03-14 10:44:27 -07:00
|
|
|
#[display(fmt="ep1")]
|
2020-01-02 20:33:37 -08:00
|
|
|
One,
|
2020-03-14 10:44:27 -07:00
|
|
|
#[display(fmt="ep2")]
|
2020-01-02 20:33:37 -08:00
|
|
|
Two,
|
2020-03-14 10:44:27 -07:00
|
|
|
#[display(fmt="ep4")]
|
2020-01-02 20:33:37 -08:00
|
|
|
Four,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TryFrom<u8> for Episode {
|
|
|
|
type Error = RoomCreationError;
|
|
|
|
|
|
|
|
fn try_from(value: u8) -> Result<Episode, RoomCreationError> {
|
|
|
|
match value {
|
2020-02-20 22:57:50 -08:00
|
|
|
1 => Ok(Episode::One),
|
|
|
|
2 => Ok(Episode::Two),
|
|
|
|
3 => Ok(Episode::Four),
|
2020-01-02 20:33:37 -08:00
|
|
|
_ => Err(RoomCreationError::InvalidEpisode(value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Into<u8> for Episode {
|
|
|
|
fn into(self) -> u8 {
|
|
|
|
match self {
|
|
|
|
Episode::One => 1,
|
|
|
|
Episode::Two => 2,
|
|
|
|
Episode::Four => 3,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-14 10:44:27 -07:00
|
|
|
#[derive(Debug, Copy, Clone, derive_more::Display)]
|
2020-01-02 20:33:37 -08:00
|
|
|
pub enum Difficulty {
|
|
|
|
Normal,
|
|
|
|
Hard,
|
|
|
|
VeryHard,
|
|
|
|
Ultimate,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TryFrom<u8> for Difficulty {
|
|
|
|
type Error = RoomCreationError;
|
|
|
|
|
|
|
|
fn try_from(value: u8) -> Result<Difficulty, RoomCreationError> {
|
|
|
|
match value {
|
|
|
|
0 => Ok(Difficulty::Normal),
|
|
|
|
1 => Ok(Difficulty::Hard),
|
|
|
|
2 => Ok(Difficulty::VeryHard),
|
|
|
|
3 => Ok(Difficulty::Ultimate),
|
|
|
|
_ => Err(RoomCreationError::InvalidDifficulty(value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Into<u8> 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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-02-20 23:02:25 -08:00
|
|
|
impl RoomMode {
|
|
|
|
fn difficulty(&self) -> Difficulty {
|
|
|
|
match self {
|
|
|
|
RoomMode::Single {difficulty, ..} => *difficulty,
|
|
|
|
RoomMode::Multi {difficulty, ..} => *difficulty,
|
|
|
|
RoomMode::Battle {difficulty, ..} => *difficulty,
|
|
|
|
RoomMode::Challenge {..} => Difficulty::Normal,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn episode(&self) -> Episode {
|
|
|
|
match self {
|
|
|
|
RoomMode::Single {episode, ..} => *episode,
|
|
|
|
RoomMode::Multi {episode, ..} => *episode,
|
|
|
|
RoomMode::Battle {episode, ..} => *episode,
|
|
|
|
RoomMode::Challenge {episode, ..} => *episode,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-01-02 20:33:37 -08:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct RoomState {
|
|
|
|
mode: RoomMode,
|
2020-01-18 23:49:15 -08:00
|
|
|
pub name: String,
|
2020-01-02 20:33:37 -08:00
|
|
|
password: [u16; 16],
|
2020-02-20 23:03:51 -08:00
|
|
|
//pub maps: [u32; 0x20],
|
|
|
|
pub maps: Maps,
|
2020-01-02 20:33:37 -08:00
|
|
|
// 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<RoomState, RoomCreationError> {
|
|
|
|
if [create_room.battle, create_room.challenge, create_room.single_player].iter().sum::<u8>() > 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()?,
|
|
|
|
}
|
|
|
|
};
|
2020-02-20 23:03:51 -08:00
|
|
|
|
|
|
|
let ep = room_mode.episode();
|
2020-01-02 20:33:37 -08:00
|
|
|
Ok(RoomState {
|
|
|
|
mode: room_mode,
|
2020-01-25 18:02:17 -08:00
|
|
|
name: String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).into(),
|
2020-01-02 20:33:37 -08:00
|
|
|
password: create_room.password,
|
2020-02-20 23:03:51 -08:00
|
|
|
//maps: [0; 0x20],
|
|
|
|
maps: Maps::new(ep),
|
2020-01-02 20:33:37 -08:00
|
|
|
})
|
|
|
|
}
|
2020-02-20 23:03:51 -08:00
|
|
|
|
|
|
|
pub fn map_headers(&self) -> [u32; 0x20] {
|
|
|
|
self.maps.map_headers()
|
|
|
|
}
|
2020-01-02 20:33:37 -08:00
|
|
|
}
|