256 lines
6.0 KiB
Rust
256 lines
6.0 KiB
Rust
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<String>,
|
|
// integer: Option<u64>,
|
|
// palette: Option<String>,
|
|
// room: Option<String>,
|
|
// script: Option<String>,
|
|
// string: Option<String>,
|
|
// thing: Option<String>,
|
|
// variable: Option<String>,
|
|
// }
|
|
//
|
|
// #[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<String>,
|
|
// params: Vec<Parameter>,
|
|
// script: String,
|
|
// }
|
|
//
|
|
// #[derive(Serialize, Deserialize)]
|
|
// pub struct ScriptInstance {
|
|
// script: String,
|
|
// params: HashMap<String, Value>,
|
|
// }
|
|
//
|
|
// #[derive(Serialize, Deserialize)]
|
|
// pub struct ScriptCollection {
|
|
// scripts: Vec<ScriptInstance>,
|
|
// /// as well as many named scripts, a trigger can have one anonymous script
|
|
// anonymous: Option<String>,
|
|
// }
|
|
//
|
|
// #[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<Palette>,
|
|
pub images: Vec<Image>,
|
|
pub tiles: Vec<Tile>,
|
|
pub entities: Vec<Entity>,
|
|
// pub variables: Vec<Variable>,
|
|
// pub triggers: HashMap<String, ScriptCollection>,
|
|
pub music: Vec<Music>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct GameParseError;
|
|
|
|
impl Game {
|
|
pub fn from_dir(path: PathBuf) -> Result<Game, GameParseError> {
|
|
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
|
|
}
|
|
}
|