|
@@ -18,26 +18,51 @@ mod monster_ai_system;
|
|
|
use monster_ai_system::MonsterAI;
|
|
|
mod map_indexing_system;
|
|
|
use map_indexing_system::MapIndexingSystem;
|
|
|
+mod melee_combat_system;
|
|
|
+use melee_combat_system::MeleeCombatSystem;
|
|
|
+mod damage_system;
|
|
|
+use damage_system::DamageSystem;
|
|
|
|
|
|
#[derive(PartialEq, Copy, Clone)]
|
|
|
-pub enum RunState { Paused, Running }
|
|
|
+pub enum RunState { AwaitingInput, PreRun, PlayerTurn, MonsterTurn }
|
|
|
|
|
|
pub struct State {
|
|
|
pub ecs: World,
|
|
|
- pub systems: Dispatcher<'static, 'static>,
|
|
|
- pub runstate : RunState
|
|
|
+ pub systems: Dispatcher<'static, 'static>
|
|
|
}
|
|
|
|
|
|
impl GameState for State {
|
|
|
fn tick(&mut self, ctx : &mut Rltk) {
|
|
|
ctx.cls();
|
|
|
+ let mut newrunstate;
|
|
|
+ {
|
|
|
+ let runstate = self.ecs.fetch::<RunState>();
|
|
|
+ newrunstate = *runstate;
|
|
|
+ }
|
|
|
|
|
|
- if self.runstate == RunState::Running {
|
|
|
- self.systems.dispatch(&self.ecs);
|
|
|
- self.runstate = RunState::Paused;
|
|
|
- } else {
|
|
|
- self.runstate = player_input(self, ctx);
|
|
|
+ match newrunstate {
|
|
|
+ RunState::PreRun => {
|
|
|
+ self.systems.dispatch(&self.ecs);
|
|
|
+ newrunstate = RunState::AwaitingInput;
|
|
|
+ }
|
|
|
+ RunState::AwaitingInput => {
|
|
|
+ newrunstate = player_input(self, ctx);
|
|
|
+ }
|
|
|
+ RunState::PlayerTurn => {
|
|
|
+ self.systems.dispatch(&self.ecs);
|
|
|
+ newrunstate = RunState::MonsterTurn;
|
|
|
+ }
|
|
|
+ RunState::MonsterTurn => {
|
|
|
+ self.systems.dispatch(&self.ecs);
|
|
|
+ newrunstate = RunState::AwaitingInput;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ let mut runwriter = self.ecs.write_resource::<RunState>();
|
|
|
+ *runwriter = newrunstate;
|
|
|
}
|
|
|
+ damage_system::delete_the_dead(&mut self.ecs);
|
|
|
|
|
|
draw_map(&self.ecs, ctx);
|
|
|
|
|
@@ -60,8 +85,9 @@ fn main() {
|
|
|
.with(MapIndexingSystem{}, "map_indexing_system", &[])
|
|
|
.with(VisibilitySystem{}, "visibility_system", &[])
|
|
|
.with(MonsterAI{}, "monster_ai", &["visibility_system", "map_indexing_system"])
|
|
|
+ .with(MeleeCombatSystem{}, "melee_combat", &["monster_ai"])
|
|
|
+ .with(DamageSystem{}, "damage", &["melee_combat"])
|
|
|
.build(),
|
|
|
- runstate : RunState::Running
|
|
|
};
|
|
|
gs.ecs.register::<Position>();
|
|
|
gs.ecs.register::<Renderable>();
|
|
@@ -70,11 +96,14 @@ fn main() {
|
|
|
gs.ecs.register::<Monster>();
|
|
|
gs.ecs.register::<Name>();
|
|
|
gs.ecs.register::<BlocksTile>();
|
|
|
+ gs.ecs.register::<CombatStats>();
|
|
|
+ gs.ecs.register::<WantsToMelee>();
|
|
|
+ gs.ecs.register::<SufferDamage>();
|
|
|
|
|
|
let map : Map = Map::new_map_rooms_and_corridors();
|
|
|
let (player_x, player_y) = map.rooms[0].center();
|
|
|
|
|
|
- gs.ecs
|
|
|
+ let player_entity = gs.ecs
|
|
|
.create_entity()
|
|
|
.with(Position { x: player_x, y: player_y })
|
|
|
.with(Renderable {
|
|
@@ -85,6 +114,7 @@ fn main() {
|
|
|
.with(Player{})
|
|
|
.with(Viewshed{ visible_tiles : Vec::new(), range: 8, dirty: true })
|
|
|
.with(Name{name: "Player".to_string() })
|
|
|
+ .with(CombatStats{ max_hp: 30, hp: 30, defense: 2, power: 5 })
|
|
|
.build();
|
|
|
|
|
|
let mut rng = rltk::RandomNumberGenerator::new();
|
|
@@ -110,11 +140,14 @@ fn main() {
|
|
|
.with(Monster{})
|
|
|
.with(Name{ name: format!("{} #{}", &name, i) })
|
|
|
.with(BlocksTile{})
|
|
|
+ .with(CombatStats{ max_hp: 16, hp: 16, defense: 1, power: 4 })
|
|
|
.build();
|
|
|
}
|
|
|
|
|
|
gs.ecs.insert(map);
|
|
|
gs.ecs.insert(Point::new(player_x, player_y));
|
|
|
+ gs.ecs.insert(player_entity);
|
|
|
+ gs.ecs.insert(RunState::PreRun);
|
|
|
|
|
|
rltk::main_loop(context, gs);
|
|
|
}
|