finishes decoupling map from camera
This commit is contained in:
parent
2ecfd25d95
commit
7f0465da73
13 changed files with 110 additions and 254 deletions
|
|
@ -3,7 +3,7 @@ use rltk::{Point, Rltk, RGB};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
use std::ops::{Add, Mul};
|
use std::ops::{Add, Mul};
|
||||||
|
|
||||||
const SHOW_BOUNDARIES: bool = true;
|
const SHOW_BOUNDARIES: bool = false;
|
||||||
|
|
||||||
pub fn get_screen_bounds(ecs: &World, ctx: &mut Rltk) -> (i32, i32, i32, i32) {
|
pub fn get_screen_bounds(ecs: &World, ctx: &mut Rltk) -> (i32, i32, i32, i32) {
|
||||||
let player_pos = ecs.fetch::<Point>();
|
let player_pos = ecs.fetch::<Point>();
|
||||||
|
|
@ -277,3 +277,37 @@ fn wall_glyph(map: &Map, x: i32, y: i32) -> rltk::FontCharType {
|
||||||
_ => 35, // We missed one?
|
_ => 35, // We missed one?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn render_debug_map(map: &Map, ctx: &mut Rltk) {
|
||||||
|
let player_pos = Point::new(map.width / 2, map.height / 2);
|
||||||
|
let (x_chars, y_chars) = ctx.get_char_size();
|
||||||
|
|
||||||
|
let center_x = (x_chars / 2) as i32;
|
||||||
|
let center_y = (y_chars / 2) as i32;
|
||||||
|
|
||||||
|
let min_x = player_pos.x - center_x;
|
||||||
|
let max_x = min_x + x_chars as i32;
|
||||||
|
let min_y = player_pos.y - center_y;
|
||||||
|
let max_y = min_y + y_chars as i32;
|
||||||
|
|
||||||
|
let map_width = map.width - 1;
|
||||||
|
let map_height = map.height - 1;
|
||||||
|
|
||||||
|
let mut y = 0;
|
||||||
|
for ty in min_y..max_y {
|
||||||
|
let mut x = 0;
|
||||||
|
for tx in min_x..max_x {
|
||||||
|
if tx > 0 && tx < map_width && ty > 0 && ty < map_height {
|
||||||
|
let idx = map.xy_idx(tx, ty);
|
||||||
|
if map.revealed_tiles[idx] {
|
||||||
|
let (glyph, fg, bg) = get_tile_glyph(idx, &*map);
|
||||||
|
ctx.set(x, y, fg, bg, glyph);
|
||||||
|
}
|
||||||
|
} else if SHOW_BOUNDARIES {
|
||||||
|
ctx.set(x, y, RGB::named(rltk::GRAY), RGB::named(rltk::BLACK), rltk::to_cp437('·'));
|
||||||
|
}
|
||||||
|
x += 1;
|
||||||
|
}
|
||||||
|
y += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -603,7 +603,6 @@ pub fn game_over(ctx: &mut Rltk) -> YesNoResult {
|
||||||
RGB::named(rltk::BLACK),
|
RGB::named(rltk::BLACK),
|
||||||
format!("- forgot the controls {} time(s)", crate::gamelog::get_event_count("looked_for_help")),
|
format!("- forgot the controls {} time(s)", crate::gamelog::get_event_count("looked_for_help")),
|
||||||
);
|
);
|
||||||
y += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match ctx.key {
|
match ctx.key {
|
||||||
|
|
|
||||||
15
src/main.rs
15
src/main.rs
|
|
@ -1,7 +1,6 @@
|
||||||
use rltk::{GameState, Point, RandomNumberGenerator, Rltk, RGB};
|
use rltk::{GameState, Point, RandomNumberGenerator, Rltk};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
use specs::saveload::{SimpleMarker, SimpleMarkerAllocator};
|
use specs::saveload::{SimpleMarker, SimpleMarkerAllocator};
|
||||||
use std::ops::{Add, Mul};
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
|
||||||
pub mod camera;
|
pub mod camera;
|
||||||
|
|
@ -82,7 +81,7 @@ impl State {
|
||||||
self.mapgen_timer = 0.0;
|
self.mapgen_timer = 0.0;
|
||||||
self.mapgen_history.clear();
|
self.mapgen_history.clear();
|
||||||
let mut rng = self.ecs.write_resource::<rltk::RandomNumberGenerator>();
|
let mut rng = self.ecs.write_resource::<rltk::RandomNumberGenerator>();
|
||||||
let mut builder = map_builders::random_builder(new_depth, &mut rng);
|
let mut builder = map_builders::random_builder(new_depth, &mut rng, 64, 64);
|
||||||
builder.build_map(&mut rng);
|
builder.build_map(&mut rng);
|
||||||
std::mem::drop(rng);
|
std::mem::drop(rng);
|
||||||
self.mapgen_history = builder.build_data.history.clone();
|
self.mapgen_history = builder.build_data.history.clone();
|
||||||
|
|
@ -416,12 +415,12 @@ impl GameState for State {
|
||||||
|
|
||||||
// Could probably toss this into a function somewhere, and/or
|
// Could probably toss this into a function somewhere, and/or
|
||||||
// have multiple simple animations for it.
|
// have multiple simple animations for it.
|
||||||
for x in 0..MAPWIDTH {
|
for x in 0..map.width {
|
||||||
let idx;
|
let idx;
|
||||||
if x % 2 == 0 {
|
if x % 2 == 0 {
|
||||||
idx = map.xy_idx(x as i32, row);
|
idx = map.xy_idx(x as i32, row);
|
||||||
} else {
|
} else {
|
||||||
idx = map.xy_idx(x as i32, (MAPHEIGHT as i32 - 1) - (row));
|
idx = map.xy_idx(x as i32, (map.height as i32 - 1) - (row));
|
||||||
}
|
}
|
||||||
if !cursed {
|
if !cursed {
|
||||||
map.revealed_tiles[idx] = true;
|
map.revealed_tiles[idx] = true;
|
||||||
|
|
@ -440,7 +439,7 @@ impl GameState for State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if row as usize == MAPHEIGHT - 1 {
|
if row as usize == map.height as usize - 1 {
|
||||||
new_runstate = RunState::MonsterTurn;
|
new_runstate = RunState::MonsterTurn;
|
||||||
} else {
|
} else {
|
||||||
new_runstate = RunState::MagicMapReveal { row: row + 1, cursed: cursed };
|
new_runstate = RunState::MagicMapReveal { row: row + 1, cursed: cursed };
|
||||||
|
|
@ -452,7 +451,7 @@ impl GameState for State {
|
||||||
}
|
}
|
||||||
if self.mapgen_history.len() != 0 {
|
if self.mapgen_history.len() != 0 {
|
||||||
ctx.cls();
|
ctx.cls();
|
||||||
draw_map(&self.mapgen_history[self.mapgen_index], ctx);
|
camera::render_debug_map(&self.mapgen_history[self.mapgen_index], ctx);
|
||||||
|
|
||||||
self.mapgen_timer += ctx.frame_time_ms;
|
self.mapgen_timer += ctx.frame_time_ms;
|
||||||
if self.mapgen_timer > 300.0 {
|
if self.mapgen_timer > 300.0 {
|
||||||
|
|
@ -545,7 +544,7 @@ fn main() -> rltk::BError {
|
||||||
gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new());
|
gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new());
|
||||||
|
|
||||||
let player_entity = spawner::player(&mut gs.ecs, 0, 0);
|
let player_entity = spawner::player(&mut gs.ecs, 0, 0);
|
||||||
gs.ecs.insert(Map::new(1));
|
gs.ecs.insert(Map::new(1, 64, 64));
|
||||||
gs.ecs.insert(Point::new(0, 0));
|
gs.ecs.insert(Point::new(0, 0));
|
||||||
gs.ecs.insert(player_entity);
|
gs.ecs.insert(player_entity);
|
||||||
gs.ecs.insert(rltk::RandomNumberGenerator::new());
|
gs.ecs.insert(rltk::RandomNumberGenerator::new());
|
||||||
|
|
|
||||||
222
src/map.rs
222
src/map.rs
|
|
@ -1,8 +1,7 @@
|
||||||
use rltk::{Algorithm2D, BaseMap, Point, Rltk, RGB};
|
use rltk::{Algorithm2D, BaseMap, Point};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::ops::{Add, Mul};
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize)]
|
#[derive(PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize)]
|
||||||
pub enum TileType {
|
pub enum TileType {
|
||||||
|
|
@ -14,9 +13,6 @@ pub enum TileType {
|
||||||
// FIXME: If the map size gets too small, entities stop being rendered starting from the right.
|
// FIXME: If the map size gets too small, entities stop being rendered starting from the right.
|
||||||
// i.e. on a map size of 40*40, only entities to the left of the player are rendered.
|
// i.e. on a map size of 40*40, only entities to the left of the player are rendered.
|
||||||
// on a map size of 42*42, the player can see entities up to 2 tiles to their right.
|
// on a map size of 42*42, the player can see entities up to 2 tiles to their right.
|
||||||
pub const MAPWIDTH: usize = 64;
|
|
||||||
pub const MAPHEIGHT: usize = 64;
|
|
||||||
pub const MAPCOUNT: usize = MAPHEIGHT * MAPWIDTH;
|
|
||||||
|
|
||||||
#[derive(Default, Serialize, Deserialize, Clone)]
|
#[derive(Default, Serialize, Deserialize, Clone)]
|
||||||
pub struct Map {
|
pub struct Map {
|
||||||
|
|
@ -46,23 +42,24 @@ impl Map {
|
||||||
(y as usize) * (self.width as usize) + (x as usize)
|
(y as usize) * (self.width as usize) + (x as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(new_depth: i32) -> Map {
|
pub fn new(new_depth: i32, width: i32, height: i32) -> Map {
|
||||||
|
let map_tile_count = (width * height) as usize;
|
||||||
let mut map = Map {
|
let mut map = Map {
|
||||||
tiles: vec![TileType::Wall; MAPCOUNT],
|
tiles: vec![TileType::Wall; map_tile_count],
|
||||||
width: MAPWIDTH as i32,
|
width: width,
|
||||||
height: MAPHEIGHT as i32,
|
height: height,
|
||||||
revealed_tiles: vec![false; MAPCOUNT],
|
revealed_tiles: vec![false; map_tile_count],
|
||||||
visible_tiles: vec![false; MAPCOUNT],
|
visible_tiles: vec![false; map_tile_count],
|
||||||
lit_tiles: vec![true; MAPCOUNT], // NYI: Light sources. Once those exist, we can set this to false.
|
lit_tiles: vec![true; map_tile_count], // NYI: Light sources. Once those exist, we can set this to false.
|
||||||
telepath_tiles: vec![false; MAPCOUNT],
|
telepath_tiles: vec![false; map_tile_count],
|
||||||
red_offset: vec![0; MAPCOUNT],
|
red_offset: vec![0; map_tile_count],
|
||||||
green_offset: vec![0; MAPCOUNT],
|
green_offset: vec![0; map_tile_count],
|
||||||
blue_offset: vec![0; MAPCOUNT],
|
blue_offset: vec![0; map_tile_count],
|
||||||
blocked: vec![false; MAPCOUNT],
|
blocked: vec![false; map_tile_count],
|
||||||
depth: new_depth,
|
depth: new_depth,
|
||||||
bloodstains: HashSet::new(),
|
bloodstains: HashSet::new(),
|
||||||
view_blocked: HashSet::new(),
|
view_blocked: HashSet::new(),
|
||||||
tile_content: vec![Vec::new(); MAPCOUNT],
|
tile_content: vec![Vec::new(); map_tile_count],
|
||||||
};
|
};
|
||||||
|
|
||||||
const MAX_OFFSET: u8 = 32;
|
const MAX_OFFSET: u8 = 32;
|
||||||
|
|
@ -163,192 +160,3 @@ impl BaseMap for Map {
|
||||||
exits
|
exits
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_map(map: &Map, ctx: &mut Rltk) {
|
|
||||||
let mut y = 0;
|
|
||||||
let mut x = 0;
|
|
||||||
|
|
||||||
for (idx, tile) in map.tiles.iter().enumerate() {
|
|
||||||
// Get our colour offsets. Credit to Brogue for the inspiration here.
|
|
||||||
let offsets = RGB::from_u8(map.red_offset[idx], map.green_offset[idx], map.blue_offset[idx]);
|
|
||||||
if map.revealed_tiles[idx] {
|
|
||||||
let mut fg = offsets.mul(2.0);
|
|
||||||
// Right now, everything always has the same background. It's a
|
|
||||||
// very dark green, just to distinguish it slightly from the
|
|
||||||
// black that is tiles we've *never* seen.
|
|
||||||
let mut bg = offsets.add(RGB::from_u8(26, 45, 45));
|
|
||||||
let glyph;
|
|
||||||
match tile {
|
|
||||||
TileType::Floor => {
|
|
||||||
glyph = rltk::to_cp437('.');
|
|
||||||
fg = fg.add(RGB::from_f32(0.1, 0.8, 0.5));
|
|
||||||
}
|
|
||||||
TileType::Wall => {
|
|
||||||
glyph = wall_glyph(&*map, x, y);
|
|
||||||
fg = fg.add(RGB::from_f32(0.6, 0.5, 0.25));
|
|
||||||
}
|
|
||||||
TileType::DownStair => {
|
|
||||||
glyph = rltk::to_cp437('>');
|
|
||||||
fg = RGB::from_f32(0., 1., 1.);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if map.bloodstains.contains(&idx) {
|
|
||||||
bg = bg.add(RGB::from_f32(0.6, 0., 0.));
|
|
||||||
}
|
|
||||||
if !map.visible_tiles[idx] {
|
|
||||||
fg = fg.mul(0.6);
|
|
||||||
bg = bg.mul(0.6);
|
|
||||||
}
|
|
||||||
ctx.set(x, y, fg, bg, glyph);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move the coordinates
|
|
||||||
x += 1;
|
|
||||||
if x > (MAPWIDTH as i32) - 1 {
|
|
||||||
x = 0;
|
|
||||||
y += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_revealed_and_wall(map: &Map, x: i32, y: i32) -> bool {
|
|
||||||
let idx = map.xy_idx(x, y);
|
|
||||||
map.tiles[idx] == TileType::Wall && map.revealed_tiles[idx]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn wall_glyph(map: &Map, x: i32, y: i32) -> rltk::FontCharType {
|
|
||||||
if x < 1 || x > map.width - 2 || y < 1 || y > map.height - 2 as i32 {
|
|
||||||
return 35;
|
|
||||||
}
|
|
||||||
let mut mask: u8 = 0;
|
|
||||||
let diagonals_matter: Vec<u8> = vec![7, 11, 13, 14, 15];
|
|
||||||
|
|
||||||
if is_revealed_and_wall(map, x, y - 1) {
|
|
||||||
// N
|
|
||||||
mask += 1;
|
|
||||||
}
|
|
||||||
if is_revealed_and_wall(map, x, y + 1) {
|
|
||||||
// S
|
|
||||||
mask += 2;
|
|
||||||
}
|
|
||||||
if is_revealed_and_wall(map, x - 1, y) {
|
|
||||||
// W
|
|
||||||
mask += 4;
|
|
||||||
}
|
|
||||||
if is_revealed_and_wall(map, x + 1, y) {
|
|
||||||
// E
|
|
||||||
mask += 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if diagonals_matter.contains(&mask) {
|
|
||||||
if is_revealed_and_wall(map, x + 1, y - 1) {
|
|
||||||
// Top right
|
|
||||||
mask += 16;
|
|
||||||
}
|
|
||||||
if is_revealed_and_wall(map, x - 1, y - 1) {
|
|
||||||
// Top left
|
|
||||||
mask += 32;
|
|
||||||
}
|
|
||||||
if is_revealed_and_wall(map, x + 1, y + 1) {
|
|
||||||
// Bottom right
|
|
||||||
mask += 64;
|
|
||||||
}
|
|
||||||
if is_revealed_and_wall(map, x - 1, y + 1) {
|
|
||||||
// Bottom left
|
|
||||||
mask += 128;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match mask {
|
|
||||||
0 => 254, // ■ (254) square pillar; but maybe ○ (9) looks better
|
|
||||||
1 => 186, // Wall only to the north
|
|
||||||
2 => 186, // Wall only to the south
|
|
||||||
3 => 186, // Wall to the north and south
|
|
||||||
4 => 205, // Wall only to the west
|
|
||||||
5 => 188, // Wall to the north and west
|
|
||||||
6 => 187, // Wall to the south and west
|
|
||||||
7 => 185, // Wall to the north, south and west
|
|
||||||
8 => 205, // Wall only to the east
|
|
||||||
9 => 200, // Wall to the north and east
|
|
||||||
10 => 201, // Wall to the south and east
|
|
||||||
11 => 204, // Wall to the north, south and east
|
|
||||||
12 => 205, // Wall to the east and west
|
|
||||||
13 => 202, // Wall to the east, west, and north
|
|
||||||
14 => 203, // Wall to the east, west, and south
|
|
||||||
15 => 206, // ╬ Wall on all sides
|
|
||||||
29 => 202,
|
|
||||||
31 => 206,
|
|
||||||
45 => 202,
|
|
||||||
46 => 203,
|
|
||||||
47 => 206,
|
|
||||||
55 => 185,
|
|
||||||
59 => 204,
|
|
||||||
63 => 203,
|
|
||||||
87 => 185,
|
|
||||||
126 => 203,
|
|
||||||
143 => 206,
|
|
||||||
77 => 202,
|
|
||||||
171 => 204,
|
|
||||||
187 => 204,
|
|
||||||
215 => 185,
|
|
||||||
190 => 203,
|
|
||||||
237 => 202,
|
|
||||||
30 => 203,
|
|
||||||
110 => 203,
|
|
||||||
111 => 206,
|
|
||||||
119 => 185,
|
|
||||||
142 => 203,
|
|
||||||
158 => 203,
|
|
||||||
235 => 204,
|
|
||||||
93 => 202,
|
|
||||||
109 => 202,
|
|
||||||
94 => 203,
|
|
||||||
174 => 203,
|
|
||||||
159 => 206,
|
|
||||||
221 => 202,
|
|
||||||
157 => 202,
|
|
||||||
79 => 206,
|
|
||||||
95 => 185,
|
|
||||||
23 => 185, // NSW and NSE + 1 diagonal
|
|
||||||
39 => 185,
|
|
||||||
71 => 185,
|
|
||||||
103 => 185,
|
|
||||||
135 => 185,
|
|
||||||
151 => 185,
|
|
||||||
199 => 185,
|
|
||||||
78 => 203,
|
|
||||||
27 => 204,
|
|
||||||
43 => 204,
|
|
||||||
75 => 204,
|
|
||||||
107 => 204,
|
|
||||||
139 => 204,
|
|
||||||
155 => 204,
|
|
||||||
173 => 202,
|
|
||||||
141 => 202,
|
|
||||||
205 => 202,
|
|
||||||
175 => 204,
|
|
||||||
203 => 204,
|
|
||||||
61 => 205, // NEW cases
|
|
||||||
125 => 205, // NEW cases
|
|
||||||
189 => 205, // NEW cases
|
|
||||||
206 => 205,
|
|
||||||
207 => 202,
|
|
||||||
222 => 205,
|
|
||||||
238 => 205,
|
|
||||||
253 => 205,
|
|
||||||
254 => 205,
|
|
||||||
167 => 186, // NSW, NW, SW
|
|
||||||
91 => 186, // NSE, NE, SE
|
|
||||||
183 => 186, // NSW, NW, SW, NE
|
|
||||||
123 => 186, // NSE, NE, SE, NW
|
|
||||||
231 => 186, // NSW, NW, SW, SE
|
|
||||||
219 => 186, // NSE, NE, SE, SW
|
|
||||||
247 => 186,
|
|
||||||
251 => 186,
|
|
||||||
127 => 187, // Everything except NE
|
|
||||||
191 => 201, // Everything except NW
|
|
||||||
223 => 188, // Everything except SE
|
|
||||||
239 => 200, // Everything except SW
|
|
||||||
_ => 35, // We missed one?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use super::{Map, Rect, TileType};
|
use super::{Map, Rect, TileType};
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn apply_room_to_map(map: &mut Map, room: &Rect) {
|
pub fn apply_room_to_map(map: &mut Map, room: &Rect) {
|
||||||
for y in room.y1 + 1..=room.y2 {
|
for y in room.y1 + 1..=room.y2 {
|
||||||
for x in room.x1 + 1..=room.x2 {
|
for x in room.x1 + 1..=room.x2 {
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,8 @@ pub struct BuilderMap {
|
||||||
pub rooms: Option<Vec<Rect>>,
|
pub rooms: Option<Vec<Rect>>,
|
||||||
pub corridors: Option<Vec<Vec<usize>>>,
|
pub corridors: Option<Vec<Vec<usize>>>,
|
||||||
pub history: Vec<Map>,
|
pub history: Vec<Map>,
|
||||||
|
pub width: i32,
|
||||||
|
pub height: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuilderMap {
|
impl BuilderMap {
|
||||||
|
|
@ -86,17 +88,19 @@ pub struct BuilderChain {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuilderChain {
|
impl BuilderChain {
|
||||||
pub fn new(new_depth: i32) -> BuilderChain {
|
pub fn new(new_depth: i32, width: i32, height: i32) -> BuilderChain {
|
||||||
BuilderChain {
|
BuilderChain {
|
||||||
starter: None,
|
starter: None,
|
||||||
builders: Vec::new(),
|
builders: Vec::new(),
|
||||||
build_data: BuilderMap {
|
build_data: BuilderMap {
|
||||||
spawn_list: Vec::new(),
|
spawn_list: Vec::new(),
|
||||||
map: Map::new(new_depth),
|
map: Map::new(new_depth, width, height),
|
||||||
starting_position: None,
|
starting_position: None,
|
||||||
rooms: None,
|
rooms: None,
|
||||||
corridors: None,
|
corridors: None,
|
||||||
history: Vec::new(),
|
history: Vec::new(),
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -166,7 +170,7 @@ fn random_room_builder(rng: &mut rltk::RandomNumberGenerator, builder: &mut Buil
|
||||||
let build_roll = rng.roll_dice(1, 3);
|
let build_roll = rng.roll_dice(1, 3);
|
||||||
// Start with a room builder.
|
// Start with a room builder.
|
||||||
match build_roll {
|
match build_roll {
|
||||||
1 => builder.start_with(SimpleMapBuilder::new()),
|
1 => builder.start_with(SimpleMapBuilder::new(None)),
|
||||||
2 => builder.start_with(BspDungeonBuilder::new()),
|
2 => builder.start_with(BspDungeonBuilder::new()),
|
||||||
_ => builder.start_with(BspInteriorBuilder::new()),
|
_ => builder.start_with(BspInteriorBuilder::new()),
|
||||||
}
|
}
|
||||||
|
|
@ -271,8 +275,8 @@ fn random_shape_builder(rng: &mut rltk::RandomNumberGenerator, builder: &mut Bui
|
||||||
builder.with(DistantExit::new());
|
builder.with(DistantExit::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn random_builder(new_depth: i32, rng: &mut rltk::RandomNumberGenerator) -> BuilderChain {
|
pub fn random_builder(new_depth: i32, rng: &mut rltk::RandomNumberGenerator, width: i32, height: i32) -> BuilderChain {
|
||||||
/*let mut builder = BuilderChain::new(new_depth);
|
let mut builder = BuilderChain::new(new_depth, width, height);
|
||||||
let type_roll = rng.roll_dice(1, 2);
|
let type_roll = rng.roll_dice(1, 2);
|
||||||
match type_roll {
|
match type_roll {
|
||||||
1 => random_room_builder(rng, &mut builder),
|
1 => random_room_builder(rng, &mut builder),
|
||||||
|
|
@ -298,14 +302,5 @@ pub fn random_builder(new_depth: i32, rng: &mut rltk::RandomNumberGenerator) ->
|
||||||
builder.with(DoorPlacement::new());
|
builder.with(DoorPlacement::new());
|
||||||
builder.with(PrefabBuilder::vaults());
|
builder.with(PrefabBuilder::vaults());
|
||||||
|
|
||||||
builder*/
|
|
||||||
|
|
||||||
let mut builder = BuilderChain::new(new_depth);
|
|
||||||
builder.start_with(BspInteriorBuilder::new());
|
|
||||||
builder.with(DoorPlacement::new());
|
|
||||||
builder.with(RoomBasedSpawner::new());
|
|
||||||
builder.with(PrefabBuilder::vaults());
|
|
||||||
builder.with(RoomBasedStairs::new());
|
|
||||||
builder.with(RoomBasedStartingPosition::new());
|
|
||||||
builder
|
builder
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,11 @@ impl PrefabBuilder {
|
||||||
build_data.spawn_list.push((idx, scroll_table(build_data.map.depth).roll(rng)));
|
build_data.spawn_list.push((idx, scroll_table(build_data.map.depth).roll(rng)));
|
||||||
// Placeholder for scroll spawn
|
// Placeholder for scroll spawn
|
||||||
}
|
}
|
||||||
|
')' => {
|
||||||
|
build_data.map.tiles[idx] = TileType::Floor;
|
||||||
|
build_data.spawn_list.push((idx, equipment_table(build_data.map.depth).roll(rng)));
|
||||||
|
// Placeholder for scroll spawn
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
rltk::console::log(format!("Unknown glyph '{}' when loading prefab", (ch as u8) as char));
|
rltk::console::log(format!("Unknown glyph '{}' when loading prefab", (ch as u8) as char));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use super::{BuilderMap, MetaMapBuilder, Rect};
|
use super::{BuilderMap, MetaMapBuilder, Rect};
|
||||||
use rltk::RandomNumberGenerator;
|
use rltk::RandomNumberGenerator;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub enum RoomSort {
|
pub enum RoomSort {
|
||||||
LEFTMOST,
|
LEFTMOST,
|
||||||
RIGHTMOST,
|
RIGHTMOST,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
use super::{apply_room_to_map, apply_vertical_tunnel, BuilderMap, InitialMapBuilder, Rect};
|
use super::{BuilderMap, InitialMapBuilder, Rect};
|
||||||
use rltk::RandomNumberGenerator;
|
use rltk::RandomNumberGenerator;
|
||||||
|
|
||||||
pub struct SimpleMapBuilder {}
|
pub struct SimpleMapBuilder {
|
||||||
|
room_params: (i32, i32, i32),
|
||||||
|
}
|
||||||
|
|
||||||
impl InitialMapBuilder for SimpleMapBuilder {
|
impl InitialMapBuilder for SimpleMapBuilder {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
|
@ -12,19 +14,28 @@ impl InitialMapBuilder for SimpleMapBuilder {
|
||||||
|
|
||||||
impl SimpleMapBuilder {
|
impl SimpleMapBuilder {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn new() -> Box<SimpleMapBuilder> {
|
pub fn new(room_params: Option<(i32, i32, i32)>) -> Box<SimpleMapBuilder> {
|
||||||
Box::new(SimpleMapBuilder {})
|
const DEFAULT_MAX_ROOMS: i32 = 40;
|
||||||
|
const DEFAULT_MIN_SIZE: i32 = 6;
|
||||||
|
const DEFAULT_MAX_SIZE: i32 = 16;
|
||||||
|
|
||||||
|
let (max_rooms, min_size, max_size);
|
||||||
|
|
||||||
|
if let Some(room_params) = room_params {
|
||||||
|
(max_rooms, min_size, max_size) = (room_params.0, room_params.1, room_params.2)
|
||||||
|
} else {
|
||||||
|
(max_rooms, min_size, max_size) = (DEFAULT_MAX_ROOMS, DEFAULT_MIN_SIZE, DEFAULT_MAX_SIZE)
|
||||||
|
}
|
||||||
|
|
||||||
|
Box::new(SimpleMapBuilder { room_params: (max_rooms, min_size, max_size) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_rooms(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
fn build_rooms(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||||
const MAX_ROOMS: i32 = 30;
|
|
||||||
const MIN_SIZE: i32 = 6;
|
|
||||||
const MAX_SIZE: i32 = 10;
|
|
||||||
let mut rooms: Vec<Rect> = Vec::new();
|
let mut rooms: Vec<Rect> = Vec::new();
|
||||||
|
|
||||||
for _i in 0..MAX_ROOMS {
|
for _i in 0..self.room_params.0 {
|
||||||
let w = rng.range(MIN_SIZE, MAX_SIZE);
|
let w = rng.range(self.room_params.1, self.room_params.2);
|
||||||
let h = rng.range(MIN_SIZE, MAX_SIZE);
|
let h = rng.range(self.room_params.1, self.room_params.2);
|
||||||
let x = rng.roll_dice(1, build_data.map.width - w - 1) - 1;
|
let x = rng.roll_dice(1, build_data.map.width - w - 1) - 1;
|
||||||
let y = rng.roll_dice(1, build_data.map.height - h - 1) - 1;
|
let y = rng.roll_dice(1, build_data.map.height - h - 1) - 1;
|
||||||
let new_room = Rect::new(x, y, w, h);
|
let new_room = Rect::new(x, y, w, h);
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ impl WaveFunctionCollapseBuilder {
|
||||||
let constraints = patterns_to_constraints(patterns, CHUNK_SIZE);
|
let constraints = patterns_to_constraints(patterns, CHUNK_SIZE);
|
||||||
self.render_tile_gallery(&constraints, CHUNK_SIZE, build_data);
|
self.render_tile_gallery(&constraints, CHUNK_SIZE, build_data);
|
||||||
|
|
||||||
build_data.map = Map::new(build_data.map.depth);
|
build_data.map = Map::new(build_data.map.depth, build_data.map.width, build_data.map.height);
|
||||||
loop {
|
loop {
|
||||||
let mut solver = Solver::new(constraints.clone(), CHUNK_SIZE, &build_data.map);
|
let mut solver = Solver::new(constraints.clone(), CHUNK_SIZE, &build_data.map);
|
||||||
while !solver.iteration(&mut build_data.map, rng) {
|
while !solver.iteration(&mut build_data.map, rng) {
|
||||||
|
|
@ -46,7 +46,7 @@ impl WaveFunctionCollapseBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_tile_gallery(&mut self, constraints: &[MapChunk], chunk_size: i32, build_data: &mut BuilderMap) {
|
fn render_tile_gallery(&mut self, constraints: &[MapChunk], chunk_size: i32, build_data: &mut BuilderMap) {
|
||||||
build_data.map = Map::new(0);
|
build_data.map = Map::new(0, build_data.width, build_data.height);
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
let mut x = 1;
|
let mut x = 1;
|
||||||
let mut y = 1;
|
let mut y = 1;
|
||||||
|
|
@ -62,7 +62,7 @@ impl WaveFunctionCollapseBuilder {
|
||||||
if y + chunk_size > build_data.map.height {
|
if y + chunk_size > build_data.map.height {
|
||||||
// Move to the next page
|
// Move to the next page
|
||||||
build_data.take_snapshot();
|
build_data.take_snapshot();
|
||||||
build_data.map = Map::new(0);
|
build_data.map = Map::new(0, build_data.width, build_data.height);
|
||||||
|
|
||||||
x = 1;
|
x = 1;
|
||||||
y = 1;
|
y = 1;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use super::{
|
use super::{
|
||||||
gamelog, BlocksTile, BlocksVisibility, CombatStats, Door, EntityMoved, Hidden, HungerClock, HungerState, Item, Map,
|
gamelog, BlocksTile, BlocksVisibility, CombatStats, Door, EntityMoved, Hidden, HungerClock, HungerState, Item, Map,
|
||||||
Monster, Name, Player, Position, Renderable, RunState, State, SufferDamage, Telepath, TileType, Viewshed,
|
Monster, Name, Player, Position, Renderable, RunState, State, SufferDamage, Telepath, TileType, Viewshed,
|
||||||
WantsToMelee, WantsToPickupItem, MAPHEIGHT, MAPWIDTH,
|
WantsToMelee, WantsToPickupItem,
|
||||||
};
|
};
|
||||||
use rltk::{Point, RandomNumberGenerator, Rltk, VirtualKeyCode};
|
use rltk::{Point, RandomNumberGenerator, Rltk, VirtualKeyCode};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
@ -24,7 +24,7 @@ pub fn try_door(i: i32, j: i32, ecs: &mut World) -> RunState {
|
||||||
let mut result = RunState::AwaitingInput;
|
let mut result = RunState::AwaitingInput;
|
||||||
let mut door_pos: Option<Point> = None;
|
let mut door_pos: Option<Point> = None;
|
||||||
|
|
||||||
for (_entity, _player, pos, viewshed) in (&entities, &mut players, &mut positions, &mut viewsheds).join() {
|
for (_entity, _player, pos) in (&entities, &mut players, &mut positions).join() {
|
||||||
let delta_x = i;
|
let delta_x = i;
|
||||||
let delta_y = j;
|
let delta_y = j;
|
||||||
|
|
||||||
|
|
@ -104,7 +104,7 @@ pub fn open(i: i32, j: i32, ecs: &mut World) -> RunState {
|
||||||
let mut result = RunState::AwaitingInput;
|
let mut result = RunState::AwaitingInput;
|
||||||
let mut door_pos: Option<Point> = None;
|
let mut door_pos: Option<Point> = None;
|
||||||
|
|
||||||
for (_entity, _player, pos, viewshed) in (&entities, &mut players, &mut positions, &mut viewsheds).join() {
|
for (_entity, _player, pos) in (&entities, &mut players, &mut positions).join() {
|
||||||
let delta_x = i;
|
let delta_x = i;
|
||||||
let delta_y = j;
|
let delta_y = j;
|
||||||
|
|
||||||
|
|
@ -173,7 +173,7 @@ pub fn kick(i: i32, j: i32, ecs: &mut World) -> RunState {
|
||||||
let names = ecs.read_storage::<Name>();
|
let names = ecs.read_storage::<Name>();
|
||||||
let mut rng = ecs.write_resource::<RandomNumberGenerator>();
|
let mut rng = ecs.write_resource::<RandomNumberGenerator>();
|
||||||
|
|
||||||
for (entity, _player, pos, viewshed) in (&entities, &mut players, &mut positions, &mut viewsheds).join() {
|
for (entity, _player, pos) in (&entities, &mut players, &mut positions).join() {
|
||||||
let delta_x = i;
|
let delta_x = i;
|
||||||
let delta_y = j;
|
let delta_y = j;
|
||||||
|
|
||||||
|
|
@ -335,8 +335,8 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) -> bool {
|
||||||
}
|
}
|
||||||
logger.period().log();
|
logger.period().log();
|
||||||
}
|
}
|
||||||
pos.x = min((MAPWIDTH as i32) - 1, max(0, pos.x + delta_x));
|
pos.x = min(map.width - 1, max(0, pos.x + delta_x));
|
||||||
pos.y = min((MAPHEIGHT as i32) - 1, max(0, pos.y + delta_y));
|
pos.y = min(map.height - 1, max(0, pos.y + delta_y));
|
||||||
|
|
||||||
// Dirty viewsheds, and check only now if telepath viewshed exists
|
// Dirty viewsheds, and check only now if telepath viewshed exists
|
||||||
viewshed.dirty = true;
|
viewshed.dirty = true;
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ pub fn load_game(ecs: &mut World) {
|
||||||
for (e, h) in (&entities, &helper).join() {
|
for (e, h) in (&entities, &helper).join() {
|
||||||
let mut worldmap = ecs.write_resource::<super::map::Map>();
|
let mut worldmap = ecs.write_resource::<super::map::Map>();
|
||||||
*worldmap = h.map.clone();
|
*worldmap = h.map.clone();
|
||||||
worldmap.tile_content = vec![Vec::new(); super::map::MAPCOUNT];
|
worldmap.tile_content = vec![Vec::new(); (worldmap.width * worldmap.height) as usize];
|
||||||
deleteme = Some(e);
|
deleteme = Some(e);
|
||||||
crate::gamelog::restore_log(&mut h.log.clone());
|
crate::gamelog::restore_log(&mut h.log.clone());
|
||||||
crate::gamelog::load_events(h.events.clone());
|
crate::gamelog::load_events(h.events.clone());
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use super::{
|
||||||
Cursed, DefenceBonus, Destructible, Digger, Door, EntryTrigger, EquipmentSlot, Equippable, Hidden, HungerClock,
|
Cursed, DefenceBonus, Destructible, Digger, Door, EntryTrigger, EquipmentSlot, Equippable, Hidden, HungerClock,
|
||||||
HungerState, InflictsDamage, Item, MagicMapper, Map, MeleePowerBonus, Mind, Monster, Name, Player, Position,
|
HungerState, InflictsDamage, Item, MagicMapper, Map, MeleePowerBonus, Mind, Monster, Name, Player, Position,
|
||||||
ProvidesHealing, ProvidesNutrition, Ranged, Rect, Renderable, SerializeMe, SingleActivation, TileType, Viewshed,
|
ProvidesHealing, ProvidesNutrition, Ranged, Rect, Renderable, SerializeMe, SingleActivation, TileType, Viewshed,
|
||||||
Wand, AOE, MAPWIDTH,
|
Wand, AOE,
|
||||||
};
|
};
|
||||||
use rltk::{console, RandomNumberGenerator, RGB};
|
use rltk::{console, RandomNumberGenerator, RGB};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
@ -141,8 +141,11 @@ pub fn spawn_region(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn_entity(ecs: &mut World, spawn: &(&usize, &String)) {
|
pub fn spawn_entity(ecs: &mut World, spawn: &(&usize, &String)) {
|
||||||
let x = (*spawn.0 % MAPWIDTH) as i32;
|
let map = ecs.fetch::<Map>();
|
||||||
let y = (*spawn.0 / MAPWIDTH) as i32;
|
let width = map.width as usize;
|
||||||
|
std::mem::drop(map);
|
||||||
|
let x = (*spawn.0 % width) as i32;
|
||||||
|
let y = (*spawn.0 / width) as i32;
|
||||||
|
|
||||||
match spawn.1.as_ref() {
|
match spawn.1.as_ref() {
|
||||||
// Monsters
|
// Monsters
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue