ActionWithDirection runstate
- setting this runstate with a function as arg will give a direction prompt, and then call the function with the selected direction as the argument. i.e. for opening a door or throwing an item in a specific direction
This commit is contained in:
parent
1f6c04a526
commit
3e2eee9709
3 changed files with 91 additions and 3 deletions
28
src/gui.rs
28
src/gui.rs
|
|
@ -1,6 +1,6 @@
|
||||||
use super::{
|
use super::{
|
||||||
gamelog, rex_assets::RexAssets, CombatStats, Equipped, Hidden, HungerClock, HungerState, InBackpack, Map, Name,
|
gamelog, player::try_door, rex_assets::RexAssets, CombatStats, Equipped, Hidden, HungerClock, HungerState,
|
||||||
Player, Point, Position, RunState, State, Viewshed,
|
InBackpack, Map, Name, Player, Point, Position, RunState, State, Viewshed,
|
||||||
};
|
};
|
||||||
use rltk::{Rltk, VirtualKeyCode, RGB};
|
use rltk::{Rltk, VirtualKeyCode, RGB};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
@ -58,6 +58,30 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
||||||
draw_tooltips(ecs, ctx);
|
draw_tooltips(ecs, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_input_direction(
|
||||||
|
ecs: &mut World,
|
||||||
|
ctx: &mut Rltk,
|
||||||
|
function: fn(i: i32, j: i32, ecs: &mut World) -> RunState,
|
||||||
|
) -> RunState {
|
||||||
|
ctx.print_color(1, 1, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK), "In what direction? [0-9]/[YUHJKLBN]");
|
||||||
|
match ctx.key {
|
||||||
|
None => return RunState::ActionWithDirection { function },
|
||||||
|
Some(key) => match key {
|
||||||
|
// Cardinals
|
||||||
|
VirtualKeyCode::Left | VirtualKeyCode::Numpad4 | VirtualKeyCode::H => return function(-1, 0, ecs),
|
||||||
|
VirtualKeyCode::Right | VirtualKeyCode::Numpad6 | VirtualKeyCode::L => return function(1, 0, ecs),
|
||||||
|
VirtualKeyCode::Up | VirtualKeyCode::Numpad8 | VirtualKeyCode::K => return function(0, -1, ecs),
|
||||||
|
VirtualKeyCode::Down | VirtualKeyCode::Numpad2 | VirtualKeyCode::J => return function(0, 1, ecs),
|
||||||
|
// Diagonals
|
||||||
|
VirtualKeyCode::Numpad9 | VirtualKeyCode::U => return function(1, -1, ecs),
|
||||||
|
VirtualKeyCode::Numpad7 | VirtualKeyCode::Y => return function(-1, -1, ecs),
|
||||||
|
VirtualKeyCode::Numpad3 | VirtualKeyCode::N => return function(1, 1, ecs),
|
||||||
|
VirtualKeyCode::Numpad1 | VirtualKeyCode::B => return function(-1, 1, ecs),
|
||||||
|
_ => return RunState::ActionWithDirection { function },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
|
fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
|
||||||
let map = ecs.fetch::<Map>();
|
let map = ecs.fetch::<Map>();
|
||||||
let names = ecs.read_storage::<Name>();
|
let names = ecs.read_storage::<Name>();
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ pub enum RunState {
|
||||||
ShowDropItem,
|
ShowDropItem,
|
||||||
ShowRemoveItem,
|
ShowRemoveItem,
|
||||||
ShowTargeting { range: i32, item: Entity, aoe: i32 },
|
ShowTargeting { range: i32, item: Entity, aoe: i32 },
|
||||||
|
ActionWithDirection { function: fn(i: i32, j: i32, ecs: &mut World) -> RunState },
|
||||||
MainMenu { menu_selection: gui::MainMenuSelection },
|
MainMenu { menu_selection: gui::MainMenuSelection },
|
||||||
SaveGame,
|
SaveGame,
|
||||||
GameOver,
|
GameOver,
|
||||||
|
|
@ -398,6 +399,9 @@ impl GameState for State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RunState::ActionWithDirection { function } => {
|
||||||
|
new_runstate = gui::get_input_direction(&mut self.ecs, ctx, try_door);
|
||||||
|
}
|
||||||
RunState::MainMenu { .. } => {
|
RunState::MainMenu { .. } => {
|
||||||
let result = gui::main_menu(self, ctx);
|
let result = gui::main_menu(self, ctx);
|
||||||
match result {
|
match result {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,65 @@ use rltk::{Point, RandomNumberGenerator, Rltk, VirtualKeyCode};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
|
|
||||||
|
pub fn try_door(i: i32, j: i32, ecs: &mut World) -> RunState {
|
||||||
|
let mut positions = ecs.write_storage::<Position>();
|
||||||
|
let mut players = ecs.write_storage::<Player>();
|
||||||
|
let mut viewsheds = ecs.write_storage::<Viewshed>();
|
||||||
|
let map = ecs.fetch::<Map>();
|
||||||
|
|
||||||
|
let entities = ecs.entities();
|
||||||
|
let mut doors = ecs.write_storage::<Door>();
|
||||||
|
let mut blocks_visibility = ecs.write_storage::<BlocksVisibility>();
|
||||||
|
let mut blocks_movement = ecs.write_storage::<BlocksTile>();
|
||||||
|
let mut renderables = ecs.write_storage::<Renderable>();
|
||||||
|
let names = ecs.read_storage::<Name>();
|
||||||
|
|
||||||
|
for (_entity, _player, pos, viewshed) in (&entities, &mut players, &mut positions, &mut viewsheds).join() {
|
||||||
|
let delta_x = i;
|
||||||
|
let delta_y = j;
|
||||||
|
|
||||||
|
if !(pos.x + delta_x < 1
|
||||||
|
|| pos.x + delta_x > map.width - 1
|
||||||
|
|| pos.y + delta_y < 1
|
||||||
|
|| pos.y + delta_y > map.height - 1)
|
||||||
|
{
|
||||||
|
let destination_idx = map.xy_idx(pos.x + delta_x, pos.y + delta_y);
|
||||||
|
|
||||||
|
for potential_target in map.tile_content[destination_idx].iter() {
|
||||||
|
let door = doors.get_mut(*potential_target);
|
||||||
|
if let Some(door) = door {
|
||||||
|
if door.open == true {
|
||||||
|
if map.tile_content[destination_idx].len() > 1 {
|
||||||
|
if let Some(name) = names.get(*potential_target) {
|
||||||
|
gamelog::Logger::new().append("The").item_name(&name.name).append("is blocked.").log();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
door.open = false;
|
||||||
|
blocks_visibility
|
||||||
|
.insert(*potential_target, BlocksVisibility {})
|
||||||
|
.expect("Unable to insert BlocksVisibility.");
|
||||||
|
blocks_movement
|
||||||
|
.insert(*potential_target, BlocksTile {})
|
||||||
|
.expect("Unable to insert BlocksTile.");
|
||||||
|
let render_data = renderables.get_mut(*potential_target).unwrap();
|
||||||
|
if let Some(name) = names.get(*potential_target) {
|
||||||
|
gamelog::Logger::new().append("You close the").item_name_n(&name.name).period().log();
|
||||||
|
}
|
||||||
|
render_data.glyph = rltk::to_cp437('+'); // Nethack open door, maybe just use '/' instead.
|
||||||
|
viewshed.dirty = true;
|
||||||
|
return RunState::PlayerTurn;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gamelog::Logger::new().append("It's already closed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gamelog::Logger::new().append("You see no door there.");
|
||||||
|
return RunState::AwaitingInput;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) -> bool {
|
pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) -> bool {
|
||||||
let mut positions = ecs.write_storage::<Position>();
|
let mut positions = ecs.write_storage::<Position>();
|
||||||
let mut players = ecs.write_storage::<Player>();
|
let mut players = ecs.write_storage::<Player>();
|
||||||
|
|
@ -47,7 +106,7 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) -> bool {
|
||||||
blocks_visibility.remove(*potential_target);
|
blocks_visibility.remove(*potential_target);
|
||||||
blocks_movement.remove(*potential_target);
|
blocks_movement.remove(*potential_target);
|
||||||
let render_data = renderables.get_mut(*potential_target).unwrap();
|
let render_data = renderables.get_mut(*potential_target).unwrap();
|
||||||
if let Some(name) = names.get(entity) {
|
if let Some(name) = names.get(*potential_target) {
|
||||||
gamelog::Logger::new().append("You open the").item_name_n(&name.name).period().log();
|
gamelog::Logger::new().append("You open the").item_name_n(&name.name).period().log();
|
||||||
}
|
}
|
||||||
render_data.glyph = rltk::to_cp437('▓'); // Nethack open door, maybe just use '/' instead.
|
render_data.glyph = rltk::to_cp437('▓'); // Nethack open door, maybe just use '/' instead.
|
||||||
|
|
@ -179,6 +238,7 @@ pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Items
|
// Items
|
||||||
|
VirtualKeyCode::C => return RunState::ActionWithDirection { function: try_door },
|
||||||
VirtualKeyCode::G => {
|
VirtualKeyCode::G => {
|
||||||
result = get_item(&mut gs.ecs);
|
result = get_item(&mut gs.ecs);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue