From e688da14ae59212b983b253c276092ac2e3202bd Mon Sep 17 00:00:00 2001 From: rascul Date: Sun, 20 Feb 2022 11:24:58 -0600 Subject: [PATCH] split stuff up into multiple files --- src/environment.rs | 126 ++++++++++++++++ src/main.rs | 318 ++++++++++++++++------------------------- src/mudlet/area.rs | 21 +++ src/mudlet/exit.rs | 16 +++ src/mudlet/mod.rs | 9 ++ src/mudlet/room.rs | 22 +++ src/mudlet/userdata.rs | 17 +++ src/tintin/exit.rs | 29 ++++ src/tintin/mod.rs | 5 + src/tintin/room.rs | 43 ++++++ 10 files changed, 408 insertions(+), 198 deletions(-) create mode 100644 src/environment.rs create mode 100644 src/mudlet/area.rs create mode 100644 src/mudlet/exit.rs create mode 100644 src/mudlet/mod.rs create mode 100644 src/mudlet/room.rs create mode 100644 src/mudlet/userdata.rs create mode 100644 src/tintin/exit.rs create mode 100644 src/tintin/mod.rs create mode 100644 src/tintin/room.rs diff --git a/src/environment.rs b/src/environment.rs new file mode 100644 index 0000000..ba0bb91 --- /dev/null +++ b/src/environment.rs @@ -0,0 +1,126 @@ +//! Room environment + +use serde_derive::Deserialize; + +/// Type of environment for the room +#[derive(Debug, Deserialize)] +pub enum Environment { + /// Inside a building + Inside, + + /// Out in the wild + Wilderness, + + /// On a road + Road, + + /// Horse load + Horse, + + /// In a swamp + Swamp, + + /// In the water + Water, + + /// A drinking source + Drink, + + /// Weapon shop + Weaponsmith, + + /// Armor shop + Armorer, + + /// Master blacksmith + Blacksmith, + + /// Bank + Bank, + + /// Stables + Stables, + + /// Place to rent + Rent, + + /// Grocer + Grocer, + + /// Warrior practice + Warrior, + + /// Rogue practice + Rogue, + + /// Hunter practice + Hunter, + + /// Possible PK objective + Pk, + + /// Other + Other, +} + +impl From for Environment { + fn from(num: i64) -> Self { + match num { + 20 => Self::Inside, + 21 => Self::Wilderness, + 22 => Self::Road, + 23 => Self::Horse, + 24 => Self::Swamp, + 25 => Self::Water, + 26 => Self::Drink, + 27 => Self::Weaponsmith, + 28 => Self::Armorer, + 29 => Self::Blacksmith, + 30 => Self::Bank, + 31 => Self::Stables, + 32 => Self::Rent, + 33 => Self::Grocer, + 34 => Self::Warrior, + 35 => Self::Rogue, + 36 => Self::Hunter, + 37 => Self::Pk, + _ => Self::Other, + } + } +} + +impl Environment { + /// Some room environments have a symbol to put in the room on the map + pub fn symbol(&self) -> String { + match self { + Self::Horse => "H", + Self::Drink => "D", + Self::Weaponsmith => "W", + Self::Armorer => "A", + Self::Blacksmith => "B", + Self::Bank => "$", + Self::Stables => "S", + Self::Rent => "R", + Self::Grocer => "G", + Self::Warrior => "W", + Self::Rogue => "R", + Self::Hunter => "H", + Self::Pk => "P", + _ => "", + } + .to_string() + } + + /// Color of the room + pub fn color(&self) -> String { + match self { + Self::Inside => "", + Self::Wilderness => "", + Self::Road => "", + Self::Swamp => "", + Self::Water => "", + _ => "", + } + .to_string() + } +} diff --git a/src/main.rs b/src/main.rs index 7095743..c7dc30b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,207 +1,129 @@ -use std::collections::{BTreeMap, HashMap}; +mod environment; +mod mudlet; +mod tintin; + +use std::collections::BTreeMap; use std::error::Error; use std::io; use std::io::Read; -use serde_derive::Deserialize; use serde_json::Value; -#[derive(Debug, Deserialize)] -struct MudletMap { - /// area id - id: i64, - - /// area name - name: String, - - /// rooms - rooms: Vec, - - #[serde(flatten)] - _extra: HashMap, -} - -#[derive(Debug, Deserialize)] -struct MudletRoom { - /// exits - exits: Vec, - - /// room number - id: i64, - - /// room name - name: String, - - /// user data - userData: MudletUserData, - - #[serde(flatten)] - _extra: HashMap, -} - -#[derive(Debug, Deserialize)] -struct MudletExit { - /// connected room - exitId: i64, - - /// direction - name: String, - - #[serde(flatten)] - _extra: HashMap, -} - -#[derive(Debug, Deserialize)] -struct MudletUserData { - /// room description - description: String, - - /// zone name - zone: String, - - #[serde(flatten)] - _extra: HashMap, -} - -#[derive(Debug)] -struct TinTinRoom { - /// room number - vnum: i64, - - /// flags - flags: i64, - - /// color - color: String, - - /// room name - name: String, - - /// room symbol - symbol: char, - - /// room description - desc: String, - - /// area that room is in - area: String, - - /// notes - note: String, - - /// type of terrain - terrain: String, - - /// extra data - data: String, - - /// movement cost - weight: f64, - - /// room id - id: String, - - /// exits - exits: Vec, -} - -#[derive(Debug)] -struct TinTinExit { - /// vnum - vnum: i64, - - /// exit name - name: String, - - /// command to use the exit - cmd: String, - - /// exit direction - dir: i8, - - /// exit flags - flags: i64, - - /// extra data - data: String, - - /// movement cost? - weight: f64, - - /// exit color - color: String, - - /// decay? - decay: f64, -} +use environment::Environment; fn main() -> Result<(), Box> { - let mut buffer = String::new(); - let mut stdin = io::stdin(); - stdin.read_to_string(&mut buffer)?; - - let mudlet_map: MudletMap = serde_json::from_str(&buffer)?; - - let mut tintin_rooms: BTreeMap = BTreeMap::new(); - - for mudlet_room in mudlet_map.rooms { - let mut tintin_exits: Vec = Vec::new(); - - for mudlet_exit in mudlet_room.exits { - let (dir_num, dir_short) = match mudlet_exit.name.as_str() { - "north" => (1, 'n'), - "east" => (2, 'e'), - "south" => (4, 's'), - "west" => (8, 'w'), - "up" => (16, 'u'), - "down" => (32, 'd'), - _ => panic!("Unknown exit: {}", mudlet_exit.name), - }; - - let tintin_exit = TinTinExit { - vnum: mudlet_exit.exitId, - name: dir_short.into(), - cmd: dir_short.into(), - dir: dir_num, - flags: 0, - data: String::new(), - weight: 1.0, - color: String::new(), - decay: 0.0, - }; - - tintin_exits.push(tintin_exit); - } - - let tintin_room = TinTinRoom { - vnum: mudlet_room.id, - flags: 0, - color: String::new(), - name: mudlet_room.name, - symbol: ' ', - desc: mudlet_room.userData.description.replace("\n", " ").replace (" ", " "), - area: mudlet_room.userData.zone, - note: String::new(), - terrain: String::new(), - data: String::new(), - weight: 1.0, - id: String::new(), - exits: tintin_exits, - }; - - tintin_rooms.insert(tintin_room.vnum, tintin_room); - } - - for (vnum, room) in tintin_rooms { - println!("R {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}}", vnum, room.flags, room.color, room.name, room.symbol, room.desc, room.area, room.note, room.terrain, room.data, room.weight, room.id); - - for exit in room.exits { - println!("E {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}}", exit.vnum, exit.name, exit.cmd, exit.dir, exit.flags, exit.data, exit.weight, exit.color, exit.decay); - } - - println!(); - } - - Ok(()) - + let mut buffer = String::new(); + let mut stdin = io::stdin(); + stdin.read_to_string(&mut buffer)?; + + let mudlet_map: Value = serde_json::from_str(&buffer)?; + + let areas = match mudlet_map.get("areas") { + Some(areas) => match areas.as_array() { + Some(areas) => areas, + None => panic!("Areas not an array"), + }, + None => panic!("No areas found"), + }; + + for area in areas { + let id: i64 = match area.get("id") { + Some(id) => match id.as_i64() { + Some(id) => id, + None => continue, + }, + None => continue, + }; + + if id < 0 { + continue; + } + + let mudlet_area: mudlet::Area = serde_json::from_value(area.to_owned())?; + + // hold the tintin version of the rooms + let mut tintin_rooms: BTreeMap = BTreeMap::new(); + + for mudlet_room in mudlet_area.rooms { + // hold the tintin version of room exits + let mut tintin_exits: Vec = Vec::new(); + + for mudlet_exit in mudlet_room.exits { + // map the exit direction + let (dir_num, dir_short) = match mudlet_exit.name.as_str() { + "north" => (1, 'n'), + "east" => (2, 'e'), + "south" => (4, 's'), + "west" => (8, 'w'), + "up" => (16, 'u'), + "down" => (32, 'd'), + _ => panic!("Unknown exit: {}", mudlet_exit.name), + }; + + // create a tintin exit from the mudlet exit + let tintin_exit = tintin::Exit { + vnum: mudlet_exit.exitId, + name: dir_short.into(), + cmd: dir_short.into(), + dir: dir_num, + flags: 0, + data: String::new(), + weight: 1.0, + color: String::new(), + decay: 0.0, + }; + + // add tintin exit to list of tintin exits for the room + tintin_exits.push(tintin_exit); + } + + let userdata = match mudlet_room.userData { + Some(userdata) => userdata, + None => continue, + }; + + let environment = Environment::from(mudlet_room.environment); + + let tintin_room = tintin::Room { + vnum: mudlet_room.id, + flags: 0, + color: environment.color(), + name: mudlet_room.name, + symbol: environment.symbol(), + desc: userdata.description.replace("\n", " ").replace(" ", " "), + area: userdata.zone, + note: String::new(), + terrain: String::new(), + data: String::new(), + weight: 1.0, + id: String::new(), + exits: tintin_exits, + }; + + tintin_rooms.insert(tintin_room.vnum, tintin_room); + } + + for (vnum, room) in tintin_rooms { + println!("R {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}}", vnum, room.flags, room.color, room.name, room.symbol, room.desc, room.area, room.note, room.terrain, room.data, room.weight, room.id); + + for exit in room.exits { + println!( + "E {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}} {{{}}}", + exit.vnum, + exit.name, + exit.cmd, + exit.dir, + exit.flags, + exit.data, + exit.weight, + exit.color, + exit.decay + ); + } + + println!(); + } + } + + Ok(()) } diff --git a/src/mudlet/area.rs b/src/mudlet/area.rs new file mode 100644 index 0000000..1a5f51f --- /dev/null +++ b/src/mudlet/area.rs @@ -0,0 +1,21 @@ +use std::collections::HashMap; + +use serde_derive::Deserialize; +use serde_json::Value; + +use crate::mudlet; + +#[derive(Debug, Deserialize)] +pub struct Area { + /// area id + //id: i64, + + /// area name + //name: String, + + /// rooms + pub rooms: Vec, + + #[serde(flatten)] + _extra: HashMap, +} diff --git a/src/mudlet/exit.rs b/src/mudlet/exit.rs new file mode 100644 index 0000000..a36c822 --- /dev/null +++ b/src/mudlet/exit.rs @@ -0,0 +1,16 @@ +use std::collections::HashMap; + +use serde_derive::Deserialize; +use serde_json::Value; + +#[derive(Debug, Deserialize)] +pub struct Exit { + /// connected room + pub exitId: i64, + + /// direction + pub name: String, + + #[serde(flatten)] + _extra: HashMap, +} diff --git a/src/mudlet/mod.rs b/src/mudlet/mod.rs new file mode 100644 index 0000000..d5dca50 --- /dev/null +++ b/src/mudlet/mod.rs @@ -0,0 +1,9 @@ +mod area; +mod exit; +mod room; +mod userdata; + +pub use area::Area; +pub use exit::Exit; +pub use room::Room; +pub use userdata::UserData; diff --git a/src/mudlet/room.rs b/src/mudlet/room.rs new file mode 100644 index 0000000..b5fd2b4 --- /dev/null +++ b/src/mudlet/room.rs @@ -0,0 +1,22 @@ +use serde_derive::Deserialize; + +use crate::mudlet; + +#[derive(Debug, Deserialize)] +pub struct Room { + /// environment + pub environment: i64, + + /// exits + pub exits: Vec, + + /// room number + pub id: i64, + + /// room name + #[serde(default)] + pub name: String, + + /// user data + pub userData: Option, +} diff --git a/src/mudlet/userdata.rs b/src/mudlet/userdata.rs new file mode 100644 index 0000000..1b0ecc4 --- /dev/null +++ b/src/mudlet/userdata.rs @@ -0,0 +1,17 @@ +use std::collections::HashMap; + +use serde_derive::Deserialize; +use serde_json::Value; + +#[derive(Debug, Deserialize)] +pub struct UserData { + /// room description + pub description: String, + + /// zone name + #[serde(default)] + pub zone: String, + + #[serde(flatten)] + _extra: HashMap, +} diff --git a/src/tintin/exit.rs b/src/tintin/exit.rs new file mode 100644 index 0000000..11f12c9 --- /dev/null +++ b/src/tintin/exit.rs @@ -0,0 +1,29 @@ +#[derive(Debug)] +pub struct Exit { + /// vnum + pub vnum: i64, + + /// exit name + pub name: String, + + /// command to use the exit + pub cmd: String, + + /// exit direction + pub dir: i8, + + /// exit flags + pub flags: i64, + + /// extra data + pub data: String, + + /// movement cost? + pub weight: f64, + + /// exit color + pub color: String, + + /// decay? + pub decay: f64, +} diff --git a/src/tintin/mod.rs b/src/tintin/mod.rs new file mode 100644 index 0000000..04c7c4d --- /dev/null +++ b/src/tintin/mod.rs @@ -0,0 +1,5 @@ +mod exit; +mod room; + +pub use exit::Exit; +pub use room::Room; diff --git a/src/tintin/room.rs b/src/tintin/room.rs new file mode 100644 index 0000000..a4866f1 --- /dev/null +++ b/src/tintin/room.rs @@ -0,0 +1,43 @@ +use crate::tintin; + +#[derive(Debug)] +pub struct Room { + /// room number + pub vnum: i64, + + /// flags + pub flags: i64, + + /// color + pub color: String, + + /// room name + pub name: String, + + /// room symbol + pub symbol: String, + + /// room description + pub desc: String, + + /// area that room is in + pub area: String, + + /// notes + pub note: String, + + /// type of terrain + pub terrain: String, + + /// extra data + pub data: String, + + /// movement cost + pub weight: f64, + + /// room id + pub id: String, + + /// exits + pub exits: Vec, +}