2022-12-27 20:16:35 +11:00
use super ::StaticItem ;
2022-12-27 23:35:27 +11:00
use once_cell ::sync ::OnceCell ;
use std ::collections ::BTreeMap ;
2022-12-28 20:00:55 +11:00
use ansi ::ansi ;
2023-01-01 00:09:25 +11:00
use async_trait ::async_trait ;
2023-01-02 13:25:05 +11:00
use serde ::{ Serialize , Deserialize } ;
2023-01-01 00:09:25 +11:00
use crate ::message_handler ::user_commands ::{
UResult , VerbContext
} ;
2022-12-27 23:35:27 +11:00
use crate ::models ::item ::Item ;
2022-12-27 20:16:35 +11:00
2022-12-27 23:35:27 +11:00
pub struct Zone {
pub code : & 'static str ,
pub display : & 'static str ,
pub outdoors : bool ,
}
static STATIC_ZONE_DETAILS : OnceCell < BTreeMap < & 'static str , Zone > > = OnceCell ::new ( ) ;
pub fn zone_details ( ) -> & 'static BTreeMap < & 'static str , Zone > {
STATIC_ZONE_DETAILS . get_or_init (
| | vec! (
Zone { code : " melbs " ,
display : " Melbs " ,
outdoors : true } ,
Zone { code : " repro_xv " ,
display : " Reprolabs XV " ,
outdoors : true } ,
) . into_iter ( ) . map ( | x | ( x . code , x ) ) . collect ( ) )
}
2022-12-29 00:37:14 +11:00
#[ derive(Eq, PartialEq, Ord, PartialOrd, Clone, Debug) ]
2022-12-27 23:35:27 +11:00
pub struct GridCoords {
2022-12-29 00:37:14 +11:00
pub x : i64 ,
pub y : i64 ,
pub z : i64
2022-12-27 23:35:27 +11:00
}
2022-12-29 18:44:50 +11:00
impl GridCoords {
pub fn apply ( self : & GridCoords , dir : & Direction ) -> GridCoords {
match dir {
Direction ::NORTH = > GridCoords { y : self . y - 1 , .. * self } ,
Direction ::SOUTH = > GridCoords { y : self . y + 1 , .. * self } ,
Direction ::EAST = > GridCoords { x : self . x + 1 , .. * self } ,
Direction ::WEST = > GridCoords { x : self . x - 1 , .. * self } ,
Direction ::NORTHEAST = > GridCoords { x : self . x + 1 , y : self . y - 1 , .. * self } ,
Direction ::SOUTHEAST = > GridCoords { x : self . x + 1 , y : self . y + 1 , .. * self } ,
Direction ::NORTHWEST = > GridCoords { x : self . x - 1 , y : self . y - 1 , .. * self } ,
Direction ::SOUTHWEST = > GridCoords { x : self . x - 1 , y : self . y + 1 , .. * self } ,
Direction ::UP = > GridCoords { z : self . z + 1 , .. * self } ,
Direction ::DOWN = > GridCoords { z : self . z - 1 , .. * self } ,
2023-01-02 13:25:05 +11:00
Direction ::IN { .. } = > self . clone ( )
2022-12-29 18:44:50 +11:00
}
}
}
2023-01-01 00:09:25 +11:00
#[ async_trait ]
pub trait ExitBlocker {
// True if they will be allowed to pass the exit, false otherwise.
async fn attempt_exit (
self : & Self ,
ctx : & mut VerbContext ,
player : & Item ,
exit : & Exit
) -> UResult < bool > ;
}
2022-12-27 23:35:27 +11:00
pub enum ExitType {
Free , // Anyone can just walk it.
2023-01-01 00:09:25 +11:00
Blocked ( & 'static ( dyn ExitBlocker + Sync + Send ) ) , // Custom code about who can pass.
2022-12-27 23:35:27 +11:00
// Future ideas: Doors with locks, etc...
}
2022-12-29 18:44:50 +11:00
#[ allow(dead_code) ]
2023-01-02 13:25:05 +11:00
#[ derive(Eq, PartialEq, Ord, PartialOrd, Clone, Debug, Serialize, Deserialize) ]
2022-12-27 23:35:27 +11:00
pub enum Direction {
NORTH ,
SOUTH ,
EAST ,
WEST ,
NORTHEAST ,
2022-12-29 18:44:50 +11:00
SOUTHEAST ,
2022-12-27 23:35:27 +11:00
NORTHWEST ,
SOUTHWEST ,
UP ,
DOWN ,
2023-01-02 13:25:05 +11:00
IN { item : String }
2022-12-27 23:35:27 +11:00
}
2022-12-29 18:44:50 +11:00
impl Direction {
2023-01-02 13:25:05 +11:00
pub fn describe ( self : & Self ) -> String {
2022-12-29 18:44:50 +11:00
match self {
2023-01-02 13:25:05 +11:00
Direction ::NORTH = > " north " . to_owned ( ) ,
Direction ::SOUTH = > " south " . to_owned ( ) ,
Direction ::EAST = > " east " . to_owned ( ) ,
Direction ::WEST = > " west " . to_owned ( ) ,
Direction ::NORTHEAST = > " northeast " . to_owned ( ) ,
Direction ::SOUTHEAST = > " southeast " . to_owned ( ) ,
Direction ::NORTHWEST = > " northwest " . to_owned ( ) ,
Direction ::SOUTHWEST = > " southwest " . to_owned ( ) ,
Direction ::UP = > " up " . to_owned ( ) ,
Direction ::DOWN = > " down " . to_owned ( ) ,
Direction ::IN { item } = > item . to_owned ( )
2022-12-29 18:44:50 +11:00
}
}
pub fn parse ( input : & str ) -> Option < & 'static Direction > {
match input {
" north " | " n " = > Some ( & Direction ::NORTH ) ,
" south " | " s " = > Some ( & Direction ::SOUTH ) ,
" east " | " e " = > Some ( & Direction ::EAST ) ,
" west " | " w " = > Some ( & Direction ::WEST ) ,
" northeast " | " ne " = > Some ( & Direction ::NORTHEAST ) ,
" southeast " | " se " = > Some ( & Direction ::SOUTHEAST ) ,
" northwest " | " nw " = > Some ( & Direction ::NORTHEAST ) ,
" southwest " | " sw " = > Some ( & Direction ::SOUTHWEST ) ,
2023-01-01 00:09:25 +11:00
" up " = > Some ( & Direction ::UP ) ,
" down " = > Some ( & Direction ::DOWN ) ,
2022-12-29 18:44:50 +11:00
_ = > None
}
}
}
2022-12-27 23:35:27 +11:00
pub enum ExitTarget {
UseGPS ,
Custom ( & 'static str )
}
pub struct Exit {
2022-12-29 18:44:50 +11:00
pub direction : Direction ,
pub target : ExitTarget ,
2023-01-01 00:09:25 +11:00
pub exit_type : ExitType ,
}
pub struct SecondaryZoneRecord {
pub zone : & 'static str ,
pub short : & 'static str ,
pub grid_coords : GridCoords
2022-12-27 23:35:27 +11:00
}
pub struct Room {
pub zone : & 'static str ,
2023-01-01 00:09:25 +11:00
// Other zones where it can be seen on the map and accessed.
pub secondary_zones : Vec < SecondaryZoneRecord > ,
2022-12-27 23:35:27 +11:00
pub code : & 'static str ,
pub name : & 'static str ,
pub short : & 'static str ,
pub grid_coords : GridCoords ,
pub description : & 'static str ,
2022-12-29 00:37:14 +11:00
pub description_less_explicit : Option < & 'static str > ,
2022-12-27 23:35:27 +11:00
pub exits : Vec < Exit >
}
static STATIC_ROOM_LIST : OnceCell < Vec < Room > > = OnceCell ::new ( ) ;
pub fn room_list ( ) -> & 'static Vec < Room > {
STATIC_ROOM_LIST . get_or_init (
| | vec! (
Room {
zone : " repro_xv " ,
2023-01-01 00:09:25 +11:00
secondary_zones : vec ! ( ) ,
2022-12-27 23:35:27 +11:00
code : " repro_xv_chargen " ,
2023-01-01 00:09:25 +11:00
name : ansi ! ( " Choice Room " ) ,
2022-12-29 18:44:50 +11:00
short : ansi ! ( " <bgwhite><green>CR<reset> " ) ,
2022-12-29 00:37:14 +11:00
description : ansi ! (
2022-12-29 16:20:34 +11:00
" A room brightly lit in unnaturally white light, covered in sparkling \
white tiles from floor to ceiling . A loudspeaker plays a message on \
loop :\ n \
\ t < blue > \ " Citizen, you are here because your memory has been wiped and \
2022-12-29 00:37:14 +11:00
you are ready to start a fresh life . As a being enhanced by \
Gazos - Murlison Co technology , the emperor has granted you the power \
to choose 14 points of upgrades to yourself . Choose wisely , as it \
will impact who you end up being , and you would need to completely \
wipe your brain again to change them . Talk to Statbot to spend your \
14 points and create your body . \ " <reset> \n \
2022-12-29 22:17:55 +11:00
[ Try < bold > - statbot hi < reset > , to send hi to statbot - the - means \
2022-12-29 00:37:14 +11:00
to whisper to a particular person in the room ] " ),
description_less_explicit : None ,
2023-01-01 00:09:25 +11:00
grid_coords : GridCoords { x : 0 , y : 0 , z : - 1 } ,
exits : vec ! ( Exit {
direction : Direction ::EAST ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Blocked ( & super ::npc ::statbot ::ChoiceRoomBlocker ) ,
} )
} ,
Room {
zone : " repro_xv " ,
secondary_zones : vec ! ( ) ,
code : " repro_xv_updates " ,
name : ansi ! ( " Update Centre " ) ,
short : ansi ! ( " <bgwhite><green>UC<reset> " ) ,
description : ansi ! (
" A room covered in posters, evidently meant to help newly wiped individuals \
get up to speed on what has happened in the world since their memory implant was \
created . A one - way opens to the east - you have a feeling that once you go through , \
there will be no coming back in here . < bold > [ Hint : Try reading the posters here . ] < reset > " ),
description_less_explicit : None ,
grid_coords : GridCoords { x : 1 , y : 0 , z : - 1 } ,
2022-12-29 18:44:50 +11:00
exits : vec ! ( Exit {
direction : Direction ::EAST ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free ,
} )
} ,
Room {
zone : " repro_xv " ,
2023-01-01 00:09:25 +11:00
secondary_zones : vec ! ( ) ,
2022-12-29 18:44:50 +11:00
code : " repro_xv_respawn " ,
2023-01-01 00:09:25 +11:00
name : ansi ! ( " Body Factory " ) ,
2022-12-29 18:44:50 +11:00
short : ansi ! ( " <bgmagenta><white>BF<reset> " ) ,
description : ansi ! (
" A room filled with glass vats full of clear fluids, with bodies of \
various stages of development floating in them . It smells like bleach . \
Being here makes you realise you aren ' t exactly alive right now .. . you \
have no body . But you sense you could go < bold > up < reset > and attach \
2022-12-31 00:59:14 +11:00
your memories to a body matching your current stats " ),
2022-12-29 18:44:50 +11:00
description_less_explicit : None ,
2023-01-01 00:09:25 +11:00
grid_coords : GridCoords { x : 2 , y : 0 , z : - 1 } ,
exits : vec ! ( Exit {
direction : Direction ::UP ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} )
} ,
Room {
zone : " repro_xv " ,
secondary_zones : vec ! ( SecondaryZoneRecord {
zone : " melbs " ,
short : ansi ! ( " <bgmagenta><white>RL<reset> " ) ,
grid_coords : GridCoords { x : 2 , y : 0 , z : 0 } ,
} ) ,
code : " repro_xv_lobby " ,
name : " Lobby " ,
short : " <= " ,
description : ansi ! (
" An entrance for an establishment called ReproLabs XV. \
It looks like they make bodies and attach peoples memories to \
them , and allow people to reclone when they die . It has an \
unattended reception desk , with chrome - plated letters reading \
ReproLabs XV stuck to the wall behind it . A pipe down to into the ground \
opens up here , but the airflow is so strong , it looks like it is out \
only - it seems to be how newly re - cloned bodies get back into the world " ),
description_less_explicit : None ,
grid_coords : GridCoords { x : 2 , y : 0 , z : 0 } ,
exits : vec ! (
Exit {
direction : Direction ::WEST ,
2023-01-02 15:39:55 +11:00
target : ExitTarget ::Custom ( " room/melbs_kingst_50 " ) ,
2023-01-01 00:09:25 +11:00
exit_type : ExitType ::Free
} )
} ,
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
2023-01-02 15:39:55 +11:00
code : " melbs_kingst_latrobest " ,
name : " King Street & Latrobe St " ,
short : ansi ! ( " <yellow>##<reset> " ) ,
description : " A wide road (5 lanes each way) intersects a narrower 3 lane road. Both have been rather poorly maintained. Potholes dot the ashphalt road. " ,
description_less_explicit : None ,
grid_coords : GridCoords { x : 1 , y : - 5 , z : 0 } ,
exits : vec ! (
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
code : " melbs_kingst_10 " ,
name : " King Street - 10 block " ,
2023-01-01 00:09:25 +11:00
short : ansi ! ( " <yellow>||<reset> " ) ,
description : " A wide road (5 lanes each way) that has been rather poorly maintained. Potholes dot the ashphalt road, while cracks line the footpaths on either side " ,
description_less_explicit : None ,
2023-01-02 15:39:55 +11:00
grid_coords : GridCoords { x : 1 , y : - 4 , z : 0 } ,
2023-01-01 00:09:25 +11:00
exits : vec ! (
2023-01-02 15:39:55 +11:00
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
2023-01-01 00:09:25 +11:00
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
2023-01-02 15:39:55 +11:00
code : " melbs_kingst_20 " ,
name : " King Street - 20 block " ,
2023-01-01 00:09:25 +11:00
short : ansi ! ( " <yellow>||<reset> " ) ,
description : " A wide road (5 lanes each way) that has been rather poorly maintained. Potholes dot the ashphalt road, while cracks line the footpaths on either side " ,
description_less_explicit : None ,
2023-01-02 15:39:55 +11:00
grid_coords : GridCoords { x : 1 , y : - 3 , z : 0 } ,
2023-01-01 00:09:25 +11:00
exits : vec ! (
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
2023-01-02 15:39:55 +11:00
code : " melbs_kingst_30 " ,
name : " King Street - 30 block " ,
2023-01-01 00:09:25 +11:00
short : ansi ! ( " <yellow>||<reset> " ) ,
description : " A wide road (5 lanes each way) that has been rather poorly maintained. Potholes dot the ashphalt road, while cracks line the footpaths on either side " ,
description_less_explicit : None ,
2023-01-02 15:39:55 +11:00
grid_coords : GridCoords { x : 1 , y : - 2 , z : 0 } ,
exits : vec ! (
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
code : " melbs_kingst_lonsdalest " ,
name : " King Street & Lonsdale St " ,
short : ansi ! ( " <yellow>##<reset> " ) ,
description : " A wide road (5 lanes each way) intersects a narrower 2 lane each way road. Both have been rather poorly maintained. Potholes dot the ashphalt road " ,
description_less_explicit : None ,
2023-01-01 00:09:25 +11:00
grid_coords : GridCoords { x : 1 , y : - 1 , z : 0 } ,
exits : vec ! (
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
2023-01-02 15:39:55 +11:00
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
code : " melbs_kingst_40 " ,
name : ansi ! ( " King Street - 40 block " ) ,
short : ansi ! ( " <yellow>||<reset> " ) ,
description : ansi ! (
" A wide road (5 lanes each way) that has been rather poorly maintained. Potholes dot the ashphalt road, while cracks line the footpaths on either side " ) ,
description_less_explicit : None ,
grid_coords : GridCoords { x : 1 , y : 0 , z : 0 } ,
exits : vec ! (
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
2023-01-01 00:09:25 +11:00
Room {
zone : " melbs " ,
2023-01-01 00:16:29 +11:00
secondary_zones : vec ! (
SecondaryZoneRecord {
zone : " repro_xv " ,
short : ansi ! ( " <bggreen><white>EX<reset> " ) ,
grid_coords : GridCoords { x : 1 , y : 0 , z : 0 }
}
) ,
2023-01-02 15:39:55 +11:00
code : " melbs_kingst_50 " ,
name : ansi ! ( " King Street - 50 block " ) ,
2023-01-01 00:09:25 +11:00
short : ansi ! ( " <yellow>||<reset> " ) ,
description : ansi ! (
" A wide road (5 lanes each way) that has been rather poorly maintained. Potholes dot the ashphalt road, while cracks line the footpaths on either side " ) ,
description_less_explicit : None ,
2023-01-02 15:39:55 +11:00
grid_coords : GridCoords { x : 1 , y : 1 , z : 0 } ,
2023-01-01 00:09:25 +11:00
exits : vec ! (
Exit {
direction : Direction ::EAST ,
target : ExitTarget ::Custom ( " room/repro_xv_lobby " ) ,
exit_type : ExitType ::Free
} ,
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
2023-01-02 15:39:55 +11:00
code : " melbs_kingst_60 " ,
name : " King Street - 60 block " ,
2023-01-01 00:09:25 +11:00
short : ansi ! ( " <yellow>||<reset> " ) ,
description : " A wide road (5 lanes each way) that has been rather poorly maintained. Potholes dot the ashphalt road, while cracks line the footpaths on either side " ,
description_less_explicit : None ,
2023-01-02 15:39:55 +11:00
grid_coords : GridCoords { x : 1 , y : 2 , z : 0 } ,
exits : vec ! (
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
code : " melbs_kingst_bourkest " ,
name : " King Street & Bourke St " ,
short : ansi ! ( " <yellow>##<reset> " ) ,
description : " A wide road (5 lanes each way) intersects a slightly narrower 4-lane road with wide but heavily cracked concrete footpaths. Potholes dot the ashphalt road. " ,
description_less_explicit : None ,
grid_coords : GridCoords { x : 1 , y : 3 , z : 0 } ,
2023-01-01 00:09:25 +11:00
exits : vec ! (
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
2023-01-02 15:39:55 +11:00
code : " melbs_kingst_70 " ,
name : " King Street - 70 block " ,
2023-01-01 00:09:25 +11:00
short : ansi ! ( " <yellow>||<reset> " ) ,
description : " A wide road (5 lanes each way) that has been rather poorly maintained. Potholes dot the ashphalt road, while cracks line the footpaths on either side " ,
description_less_explicit : None ,
2023-01-02 15:39:55 +11:00
grid_coords : GridCoords { x : 1 , y : 4 , z : 0 } ,
exits : vec ! (
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
code : " melbs_kingst_80 " ,
name : " King Street - 80 block " ,
short : ansi ! ( " <yellow>||<reset> " ) ,
description : " A wide road (5 lanes each way) that has been rather poorly maintained. Potholes dot the ashphalt road, while cracks line the footpaths on either side " ,
description_less_explicit : None ,
grid_coords : GridCoords { x : 1 , y : 5 , z : 0 } ,
2023-01-01 00:09:25 +11:00
exits : vec ! (
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
2023-01-02 15:39:55 +11:00
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
2023-01-01 00:09:25 +11:00
)
2022-12-27 23:35:27 +11:00
} ,
2023-01-02 15:39:55 +11:00
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
code : " melbs_kingst_90 " ,
name : " King Street - 90 block " ,
short : ansi ! ( " <yellow>||<reset> " ) ,
description : " A wide road (5 lanes each way) that has been rather poorly maintained. Potholes dot the ashphalt road, while cracks line the footpaths on either side " ,
description_less_explicit : None ,
grid_coords : GridCoords { x : 1 , y : 6 , z : 0 } ,
exits : vec ! (
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
code : " melbs_kingst_collinsst " ,
name : " King Street & Collins St " ,
short : ansi ! ( " <yellow>##<reset> " ) ,
description : " A wide road (5 lanes each way) intersects another wide 4-lane road. Potholes dot the ashphalt road, while cracks line the footpaths on either side " ,
description_less_explicit : None ,
grid_coords : GridCoords { x : 1 , y : 7 , z : 0 } ,
exits : vec ! (
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
code : " melbs_kingst_100 " ,
name : " King Street - 100 block " ,
short : ansi ! ( " <yellow>||<reset> " ) ,
description : " A wide road (5 lanes each way) that has been rather poorly maintained. Potholes dot the ashphalt road, while cracks line the footpaths on either side " ,
description_less_explicit : None ,
grid_coords : GridCoords { x : 1 , y : 8 , z : 0 } ,
exits : vec ! (
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
code : " melbs_kingst_110 " ,
name : " King Street - 110 block " ,
short : ansi ! ( " <yellow>||<reset> " ) ,
description : " A wide road (5 lanes each way) that has been rather poorly maintained. Potholes dot the ashphalt road, while cracks line the footpaths on either side " ,
description_less_explicit : None ,
grid_coords : GridCoords { x : 1 , y : 9 , z : 0 } ,
exits : vec ! (
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
code : " melbs_kingst_120 " ,
name : " King Street - 120 block " ,
short : ansi ! ( " <yellow>||<reset> " ) ,
description : " A wide road (5 lanes each way) that has been rather poorly maintained. Potholes dot the ashphalt road, while cracks line the footpaths on either side " ,
description_less_explicit : None ,
grid_coords : GridCoords { x : 1 , y : 10 , z : 0 } ,
exits : vec ! (
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
Exit {
direction : Direction ::SOUTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
Room {
zone : " melbs " ,
secondary_zones : vec ! ( ) ,
code : " melbs_kingst_flinderst " ,
name : " King Street & Flinders St " ,
short : ansi ! ( " <yellow>##<reset> " ) ,
description : " A wide road (5 lanes each way) intersects a wide road with rusted tram tracks in the middle. Potholes dot the ashphalt road. " ,
description_less_explicit : None ,
grid_coords : GridCoords { x : 1 , y : 11 , z : 0 } ,
exits : vec ! (
Exit {
direction : Direction ::NORTH ,
target : ExitTarget ::UseGPS ,
exit_type : ExitType ::Free
} ,
)
} ,
2022-12-27 23:35:27 +11:00
) . into_iter ( ) . collect ( ) )
}
static STATIC_ROOM_MAP_BY_CODE : OnceCell < BTreeMap < & 'static str , & 'static Room > > = OnceCell ::new ( ) ;
pub fn room_map_by_code ( ) -> & 'static BTreeMap < & 'static str , & 'static Room > {
STATIC_ROOM_MAP_BY_CODE . get_or_init (
| | room_list ( ) . iter ( ) . map ( | r | ( r . code , r ) ) . collect ( ) )
}
2022-12-29 18:44:50 +11:00
static STATIC_ROOM_MAP_BY_ZLOC : OnceCell < BTreeMap < ( & 'static str , & 'static GridCoords ) ,
& 'static Room > > = OnceCell ::new ( ) ;
pub fn room_map_by_zloc ( ) -> & 'static BTreeMap < ( & 'static str , & 'static GridCoords ) , & 'static Room > {
STATIC_ROOM_MAP_BY_ZLOC . get_or_init (
2023-01-01 00:09:25 +11:00
| | room_list ( ) . iter ( )
. map ( | r | ( ( r . zone , & r . grid_coords ) , r ) )
. chain ( room_list ( ) . iter ( )
. flat_map ( | r | r . secondary_zones . iter ( )
. map ( | sz | ( ( sz . zone , & sz . grid_coords ) , r ) )
. collect ::< Vec < ( ( & 'static str , & 'static GridCoords ) , & 'static Room ) > > ( ) ) )
. collect ( ) )
2022-12-29 00:37:14 +11:00
}
2022-12-27 23:35:27 +11:00
pub fn room_static_items ( ) -> Box < dyn Iterator < Item = StaticItem > > {
Box ::new ( room_list ( ) . iter ( ) . map ( | r | StaticItem {
item_code : r . code ,
initial_item : Box ::new ( | | Item {
item_code : r . code . to_owned ( ) ,
item_type : " room " . to_owned ( ) ,
2022-12-29 18:44:50 +11:00
display : r . name . to_owned ( ) ,
2022-12-31 00:59:14 +11:00
details : Some ( r . description . to_owned ( ) ) ,
details_less_explicit : r . description_less_explicit . map ( | d | d . to_owned ( ) ) ,
location : format ! ( " zone/{} " , r . zone ) ,
2022-12-27 23:35:27 +11:00
is_static : true ,
.. Item ::default ( )
} )
} ) )
}
2022-12-29 18:44:50 +11:00
pub fn resolve_exit ( room : & Room , exit : & Exit ) -> Option < & 'static Room > {
match exit . target {
ExitTarget ::Custom ( t ) = > t . split_once ( " / " ) . and_then (
| ( t , c ) |
if t ! = " room " {
None
} else {
room_map_by_code ( ) . get ( c ) . map ( | r | * r )
} ) ,
ExitTarget ::UseGPS = >
room_map_by_zloc ( ) . get ( & ( room . zone , & room . grid_coords . apply ( & exit . direction ) ) ) . map ( | r | * r )
}
}
2022-12-27 23:35:27 +11:00
#[ cfg(test) ]
mod test {
use super ::* ;
#[ test ]
fn room_zones_should_exist ( ) {
for room in room_list ( ) {
zone_details ( ) . get ( room . zone ) . expect (
& format! ( " zone {} for room {} should exist " , room . zone , room . code ) ) ;
}
}
#[ test ]
fn room_map_by_code_should_have_repro_xv_chargen ( ) {
assert_eq! ( room_map_by_code ( ) . get ( " repro_xv_chargen " ) . expect ( " repro_xv_chargen to exist " ) . code ,
" repro_xv_chargen " ) ;
}
2022-12-27 20:16:35 +11:00
}