finished combat chapter 8
This commit is contained in:
parent
c977f355f8
commit
4fbb2a881a
@ -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
27
src/systems/combat.rs
Normal 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);
|
||||||
|
});
|
||||||
|
}
|
@ -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())
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user