97 lines
3.8 KiB
Rust
97 lines
3.8 KiB
Rust
use crate::{
|
|
components::{monster::*, *},
|
|
resources::Resources,
|
|
tile_data::TileType,
|
|
};
|
|
|
|
use bracket_lib::{prelude::*, random::RandomNumberGenerator};
|
|
use hecs::*;
|
|
|
|
pub fn run(world: &mut World, resources: &mut Resources) {
|
|
let player_position = world
|
|
.query::<(&Player, &Position)>()
|
|
.iter()
|
|
.map(|(_, (_, &pos))| pos)
|
|
.collect::<Vec<_>>()
|
|
.first()
|
|
.cloned();
|
|
|
|
if let Some(player_pos) = player_position {
|
|
let mut to_kill: Vec<Entity> = Vec::new();
|
|
for (entity, (monster, position, renderable)) in
|
|
&mut world.query::<(&mut Monster, &mut Position, &mut Renderable)>()
|
|
{
|
|
if resources.clock.has_ticked {
|
|
monster.ticks_until_move -= 1;
|
|
if monster.ticks_until_move <= 0 {
|
|
// Change glyph
|
|
let mut rng = RandomNumberGenerator::new();
|
|
if let Some(glyph) =
|
|
rng.random_slice_entry(&monster::glyphs_for_kind(monster.kind))
|
|
{
|
|
renderable.glyph = *glyph;
|
|
}
|
|
|
|
// Move monster
|
|
let (mut delta_x, mut delta_y) = (0, 0);
|
|
if player_pos.x < position.x {
|
|
delta_x = -1;
|
|
}
|
|
if player_pos.x > position.x {
|
|
delta_x = 1;
|
|
}
|
|
if player_pos.y < position.y {
|
|
delta_y = -1;
|
|
}
|
|
if player_pos.y > position.y {
|
|
delta_y = 1;
|
|
}
|
|
let destination = Point {
|
|
x: position.x + delta_x,
|
|
y: position.y + delta_y,
|
|
};
|
|
|
|
if let Some(e) = resources.map.get_tile_content_at(destination) {
|
|
if let Ok(_player) = world.get::<Player>(e) {
|
|
// TODO: Sound
|
|
resources.map.clear_tile_content_at(Point::from(*position));
|
|
resources.stats.take_gems(damage_for_kind(monster.kind));
|
|
resources.sound_output.play_sound(sound_effect_for_kind(
|
|
monster.kind,
|
|
&resources.sound_effects,
|
|
));
|
|
to_kill.push(entity);
|
|
}
|
|
} else {
|
|
let tile = resources.map.get_tile_at_mut(destination);
|
|
match tile {
|
|
TileType::Wall => {}
|
|
TileType::Block => {
|
|
resources.sound_output.play_sound(sound_effect_for_kind(
|
|
monster.kind,
|
|
&resources.sound_effects,
|
|
));
|
|
resources.stats.add_score(1);
|
|
*tile = TileType::Floor;
|
|
to_kill.push(entity);
|
|
resources.map.clear_tile_content_at(Point::from(*position));
|
|
}
|
|
_ => {
|
|
resources.map.clear_tile_content_at(Point::from(*position));
|
|
position.x = destination.x;
|
|
position.y = destination.y;
|
|
resources.map.set_tile_content_at(destination, entity);
|
|
}
|
|
}
|
|
}
|
|
|
|
monster.ticks_until_move = ticks_for_kind(monster.kind);
|
|
}
|
|
}
|
|
}
|
|
|
|
for e in to_kill {
|
|
let _ = world.despawn(e);
|
|
}
|
|
}
|
|
}
|