finished combat chapter 8

This commit is contained in:
Tyrel Souza 2021-08-29 23:50:50 -04:00
parent c977f355f8
commit 4fbb2a881a
5 changed files with 121 additions and 18 deletions

View File

@ -21,6 +21,12 @@ pub struct WantsToMove {
pub destination: Point, pub destination: Point,
} }
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct WantsToAttack {
pub attacker: Entity,
pub victim: Entity,
}
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
pub struct Health { pub struct Health {
pub current: i32, pub current: i32,

27
src/systems/combat.rs Normal file
View File

@ -0,0 +1,27 @@
use crate::prelude::*;
#[system]
#[read_component(WantsToAttack)]
#[write_component(Health)]
pub fn combat(ecs: &mut SubWorld, commands: &mut CommandBuffer) {
let mut attackers = <(Entity, &WantsToAttack)>::query();
let victims: Vec<(Entity, Entity)> = attackers
.iter(ecs)
.map(|(entity, attack)| (*entity, attack.victim))
.collect();
victims.iter().for_each(|(message, victim)| {
if let Ok(mut health) = ecs
.entry_mut(*victim)
.unwrap()
.get_component_mut::<Health>()
{
println!("Health before attack: {}", health.current);
health.current -= 1;
if health.current < 1 {
commands.remove(*victim);
}
println!("Health after attack: {}", health.current);
}
commands.remove(*message);
});
}

View File

@ -1,4 +1,5 @@
use crate::prelude::*; use crate::prelude::*;
mod combat;
mod end_turn; mod end_turn;
mod entity_render; mod entity_render;
mod hud; mod hud;
@ -20,6 +21,8 @@ pub fn input_build_scheduler() -> Schedule {
} }
pub fn player_build_scheduler() -> Schedule { pub fn player_build_scheduler() -> Schedule {
Schedule::builder() Schedule::builder()
.add_system(combat::combat_system())
.flush()
.add_system(movement::movement_system()) .add_system(movement::movement_system())
.flush() .flush()
.add_system(map_render::map_render_system()) .add_system(map_render::map_render_system())
@ -32,6 +35,8 @@ pub fn monster_build_scheduler() -> Schedule {
Schedule::builder() Schedule::builder()
.add_system(random_move::random_move_system()) .add_system(random_move::random_move_system())
.flush() .flush()
.add_system(combat::combat_system())
.flush()
.add_system(movement::movement_system()) .add_system(movement::movement_system())
.flush() .flush()
.add_system(map_render::map_render_system()) .add_system(map_render::map_render_system())

View File

@ -3,6 +3,8 @@ use crate::prelude::*;
#[system] #[system]
#[read_component(Point)] #[read_component(Point)]
#[read_component(Player)] #[read_component(Player)]
#[read_component(Enemy)]
#[write_component(Health)]
pub fn player_input( pub fn player_input(
ecs: &mut SubWorld, ecs: &mut SubWorld,
commands: &mut CommandBuffer, commands: &mut CommandBuffer,
@ -18,16 +20,52 @@ pub fn player_input(
VirtualKeyCode::Down => Point::new(0, 1), VirtualKeyCode::Down => Point::new(0, 1),
_ => Point::new(0, 0), _ => Point::new(0, 0),
}; };
players.iter(ecs).for_each(|(entity, pos)| { let (player_entity, destination) = players
let destination = *pos + delta; .iter(ecs)
.find_map(|(entity, pos)| Some((*entity, *pos + delta)))
.unwrap();
let mut enemies = <(Entity, &Point)>::query().filter(component::<Enemy>());
let mut did_something = false;
if delta.x != 0 || delta.y != 0 {
let mut hit_something = false;
enemies
.iter(ecs)
.filter(|(_, pos)| **pos == destination)
.for_each(|(entity, _)| {
hit_something = true;
did_something = true;
commands.push(( commands.push((
(), (),
WantsToMove { WantsToAttack {
entity: *entity, attacker: player_entity,
destination, victim: *entity,
}, },
)); ));
}); });
if !hit_something {
did_something = true;
commands.push((
(),
WantsToMove {
entity: player_entity,
destination,
},
));
}
}
if !did_something {
if let Ok(mut health) = ecs
.entry_mut(player_entity)
.unwrap()
.get_component_mut::<Health>()
{
health.current = i32::min(health.max, health.current + 1);
}
}
*turn_state = TurnState::PlayerTurn; *turn_state = TurnState::PlayerTurn;
} }
} }

View File

@ -3,9 +3,12 @@ pub use crate::prelude::*;
#[system] #[system]
#[read_component(Point)] #[read_component(Point)]
#[read_component(MovingRandomly)] #[read_component(MovingRandomly)]
#[read_component(Health)]
#[read_component(Player)]
pub fn random_move(ecs: &mut SubWorld, commands: &mut CommandBuffer) { pub fn random_move(ecs: &mut SubWorld, commands: &mut CommandBuffer) {
let mut movers = <(Entity, &Point, &MovingRandomly)>::query(); let mut movers = <(Entity, &Point, &MovingRandomly)>::query();
movers.iter_mut(ecs).for_each(|(entity, pos, _)| { let mut positions = <(Entity, &Point, &Health)>::query();
movers.iter(ecs).for_each(|(entity, pos, _)| {
let mut rng = RandomNumberGenerator::new(); let mut rng = RandomNumberGenerator::new();
let destination = match rng.range(0, 4) { let destination = match rng.range(0, 4) {
0 => Point::new(-1, 0), 0 => Point::new(-1, 0),
@ -13,6 +16,29 @@ pub fn random_move(ecs: &mut SubWorld, commands: &mut CommandBuffer) {
2 => Point::new(0, -1), 2 => Point::new(0, -1),
_ => Point::new(0, 1), _ => Point::new(0, 1),
} + *pos; } + *pos;
let mut attacked = false;
positions
.iter(ecs)
.filter(|(_, target_pos, _)| **target_pos == destination)
.for_each(|(victim, _, _)| {
if ecs
.entry_ref(*victim)
.unwrap()
.get_component::<Player>()
.is_ok()
{
commands.push((
(),
WantsToAttack {
attacker: *entity,
victim: *victim,
},
));
}
attacked = true
});
if !attacked {
commands.push(( commands.push((
(), (),
WantsToMove { WantsToMove {
@ -20,5 +46,6 @@ pub fn random_move(ecs: &mut SubWorld, commands: &mut CommandBuffer) {
destination, destination,
}, },
)); ));
}
}); });
} }