M Cargo.toml => Cargo.toml +1 -1
@@ 1,7 1,7 @@
[package]
name = "atonement-game"
version = "0.1.0"
-authors = ["david"]
+authors = ["David Hagerty <david@dathagerty.com>"]
edition = "2018"
readme = "README.md"
license = "GPLv3"
M src/components/input.rs => src/components/input.rs +0 -26
@@ 16,35 16,9 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-use std::collections::HashMap;
-
-use rltk::VirtualKeyCode;
use specs::prelude::*;
use specs_derive::Component;
-use crate::components::position::{Direction, WantsToMove};
-
-#[derive(PartialEq, Copy, Clone)]
-pub enum Command {
- Move(WantsToMove)
-}
-
-#[derive(Default)]
-pub struct Keymap(pub HashMap<VirtualKeyCode, Command>);
-
-impl Keymap {
- pub fn load(&mut self) {
- self.0.insert(VirtualKeyCode::H, Command::Move(WantsToMove{direction: Direction::Left}));
- self.0.insert(VirtualKeyCode::J, Command::Move(WantsToMove{direction: Direction::Down}));
- self.0.insert(VirtualKeyCode::K, Command::Move(WantsToMove{direction: Direction::Up}));
- self.0.insert(VirtualKeyCode::L, Command::Move(WantsToMove{direction: Direction::Right}));
- self.0.insert(VirtualKeyCode::U, Command::Move(WantsToMove{direction: Direction::UpLeft}));
- self.0.insert(VirtualKeyCode::I, Command::Move(WantsToMove{direction: Direction::UpRight}));
- self.0.insert(VirtualKeyCode::N, Command::Move(WantsToMove{direction: Direction::DownLeft}));
- self.0.insert(VirtualKeyCode::M, Command::Move(WantsToMove{direction: Direction::DownRight}));
- }
-}
-
#[derive(Component, Default)]
#[storage(NullStorage)]
pub struct Controllable {}
M src/components/position.rs => src/components/position.rs +1 -1
@@ 40,7 40,7 @@ pub struct Position {
pub y: i32,
}
-#[derive(Component, PartialEq, Copy, Clone)]
+#[derive(Component, PartialEq, Copy, Clone, Debug)]
pub struct WantsToMove {
pub direction: Direction
}
M src/components/renderable.rs => src/components/renderable.rs +1 -0
@@ 22,6 22,7 @@ use specs_derive::Component;
#[derive(Component)]
pub struct Renderable {
+ pub character: char,
pub glyph: u16,
pub foreground_color: RGB,
pub background_color: RGB
M src/entities/mod.rs => src/entities/mod.rs +3 -0
@@ 28,6 28,7 @@ pub fn new_player(ecs: &mut World, x: i32, y: i32) {
ecs.create_entity()
.with(Position { x, y })
.with(Renderable {
+ character: '@',
glyph: rltk::to_cp437('@'),
foreground_color: RGB::named(rltk::WHITE),
background_color: RGB::named(rltk::BLACK),
@@ 46,6 47,7 @@ pub fn new_friendly(ecs: &mut World, x: i32, y: i32) {
ecs.create_entity()
.with(Position { x, y })
.with(Renderable {
+ character: 'B',
glyph: rltk::to_cp437('B'),
foreground_color: RGB::named(rltk::AZURE3),
background_color: RGB::named(rltk::BLACK),
@@ 61,6 63,7 @@ pub fn new_enemy(ecs: &mut World, x: i32, y: i32) {
ecs.create_entity()
.with(Position { x, y })
.with(Renderable {
+ character: 'e',
glyph: rltk::to_cp437('e'),
foreground_color: RGB::named(rltk::RED),
background_color: RGB::named(rltk::BLACK),
A src/input.rs => src/input.rs +58 -0
@@ 0,0 1,58 @@
+use rltk::{Rltk, VirtualKeyCode};
+use crate::{State, RunState};
+use crate::components::position::{WantsToMove, Direction};
+use std::collections::HashMap;
+use specs::{WorldExt, Entity, Join};
+use crate::components::input::Controllable;
+
+#[derive(PartialEq, Copy, Clone, Debug)]
+pub enum Command {
+ Move(WantsToMove)
+}
+
+#[derive(Default)]
+pub struct Keymap(pub HashMap<VirtualKeyCode, Command>);
+
+impl Keymap {
+ pub fn load(&mut self) {
+ self.0.insert(VirtualKeyCode::H, Command::Move(WantsToMove{direction: Direction::Left}));
+ self.0.insert(VirtualKeyCode::J, Command::Move(WantsToMove{direction: Direction::Down}));
+ self.0.insert(VirtualKeyCode::K, Command::Move(WantsToMove{direction: Direction::Up}));
+ self.0.insert(VirtualKeyCode::L, Command::Move(WantsToMove{direction: Direction::Right}));
+ self.0.insert(VirtualKeyCode::U, Command::Move(WantsToMove{direction: Direction::UpLeft}));
+ self.0.insert(VirtualKeyCode::I, Command::Move(WantsToMove{direction: Direction::UpRight}));
+ self.0.insert(VirtualKeyCode::N, Command::Move(WantsToMove{direction: Direction::DownLeft}));
+ self.0.insert(VirtualKeyCode::M, Command::Move(WantsToMove{direction: Direction::DownRight}));
+ }
+}
+
+pub fn get_input(gs: &mut State, ctx: &mut Rltk) -> RunState {
+ let km = gs.ecs.fetch::<Keymap>();
+ let controllables = gs.ecs.read_storage::<Controllable>();
+ let entities = gs.ecs.entities();
+ let mut wants_to_move = gs.ecs.write_storage::<WantsToMove>();
+ let mut commanded = false;
+ for (entity, _controllable) in (&entities, &controllables).join() {
+ match ctx.key {
+ None => {}
+ Some(key) => {
+ match km.0.get(&key) {
+ None => {}
+ Some(command) => {
+ println!("Got command: {:#?}", command);
+ match command {
+ Command::Move(movement) => {
+ commanded = true;
+ wants_to_move.insert(entity, *movement).expect("could not insert command")
+ }
+ };
+ }
+ }
+ }
+ }
+ }
+ if commanded {
+ return RunState::ProcessTurns;
+ }
+ return RunState::AwaitingInput;
+}<
\ No newline at end of file
M src/main.rs => src/main.rs +34 -41
@@ 19,23 19,25 @@
use std::borrow::BorrowMut;
use std::collections::HashMap;
-use rltk::prelude::*;
use rltk::{BError, GameState, Rltk};
+use rltk::prelude::*;
use specs::join::Join;
use specs::prelude::*;
-use crate::components::ai::HasAttitude;
-use crate::components::input::{Controllable, Keymap};
+use crate::components::input::{Controllable};
use crate::components::position::{Direction, Moveable, Position, WantsToMove};
use crate::components::renderable::{Renderable, ViewShed};
use crate::entities::*;
use crate::map::*;
use crate::systems::visibility::VisibilitySystem;
+use crate::components::ai::HasAttitude;
+use crate::input::{Keymap, get_input};
mod components;
mod entities;
-mod map;
mod systems;
+mod map;
+mod input;
const MAP_HEIGHT: i32 = 100;
const MAP_WIDTH: i32 = 160;
@@ 44,10 46,10 @@ const MAP_WIDTH: i32 = 160;
pub enum RunState {
PreRun,
AwaitingInput,
- PlayerTurn,
+ ProcessTurns,
}
-struct State {
+pub struct State {
ecs: World,
}
@@ 63,19 65,14 @@ impl GameState for State {
match newrunstate {
RunState::PreRun => {
- println!("pre-run");
self.run_systems();
newrunstate = RunState::AwaitingInput;
}
RunState::AwaitingInput => {
- println!("awaiting input");
- let mut controller = Controllable {};
- controller.run_now(&self.ecs);
- self.ecs.maintain();
- newrunstate = RunState::PlayerTurn;
+ newrunstate = get_input(self, ctx)
}
- RunState::PlayerTurn => {
- println!("player turn");
+ RunState::ProcessTurns => {
+ println!("RunState::ProcessTurns");
self.run_systems();
newrunstate = RunState::AwaitingInput;
}
@@ 92,23 89,17 @@ impl GameState for State {
let positions = self.ecs.read_storage::<Position>();
let renderables = self.ecs.read_storage::<Renderable>();
for (position, renderable) in (&positions, &renderables).join() {
- ctx.set(
- position.x,
- position.y,
- renderable.foreground_color,
- renderable.background_color,
- renderable.glyph,
- );
+ if map.visible_tiles[map.xy_idx(position.x, position.y)] {
+ ctx.set(position.x, position.y, renderable.foreground_color, renderable.background_color, renderable.glyph);
+ }
}
}
}
impl State {
fn run_systems(&mut self) {
- let mut mover = WantsToMove {
- direction: Direction::None,
- };
- let mut visibility = VisibilitySystem {};
+ let mut mover = WantsToMove{ direction: Direction::None};
+ let mut visibility = VisibilitySystem{};
mover.run_now(&self.ecs);
visibility.run_now(&self.ecs);
self.ecs.maintain();
@@ 120,15 111,17 @@ fn main() -> BError {
.unwrap()
.with_title("Atonement")
.build()?;
- let mut gameState = State { ecs: World::new() };
-
- gameState.ecs.register::<Position>();
- gameState.ecs.register::<Renderable>();
- gameState.ecs.register::<Controllable>();
- gameState.ecs.register::<WantsToMove>();
- gameState.ecs.register::<Moveable>();
- gameState.ecs.register::<ViewShed>();
- gameState.ecs.register::<HasAttitude>();
+ let mut gs = State {
+ ecs: World::new(),
+ };
+
+ gs.ecs.register::<Position>();
+ gs.ecs.register::<Renderable>();
+ gs.ecs.register::<Controllable>();
+ gs.ecs.register::<WantsToMove>();
+ gs.ecs.register::<Moveable>();
+ gs.ecs.register::<ViewShed>();
+ gs.ecs.register::<HasAttitude>();
let mut keymap = Keymap(HashMap::new());
keymap.load();
@@ 136,16 129,16 @@ fn main() -> BError {
let map = Map::new_dungeon(MAP_WIDTH, MAP_HEIGHT);
let (px, py) = map.rooms[0].center();
- new_player(gameState.ecs.borrow_mut(), px, py);
- new_friendly(gameState.ecs.borrow_mut(), px + 3, py + 3);
+ new_player(gs.ecs.borrow_mut(), px, py);
+ new_friendly(gs.ecs.borrow_mut(), px+3, py+3);
for room in map.rooms[1..].iter() {
- new_enemy(gameState.ecs.borrow_mut(), room.center().0, room.center().1)
+ new_enemy(gs.ecs.borrow_mut(), room.center().0, room.center().1)
}
- gameState.ecs.insert(keymap);
- gameState.ecs.insert(map);
- gameState.ecs.insert(RunState::PreRun);
+ gs.ecs.insert(keymap);
+ gs.ecs.insert(map);
+ gs.ecs.insert(RunState::PreRun);
- rltk::main_loop(context, gameState)
+ rltk::main_loop(context, gs)
}
D src/systems/input.rs => src/systems/input.rs +0 -45
@@ 1,45 0,0 @@
-/*
- atonement, a roguelike game set in the Wild West
- Copyright (C) 2020 David Hagerty (gloatingfiddle)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
-*/
-
-use rltk::INPUT;
-use specs::{Entities, Read, ReadStorage, System, WriteStorage};
-use specs::join::Join;
-
-use crate::components::input::{Controllable, Keymap, Command};
-use crate::components::position::WantsToMove;
-
-impl<'a> System<'a> for Controllable {
- type SystemData = (Entities<'a>,
- ReadStorage<'a, Controllable>,
- WriteStorage<'a, WantsToMove>,
- Read<'a, Keymap>,
- );
-
- fn run(&mut self, (entities, controllables, mut wants_to_move, keymap) : Self::SystemData) {
- let input = INPUT.lock();
- for (entity, _controllable) in (&entities, &controllables).join() {
- keymap.0.iter().for_each(|(key, command)| {
- if input.is_key_pressed(*key) {
- match *command {
- Command::Move(movement) => wants_to_move.insert(entity, movement).expect("add failed!"),
- };
- }
- });
- }
- }
-}>
\ No newline at end of file
M src/systems/mod.rs => src/systems/mod.rs +0 -1
@@ 17,5 17,4 @@
*/
pub mod movement;
-pub mod input;
pub mod visibility;
M src/systems/visibility.rs => src/systems/visibility.rs +1 -0
@@ 53,6 53,7 @@ impl<'a> System<'a> for VisibilitySystem {
*t = false
}
for v in vs.visible_tiles.iter() {
+ println!("updating visible tiles");
let idx = map.xy_idx(v.x, v.y);
map.revealed_tiles[idx] = true;
map.visible_tiles[idx] = true;