2020-06-05 22:10:53 -06:00
|
|
|
use std::collections::HashMap;
|
2020-01-02 20:33:37 -08:00
|
|
|
use std::convert::{From, Into, TryFrom, TryInto};
|
2022-10-18 04:46:21 -06:00
|
|
|
use std::path::PathBuf;
|
2022-10-18 17:55:47 -06:00
|
|
|
use async_std::sync::{Arc, RwLock, RwLockReadGuard};
|
2022-10-18 04:46:21 -06:00
|
|
|
use futures::future::BoxFuture;
|
2022-10-18 17:55:47 -06:00
|
|
|
use futures::stream::{FuturesOrdered, Stream};
|
2020-01-02 20:33:37 -08:00
|
|
|
|
2021-12-28 14:16:05 -07:00
|
|
|
use thiserror::Error;
|
2020-04-21 07:20:25 -06:00
|
|
|
use rand::Rng;
|
2022-10-18 17:55:47 -06:00
|
|
|
|
2020-02-20 23:03:51 -08:00
|
|
|
use crate::ship::map::Maps;
|
2020-04-06 23:42:38 -07:00
|
|
|
use crate::ship::drops::DropTable;
|
|
|
|
use crate::entity::character::SectionID;
|
2020-06-05 22:10:53 -06:00
|
|
|
use crate::ship::monster::{load_monster_stats_table, MonsterType, MonsterStats};
|
2020-08-04 20:43:02 -06:00
|
|
|
use crate::ship::map::area::MapAreaLookup;
|
2021-07-18 18:40:10 +00:00
|
|
|
use crate::ship::map::enemy::RareMonsterAppearTable;
|
2022-01-27 01:07:19 +00:00
|
|
|
use crate::ship::quests;
|
2022-10-19 19:10:15 -06:00
|
|
|
use crate::ship::ship::{ShipError, ShipEvent};
|
2022-10-18 17:55:47 -06:00
|
|
|
use crate::ship::location::{MAX_ROOMS, RoomId};
|
2022-10-18 04:46:21 -06:00
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct Rooms([Arc<RwLock<Option<RoomState>>>; MAX_ROOMS]);
|
|
|
|
|
|
|
|
impl Default for Rooms {
|
|
|
|
fn default() -> Rooms {
|
|
|
|
Rooms(core::array::from_fn(|_| Arc::new(RwLock::new(None))))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Rooms {
|
2023-01-28 20:12:20 -07:00
|
|
|
pub async fn add(&self, room_id: RoomId, room: RoomState) -> Result<(), anyhow::Error> {
|
2022-10-18 04:46:21 -06:00
|
|
|
*self.0
|
|
|
|
.get(room_id.0)
|
2022-10-18 17:55:47 -06:00
|
|
|
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?
|
2022-10-18 04:46:21 -06:00
|
|
|
.write()
|
|
|
|
.await = Some(room);
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn remove(&self, room_id: RoomId) {
|
|
|
|
if let Some(room) = self.0.get(room_id.0) {
|
|
|
|
*room
|
|
|
|
.write()
|
|
|
|
.await = None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn exists(&self, room_id: RoomId) -> bool {
|
|
|
|
match self.0.get(room_id.0) {
|
|
|
|
Some(room) => {
|
|
|
|
room
|
|
|
|
.read()
|
|
|
|
.await
|
|
|
|
.is_some()
|
|
|
|
},
|
|
|
|
None => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-28 20:12:20 -07:00
|
|
|
pub async fn with<'a, T, F>(&'a self, room_id: RoomId, func: F) -> Result<T, anyhow::Error>
|
2022-10-18 04:46:21 -06:00
|
|
|
where
|
|
|
|
T: Send,
|
|
|
|
F: for<'b> FnOnce(&'b RoomState) -> BoxFuture<'b, T> + Send + 'a
|
|
|
|
{
|
|
|
|
let room = self.0
|
|
|
|
.get(room_id.0)
|
2022-10-18 17:55:47 -06:00
|
|
|
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?
|
2022-10-18 04:46:21 -06:00
|
|
|
.read()
|
|
|
|
.await;
|
|
|
|
if let Some(room) = room.as_ref() {
|
|
|
|
Ok(func(room).await)
|
|
|
|
}
|
|
|
|
else {
|
2023-01-28 20:12:20 -07:00
|
|
|
Err(ShipError::InvalidRoom(room_id.0 as u32).into())
|
2022-10-18 04:46:21 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-28 20:12:20 -07:00
|
|
|
pub async fn with_mut<'a, T, F>(&'a self, room_id: RoomId, func: F) -> Result<T, anyhow::Error>
|
2022-10-18 04:46:21 -06:00
|
|
|
where
|
|
|
|
T: Send,
|
|
|
|
F: for<'b> FnOnce(&'b mut RoomState) -> BoxFuture<'b, T> + Send + 'a
|
|
|
|
{
|
|
|
|
let mut room = self.0
|
|
|
|
.get(room_id.0)
|
2022-10-18 17:55:47 -06:00
|
|
|
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?
|
2022-10-18 04:46:21 -06:00
|
|
|
.write()
|
|
|
|
.await;
|
|
|
|
|
|
|
|
if let Some(room) = room.as_mut() {
|
|
|
|
Ok(func(room).await)
|
|
|
|
}
|
|
|
|
else {
|
2023-01-28 20:12:20 -07:00
|
|
|
Err(ShipError::InvalidRoom(room_id.0 as u32).into())
|
2022-10-18 04:46:21 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-18 17:55:47 -06:00
|
|
|
pub async fn get(&self, room_id: RoomId) -> RwLockReadGuard<Option<RoomState>> {
|
2022-10-18 04:46:21 -06:00
|
|
|
self.0
|
|
|
|
.get(room_id.0)
|
|
|
|
.unwrap()
|
|
|
|
.read()
|
|
|
|
.await
|
|
|
|
}
|
|
|
|
|
2022-10-18 17:55:47 -06:00
|
|
|
pub fn stream(&self) -> impl Stream<Item = RwLockReadGuard<Option<RoomState>>> {
|
2022-10-18 04:46:21 -06:00
|
|
|
self.0
|
|
|
|
.iter()
|
|
|
|
.map(|room| async move {
|
|
|
|
room
|
|
|
|
.read()
|
|
|
|
.await
|
|
|
|
})
|
|
|
|
.collect::<FuturesOrdered<_>>()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-23 18:18:36 +00:00
|
|
|
#[derive(Debug, Error)]
|
|
|
|
#[error("")]
|
2020-01-02 20:33:37 -08:00
|
|
|
pub enum RoomCreationError {
|
|
|
|
InvalidMode,
|
|
|
|
InvalidEpisode(u8),
|
|
|
|
InvalidDifficulty(u8),
|
2020-10-30 22:58:10 -06:00
|
|
|
CouldNotLoadMonsterStats(RoomMode),
|
2022-01-27 01:07:19 +00:00
|
|
|
CouldNotLoadQuests,
|
2020-01-02 20:33:37 -08:00
|
|
|
}
|
|
|
|
|
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))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-18 17:38:36 -06:00
|
|
|
impl From<Episode> for u8 {
|
|
|
|
fn from(other: Episode) -> u8 {
|
|
|
|
match other {
|
2020-01-02 20:33:37 -08:00
|
|
|
Episode::One => 1,
|
|
|
|
Episode::Two => 2,
|
|
|
|
Episode::Four => 3,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-24 15:59:48 -06:00
|
|
|
impl Episode {
|
|
|
|
pub fn from_quest(value: u8) -> Result<Episode, RoomCreationError> {
|
|
|
|
match value {
|
|
|
|
0 => Ok(Episode::One),
|
|
|
|
1 => Ok(Episode::Two),
|
|
|
|
2 => Ok(Episode::Four),
|
|
|
|
_ => Err(RoomCreationError::InvalidEpisode(value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-27 18:16:27 -06:00
|
|
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, 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))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-18 17:38:36 -06:00
|
|
|
impl From<Difficulty> for u8 {
|
|
|
|
fn from(other: Difficulty) -> u8 {
|
|
|
|
match other {
|
2020-01-02 20:33:37 -08:00
|
|
|
Difficulty::Normal => 0,
|
|
|
|
Difficulty::Hard => 1,
|
|
|
|
Difficulty::VeryHard => 2,
|
|
|
|
Difficulty::Ultimate => 3,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-27 01:07:19 +00:00
|
|
|
#[derive(Debug, Copy, Clone, derive_more::Display)]
|
2020-01-02 20:33:37 -08:00
|
|
|
pub enum RoomMode {
|
2022-01-27 01:07:19 +00:00
|
|
|
#[display(fmt="single")]
|
2020-01-02 20:33:37 -08:00
|
|
|
Single {
|
|
|
|
episode: Episode,
|
|
|
|
difficulty: Difficulty,
|
|
|
|
},
|
2022-01-27 01:07:19 +00:00
|
|
|
#[display(fmt="multi")]
|
2020-01-02 20:33:37 -08:00
|
|
|
Multi {
|
|
|
|
episode: Episode,
|
|
|
|
difficulty: Difficulty,
|
|
|
|
},
|
2022-01-27 01:07:19 +00:00
|
|
|
#[display(fmt="challenge")]
|
2020-01-02 20:33:37 -08:00
|
|
|
Challenge {
|
|
|
|
episode: Episode,
|
|
|
|
},
|
2022-01-27 01:07:19 +00:00
|
|
|
#[display(fmt="battle")]
|
2020-01-02 20:33:37 -08:00
|
|
|
Battle {
|
|
|
|
episode: Episode,
|
|
|
|
difficulty: Difficulty,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-02-20 23:02:25 -08:00
|
|
|
impl RoomMode {
|
2020-03-17 08:02:17 -03:00
|
|
|
pub fn difficulty(&self) -> Difficulty {
|
2020-02-20 23:02:25 -08:00
|
|
|
match self {
|
|
|
|
RoomMode::Single {difficulty, ..} => *difficulty,
|
|
|
|
RoomMode::Multi {difficulty, ..} => *difficulty,
|
|
|
|
RoomMode::Battle {difficulty, ..} => *difficulty,
|
|
|
|
RoomMode::Challenge {..} => Difficulty::Normal,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-17 08:02:17 -03:00
|
|
|
pub fn episode(&self) -> Episode {
|
2020-02-20 23:02:25 -08:00
|
|
|
match self {
|
|
|
|
RoomMode::Single {episode, ..} => *episode,
|
|
|
|
RoomMode::Multi {episode, ..} => *episode,
|
|
|
|
RoomMode::Battle {episode, ..} => *episode,
|
|
|
|
RoomMode::Challenge {episode, ..} => *episode,
|
|
|
|
}
|
|
|
|
}
|
2020-04-24 20:38:56 -06:00
|
|
|
|
|
|
|
pub fn battle(&self) -> u8 {
|
|
|
|
match self {
|
|
|
|
RoomMode::Battle {..} => 1,
|
|
|
|
_ => 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn challenge(&self) -> u8 {
|
|
|
|
match self {
|
|
|
|
RoomMode::Challenge {..} => 1,
|
|
|
|
_ => 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn single_player(&self) -> u8 {
|
|
|
|
match self {
|
|
|
|
RoomMode::Single {..} => 1,
|
|
|
|
_ => 0,
|
|
|
|
}
|
|
|
|
}
|
2020-02-20 23:02:25 -08:00
|
|
|
}
|
2022-02-07 03:01:29 +00:00
|
|
|
pub enum QuestCategoryType {
|
|
|
|
Standard,
|
|
|
|
Government,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<usize> for QuestCategoryType {
|
|
|
|
fn from(f: usize) -> QuestCategoryType {
|
|
|
|
match f {
|
|
|
|
0 => QuestCategoryType::Standard,
|
|
|
|
1 => QuestCategoryType::Government,
|
|
|
|
_ => QuestCategoryType::Standard, // TODO: panic?
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-02-20 23:02:25 -08:00
|
|
|
|
2022-02-07 03:01:29 +00:00
|
|
|
impl QuestCategoryType {
|
|
|
|
pub fn value(&self) -> usize {
|
|
|
|
match self {
|
|
|
|
QuestCategoryType::Standard => 0,
|
|
|
|
QuestCategoryType::Government => 1,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-02-20 23:02:25 -08:00
|
|
|
|
2020-01-02 20:33:37 -08:00
|
|
|
pub struct RoomState {
|
2020-03-17 08:02:17 -03:00
|
|
|
pub mode: RoomMode,
|
2020-01-18 23:49:15 -08:00
|
|
|
pub name: String,
|
2020-03-17 08:02:17 -03:00
|
|
|
pub password: [u16; 16],
|
2020-02-20 23:03:51 -08:00
|
|
|
pub maps: Maps,
|
2020-04-12 14:27:06 -07:00
|
|
|
pub drop_table: Box<DropTable<rand_chacha::ChaCha20Rng>>,
|
2020-04-21 07:20:25 -06:00
|
|
|
pub section_id: SectionID,
|
|
|
|
pub random_seed: u32,
|
2020-04-21 08:51:06 -06:00
|
|
|
pub bursting: bool,
|
2020-06-05 22:10:53 -06:00
|
|
|
pub monster_stats: Box<HashMap<MonsterType, MonsterStats>>,
|
2020-08-04 20:43:02 -06:00
|
|
|
pub map_areas: MapAreaLookup,
|
2021-07-18 18:40:10 +00:00
|
|
|
pub rare_monster_table: Box<RareMonsterAppearTable>,
|
2022-02-07 03:01:29 +00:00
|
|
|
pub quest_group: QuestCategoryType,
|
2022-02-06 21:53:11 +00:00
|
|
|
pub quests: Vec<quests::QuestList>,
|
2020-01-02 20:33:37 -08:00
|
|
|
// items on ground
|
|
|
|
// enemy info
|
|
|
|
}
|
|
|
|
|
|
|
|
impl RoomState {
|
2020-03-18 21:46:13 -03:00
|
|
|
pub fn get_flags_for_room_list(&self) -> u8 {
|
2020-03-18 01:36:46 -03:00
|
|
|
let mut flags = 0u8;
|
|
|
|
|
2020-03-18 21:46:13 -03:00
|
|
|
match self.mode {
|
2020-03-18 01:36:46 -03:00
|
|
|
RoomMode::Single {..} => {flags += 0x04}
|
|
|
|
RoomMode::Battle {..} => {flags += 0x10},
|
|
|
|
RoomMode::Challenge {..} => {flags += 0x20},
|
|
|
|
_ => {flags += 0x40},
|
|
|
|
};
|
|
|
|
|
2020-03-18 21:46:13 -03:00
|
|
|
if self.password[0] > 0 {
|
2020-03-18 01:36:46 -03:00
|
|
|
flags += 0x02;
|
|
|
|
}
|
|
|
|
flags
|
|
|
|
}
|
|
|
|
|
2020-03-18 21:46:13 -03:00
|
|
|
pub fn get_episode_for_room_list(&self) -> u8 {
|
|
|
|
let episode: u8 = self.mode.episode().into();
|
2020-03-18 01:36:46 -03:00
|
|
|
|
2020-03-18 21:46:13 -03:00
|
|
|
match self.mode {
|
|
|
|
RoomMode::Single {..} => episode + 0x10,
|
|
|
|
_ => episode + 0x40,
|
2020-03-18 01:36:46 -03:00
|
|
|
}
|
2020-03-18 21:46:13 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_difficulty_for_room_list(&self) -> u8 {
|
|
|
|
let difficulty: u8 = self.mode.difficulty().into();
|
|
|
|
difficulty + 0x22
|
2020-03-18 01:36:46 -03:00
|
|
|
}
|
|
|
|
|
2022-02-06 21:53:11 +00:00
|
|
|
pub fn set_quest_group(&mut self, group: usize) {
|
2022-02-07 03:01:29 +00:00
|
|
|
self.quest_group = QuestCategoryType::from(group);
|
2022-02-06 21:53:11 +00:00
|
|
|
}
|
|
|
|
|
2022-10-19 19:10:15 -06:00
|
|
|
pub fn from_create_room(create_room: &libpso::packet::ship::CreateRoom, section_id: SectionID, event: ShipEvent) -> Result<RoomState, RoomCreationError> {
|
2020-01-02 20:33:37 -08:00
|
|
|
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
|
|
|
|
2021-07-23 01:45:02 +00:00
|
|
|
let rare_monster_table = RareMonsterAppearTable::new(room_mode.episode());
|
2022-02-06 21:53:11 +00:00
|
|
|
|
|
|
|
// push the usual set of quests for the selected mode
|
2022-01-27 01:07:19 +00:00
|
|
|
let mut qpath = PathBuf::from("data/quests/bb");
|
|
|
|
qpath.push(room_mode.episode().to_string());
|
|
|
|
qpath.push(room_mode.to_string());
|
|
|
|
qpath.push("quests.toml");
|
2022-02-06 21:53:11 +00:00
|
|
|
let mut room_quests = Vec::new();
|
2022-10-18 04:46:21 -06:00
|
|
|
let quest_list = match quests::load_quests(qpath) {
|
2022-01-27 01:07:19 +00:00
|
|
|
Ok(qlist) => qlist,
|
|
|
|
Err(_) => return Err(RoomCreationError::CouldNotLoadQuests),
|
|
|
|
};
|
2021-07-18 18:40:10 +00:00
|
|
|
|
2022-02-06 21:53:11 +00:00
|
|
|
room_quests.push(quest_list);
|
2022-02-06 21:56:34 +00:00
|
|
|
|
2022-02-06 21:53:11 +00:00
|
|
|
// if multiplayer also push the government quests
|
|
|
|
if let RoomMode::Multi {..} = room_mode {
|
|
|
|
qpath = PathBuf::from("data/quests/bb/");
|
|
|
|
qpath.push(room_mode.episode().to_string());
|
|
|
|
qpath.push("government/quests.toml");
|
|
|
|
|
2022-10-18 04:46:21 -06:00
|
|
|
let quest_list = match quests::load_quests(qpath) {
|
2022-02-06 21:53:11 +00:00
|
|
|
Ok(qlist) => qlist,
|
|
|
|
Err(_) => return Err(RoomCreationError::CouldNotLoadQuests),
|
|
|
|
};
|
|
|
|
|
|
|
|
room_quests.push(quest_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-01-02 20:33:37 -08:00
|
|
|
Ok(RoomState {
|
2021-06-18 17:38:36 -06:00
|
|
|
monster_stats: Box::new(load_monster_stats_table(&room_mode).map_err(|_| RoomCreationError::CouldNotLoadMonsterStats(room_mode))?),
|
2020-01-02 20:33:37 -08:00
|
|
|
mode: room_mode,
|
2021-07-23 01:45:02 +00:00
|
|
|
random_seed: rand::thread_rng().gen(),
|
2021-07-18 18:40:10 +00:00
|
|
|
rare_monster_table: Box::new(rare_monster_table.clone()),
|
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,
|
2022-10-19 19:10:15 -06:00
|
|
|
maps: Maps::new(room_mode, &rare_monster_table, event),
|
2021-06-18 20:38:29 -06:00
|
|
|
section_id,
|
2020-04-12 14:27:06 -07:00
|
|
|
drop_table: Box::new(DropTable::new(room_mode.episode(), room_mode.difficulty(), section_id)),
|
2020-04-21 08:51:06 -06:00
|
|
|
bursting: false,
|
2020-08-04 20:43:02 -06:00
|
|
|
map_areas: MapAreaLookup::new(&room_mode.episode()),
|
2022-02-07 03:01:29 +00:00
|
|
|
quest_group: QuestCategoryType::Standard,
|
2022-01-27 01:07:19 +00:00
|
|
|
quests: room_quests,
|
2020-01-02 20:33:37 -08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|