use std::fs; use std::path::PathBuf; mod colour; mod config; mod entity; mod image; mod mock; mod music; mod palette; mod scene; mod tile; pub use colour::Colour; pub use config::Config; pub use entity::Entity; pub use crate::image::Image; pub use music::Music; pub use palette::Palette; pub use scene::Scene; pub use tile::Tile; #[derive(Debug, Eq, Hash, PartialEq)] pub struct Position { x: u8, y: u8, } // #[derive(Serialize, Deserialize)] // pub enum DataType { // Image, // Integer, // Palette, // Room, // Script, // String, // Thing, // Variable, // } // // /// todo refactor, this is stupid // #[derive(Serialize, Deserialize)] // pub struct Value { // data_type: DataType, // image: Option, // integer: Option, // palette: Option, // room: Option, // script: Option, // string: Option, // thing: Option, // variable: Option, // } // // #[derive(Serialize, Deserialize)] // pub struct Variable { // name: String, // data_type: DataType, // default: Value, // } // // #[derive(Serialize, Deserialize)] // pub struct Parameter { // name: String, // data_type: DataType, // default: Value, // } // // #[derive(Serialize, Deserialize)] // pub struct Script { // name: Option, // params: Vec, // script: String, // } // // #[derive(Serialize, Deserialize)] // pub struct ScriptInstance { // script: String, // params: HashMap, // } // // #[derive(Serialize, Deserialize)] // pub struct ScriptCollection { // scripts: Vec, // /// as well as many named scripts, a trigger can have one anonymous script // anonymous: Option, // } // // #[derive(Serialize, Deserialize)] // pub struct Version { // major: u8, // minor: u8, // } // // impl Version { // pub fn default() -> Version { // Version { major: 0, minor: 1 } // } // } pub struct Game { pub config: Config, pub palettes: Vec, pub images: Vec, pub tiles: Vec, pub entities: Vec, // pub variables: Vec, // pub triggers: HashMap, pub music: Vec, } #[derive(Debug)] pub struct GameParseError; impl Game { pub fn from_dir(path: PathBuf) -> Result { let mut images = Vec::new(); let mut tiles = Vec::new(); let mut entities = Vec::new(); let mut music = Vec::new(); let mut palettes = Vec::new(); let mut music_dir = path.clone(); music_dir.push("music"); let music_files = music_dir.read_dir(); if music_files.is_ok() { for file in music_files.unwrap() { let file = file.unwrap(); music.push(Music::from_file(file.path())); } } let mut palettes_dir = path.clone(); palettes_dir.push("palettes"); let palette_files = palettes_dir.read_dir() .expect("couldn't read palettes dir"); for file in palette_files { let file = file.unwrap(); palettes.push(Palette::from_file(file.path())); } let mut images_dir = path.clone(); images_dir.push("images"); let image_files = images_dir.read_dir() .expect("couldn't read image dir"); for file in image_files { let file = file.unwrap(); images.push(Image::from_file(file.path())); } let mut tiles_dir = path.clone(); tiles_dir.push("tiles"); let tiles_files = tiles_dir.read_dir() .expect("couldn't read tile dir"); for file in tiles_files { let file = file.unwrap(); tiles.push(Tile::from_file(file.path())); } let mut entities_dir = path.clone(); entities_dir.push("entities"); let entities_files = entities_dir.read_dir() .expect("couldn't read tile dir"); for file in entities_files { let file = file.unwrap(); entities.push(Entity::from_file(file.path())); } let mut game_config = path.clone(); game_config.push("game.toml"); let config = fs::read_to_string(game_config) .expect("Couldn't load game config"); let config: Config = toml::from_str(&config) .expect("Couldn't parse game config"); Ok(Game { config, images, tiles, palettes, music, entities }) } // todo Result<&Image>? pub fn get_image_by_name(&self, name: String) -> Option<&Image> { for image in self.images.iter() { if image.name == name { return Some(&image); } } None } pub fn get_entities_by_tag(&self, tag: &String) -> Vec<&Entity> { let mut entities = Vec::new(); for entity in self.entities.iter() { if entity.tags.contains(tag) { entities.push(entity); } } entities } // todo Result<&Entity>? pub fn get_entity_by_name(&self, name: String) -> Option<&Entity> { for entity in self.entities.iter() { if entity.name == name { return Some(&entity); } } None } // todo Result<&Music>? pub fn get_music_by_name(&self, name: String) -> Option<&Music> { for music in self.music.iter() { if music.name == name { return Some(&music); } } None } // todo Result<&Palette>? pub fn get_palette_by_name(&self, name: String) -> Option<&Palette> { for palette in self.palettes.iter() { if palette.name == name { return Some(&palette); } } None } // todo Result<&Tile>? pub fn get_tile_by_name(&self, name: String) -> Option<&Tile> { for tile in self.tiles.iter() { if tile.name == name { return Some(&tile); } } None } }