Implement and use map indexing system
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Alex Page 2022-01-28 03:05:56 -05:00
parent 1918f2436a
commit 8e80ff3639
6 changed files with 79 additions and 74 deletions

View file

@ -56,7 +56,7 @@ fn main() -> BError {
ecs.register::<Monster>();
ecs.register::<Player>();
let mut map = Map::new();
let map = Map::new();
let mut rng = RandomNumberGenerator::new();
for (i, tile) in &mut map.get_tiles().iter().enumerate() {
if rng.roll_dice(1, 16) < 2 && *tile == TileType::Floor {
@ -80,16 +80,6 @@ fn main() -> BError {
}
}
{
let entities = ecs.entities();
let positions = ecs.read_storage::<Position>();
let monsters = ecs.read_storage::<Monster>();
for (entity, _monster, pos) in (&entities, &monsters, &positions).join() {
map.set_tile_at(Point { x: pos.x, y: pos.y }, TileType::Monster(entity));
}
}
let player_start_pos = Point { x: 40, y: 22 };
ecs.create_entity()
@ -107,8 +97,6 @@ fn main() -> BError {
})
.build();
map.set_tile_at(player_start_pos, TileType::Player);
ecs.insert(map);
ecs.insert(Point::new(player_start_pos.x, player_start_pos.y));

View file

@ -7,8 +7,6 @@ use specs::Entity;
#[derive(PartialEq, Copy, Clone)]
pub enum TileType {
Player,
Monster(Entity),
Wall,
BreakableWall,
Floor,
@ -16,6 +14,7 @@ pub enum TileType {
pub struct Map {
tiles: Vec<TileType>,
tile_content: Vec<Option<Entity>>,
border_fg: RGB,
border_bg: RGB,
}
@ -47,11 +46,26 @@ impl Map {
}
Self {
tiles,
tile_content: vec![None; MAP_SIZE],
border_fg: RGB::named(vga::get_by_index(rng.range(8, 15))),
border_bg: RGB::named(vga::get_by_index(rng.range(1, 7) as usize)),
}
}
pub fn clear_all_tile_content(&mut self) {
self.tile_content.iter_mut().for_each(|tile| {
*tile = None;
});
}
pub fn get_tile_content(&self, index: usize) -> Option<Entity> {
self.tile_content[index]
}
pub fn set_tile_content(&mut self, index: usize, entity: Entity) {
self.tile_content[index] = Some(entity);
}
pub fn get_tiles(&self) -> &Vec<TileType> {
&self.tiles
}
@ -75,15 +89,6 @@ impl Map {
let (x, y) = (point.x as usize, point.y as usize);
match tile {
TileType::Player | TileType::Monster(_) => {
ctx.set(
x + MAP_X,
y + MAP_Y,
RGB::named(vga::BLACK),
RGB::named(vga::BLACK),
to_cp437(' '),
);
}
TileType::Floor => {
ctx.set(
x + MAP_X,

View file

@ -2,9 +2,8 @@ use std::time::{Duration, Instant};
use crate::components::monster::damage_for_kind;
use crate::components::{Monster, Player, Position, Renderable};
use crate::resources::map::TileType;
use crate::resources::{Clock, Map, ShowDebugInfo, SoundEffects, SoundOutput, Stats};
use crate::systems::MonsterMotion;
use crate::systems::{MapIndexingSystem, MonsterAiSystem};
use crate::{constants::*, sidebar};
use bracket_lib::prelude::*;
use specs::prelude::*;
@ -91,7 +90,8 @@ impl State {
let entities = self.ecs.entities();
let mut positions = self.ecs.write_storage::<Position>();
let mut players = self.ecs.write_storage::<Player>();
let mut map = self.ecs.write_resource::<Map>();
let monsters = self.ecs.write_storage::<Monster>();
let map = self.ecs.read_resource::<Map>();
let mut stats = self.ecs.write_resource::<Stats>();
let mut sound_system = self.ecs.write_resource::<SoundOutput>();
@ -109,18 +109,14 @@ impl State {
if map.is_solid(destination) {
sound_system.play_sound(sound_effects.blocked.clone());
} else {
if let TileType::Monster(monster) = map.get_tile_at(destination) {
if let Some(monster_component) =
self.ecs.read_component::<Monster>().get(monster)
{
if let Some(e) = map.get_tile_content(map.point2d_to_index(destination)) {
if let Some(monster) = monsters.get(e) {
if stats.gems > 0 {
stats.gems -= damage_for_kind(monster_component.kind);
stats.gems -= damage_for_kind(monster.kind);
}
let _ = entities.delete(monster);
let _ = entities.delete(e);
}
}
map.set_tile_at(Point { x: pos.x, y: pos.y }, TileType::Floor);
map.set_tile_at(destination, TileType::Player);
pos.x = destination.x;
pos.y = destination.y;
@ -144,8 +140,10 @@ impl State {
}
fn run_systems(&mut self) {
let mut mm = MonsterMotion {};
mm.run_now(&self.ecs);
let mut map_indexing_system = MapIndexingSystem {};
map_indexing_system.run_now(&self.ecs);
let mut monster_ai_system = MonsterAiSystem {};
monster_ai_system.run_now(&self.ecs);
self.ecs.maintain();
self.ecs.write_resource::<Clock>().try_tick();
}

View file

@ -0,0 +1,27 @@
use bracket_lib::prelude::*;
use specs::prelude::*;
use crate::{components::Position, resources::Map};
pub struct MapIndexingSystem {}
impl<'a> System<'a> for MapIndexingSystem {
type SystemData = (
WriteExpect<'a, Map>,
ReadStorage<'a, Position>,
Entities<'a>,
);
fn run(&mut self, data: Self::SystemData) {
let (mut map, position, entities) = data;
map.clear_all_tile_content();
for (entity, position) in (&entities, &position).join() {
let index = map.point2d_to_index(Point {
x: position.x,
y: position.y,
});
map.set_tile_content(index, entity);
}
}
}

View file

@ -1,3 +1,5 @@
pub mod monster_motion;
pub mod map_indexing_system;
pub mod monster_ai_system;
pub use monster_motion::MonsterMotion;
pub use map_indexing_system::MapIndexingSystem;
pub use monster_ai_system::MonsterAiSystem;

View file

@ -1,7 +1,7 @@
use crate::{
components::{
monster::{self, damage_for_kind, ticks_for_kind},
Monster, Position, Renderable,
Monster, Player, Position, Renderable,
},
resources::map::TileType,
resources::{Clock, Map, Stats},
@ -9,19 +9,20 @@ use crate::{
use bracket_lib::{prelude::*, random::RandomNumberGenerator};
use specs::prelude::*;
pub struct MonsterMotion {}
pub struct MonsterAiSystem {}
#[allow(clippy::type_complexity)]
impl<'a> System<'a> for MonsterMotion {
impl<'a> System<'a> for MonsterAiSystem {
type SystemData = (
Entities<'a>,
ReadExpect<'a, Clock>,
ReadExpect<'a, Point>,
WriteExpect<'a, Map>,
ReadExpect<'a, Map>,
WriteExpect<'a, Stats>,
WriteStorage<'a, Monster>,
WriteStorage<'a, Position>,
WriteStorage<'a, Renderable>,
ReadStorage<'a, Player>,
);
fn run(
@ -30,11 +31,12 @@ impl<'a> System<'a> for MonsterMotion {
entities,
clock,
player_pos,
mut map,
map,
mut stats,
mut monsters,
mut positions,
mut renderables,
players,
): Self::SystemData,
) {
let mut data = (&entities, &mut monsters, &mut positions, &mut renderables)
@ -72,42 +74,25 @@ impl<'a> System<'a> for MonsterMotion {
y: position.y + delta_y,
};
//for (entity, monster, position, renderable) in &data {}
match map.get_tile_at(destination) {
TileType::Player => {
if let Some(e) = map.get_tile_content(map.point2d_to_index(destination)) {
if let Some(_player) = players.get(e) {
// TODO: Sound
if stats.gems > 0 {
stats.gems -= damage_for_kind(monster.kind);
}
map.set_tile_at(
Point {
x: position.x,
y: position.y,
},
TileType::Floor,
);
let _ = entities.delete(*entity);
continue;
}
TileType::Monster(_) => {}
TileType::Wall => {}
TileType::BreakableWall => {
// TODO: Sound
map.set_tile_at(destination, TileType::Floor);
let _ = entities.delete(*entity);
}
TileType::Floor => {
map.set_tile_at(
Point {
x: position.x,
y: position.y,
},
TileType::Floor,
);
map.set_tile_at(destination, TileType::Monster(*entity));
position.x = destination.x;
position.y = destination.y;
} else {
match map.get_tile_at(destination) {
TileType::Wall => {}
TileType::BreakableWall => {
// TODO: Sound
let _ = entities.delete(*entity);
}
TileType::Floor => {
position.x = destination.x;
position.y = destination.y;
}
}
}