player.rs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. extern crate rltk;
  2. use rltk::{Point, Rltk, VirtualKeyCode};
  3. extern crate specs;
  4. use super::{CombatStats, Map, Player, Position, RunState, State, Viewshed, WantsToMelee};
  5. use specs::prelude::*;
  6. use std::cmp::{max, min};
  7. pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
  8. let mut positions = ecs.write_storage::<Position>();
  9. let players = ecs.read_storage::<Player>();
  10. let mut viewsheds = ecs.write_storage::<Viewshed>();
  11. let entities = ecs.entities();
  12. let combat_stats = ecs.read_storage::<CombatStats>();
  13. let map = ecs.fetch::<Map>();
  14. let mut wants_to_melee = ecs.write_storage::<WantsToMelee>();
  15. for (entity, _player, pos, viewshed) in
  16. (&entities, &players, &mut positions, &mut viewsheds).join()
  17. {
  18. let destination_idx = map.xy_idx(pos.x + delta_x, pos.y + delta_y);
  19. for potential_target in map.tile_content[destination_idx].iter() {
  20. let target = combat_stats.get(*potential_target);
  21. if let Some(_target) = target {
  22. wants_to_melee
  23. .insert(
  24. entity,
  25. WantsToMelee {
  26. target: *potential_target,
  27. },
  28. )
  29. .expect("Add target failed");
  30. return;
  31. }
  32. }
  33. if !map.blocked[destination_idx] {
  34. pos.x = min(79, max(0, pos.x + delta_x));
  35. pos.y = min(49, max(0, pos.y + delta_y));
  36. viewshed.dirty = true;
  37. let mut ppos = ecs.write_resource::<Point>();
  38. ppos.x = pos.x;
  39. ppos.y = pos.y;
  40. }
  41. }
  42. }
  43. pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState {
  44. // Player movement
  45. match ctx.key {
  46. None => return RunState::AwaitingInput, // Nothing happened
  47. Some(key) => match key {
  48. VirtualKeyCode::Left | VirtualKeyCode::Numpad4 | VirtualKeyCode::H => {
  49. try_move_player(-1, 0, &mut gs.ecs)
  50. }
  51. VirtualKeyCode::Right | VirtualKeyCode::Numpad6 | VirtualKeyCode::L => {
  52. try_move_player(1, 0, &mut gs.ecs)
  53. }
  54. VirtualKeyCode::Up | VirtualKeyCode::Numpad8 | VirtualKeyCode::K => {
  55. try_move_player(0, -1, &mut gs.ecs)
  56. }
  57. VirtualKeyCode::Down | VirtualKeyCode::Numpad2 | VirtualKeyCode::J => {
  58. try_move_player(0, 1, &mut gs.ecs)
  59. }
  60. // Diagonals
  61. VirtualKeyCode::Numpad9 | VirtualKeyCode::U => try_move_player(1, -1, &mut gs.ecs),
  62. VirtualKeyCode::Numpad7 | VirtualKeyCode::Y => try_move_player(-1, -1, &mut gs.ecs),
  63. VirtualKeyCode::Numpad3 | VirtualKeyCode::N => try_move_player(1, 1, &mut gs.ecs),
  64. VirtualKeyCode::Numpad1 | VirtualKeyCode::B => try_move_player(-1, 1, &mut gs.ecs),
  65. _ => return RunState::AwaitingInput,
  66. },
  67. }
  68. RunState::PlayerTurn
  69. }