#![allow(dead_code, clippy::doc_markdown, unused_imports, unused_variables)]
#![cfg_attr(feature = "dev", feature(plugin, custom_attribute))]
#![cfg_attr(feature = "dev", plugin(flamer))]
#[cfg(feature = "dev")]
extern crate flame;
#[macro_use]
extern crate failure;
#[macro_use]
extern crate lazy_static;
extern crate num;
extern crate num_traits;
extern crate over;
extern crate rand;
extern crate tcod;
#[macro_use]
pub mod util;
pub mod actor;
pub mod console;
pub mod coord;
pub mod database;
pub mod defs;
pub mod dungeon;
pub mod error;
pub mod game_data;
pub mod generate;
pub mod item;
pub mod material;
pub mod name_gen;
pub mod object;
pub mod player;
pub mod tile;
pub mod ui;
mod constants;
#[cfg(test)]
mod tests;
use crate::console::DrawConsole;
use crate::database::{load_data, Database};
use crate::dungeon::{Dungeon, DungeonList};
use crate::error::GameError;
use crate::game_data::{GameData, GameLoopOutcome};
use std::sync::{Arc, Mutex, RwLock};
pub type GameResult<T> = Result<T, failure::Error>;
lazy_static! {
static ref DATABASE: RwLock<Database> = {
RwLock::new(handle_error(dev_time!(load_data(), "Loading database...")))
};
static ref GAMEDATA: RwLock<GameData> = {
RwLock::new(handle_error(GameData::new()))
};
pub static ref CONSOLE: Mutex<DrawConsole> = {
let game_data = GAMEDATA.read().unwrap();
Mutex::new(dev_time!(DrawConsole::new(&game_data.console_settings),
"Initializing draw console..."))
};
}
pub fn run_game() -> GameResult<()> {
lazy_static::initialize(&DATABASE);
lazy_static::initialize(&GAMEDATA);
lazy_static::initialize(&CONSOLE);
#[cfg(feature = "dev")]
for race in &["human", "elf", "dwarf", "dragon"] {
let name_profile = DATABASE
.read()
.unwrap()
.get_obj("name_profiles")?
.get_obj(race)?;
println!("{} names:", util::string::capitalize(race));
for _ in 1..10 {
println!("{}", name_gen::name_gen(&name_profile)?);
}
println!();
}
let mut dungeon_list = init_new_game()?;
loop {
let dungeon = dungeon_list.current_dungeon();
debug_assert!(dungeon.num_actors() > 0);
match dungeon.run_loop() {
GameLoopOutcome::DepthChanged => {
unimplemented!(); }
GameLoopOutcome::WindowClosed => {
println!("\nWindow closed. Goodbye!");
break;
}
GameLoopOutcome::PlayerDead => {
unimplemented!(); }
GameLoopOutcome::QuitGame => {
println!("\nQuitting. Goodbye!");
break;
}
GameLoopOutcome::NoActors => {
unreachable!();
}
GameLoopOutcome::None => {
unimplemented!(); }
}
}
Ok(())
}
fn init_new_game() -> GameResult<DungeonList> {
let dungeon_list = dev_time!(DungeonList::new()?, "Generating game world...");
Ok(dungeon_list)
}
pub fn handle_error<T>(result: Result<T, failure::Error>) -> T {
if let Err(error) = result {
println!("------");
println!("Error:");
let mut i = 1;
for cause in error.causes() {
println!("{}{}", " ".repeat(i), cause);
i += 1;
}
println!("------");
::std::process::exit(1);
}
result.unwrap()
}