use crate::actor::{Actor, Behavior};
use crate::console::KeyCode::*;
use crate::console::*;
use crate::constants;
use crate::coord::Coord;
use crate::dungeon::{ActResult, Dungeon};
use crate::game_data::GameData;
use crate::ui;
use crate::util;
use crate::util::direction::CompassDirection;
use crate::{GameResult, CONSOLE};
#[cfg(feature = "dev")]
use flame;
use std::fs::File;
use std::rc::Rc;
use std::{thread, time};
pub fn player_act(player: &mut Actor, dungeon: &mut Dungeon) -> ActResult {
let mut end_turn = false;
let mut input_flags = EventFlags::empty();
input_flags.insert(input::KEY);
input_flags.insert(input::MOUSE_PRESS);
while !end_turn {
ui::draw_all(dungeon);
let console = CONSOLE.lock().unwrap();
let (flags, event) = loop {
if console.window_closed() {
return ActResult::WindowClosed;
}
if let Some((flags, event)) = console.check_for_event(input_flags) {
break (flags, event);
}
thread::sleep(time::Duration::from_millis(1));
};
let (result, end) = player_process_event(player, dungeon, flags, event);
if result != ActResult::None {
return result;
}
end_turn = end;
calc_fov(player, dungeon);
}
ActResult::None
}
pub fn player_process_event(
player: &mut Actor,
dungeon: &mut Dungeon,
flags: EventFlags,
event: Event,
) -> (ActResult, bool) {
match event {
Event::Key(key) => {
if flags.contains(input::KEY_PRESS) {
#[allow(clippy::match_same_arms)]
match key.code {
Left => return player.try_move_dir(dungeon, CompassDirection::W),
Up => return player.try_move_dir(dungeon, CompassDirection::N),
Right => return player.try_move_dir(dungeon, CompassDirection::E),
Down => return player.try_move_dir(dungeon, CompassDirection::S),
Escape => return (ActResult::QuitGame, false),
F1 => {
#[cfg(feature = "dev")]
{
println!("Writing flame report to {}...", constants::FLAME_PATH);
flame::dump_html(&mut File::create(constants::FLAME_PATH).unwrap())
.unwrap();
println!("Done.");
}
}
_ => (),
}
} else {
match key.printable {
_ => (),
}
}
}
Event::Mouse(mouse) => {
#[cfg(feature = "dev")]
{
let view = ui::calc_game_view();
let (mouse_x, mouse_y) = (mouse.cx, mouse.cy);
let (game_x, game_y) = (mouse_x as i32 + view.left, mouse_y as i32 + view.top);
let coord = Coord::new(game_x, game_y);
if dungeon.in_bounds(coord) {
let tile = &dungeon[coord];
println!("\nTile at ({}, {}) contains:", game_x, game_y);
if let Some(ref actor) = tile.actor {
println!(" - Actor: {:#?}", actor);
}
if let Some(ref object) = tile.object {
println!(" - Object: {:#?}", object);
}
if let Some(ref item_stash) = tile.item_stash {
println!(" - Item stash: {:#?}", item_stash);
}
println!(" - Tile info: {:#?}", tile.info);
}
}
}
}
(ActResult::None, false)
}
pub fn calc_fov(player: &Actor, dungeon: &mut Dungeon) {
let inner = player.inner.lock().unwrap();
let origin = inner.coord;
let fov_radius = inner.fov_radius as i32;
dungeon.calc_fov(origin, fov_radius);
}