diff --git a/src/lib.rs b/src/lib.rs index e3226ad..9afd193 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,12 @@ pub struct Position { y: u8, } +impl Position { + pub fn to_index(&self, width: u8) -> u16 { + (self.y * width + self.x) as u16 + } +} + // #[derive(Serialize, Deserialize)] // pub enum DataType { // Image, @@ -100,10 +106,11 @@ pub struct Position { pub struct Game { pub config: Config, - pub palettes: Vec, - pub images: Vec, - pub tiles: Vec, pub entities: Vec, + pub images: Vec, + pub palettes: Vec, + pub scenes: Vec, + pub tiles: Vec, // pub variables: Vec, // pub triggers: HashMap, pub music: Vec, @@ -113,12 +120,32 @@ pub struct Game { pub struct GameParseError; impl Game { + pub fn new() -> Self { + Self { + config: Config { + name: None, + width: 16, + height: 9, + tick: 400, + starting_room: None, + version: (0, 1) + }, + entities: vec![], + images: vec![], + palettes: vec![], + scenes: vec![], + tiles: vec![], + music: vec![] + } + } + 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 scenes = Vec::new(); let mut music_dir = path.clone(); music_dir.push("music"); @@ -176,6 +203,17 @@ impl Game { entities.push(Entity::from_file(file.path())); } + let mut scenes_dir = path.clone(); + scenes_dir.push("scenes"); + + let scenes_files = scenes_dir.read_dir() + .expect("couldn't read scene dir"); + + for file in scenes_files { + let file = file.unwrap(); + scenes.push(Scene::from_file(file.path())); + } + let mut game_config = path.clone(); game_config.push("game.toml"); let config = fs::read_to_string(game_config) @@ -183,7 +221,7 @@ impl Game { let config: Config = toml::from_str(&config) .expect("Couldn't parse game config"); - Ok(Game { config, images, tiles, palettes, music, entities }) + Ok(Game { config, images, tiles, palettes, music, entities, scenes }) } // todo Result<&Image>? @@ -213,7 +251,7 @@ impl Game { pub fn get_entity_by_name(&self, name: String) -> Option<&Entity> { for entity in self.entities.iter() { if entity.name == name { - return Some(&entity); + return Some(entity); } } @@ -224,7 +262,7 @@ impl Game { pub fn get_music_by_name(&self, name: String) -> Option<&Music> { for music in self.music.iter() { if music.name == name { - return Some(&music); + return Some(music); } } @@ -232,10 +270,10 @@ impl Game { } // todo Result<&Palette>? - pub fn get_palette_by_name(&self, name: String) -> Option<&Palette> { - for palette in self.palettes.iter() { + pub fn find_palette(&mut self, name: &str) -> Option<&mut Palette> { + for palette in self.palettes.iter_mut() { if palette.name == name { - return Some(&palette); + return Some(palette); } } @@ -246,10 +284,48 @@ impl Game { pub fn get_tile_by_name(&self, name: String) -> Option<&Tile> { for tile in self.tiles.iter() { if tile.name == name { - return Some(&tile); + return Some(tile); } } None } + + pub fn get_scene_by_name(&mut self, name: String) -> Option<&mut Scene> { + for scene in self.scenes.iter_mut() { + if scene.name == name { + return Some(scene); + } + } + + None + } + + pub fn remove_entity(&mut self, scene_name: String, position: Position) { + let width = self.config.width.clone(); + self.get_scene_by_name(scene_name).unwrap() + .foreground[position.to_index(width) as usize] = None; + } +} + +#[cfg(test)] +mod test { + use crate::{Position, Game}; + + #[test] + fn position_to_index() { + assert_eq!(Position { x: 1, y: 5 }.to_index(8), 41); + assert_eq!(Position { x: 0, y: 0 }.to_index(8), 0); + } + + #[test] + fn remove_entity() { + let mut game = Game::new(); + + game.scenes.push(crate::mock::scenes::zero()); + + game.remove_entity("zero".into(), Position { x: 1, y: 1 }); + + assert_eq!(game.scenes[0].foreground[9], None); + } }