Implement and use map indexing system
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
1918f2436a
commit
8e80ff3639
6 changed files with 79 additions and 74 deletions
14
src/main.rs
14
src/main.rs
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
24
src/state.rs
24
src/state.rs
|
@ -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();
|
||||
}
|
||||
|
|
27
src/systems/map_indexing_system.rs
Normal file
27
src/systems/map_indexing_system.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue