multiple levels
This commit is contained in:
parent
c17b62985b
commit
da36acbade
@ -8,7 +8,9 @@ pub struct Render {
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct Player;
|
||||
pub struct Player {
|
||||
pub map_level: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct Enemy;
|
||||
|
78
src/main.rs
78
src/main.rs
@ -11,8 +11,8 @@ mod prelude {
|
||||
pub use legion::systems::CommandBuffer;
|
||||
pub use legion::world::SubWorld;
|
||||
pub use legion::*;
|
||||
pub const SCREEN_WIDTH: i32 = 80;
|
||||
pub const SCREEN_HEIGHT: i32 = 50;
|
||||
pub const SCREEN_WIDTH: i32 = 60;
|
||||
pub const SCREEN_HEIGHT: i32 = 40;
|
||||
pub const DISPLAY_WIDTH: i32 = SCREEN_WIDTH / 2;
|
||||
pub const DISPLAY_HEIGHT: i32 = SCREEN_HEIGHT / 2;
|
||||
pub use crate::camera::*;
|
||||
@ -33,21 +33,80 @@ struct State {
|
||||
monster_systems: Schedule,
|
||||
}
|
||||
impl State {
|
||||
fn advance_level(&mut self) {
|
||||
let player_entity = *<Entity>::query()
|
||||
.filter(component::<Player>())
|
||||
.iter(&mut self.ecs)
|
||||
.nth(0)
|
||||
.unwrap();
|
||||
use std::collections::HashSet;
|
||||
let mut entities_to_keep = HashSet::new();
|
||||
entities_to_keep.insert(player_entity);
|
||||
|
||||
<(Entity, &Carried)>::query()
|
||||
.iter(&self.ecs)
|
||||
.filter(|(_e, carry)| carry.0 == player_entity)
|
||||
.map(|(e, _carry)| *e)
|
||||
.for_each(|e| {
|
||||
entities_to_keep.insert(e);
|
||||
});
|
||||
let mut cb = CommandBuffer::new(&mut self.ecs);
|
||||
for e in Entity::query().iter(&self.ecs) {
|
||||
if !entities_to_keep.contains(e) {
|
||||
cb.remove(*e);
|
||||
}
|
||||
}
|
||||
cb.flush(&mut self.ecs);
|
||||
|
||||
<&mut FieldOfView>::query()
|
||||
.iter_mut(&mut self.ecs)
|
||||
.for_each(|fov| fov.is_dirty = true);
|
||||
|
||||
let mut rng = RandomNumberGenerator::new();
|
||||
let mut map_builder = MapBuilder::new(&mut rng);
|
||||
let mut map_level = 0;
|
||||
<(&mut Player, &mut Point)>::query()
|
||||
.iter_mut(&mut self.ecs)
|
||||
.for_each(|(player, pos)| {
|
||||
player.map_level += 1;
|
||||
map_level = player.map_level;
|
||||
pos.x = map_builder.player_start.x;
|
||||
pos.y = map_builder.player_start.y;
|
||||
});
|
||||
if map_level == 2 {
|
||||
spawn_amulet_of_yala(&mut self.ecs, map_builder.amulet_start);
|
||||
} else {
|
||||
let exit_idx = map_builder.map.point2d_to_index(map_builder.amulet_start);
|
||||
map_builder.map.tiles[exit_idx] = TileType::Exit;
|
||||
}
|
||||
|
||||
map_builder
|
||||
.monster_spawns
|
||||
.iter()
|
||||
.for_each(|pos| spawn_entity(&mut self.ecs, &mut rng, *pos));
|
||||
|
||||
self.resources.insert(map_builder.map);
|
||||
self.resources.insert(Camera::new(map_builder.player_start));
|
||||
self.resources.insert(TurnState::AwaitingInput);
|
||||
self.resources.insert(map_builder.theme);
|
||||
}
|
||||
|
||||
fn new() -> Self {
|
||||
let mut ecs = World::default();
|
||||
let mut resources = Resources::default();
|
||||
let mut rng = RandomNumberGenerator::new();
|
||||
let map_builder = MapBuilder::new(&mut rng);
|
||||
|
||||
let mut map_builder = MapBuilder::new(&mut rng);
|
||||
spawn_player(&mut ecs, map_builder.player_start);
|
||||
spawn_amulet_of_yala(&mut ecs, map_builder.amulet_start);
|
||||
//spawn_amulet_of_yala(&mut ecs, map_builder.amulet_start);
|
||||
let exit_idx = map_builder.map.point2d_to_index(map_builder.amulet_start);
|
||||
map_builder.map.tiles[exit_idx] = TileType::Exit;
|
||||
|
||||
map_builder
|
||||
.monster_spawns
|
||||
.iter()
|
||||
.for_each(|pos| spawn_entity(&mut ecs, &mut rng, *pos));
|
||||
resources.insert(map_builder.map);
|
||||
resources.insert(Camera::new(map_builder.player_start));
|
||||
|
||||
resources.insert(TurnState::AwaitingInput);
|
||||
resources.insert(map_builder.theme);
|
||||
State {
|
||||
@ -89,9 +148,11 @@ impl State {
|
||||
self.ecs = World::default();
|
||||
self.resources = Resources::default();
|
||||
let mut rng = RandomNumberGenerator::new();
|
||||
let map_builder = MapBuilder::new(&mut rng);
|
||||
let mut map_builder = MapBuilder::new(&mut rng);
|
||||
spawn_player(&mut self.ecs, map_builder.player_start);
|
||||
spawn_amulet_of_yala(&mut self.ecs, map_builder.amulet_start);
|
||||
//spawn_amulet_of_yala(&mut self.ecs, map_builder.amulet_start);
|
||||
let exit_idx = map_builder.map.point2d_to_index(map_builder.amulet_start);
|
||||
map_builder.map.tiles[exit_idx] = TileType::Exit;
|
||||
map_builder
|
||||
.monster_spawns
|
||||
.iter()
|
||||
@ -148,6 +209,7 @@ impl GameState for State {
|
||||
.execute(&mut self.ecs, &mut self.resources),
|
||||
TurnState::GameOver => self.game_over(ctx),
|
||||
TurnState::Victory => self.victory(ctx),
|
||||
TurnState::NextLevel => self.advance_level(),
|
||||
}
|
||||
render_draw_buffer(ctx).expect("Render error");
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ const NUM_TILES: usize = (SCREEN_WIDTH * SCREEN_HEIGHT) as usize;
|
||||
pub enum TileType {
|
||||
Wall,
|
||||
Floor,
|
||||
Exit,
|
||||
}
|
||||
|
||||
pub struct Map {
|
||||
@ -29,7 +30,9 @@ impl Map {
|
||||
}
|
||||
|
||||
pub fn can_enter_tile(&self, point: Point) -> bool {
|
||||
self.in_bounds(point) && self.tiles[map_idx(point.x, point.y)] == TileType::Floor
|
||||
self.in_bounds(point)
|
||||
&& (self.tiles[map_idx(point.x, point.y)] == TileType::Floor
|
||||
|| self.tiles[map_idx(point.x, point.y)] == TileType::Exit)
|
||||
}
|
||||
|
||||
pub fn try_idx(&self, point: Point) -> Option<usize> {
|
||||
|
@ -13,6 +13,7 @@ impl MapTheme for DungeonTheme {
|
||||
match tile_type {
|
||||
TileType::Floor => to_cp437('.'),
|
||||
TileType::Wall => to_cp437('#'),
|
||||
TileType::Exit => to_cp437('>'),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -28,6 +29,7 @@ impl MapTheme for ForestTheme {
|
||||
match tile_type {
|
||||
TileType::Floor => to_cp437(';'),
|
||||
TileType::Wall => to_cp437('"'),
|
||||
TileType::Exit => to_cp437('>'),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ pub use crate::prelude::*;
|
||||
|
||||
pub fn spawn_player(ecs: &mut World, pos: Point) {
|
||||
ecs.push((
|
||||
Player,
|
||||
Player { map_level: 0 },
|
||||
pos,
|
||||
Render {
|
||||
color: ColorPair::new(WHITE, BLACK),
|
||||
|
@ -5,10 +5,11 @@ use crate::prelude::*;
|
||||
#[read_component(Point)]
|
||||
#[read_component(Player)]
|
||||
#[read_component(AmuletOfYala)]
|
||||
pub fn end_turn(ecs: &SubWorld, #[resource] turn_state: &mut TurnState) {
|
||||
pub fn end_turn(ecs: &SubWorld, #[resource] turn_state: &mut TurnState, #[resource] map: &Map) {
|
||||
let mut player_hp = <(&Health, &Point)>::query().filter(component::<Player>());
|
||||
let mut amulet = <&Point>::query().filter(component::<AmuletOfYala>());
|
||||
let amulet_pos = amulet.iter(ecs).nth(0).unwrap();
|
||||
let amulet_default = Point::new(-1, -1);
|
||||
let amulet_pos = amulet.iter(ecs).nth(0).unwrap_or(&amulet_default);
|
||||
|
||||
let current_state = turn_state.clone();
|
||||
let mut new_state = match turn_state {
|
||||
@ -24,6 +25,10 @@ pub fn end_turn(ecs: &SubWorld, #[resource] turn_state: &mut TurnState) {
|
||||
if pos == amulet_pos {
|
||||
new_state = TurnState::Victory;
|
||||
}
|
||||
let idx = map.point2d_to_index(*pos);
|
||||
if map.tiles[idx] == TileType::Exit {
|
||||
new_state = TurnState::NextLevel;
|
||||
}
|
||||
});
|
||||
*turn_state = new_state;
|
||||
}
|
||||
|
@ -12,7 +12,10 @@ pub fn hud(ecs: &SubWorld) {
|
||||
|
||||
let mut draw_batch = DrawBatch::new();
|
||||
draw_batch.target(2);
|
||||
draw_batch.print_centered(1, "Explore the Dungeon. Cursor keys to move.");
|
||||
draw_batch.print_centered(
|
||||
1,
|
||||
"Explore the Dungeon. Arrow keys to move and attack. G to get item. 1-9 to use item.",
|
||||
);
|
||||
draw_batch.bar_horizontal(
|
||||
Point::zero(),
|
||||
SCREEN_WIDTH * 2,
|
||||
@ -26,6 +29,17 @@ pub fn hud(ecs: &SubWorld) {
|
||||
ColorPair::new(WHITE, RED),
|
||||
);
|
||||
|
||||
let (player, map_level) = <(Entity, &Player)>::query()
|
||||
.iter(ecs)
|
||||
.find_map(|(entity, player)| Some((*entity, player.map_level)))
|
||||
.unwrap();
|
||||
draw_batch.print_color_right(
|
||||
Point::new(SCREEN_WIDTH * 2, 1),
|
||||
format!("DUNGEON LEVEL: {}", map_level + 1),
|
||||
ColorPair::new(YELLOW, BLACK),
|
||||
);
|
||||
|
||||
// Inventory
|
||||
let player = <(Entity, &Player)>::query()
|
||||
.iter(ecs)
|
||||
.find_map(|(entity, _player)| Some(*entity))
|
||||
|
@ -5,4 +5,5 @@ pub enum TurnState {
|
||||
MonsterTurn,
|
||||
GameOver,
|
||||
Victory,
|
||||
NextLevel,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user