use std::{env, thread, time};
use crate::{floor::Floor, unit::UnitType, Player};
#[cfg(feature = "ncurses")]
pub mod curses;
pub mod systems;
pub mod world;
use systems::{player_system, shooter_system, sludge_system, ui_system};
use world::World;
const DEFAULT_GAME_LOOP_DELAY: u64 = 1000;
pub fn start(
player_name: String,
warrior_level: usize,
floor: Floor,
player_generator: fn() -> Box<dyn Player + Send + Sync>,
) -> Result<(), String> {
let player = player_generator();
#[cfg(feature = "ncurses")]
let mut c = curses::Curses::new();
#[cfg(not(feature = "ncurses"))]
println!("{}", floor.draw());
let mut step = 0;
let mut warrior = None;
let mut other_units = Vec::new();
for unit in &floor.units {
match unit.unit_type {
UnitType::Warrior => {
warrior = Some(unit.clone());
}
_ => {
other_units.push(unit.clone());
}
}
}
let warrior = warrior.unwrap();
let mut world = World::new(
player_name,
warrior_level,
floor,
player,
warrior,
other_units,
);
let override_delay = env::var("GAME_LOOP_DELAY")
.ok()
.and_then(|s| s.parse::<u64>().ok());
loop {
step += 1;
if step > 100 {
return Err(format!(
"{} seems to have gotten lost...",
&world.player_name
));
}
let (current, _) = world.warrior.hp;
if current == 0 {
return Err(format!("{} died!", &world.player_name));
}
if world.warrior.position == world.floor.stairs {
return Ok(());
}
let mut events = Vec::new();
let mut player_events = player_system(&mut world);
events.append(&mut player_events);
let mut sludge_events = sludge_system(&mut world);
events.append(&mut sludge_events);
let mut shooter_events = shooter_system(&mut world);
events.append(&mut shooter_events);
let num_events = events.len() as u64;
#[cfg(feature = "ncurses")]
ui_system(&world, events, &mut c);
#[cfg(not(feature = "ncurses"))]
ui_system(&world, events);
let delay = match override_delay {
Some(delay) => delay,
None => DEFAULT_GAME_LOOP_DELAY + num_events * 200,
};
thread::sleep(time::Duration::from_millis(delay));
}
}