113 lines
4.2 KiB
Rust
113 lines
4.2 KiB
Rust
use std::{collections::HashMap, io::BufReader, path::PathBuf, time::Duration};
|
|
|
|
use definitions::parser::DefinitionParser;
|
|
use sim::{Creature, Site, SiteArea, World};
|
|
|
|
pub mod definitions;
|
|
pub mod sim;
|
|
|
|
const SAVE_FILE: &str = "world.bin";
|
|
|
|
fn main() {
|
|
let mut parse_error_files = vec![];
|
|
let mut site_definitions = HashMap::new();
|
|
let mut creature_definitions = HashMap::new();
|
|
for entry in std::fs::read_dir(resources_path()).unwrap().flatten() {
|
|
if entry.file_name().to_string_lossy().ends_with(".def") {
|
|
let source = BufReader::new(std::fs::File::open(entry.path()).unwrap());
|
|
match DefinitionParser::parse(source) {
|
|
Ok(defs) => {
|
|
for def in defs.0 {
|
|
if let Some(prev) = site_definitions.insert(def.id.clone(), def) {
|
|
eprintln!("Duplicate site definition '{}'", prev.id);
|
|
}
|
|
}
|
|
for def in defs.1 {
|
|
if let Some(prev) = creature_definitions.insert(def.id.clone(), def) {
|
|
eprintln!("Duplicate site definition '{}'", prev.id);
|
|
}
|
|
}
|
|
}
|
|
Err(err) => {
|
|
parse_error_files.push((err, entry.path()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (err, path) in parse_error_files.iter() {
|
|
eprintln!("Error\t{path:?}\n\t{err:?}")
|
|
}
|
|
if !parse_error_files.is_empty() {
|
|
eprintln!("{} file(s) had parsing errors!", parse_error_files.len())
|
|
}
|
|
|
|
let site_def = site_definitions.get("CAVE").unwrap();
|
|
let mut world = match std::fs::read(SAVE_FILE) {
|
|
Ok(data) => bincode::deserialize(&data).expect("Loading world data from file"),
|
|
Err(_) => {
|
|
let mut world = World::default();
|
|
|
|
let mut site = Site::generate_from_def(site_def);
|
|
site.populate_randomly(&creature_definitions.values().collect::<Vec<_>>());
|
|
|
|
let bandit_def = creature_definitions.get("BANDIT").unwrap();
|
|
let spider_def = creature_definitions.get("SPIDER").unwrap();
|
|
let site = Site::new(
|
|
site_def.clone(),
|
|
"Gorbo's cave",
|
|
vec![
|
|
SiteArea::from_creatures(&vec![
|
|
Creature::generate_from_def(
|
|
creature_definitions.get("DRAGON").unwrap().clone(),
|
|
),
|
|
Creature::generate_from_def(
|
|
creature_definitions.get("INDESTRUCTIBLE").unwrap().clone(),
|
|
),
|
|
]),
|
|
SiteArea::from_creatures(&vec![
|
|
Creature::generate_from_def(bandit_def.clone()),
|
|
Creature::generate_from_def(spider_def.clone()),
|
|
]),
|
|
SiteArea::from_creatures(&vec![
|
|
Creature::generate_from_def(bandit_def.clone()),
|
|
Creature::generate_from_def(bandit_def.clone()),
|
|
Creature::generate_from_def(bandit_def.clone()),
|
|
]),
|
|
SiteArea::from_creatures(&vec![
|
|
Creature::generate_from_def(spider_def.clone()),
|
|
Creature::generate_from_def(spider_def.clone()),
|
|
]),
|
|
],
|
|
);
|
|
|
|
world.sites.push(site);
|
|
std::fs::write("world.bin", bincode::serialize(&world).unwrap()).unwrap();
|
|
world
|
|
}
|
|
};
|
|
|
|
for site in world.sites.iter() {
|
|
println!("{site}")
|
|
}
|
|
|
|
let mut input = String::new();
|
|
loop {
|
|
std::io::stdin().read_line(&mut input).unwrap();
|
|
if ["q", "quit", "exit"]
|
|
.iter()
|
|
.any(|quit_cmd| input.trim() == *quit_cmd)
|
|
{
|
|
break;
|
|
}
|
|
let start = std::time::Instant::now();
|
|
world.advance_time(Duration::from_secs(3600));
|
|
let end = std::time::Instant::now();
|
|
println!("World tick: {}us", (end - start).as_micros());
|
|
}
|
|
}
|
|
|
|
fn resources_path() -> PathBuf {
|
|
PathBuf::from(".").join("defs")
|
|
}
|