overmap, refactor offsets
This commit is contained in:
parent
9e294a1680
commit
746de971f0
14 changed files with 322 additions and 95 deletions
|
|
@ -7,13 +7,24 @@ const SHOW_BOUNDARIES: bool = false;
|
||||||
|
|
||||||
pub fn get_screen_bounds(ecs: &World, _ctx: &mut Rltk) -> (i32, i32, i32, i32, i32, i32) {
|
pub fn get_screen_bounds(ecs: &World, _ctx: &mut Rltk) -> (i32, i32, i32, i32, i32, i32) {
|
||||||
let player_pos = ecs.fetch::<Point>();
|
let player_pos = ecs.fetch::<Point>();
|
||||||
let (x_chars, y_chars, x_offset, y_offset) = (69, 41, 1, 10);
|
let map = ecs.fetch::<Map>();
|
||||||
|
let (x_chars, y_chars, mut x_offset, mut y_offset) = (69, 41, 1, 10);
|
||||||
|
|
||||||
let centre_x = (x_chars / 2) as i32;
|
let centre_x = (x_chars / 2) as i32;
|
||||||
let centre_y = (y_chars / 2) as i32;
|
let centre_y = (y_chars / 2) as i32;
|
||||||
|
|
||||||
let min_x = player_pos.x - centre_x;
|
let min_x = if map.width < (x_chars as i32) {
|
||||||
let min_y = player_pos.y - centre_y;
|
x_offset += ((x_chars as i32) - map.width) / 2;
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
(player_pos.x - centre_x).clamp(0, map.width - (x_chars as i32))
|
||||||
|
};
|
||||||
|
let min_y = if map.height < (y_chars as i32) {
|
||||||
|
y_offset += ((y_chars as i32) - map.height) / 2;
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
(player_pos.y - centre_y).clamp(0, map.height - (y_chars as i32))
|
||||||
|
};
|
||||||
let max_x = min_x + (x_chars as i32);
|
let max_x = min_x + (x_chars as i32);
|
||||||
let max_y = min_y + (y_chars as i32);
|
let max_y = min_y + (y_chars as i32);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ pub const WITH_SCANLINES: bool = false; // Adds scanlines to the screen.
|
||||||
pub const WITH_SCREEN_BURN: bool = false; // Requires WITH_SCANLINES.
|
pub const WITH_SCREEN_BURN: bool = false; // Requires WITH_SCANLINES.
|
||||||
pub const WITH_DARKEN_BY_DISTANCE: bool = true; // If further away tiles should get darkened, instead of a harsh transition to non-visible.
|
pub const WITH_DARKEN_BY_DISTANCE: bool = true; // If further away tiles should get darkened, instead of a harsh transition to non-visible.
|
||||||
|
|
||||||
pub const MAX_COLOUR_OFFSET_PERCENT: i32 = 30;
|
pub const MAX_COLOUR_OFFSET: i32 = 30;
|
||||||
pub const WITH_SCANLINES_BRIGHTEN_AMOUNT: f32 = 0.1; // 0.0 = no brightening, 1.0 = full brightening.
|
pub const WITH_SCANLINES_BRIGHTEN_AMOUNT: f32 = 0.1; // 0.0 = no brightening, 1.0 = full brightening.
|
||||||
pub const NON_VISIBLE_MULTIPLIER: f32 = 0.3; // 0.0 = black, 1.0 = full colour.
|
pub const NON_VISIBLE_MULTIPLIER: f32 = 0.3; // 0.0 = black, 1.0 = full colour.
|
||||||
pub const NON_VISIBLE_MULTIPLIER_IF_SCANLINES: f32 = 0.8; // as above, but when using scanlines. should be higher.
|
pub const NON_VISIBLE_MULTIPLIER_IF_SCANLINES: f32 = 0.8; // as above, but when using scanlines. should be higher.
|
||||||
|
|
@ -35,6 +35,8 @@ pub const SAND_COLOUR: (u8, u8, u8) = (70, 70, 21);
|
||||||
pub const SHALLOW_WATER_COLOUR: (u8, u8, u8) = (24, 47, 99);
|
pub const SHALLOW_WATER_COLOUR: (u8, u8, u8) = (24, 47, 99);
|
||||||
pub const DEEP_WATER_COLOUR: (u8, u8, u8) = (18, 33, 63);
|
pub const DEEP_WATER_COLOUR: (u8, u8, u8) = (18, 33, 63);
|
||||||
pub const BARS_COLOUR: (u8, u8, u8) = (100, 100, 100);
|
pub const BARS_COLOUR: (u8, u8, u8) = (100, 100, 100);
|
||||||
|
pub const IMPASSABLE_MOUNTAIN_COLOUR: (u8, u8, u8) = (35, 38, 36);
|
||||||
|
pub const IMPASSABLE_MOUNTAIN_FG_COLOUR: (u8, u8, u8) = (0, 0, 0);
|
||||||
// FOREST THEME
|
// FOREST THEME
|
||||||
pub const FOREST_WALL_COLOUR: (u8, u8, u8) = (0, 153, 0);
|
pub const FOREST_WALL_COLOUR: (u8, u8, u8) = (0, 153, 0);
|
||||||
|
|
||||||
|
|
@ -56,6 +58,7 @@ pub const SAND_GLYPH: char = '.';
|
||||||
pub const SHALLOW_WATER_GLYPH: char = '~';
|
pub const SHALLOW_WATER_GLYPH: char = '~';
|
||||||
pub const DEEP_WATER_GLYPH: char = '≈';
|
pub const DEEP_WATER_GLYPH: char = '≈';
|
||||||
pub const BARS_GLYPH: char = '#';
|
pub const BARS_GLYPH: char = '#';
|
||||||
|
pub const IMPASSABLE_MOUNTAIN_GLYPH: char = '▲';
|
||||||
|
|
||||||
// FOREST THEME
|
// FOREST THEME
|
||||||
pub const FOREST_WALL_GLYPH: char = '♣';
|
pub const FOREST_WALL_GLYPH: char = '♣';
|
||||||
|
|
|
||||||
|
|
@ -723,7 +723,7 @@ fn main() -> rltk::BError {
|
||||||
// Insert calls
|
// Insert calls
|
||||||
gs.ecs.insert(rltk::RandomNumberGenerator::new());
|
gs.ecs.insert(rltk::RandomNumberGenerator::new());
|
||||||
gs.ecs.insert(map::MasterDungeonMap::new()); // Master map list
|
gs.ecs.insert(map::MasterDungeonMap::new()); // Master map list
|
||||||
gs.ecs.insert(Map::new(1, 64, 64, 0, "New Map")); // Map
|
gs.ecs.insert(Map::new(true, 1, 64, 64, 0, "New Map")); // Map
|
||||||
gs.ecs.insert(Point::new(0, 0)); // Player pos
|
gs.ecs.insert(Point::new(0, 0)); // Player pos
|
||||||
gs.ecs.insert(gui::Ancestry::Dwarf); // ancestry
|
gs.ecs.insert(gui::Ancestry::Dwarf); // ancestry
|
||||||
let player_entity = spawner::player(&mut gs.ecs, 0, 0);
|
let player_entity = spawner::player(&mut gs.ecs, 0, 0);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ pub use interval_spawning_system::try_spawn_interval;
|
||||||
pub mod dungeon;
|
pub mod dungeon;
|
||||||
pub use dungeon::{ level_transition, MasterDungeonMap };
|
pub use dungeon::{ level_transition, MasterDungeonMap };
|
||||||
pub mod themes;
|
pub mod themes;
|
||||||
use crate::data::visuals::MAX_COLOUR_OFFSET_PERCENT;
|
use crate::data::visuals::MAX_COLOUR_OFFSET;
|
||||||
|
|
||||||
// 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.
|
||||||
|
|
@ -16,6 +16,7 @@ use crate::data::visuals::MAX_COLOUR_OFFSET_PERCENT;
|
||||||
|
|
||||||
#[derive(Default, Serialize, Deserialize, Clone)]
|
#[derive(Default, Serialize, Deserialize, Clone)]
|
||||||
pub struct Map {
|
pub struct Map {
|
||||||
|
pub overmap: bool,
|
||||||
pub tiles: Vec<TileType>,
|
pub tiles: Vec<TileType>,
|
||||||
pub width: i32,
|
pub width: i32,
|
||||||
pub height: i32,
|
pub height: i32,
|
||||||
|
|
@ -23,7 +24,7 @@ pub struct Map {
|
||||||
pub visible_tiles: Vec<bool>,
|
pub visible_tiles: Vec<bool>,
|
||||||
pub lit_tiles: Vec<bool>,
|
pub lit_tiles: Vec<bool>,
|
||||||
pub telepath_tiles: Vec<bool>,
|
pub telepath_tiles: Vec<bool>,
|
||||||
pub colour_offset: Vec<(f32, f32, f32)>,
|
pub colour_offset: Vec<(i32, i32, i32)>,
|
||||||
pub additional_fg_offset: rltk::RGB,
|
pub additional_fg_offset: rltk::RGB,
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
@ -37,10 +38,11 @@ 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<S: ToString>(new_id: i32, width: i32, height: i32, difficulty: i32, name: S) -> Map {
|
pub fn new<S: ToString>(overmap: bool, new_id: i32, width: i32, height: i32, difficulty: i32, name: S) -> Map {
|
||||||
let map_tile_count = (width * height) as usize;
|
let map_tile_count = (width * height) as usize;
|
||||||
crate::spatial::set_size(map_tile_count);
|
crate::spatial::set_size(map_tile_count);
|
||||||
let mut map = Map {
|
let mut map = Map {
|
||||||
|
overmap: overmap,
|
||||||
tiles: vec![TileType::Wall; map_tile_count],
|
tiles: vec![TileType::Wall; map_tile_count],
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
|
|
@ -48,11 +50,11 @@ impl Map {
|
||||||
visible_tiles: vec![false; map_tile_count],
|
visible_tiles: vec![false; map_tile_count],
|
||||||
lit_tiles: vec![true; map_tile_count], // 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; map_tile_count],
|
telepath_tiles: vec![false; map_tile_count],
|
||||||
colour_offset: vec![(1.0, 1.0, 1.0); map_tile_count],
|
colour_offset: vec![(0, 0, 0); map_tile_count],
|
||||||
additional_fg_offset: rltk::RGB::from_u8(
|
additional_fg_offset: rltk::RGB::from_u8(
|
||||||
MAX_COLOUR_OFFSET_PERCENT as u8,
|
MAX_COLOUR_OFFSET as u8,
|
||||||
MAX_COLOUR_OFFSET_PERCENT as u8,
|
MAX_COLOUR_OFFSET as u8,
|
||||||
MAX_COLOUR_OFFSET_PERCENT as u8
|
MAX_COLOUR_OFFSET as u8
|
||||||
),
|
),
|
||||||
id: new_id,
|
id: new_id,
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
|
|
@ -61,16 +63,13 @@ impl Map {
|
||||||
view_blocked: HashSet::new(),
|
view_blocked: HashSet::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const TWICE_OFFSET: i32 = MAX_COLOUR_OFFSET_PERCENT * 2;
|
const TWICE_OFFSET: i32 = MAX_COLOUR_OFFSET * 2;
|
||||||
let mut rng = rltk::RandomNumberGenerator::new();
|
let mut rng = rltk::RandomNumberGenerator::new();
|
||||||
|
|
||||||
for idx in 0..map.colour_offset.len() {
|
for idx in 0..map.colour_offset.len() {
|
||||||
let red_roll: f32 =
|
let red_roll: i32 = rng.roll_dice(1, TWICE_OFFSET) - MAX_COLOUR_OFFSET;
|
||||||
((rng.roll_dice(1, TWICE_OFFSET - 1) + 1 - MAX_COLOUR_OFFSET_PERCENT) as f32) / 100f32 + 1.0;
|
let blue_roll: i32 = rng.roll_dice(1, TWICE_OFFSET) - MAX_COLOUR_OFFSET;
|
||||||
let green_roll: f32 =
|
let green_roll: i32 = rng.roll_dice(1, TWICE_OFFSET) - MAX_COLOUR_OFFSET;
|
||||||
((rng.roll_dice(1, TWICE_OFFSET - 1) + 1 - MAX_COLOUR_OFFSET_PERCENT) as f32) / 100f32 + 1.0;
|
|
||||||
let blue_roll: f32 =
|
|
||||||
((rng.roll_dice(1, TWICE_OFFSET - 1) + 1 - MAX_COLOUR_OFFSET_PERCENT) as f32) / 100f32 + 1.0;
|
|
||||||
map.colour_offset[idx] = (red_roll, green_roll, blue_roll);
|
map.colour_offset[idx] = (red_roll, green_roll, blue_roll);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ pub fn get_tile_renderables_for_id(
|
||||||
other_pos: Option<Point>,
|
other_pos: Option<Point>,
|
||||||
debug: Option<bool>
|
debug: Option<bool>
|
||||||
) -> (rltk::FontCharType, RGB, RGB) {
|
) -> (rltk::FontCharType, RGB, RGB) {
|
||||||
let (glyph, mut fg, mut bg) = match map.id {
|
let (glyph, mut fg, mut bg, offset_mod) = match map.id {
|
||||||
2 => get_forest_theme_renderables(idx, map, debug),
|
3 => get_forest_theme_renderables(idx, map, debug),
|
||||||
_ => get_default_theme_renderables(idx, map, debug),
|
_ => get_default_theme_renderables(idx, map, debug),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -24,7 +24,7 @@ pub fn get_tile_renderables_for_id(
|
||||||
}
|
}
|
||||||
|
|
||||||
fg = fg.add(map.additional_fg_offset);
|
fg = fg.add(map.additional_fg_offset);
|
||||||
(fg, bg) = apply_colour_offset(fg, bg, map, idx);
|
(fg, bg) = apply_colour_offset(fg, bg, map, idx, offset_mod);
|
||||||
if CONFIG.visuals.with_scanlines && WITH_SCANLINES_BRIGHTEN_AMOUNT > 0.0 {
|
if CONFIG.visuals.with_scanlines && WITH_SCANLINES_BRIGHTEN_AMOUNT > 0.0 {
|
||||||
(fg, bg) = brighten_by(fg, bg, WITH_SCANLINES_BRIGHTEN_AMOUNT);
|
(fg, bg) = brighten_by(fg, bg, WITH_SCANLINES_BRIGHTEN_AMOUNT);
|
||||||
}
|
}
|
||||||
|
|
@ -60,12 +60,13 @@ pub fn get_tile_renderables_for_id(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn get_default_theme_renderables(idx: usize, map: &Map, debug: Option<bool>) -> (rltk::FontCharType, RGB, RGB) {
|
pub fn get_default_theme_renderables(idx: usize, map: &Map, debug: Option<bool>) -> (rltk::FontCharType, RGB, RGB, (f32, f32, f32)) {
|
||||||
let glyph: rltk::FontCharType;
|
let glyph: rltk::FontCharType;
|
||||||
#[allow(unused_assignments)]
|
#[allow(unused_assignments)]
|
||||||
let mut fg: RGB = RGB::new();
|
let mut fg: RGB = RGB::new();
|
||||||
#[allow(unused_assignments)]
|
#[allow(unused_assignments)]
|
||||||
let mut bg: RGB = RGB::new();
|
let mut bg: RGB = RGB::new();
|
||||||
|
let mut offset_mod: (f32, f32, f32) = (0.5, 0.2, 0.0);
|
||||||
|
|
||||||
match map.tiles[idx] {
|
match map.tiles[idx] {
|
||||||
TileType::Floor => { glyph = rltk::to_cp437(FLOOR_GLYPH); fg = RGB::named(FLOOR_COLOUR); bg = RGB::named(DEFAULT_BG_COLOUR); }
|
TileType::Floor => { glyph = rltk::to_cp437(FLOOR_GLYPH); fg = RGB::named(FLOOR_COLOUR); bg = RGB::named(DEFAULT_BG_COLOUR); }
|
||||||
|
|
@ -84,26 +85,28 @@ pub fn get_default_theme_renderables(idx: usize, map: &Map, debug: Option<bool>)
|
||||||
TileType::ShallowWater => { glyph = rltk::to_cp437(SHALLOW_WATER_GLYPH); bg = RGB::named(SHALLOW_WATER_COLOUR); }
|
TileType::ShallowWater => { glyph = rltk::to_cp437(SHALLOW_WATER_GLYPH); bg = RGB::named(SHALLOW_WATER_COLOUR); }
|
||||||
TileType::DeepWater => { glyph = rltk::to_cp437(DEEP_WATER_GLYPH); bg = RGB::named(DEEP_WATER_COLOUR); }
|
TileType::DeepWater => { glyph = rltk::to_cp437(DEEP_WATER_GLYPH); bg = RGB::named(DEEP_WATER_COLOUR); }
|
||||||
TileType::Bars => { glyph = rltk::to_cp437(BARS_GLYPH); fg = RGB::named(BARS_COLOUR); bg = RGB::named(FLOOR_COLOUR); }
|
TileType::Bars => { glyph = rltk::to_cp437(BARS_GLYPH); fg = RGB::named(BARS_COLOUR); bg = RGB::named(FLOOR_COLOUR); }
|
||||||
|
TileType::ImpassableMountain => { glyph = rltk::to_cp437(IMPASSABLE_MOUNTAIN_GLYPH); bg = RGB::named(IMPASSABLE_MOUNTAIN_COLOUR); fg = RGB::named((20, 20, 20)) }
|
||||||
}
|
}
|
||||||
return (glyph, fg, bg);
|
return (glyph, fg, bg, offset_mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn get_forest_theme_renderables(idx:usize, map: &Map, debug: Option<bool>) -> (rltk::FontCharType, RGB, RGB) {
|
fn get_forest_theme_renderables(idx:usize, map: &Map, debug: Option<bool>) -> (rltk::FontCharType, RGB, RGB, (f32, f32, f32)) {
|
||||||
let glyph;
|
let glyph;
|
||||||
#[allow(unused_assignments)]
|
#[allow(unused_assignments)]
|
||||||
let mut fg = RGB::new();
|
let mut fg = RGB::new();
|
||||||
#[allow(unused_assignments)]
|
#[allow(unused_assignments)]
|
||||||
let mut bg = RGB::new();
|
let mut bg = RGB::new();
|
||||||
|
let mut offset_mod: (f32, f32, f32) = (1.0, 1.0, 1.0);
|
||||||
|
|
||||||
match map.tiles[idx] {
|
match map.tiles[idx] {
|
||||||
TileType::Wall => { glyph = rltk::to_cp437(FOREST_WALL_GLYPH); fg = RGB::named(FOREST_WALL_COLOUR); bg = RGB::named(GRASS_COLOUR) }
|
TileType::Wall => { glyph = rltk::to_cp437(FOREST_WALL_GLYPH); fg = RGB::named(FOREST_WALL_COLOUR); bg = RGB::named(GRASS_COLOUR) }
|
||||||
TileType::Road => { glyph = rltk::to_cp437(ROAD_GLYPH); bg = RGB::named(ROAD_COLOUR); }
|
TileType::Road => { glyph = rltk::to_cp437(ROAD_GLYPH); bg = RGB::named(ROAD_COLOUR); }
|
||||||
TileType::ShallowWater => { glyph = rltk::to_cp437(SHALLOW_WATER_GLYPH); bg = RGB::named(SHALLOW_WATER_COLOUR); }
|
TileType::ShallowWater => { glyph = rltk::to_cp437(SHALLOW_WATER_GLYPH); bg = RGB::named(SHALLOW_WATER_COLOUR); }
|
||||||
_ => { (glyph, fg, _) = get_default_theme_renderables(idx, map, debug); bg = RGB::named(GRASS_COLOUR) }
|
_ => { (glyph, fg, _, offset_mod) = get_default_theme_renderables(idx, map, debug); bg = RGB::named(GRASS_COLOUR) }
|
||||||
}
|
}
|
||||||
|
|
||||||
(glyph, fg, bg)
|
(glyph, fg, bg, offset_mod)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_revealed_and_wall(map: &Map, x: i32, y: i32, debug: Option<bool>) -> bool {
|
fn is_revealed_and_wall(map: &Map, x: i32, y: i32, debug: Option<bool>) -> bool {
|
||||||
|
|
@ -248,10 +251,17 @@ fn wall_glyph(map: &Map, x: i32, y: i32, debug: Option<bool>) -> rltk::FontCharT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_colour_offset(mut fg: RGB, mut bg: RGB, map: &Map, idx: usize) -> (RGB, RGB) {
|
fn apply_colour_offset(mut fg: RGB, mut bg: RGB, map: &Map, idx: usize, offset_mod: (f32, f32, f32)) -> (RGB, RGB) {
|
||||||
let offsets = map.colour_offset[idx];
|
let mut offsets = map.colour_offset[idx];
|
||||||
fg = multiply_by_float(fg.add(map.additional_fg_offset), offsets);
|
let mut additional_fg_offset = map.additional_fg_offset;
|
||||||
bg = multiply_by_float(bg, offsets);
|
offsets.0 = ((offsets.0 as f32) * offset_mod.0) as i32;
|
||||||
|
offsets.1 = ((offsets.1 as f32) * offset_mod.1) as i32;
|
||||||
|
offsets.2 = ((offsets.2 as f32) * offset_mod.2) as i32;
|
||||||
|
additional_fg_offset.r *= offset_mod.0;
|
||||||
|
additional_fg_offset.g *= offset_mod.1;
|
||||||
|
additional_fg_offset.b *= offset_mod.2;
|
||||||
|
fg = add_i32_offsets(fg.add(additional_fg_offset), offsets);
|
||||||
|
bg = add_i32_offsets(bg, offsets);
|
||||||
return (fg, bg);
|
return (fg, bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -262,6 +272,14 @@ fn apply_bloodstain_if_necessary(mut bg: RGB, map: &Map, idx: usize) -> RGB {
|
||||||
return bg;
|
return bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_i32_offsets(rgb: RGB, offsets: (i32, i32, i32)) -> RGB {
|
||||||
|
let r = rgb.r + (offsets.0 as f32) / 255.0;
|
||||||
|
let g = rgb.g + (offsets.1 as f32) / 255.0;
|
||||||
|
let b = rgb.b + (offsets.2 as f32) / 255.0;
|
||||||
|
|
||||||
|
return rltk::RGB::from_f32(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn multiply_by_float(rgb: rltk::RGB, offsets: (f32, f32, f32)) -> RGB {
|
pub fn multiply_by_float(rgb: rltk::RGB, offsets: (f32, f32, f32)) -> RGB {
|
||||||
let r = rgb.r * offsets.0;
|
let r = rgb.r * offsets.0;
|
||||||
let g = rgb.g * offsets.1;
|
let g = rgb.g * offsets.1;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use serde::{ Deserialize, Serialize };
|
||||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize)]
|
#[derive(PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize)]
|
||||||
pub enum TileType {
|
pub enum TileType {
|
||||||
// Walls (opaque)
|
// Walls (opaque)
|
||||||
|
ImpassableMountain,
|
||||||
Wall,
|
Wall,
|
||||||
// Impassable (transparent)
|
// Impassable (transparent)
|
||||||
DeepWater,
|
DeepWater,
|
||||||
|
|
@ -44,6 +45,7 @@ pub fn tile_walkable(tt: TileType) -> bool {
|
||||||
|
|
||||||
pub fn tile_opaque(tt: TileType) -> bool {
|
pub fn tile_opaque(tt: TileType) -> bool {
|
||||||
match tt {
|
match tt {
|
||||||
|
TileType::ImpassableMountain => true,
|
||||||
TileType::Wall => true,
|
TileType::Wall => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ pub fn forest_builder(
|
||||||
difficulty: i32,
|
difficulty: i32,
|
||||||
initial_player_level: i32
|
initial_player_level: i32
|
||||||
) -> BuilderChain {
|
) -> BuilderChain {
|
||||||
let mut chain = BuilderChain::new(new_id, width, height, difficulty, "the woods", initial_player_level);
|
let mut chain = BuilderChain::new(false, new_id, width, height, difficulty, "the woods", initial_player_level);
|
||||||
chain.start_with(CellularAutomataBuilder::new());
|
chain.start_with(CellularAutomataBuilder::new());
|
||||||
chain.with(AreaStartingPosition::new(XStart::CENTRE, YStart::CENTRE));
|
chain.with(AreaStartingPosition::new(XStart::CENTRE, YStart::CENTRE));
|
||||||
chain.with(CullUnreachable::new());
|
chain.with(CullUnreachable::new());
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ pub struct BuilderChain {
|
||||||
|
|
||||||
impl BuilderChain {
|
impl BuilderChain {
|
||||||
pub fn new<S: ToString>(
|
pub fn new<S: ToString>(
|
||||||
|
overmap: bool,
|
||||||
new_id: i32,
|
new_id: i32,
|
||||||
width: i32,
|
width: i32,
|
||||||
height: i32,
|
height: i32,
|
||||||
|
|
@ -109,7 +110,7 @@ impl BuilderChain {
|
||||||
builders: Vec::new(),
|
builders: Vec::new(),
|
||||||
build_data: BuilderMap {
|
build_data: BuilderMap {
|
||||||
spawn_list: Vec::new(),
|
spawn_list: Vec::new(),
|
||||||
map: Map::new(new_id, width, height, difficulty, name),
|
map: Map::new(overmap, new_id, width, height, difficulty, name),
|
||||||
starting_position: None,
|
starting_position: None,
|
||||||
rooms: None,
|
rooms: None,
|
||||||
corridors: None,
|
corridors: None,
|
||||||
|
|
@ -316,6 +317,13 @@ fn random_shape_builder(rng: &mut rltk::RandomNumberGenerator, builder: &mut Bui
|
||||||
return want_doors;
|
return want_doors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn overmap_builder() -> BuilderChain {
|
||||||
|
let mut builder = BuilderChain::new(true, 1, 69, 41, 0, "the world", 1);
|
||||||
|
builder.start_with(PrefabBuilder::overmap());
|
||||||
|
builder.with(AreaStartingPosition::new(XStart::CENTRE, YStart::CENTRE));
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn random_builder(
|
pub fn random_builder(
|
||||||
new_id: i32,
|
new_id: i32,
|
||||||
rng: &mut rltk::RandomNumberGenerator,
|
rng: &mut rltk::RandomNumberGenerator,
|
||||||
|
|
@ -325,7 +333,7 @@ pub fn random_builder(
|
||||||
initial_player_level: i32
|
initial_player_level: i32
|
||||||
) -> BuilderChain {
|
) -> BuilderChain {
|
||||||
rltk::console::log(format!("DEBUGINFO: Building random (ID:{}, DIFF:{})", new_id, difficulty));
|
rltk::console::log(format!("DEBUGINFO: Building random (ID:{}, DIFF:{})", new_id, difficulty));
|
||||||
let mut builder = BuilderChain::new(new_id, width, height, difficulty, "the dungeon", initial_player_level);
|
let mut builder = BuilderChain::new(false, new_id, width, height, difficulty, "the dungeon", initial_player_level);
|
||||||
let type_roll = rng.roll_dice(1, 2);
|
let type_roll = rng.roll_dice(1, 2);
|
||||||
let mut want_doors = true;
|
let mut want_doors = true;
|
||||||
match type_roll {
|
match type_roll {
|
||||||
|
|
@ -378,8 +386,9 @@ pub fn level_builder(
|
||||||
// TODO: With difficulty and ID/depth decoupled, this can be used for branches later.
|
// TODO: With difficulty and ID/depth decoupled, this can be used for branches later.
|
||||||
let difficulty = new_id;
|
let difficulty = new_id;
|
||||||
match new_id {
|
match new_id {
|
||||||
1 => town_builder(new_id, rng, width, height, 0, initial_player_level),
|
1 => overmap_builder(),
|
||||||
2 => forest_builder(new_id, rng, width, height, 1, initial_player_level),
|
2 => town_builder(new_id, rng, width, height, 0, initial_player_level),
|
||||||
|
3 => forest_builder(new_id, rng, width, height, 1, initial_player_level),
|
||||||
_ => random_builder(new_id, rng, width, height, difficulty, initial_player_level),
|
_ => random_builder(new_id, rng, width, height, difficulty, initial_player_level),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{spawner, BuilderMap, InitialMapBuilder, MetaMapBuilder, Position, TileType};
|
use super::{ spawner, BuilderMap, InitialMapBuilder, MetaMapBuilder, Position, TileType };
|
||||||
use rltk::RandomNumberGenerator;
|
use rltk::RandomNumberGenerator;
|
||||||
pub mod prefab_levels;
|
pub mod prefab_levels;
|
||||||
pub mod prefab_sections;
|
pub mod prefab_sections;
|
||||||
|
|
@ -8,9 +8,13 @@ use std::collections::HashSet;
|
||||||
#[derive(PartialEq, Copy, Clone)]
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub enum PrefabMode {
|
pub enum PrefabMode {
|
||||||
RexLevel { template: &'static str },
|
Overmap,
|
||||||
Constant { level: prefab_levels::PrefabLevel },
|
Constant {
|
||||||
Sectional { section: prefab_sections::PrefabSection },
|
level: prefab_levels::PrefabLevel,
|
||||||
|
},
|
||||||
|
Sectional {
|
||||||
|
section: prefab_sections::PrefabSection,
|
||||||
|
},
|
||||||
RoomVaults,
|
RoomVaults,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,8 +43,8 @@ impl PrefabBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn rex_level(template: &'static str) -> Box<PrefabBuilder> {
|
pub fn overmap() -> Box<PrefabBuilder> {
|
||||||
Box::new(PrefabBuilder { mode: PrefabMode::RexLevel { template } })
|
Box::new(PrefabBuilder { mode: PrefabMode::Overmap })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
|
@ -60,8 +64,8 @@ impl PrefabBuilder {
|
||||||
|
|
||||||
fn build(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
fn build(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
PrefabMode::RexLevel { template } => self.load_rex_map(&template, rng, build_data),
|
PrefabMode::Overmap => self.load_ascii_map(&prefab_levels::OVERMAP, rng, build_data, true),
|
||||||
PrefabMode::Constant { level } => self.load_ascii_map(&level, rng, build_data),
|
PrefabMode::Constant { level } => self.load_ascii_map(&level, rng, build_data, false),
|
||||||
PrefabMode::Sectional { section } => self.apply_sectional(§ion, rng, build_data),
|
PrefabMode::Sectional { section } => self.apply_sectional(§ion, rng, build_data),
|
||||||
PrefabMode::RoomVaults => self.apply_room_vaults(rng, build_data),
|
PrefabMode::RoomVaults => self.apply_room_vaults(rng, build_data),
|
||||||
}
|
}
|
||||||
|
|
@ -71,13 +75,24 @@ impl PrefabBuilder {
|
||||||
fn char_to_map(&mut self, ch: char, idx: usize, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
fn char_to_map(&mut self, ch: char, idx: usize, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
|
||||||
let difficulty = (build_data.map.difficulty + build_data.initial_player_level) / 2;
|
let difficulty = (build_data.map.difficulty + build_data.initial_player_level) / 2;
|
||||||
match ch {
|
match ch {
|
||||||
' ' => build_data.map.tiles[idx] = TileType::Floor,
|
' ' => {
|
||||||
'#' => build_data.map.tiles[idx] = TileType::Wall,
|
build_data.map.tiles[idx] = TileType::Floor;
|
||||||
'>' => build_data.map.tiles[idx] = TileType::DownStair,
|
}
|
||||||
'≈' => build_data.map.tiles[idx] = TileType::Floor, // Placeholder for vines/brush
|
'.' => {
|
||||||
|
build_data.map.tiles[idx] = TileType::Grass;
|
||||||
|
}
|
||||||
|
'#' => {
|
||||||
|
build_data.map.tiles[idx] = TileType::Wall;
|
||||||
|
}
|
||||||
|
'>' => {
|
||||||
|
build_data.map.tiles[idx] = TileType::DownStair;
|
||||||
|
}
|
||||||
|
'≈' => {
|
||||||
|
build_data.map.tiles[idx] = TileType::DeepWater;
|
||||||
|
} // Placeholder for vines/brush
|
||||||
'@' => {
|
'@' => {
|
||||||
let x = idx as i32 % build_data.map.width;
|
let x = (idx as i32) % build_data.map.width;
|
||||||
let y = idx as i32 / build_data.map.width;
|
let y = (idx as i32) / build_data.map.width;
|
||||||
build_data.map.tiles[idx] = TileType::Floor;
|
build_data.map.tiles[idx] = TileType::Floor;
|
||||||
build_data.starting_position = Some(Position { x: x as i32, y: y as i32 });
|
build_data.starting_position = Some(Position { x: x as i32, y: y as i32 });
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +137,48 @@ impl PrefabBuilder {
|
||||||
build_data.spawn_list.push((idx, spawner::equipment_table(Some(difficulty)).roll(rng)));
|
build_data.spawn_list.push((idx, spawner::equipment_table(Some(difficulty)).roll(rng)));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn overmap_char_to_map(
|
||||||
|
&mut self,
|
||||||
|
ch: char,
|
||||||
|
idx: usize,
|
||||||
|
_rng: &mut RandomNumberGenerator,
|
||||||
|
build_data: &mut BuilderMap
|
||||||
|
) {
|
||||||
|
match ch {
|
||||||
|
' ' => {
|
||||||
|
build_data.map.tiles[idx] = TileType::Floor;
|
||||||
|
}
|
||||||
|
'.' => {
|
||||||
|
build_data.map.tiles[idx] = TileType::Grass;
|
||||||
|
}
|
||||||
|
'#' => {
|
||||||
|
build_data.map.tiles[idx] = TileType::Wall;
|
||||||
|
}
|
||||||
|
'>' => {
|
||||||
|
build_data.map.tiles[idx] = TileType::DownStair;
|
||||||
|
}
|
||||||
|
'~' => {
|
||||||
|
build_data.map.tiles[idx] = TileType::ShallowWater;
|
||||||
|
}
|
||||||
|
'≈' => {
|
||||||
|
build_data.map.tiles[idx] = TileType::DeepWater;
|
||||||
|
}
|
||||||
|
'@' => {
|
||||||
|
let x = (idx as i32) % build_data.map.width;
|
||||||
|
let y = (idx as i32) / build_data.map.width;
|
||||||
|
build_data.map.tiles[idx] = TileType::Grass;
|
||||||
|
build_data.starting_position = Some(Position { x: x as i32, y: y as i32 });
|
||||||
|
}
|
||||||
|
'^' => {
|
||||||
|
build_data.map.tiles[idx] = TileType::ImpassableMountain;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
rltk::console::log(format!("Unknown glyph '{}' when loading overmap", ch as u8 as char));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -135,7 +191,7 @@ impl PrefabBuilder {
|
||||||
for y in 0..layer.height {
|
for y in 0..layer.height {
|
||||||
for x in 0..layer.width {
|
for x in 0..layer.width {
|
||||||
let cell = layer.get(x, y).unwrap();
|
let cell = layer.get(x, y).unwrap();
|
||||||
if x < build_data.map.width as usize && y < build_data.map.height as usize {
|
if x < (build_data.map.width as usize) && y < (build_data.map.height as usize) {
|
||||||
let idx = build_data.map.xy_idx(x as i32, y as i32);
|
let idx = build_data.map.xy_idx(x as i32, y as i32);
|
||||||
// We're doing some nasty casting to make it easier to type things like '#' in the match
|
// We're doing some nasty casting to make it easier to type things like '#' in the match
|
||||||
self.char_to_map(cell.ch as u8 as char, idx, rng, build_data);
|
self.char_to_map(cell.ch as u8 as char, idx, rng, build_data);
|
||||||
|
|
@ -146,9 +202,12 @@ impl PrefabBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_ascii_to_vec(template: &str) -> Vec<char> {
|
fn read_ascii_to_vec(template: &str) -> Vec<char> {
|
||||||
let mut string_vec: Vec<char> = template.chars().filter(|a| *a != '\r' && *a != '\n').collect();
|
let mut string_vec: Vec<char> = template
|
||||||
|
.chars()
|
||||||
|
.filter(|a| *a != '\r' && *a != '\n')
|
||||||
|
.collect();
|
||||||
for c in string_vec.iter_mut() {
|
for c in string_vec.iter_mut() {
|
||||||
if *c as u8 == 160u8 {
|
if (*c as u8) == 160u8 {
|
||||||
*c = ' ';
|
*c = ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -161,16 +220,21 @@ impl PrefabBuilder {
|
||||||
level: &prefab_levels::PrefabLevel,
|
level: &prefab_levels::PrefabLevel,
|
||||||
rng: &mut RandomNumberGenerator,
|
rng: &mut RandomNumberGenerator,
|
||||||
build_data: &mut BuilderMap,
|
build_data: &mut BuilderMap,
|
||||||
|
overmap: bool
|
||||||
) {
|
) {
|
||||||
let string_vec = PrefabBuilder::read_ascii_to_vec(level.template);
|
let string_vec = PrefabBuilder::read_ascii_to_vec(level.template);
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
for ty in 0..level.height {
|
for ty in 0..level.height {
|
||||||
for tx in 0..level.width {
|
for tx in 0..level.width {
|
||||||
if tx < build_data.map.width as usize && ty < build_data.map.height as usize {
|
if tx < (build_data.map.width as usize) && ty < (build_data.map.height as usize) {
|
||||||
let idx = build_data.map.xy_idx(tx as i32, ty as i32);
|
let idx = build_data.map.xy_idx(tx as i32, ty as i32);
|
||||||
if i < string_vec.len() {
|
if i < string_vec.len() {
|
||||||
self.char_to_map(string_vec[i], idx, rng, build_data);
|
if overmap {
|
||||||
|
self.overmap_char_to_map(string_vec[i], idx, rng, build_data);
|
||||||
|
} else {
|
||||||
|
self.char_to_map(string_vec[i], idx, rng, build_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
|
|
@ -182,14 +246,14 @@ impl PrefabBuilder {
|
||||||
&mut self,
|
&mut self,
|
||||||
mut filter: F,
|
mut filter: F,
|
||||||
_rng: &mut RandomNumberGenerator,
|
_rng: &mut RandomNumberGenerator,
|
||||||
build_data: &mut BuilderMap,
|
build_data: &mut BuilderMap
|
||||||
) where
|
)
|
||||||
F: FnMut(i32, i32) -> bool,
|
where F: FnMut(i32, i32) -> bool
|
||||||
{
|
{
|
||||||
let width = build_data.map.width;
|
let width = build_data.map.width;
|
||||||
build_data.spawn_list.retain(|(idx, _name)| {
|
build_data.spawn_list.retain(|(idx, _name)| {
|
||||||
let x = *idx as i32 % width;
|
let x = (*idx as i32) % width;
|
||||||
let y = *idx as i32 / width;
|
let y = (*idx as i32) / width;
|
||||||
filter(x, y)
|
filter(x, y)
|
||||||
});
|
});
|
||||||
build_data.take_snapshot();
|
build_data.take_snapshot();
|
||||||
|
|
@ -200,7 +264,7 @@ impl PrefabBuilder {
|
||||||
&mut self,
|
&mut self,
|
||||||
section: &prefab_sections::PrefabSection,
|
section: &prefab_sections::PrefabSection,
|
||||||
rng: &mut RandomNumberGenerator,
|
rng: &mut RandomNumberGenerator,
|
||||||
build_data: &mut BuilderMap,
|
build_data: &mut BuilderMap
|
||||||
) {
|
) {
|
||||||
use prefab_sections::*;
|
use prefab_sections::*;
|
||||||
|
|
||||||
|
|
@ -209,36 +273,52 @@ impl PrefabBuilder {
|
||||||
// Place the new section
|
// Place the new section
|
||||||
let chunk_x;
|
let chunk_x;
|
||||||
match section.placement.0 {
|
match section.placement.0 {
|
||||||
HorizontalPlacement::Left => chunk_x = 0,
|
HorizontalPlacement::Left => {
|
||||||
HorizontalPlacement::Center => chunk_x = (build_data.map.width / 2) - (section.width as i32 / 2),
|
chunk_x = 0;
|
||||||
HorizontalPlacement::Right => chunk_x = (build_data.map.width - 1) - section.width as i32,
|
}
|
||||||
|
HorizontalPlacement::Center => {
|
||||||
|
chunk_x = build_data.map.width / 2 - (section.width as i32) / 2;
|
||||||
|
}
|
||||||
|
HorizontalPlacement::Right => {
|
||||||
|
chunk_x = build_data.map.width - 1 - (section.width as i32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let chunk_y;
|
let chunk_y;
|
||||||
match section.placement.1 {
|
match section.placement.1 {
|
||||||
VerticalPlacement::Top => chunk_y = 0,
|
VerticalPlacement::Top => {
|
||||||
VerticalPlacement::Center => chunk_y = (build_data.map.height / 2) - (section.height as i32 / 2),
|
chunk_y = 0;
|
||||||
VerticalPlacement::Bottom => chunk_y = (build_data.map.height - 1) - section.height as i32,
|
}
|
||||||
|
VerticalPlacement::Center => {
|
||||||
|
chunk_y = build_data.map.height / 2 - (section.height as i32) / 2;
|
||||||
|
}
|
||||||
|
VerticalPlacement::Bottom => {
|
||||||
|
chunk_y = build_data.map.height - 1 - (section.height as i32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the map
|
// Build the map
|
||||||
self.apply_previous_iteration(
|
self.apply_previous_iteration(
|
||||||
|x, y| {
|
|x, y| {
|
||||||
x < chunk_x
|
x < chunk_x ||
|
||||||
|| x > (chunk_x + section.width as i32)
|
x > chunk_x + (section.width as i32) ||
|
||||||
|| y < chunk_y
|
y < chunk_y ||
|
||||||
|| y > (chunk_y + section.height as i32)
|
y > chunk_y + (section.height as i32)
|
||||||
},
|
},
|
||||||
rng,
|
rng,
|
||||||
build_data,
|
build_data
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
for ty in 0..section.height {
|
for ty in 0..section.height {
|
||||||
for tx in 0..section.width {
|
for tx in 0..section.width {
|
||||||
if tx > 0 && tx < build_data.map.width as usize - 1 && ty < build_data.map.height as usize - 1 && ty > 0
|
if
|
||||||
|
tx > 0 &&
|
||||||
|
tx < (build_data.map.width as usize) - 1 &&
|
||||||
|
ty < (build_data.map.height as usize) - 1 &&
|
||||||
|
ty > 0
|
||||||
{
|
{
|
||||||
let idx = build_data.map.xy_idx(tx as i32 + chunk_x, ty as i32 + chunk_y);
|
let idx = build_data.map.xy_idx((tx as i32) + chunk_x, (ty as i32) + chunk_y);
|
||||||
if i < string_vec.len() {
|
if i < string_vec.len() {
|
||||||
self.char_to_map(string_vec[i], idx, rng, build_data);
|
self.char_to_map(string_vec[i], idx, rng, build_data);
|
||||||
}
|
}
|
||||||
|
|
@ -274,7 +354,7 @@ impl PrefabBuilder {
|
||||||
FLUFF2_6X3,
|
FLUFF2_6X3,
|
||||||
HOUSE_NOTRAP_7X7,
|
HOUSE_NOTRAP_7X7,
|
||||||
HOUSE_TRAP_7X7,
|
HOUSE_TRAP_7X7,
|
||||||
ORC_HOUSE_8X8,
|
ORC_HOUSE_8X8
|
||||||
];
|
];
|
||||||
|
|
||||||
// Filter the vault list down to ones that are applicable to the current id
|
// Filter the vault list down to ones that are applicable to the current id
|
||||||
|
|
@ -313,8 +393,12 @@ impl PrefabBuilder {
|
||||||
let roll = rng.roll_dice(1, 4);
|
let roll = rng.roll_dice(1, 4);
|
||||||
match roll {
|
match roll {
|
||||||
1 => {}
|
1 => {}
|
||||||
2 => flip_x = true,
|
2 => {
|
||||||
3 => flip_y = true,
|
flip_x = true;
|
||||||
|
}
|
||||||
|
3 => {
|
||||||
|
flip_y = true;
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
flip_x = true;
|
flip_x = true;
|
||||||
flip_y = true;
|
flip_y = true;
|
||||||
|
|
@ -328,14 +412,15 @@ impl PrefabBuilder {
|
||||||
|
|
||||||
let mut idx = 0usize;
|
let mut idx = 0usize;
|
||||||
loop {
|
loop {
|
||||||
let x = (idx % build_data.map.width as usize) as i32;
|
let x = (idx % (build_data.map.width as usize)) as i32;
|
||||||
let y = (idx / build_data.map.width as usize) as i32;
|
let y = (idx / (build_data.map.width as usize)) as i32;
|
||||||
|
|
||||||
// Check that we won't overflow the map
|
// Check that we won't overflow the map
|
||||||
if x > 1
|
if
|
||||||
&& (x + vault.width as i32) < build_data.map.width - 2
|
x > 1 &&
|
||||||
&& y > 1
|
x + (vault.width as i32) < build_data.map.width - 2 &&
|
||||||
&& (y + vault.height as i32) < build_data.map.height - 2
|
y > 1 &&
|
||||||
|
y + (vault.height as i32) < build_data.map.height - 2
|
||||||
{
|
{
|
||||||
let mut possible = true;
|
let mut possible = true;
|
||||||
for ty in 0..vault.height as i32 {
|
for ty in 0..vault.height as i32 {
|
||||||
|
|
@ -379,7 +464,10 @@ impl PrefabBuilder {
|
||||||
let idx = e.0 as i32;
|
let idx = e.0 as i32;
|
||||||
let x = idx % width;
|
let x = idx % width;
|
||||||
let y = idx / height;
|
let y = idx / height;
|
||||||
x < chunk_x || x > chunk_x + vault.width as i32 || y < chunk_y || y > chunk_y + vault.height as i32
|
x < chunk_x ||
|
||||||
|
x > chunk_x + (vault.width as i32) ||
|
||||||
|
y < chunk_y ||
|
||||||
|
y > chunk_y + (vault.height as i32)
|
||||||
});
|
});
|
||||||
|
|
||||||
let string_vec = PrefabBuilder::read_ascii_to_vec(vault.template);
|
let string_vec = PrefabBuilder::read_ascii_to_vec(vault.template);
|
||||||
|
|
@ -390,17 +478,22 @@ impl PrefabBuilder {
|
||||||
let mut y_: i32 = tile_y as i32;
|
let mut y_: i32 = tile_y as i32;
|
||||||
// Handle flipping
|
// Handle flipping
|
||||||
if flip_x {
|
if flip_x {
|
||||||
x_ = vault.width as i32 - 1 - x_;
|
x_ = (vault.width as i32) - 1 - x_;
|
||||||
}
|
}
|
||||||
if flip_y {
|
if flip_y {
|
||||||
y_ = vault.height as i32 - 1 - y_;
|
y_ = (vault.height as i32) - 1 - y_;
|
||||||
}
|
}
|
||||||
if x_ < 0 || y_ < 0 {
|
if x_ < 0 || y_ < 0 {
|
||||||
// If either of these go below 0, we run the risk of CTD, so just panic.
|
// If either of these go below 0, we run the risk of CTD, so just panic.
|
||||||
// Something went wrong with flipping/rotating/defining a vault.
|
// Something went wrong with flipping/rotating/defining a vault.
|
||||||
panic!(
|
panic!(
|
||||||
"X or Y went below 0 when trying to place a vault! DEBUGINFO == [H: {}, W: {}; FLIPPED X: {}, FLIPPED Y: {}; X_: {}, Y_: {}]",
|
"X or Y went below 0 when trying to place a vault! DEBUGINFO == [H: {}, W: {}; FLIPPED X: {}, FLIPPED Y: {}; X_: {}, Y_: {}]",
|
||||||
vault.width, vault.height, flip_x, flip_y, x_, y_
|
vault.width,
|
||||||
|
vault.height,
|
||||||
|
flip_x,
|
||||||
|
flip_y,
|
||||||
|
x_,
|
||||||
|
y_
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let idx = build_data.map.xy_idx(x_ + chunk_x, y_ + chunk_y);
|
let idx = build_data.map.xy_idx(x_ + chunk_x, y_ + chunk_y);
|
||||||
|
|
|
||||||
41
src/map_builders/prefab_builder/overmap
Normal file
41
src/map_builders/prefab_builder/overmap
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
~~~~~~~~~.................~~~.......~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
~~~~~~~~...........................~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
~~~~~~~............................~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
~~~~....~..........................~~~~~~~~~~~~~.....~~~~~~~
|
||||||
|
~~~....~...........................~..~~~~~~~~~~......~~~~~~
|
||||||
|
~~~.................~.................~~~~~~~~~........~...~
|
||||||
|
~~~.................~.......................................
|
||||||
|
~~~~........................................................
|
||||||
|
~~~~~~......................................................
|
||||||
|
~~~~~~..................................~...................
|
||||||
|
~~~~~........~~.........................~...................
|
||||||
|
~~~~~......~~~.~............................................
|
||||||
|
~~~~.......~~..~...........................................~
|
||||||
|
~~~........~...............................................~
|
||||||
|
~~~~......~...............................................~~
|
||||||
|
~~~~~......................................................~
|
||||||
|
~~~~~...~................~..................................
|
||||||
|
~~~~~~~~~~~............~~~..................................
|
||||||
|
~~~~~~~~~~...........~..~...................................
|
||||||
|
~~~~~~~~~~~............~....................................
|
||||||
|
~~~~~~~~~..............~....................................
|
||||||
|
~~~~~~~~.............~~...................................~~
|
||||||
|
~~~~~~~..............~.....................................~
|
||||||
|
~~~~~......................................................~
|
||||||
|
~~~~~.................~~...................................~
|
||||||
|
~~~~..................~.~~~.................................
|
||||||
|
~~~~..............~.......~.................................
|
||||||
|
~.................~~..................~~....................
|
||||||
|
~...............~..~..................~~~...................
|
||||||
|
..~......~~~~~~~~.....~~~.............~~....................
|
||||||
|
..~~.....~~~~~~~~~~...~~~...................................
|
||||||
|
..~~~~~~~~~~~~~~~~..~~~~~~..................................
|
||||||
|
....~~~~~~~~~~~~...~~~~~~~..............~~~~................
|
||||||
|
........~~~~~~~~..........~.~....~......~......~.......~....
|
||||||
|
~...~...~~~~~~~~...........................................~
|
||||||
|
...~~.......~~~~............................................
|
||||||
|
...............~............................................
|
||||||
|
.................................~..........................
|
||||||
|
~~...............................~~.....~...................
|
||||||
|
~~~..............................~~.........................
|
||||||
|
~~~......................................~~~.~~~~...........
|
||||||
|
|
@ -7,9 +7,11 @@ pub struct PrefabLevel {
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub const WFC_POPULATED: PrefabLevel = PrefabLevel { template: LEVEL_MAP, width: 80, height: 43 };
|
pub const WFC_POPULATED: PrefabLevel = PrefabLevel { template: LEVEL_MAP, width: 80, height: 43 };
|
||||||
|
pub const OVERMAP: PrefabLevel = PrefabLevel { template: OVERMAP_TEMPLATE, width: 69, height: 41 };
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
const LEVEL_MAP: &str = "
|
const LEVEL_MAP: &str =
|
||||||
|
"
|
||||||
################################################################################
|
################################################################################
|
||||||
# ######################################################## #########
|
# ######################################################## #########
|
||||||
# @ ###### ######### #### ################### #######
|
# @ ###### ######### #### ################### #######
|
||||||
|
|
@ -53,3 +55,47 @@ const LEVEL_MAP: &str = "
|
||||||
#!%^ ### ### ############### ######## ##### g #### # g# #
|
#!%^ ### ### ############### ######## ##### g #### # g# #
|
||||||
# %^## ^ ### ############### ######## ##### ##################
|
# %^## ^ ### ############### ######## ##### ##################
|
||||||
################################################################################";
|
################################################################################";
|
||||||
|
|
||||||
|
const OVERMAP_TEMPLATE: &str =
|
||||||
|
"
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈........≈≈≈≈≈≈≈≈
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈...........≈≈≈≈≈≈≈
|
||||||
|
^^^^^^^^^^^^^^^....^^^^^^≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈.............≈≈≈≈≈
|
||||||
|
^^^^^^^^^^^^^^...........≈≈≈≈≈≈≈≈≈........≈≈≈≈≈≈≈≈..............≈≈≈≈≈
|
||||||
|
^^^^^^^^^^^^^............≈≈≈≈≈≈≈≈...........≈≈≈≈≈..............≈≈≈≈≈≈
|
||||||
|
^^^^^^^^^^^.............≈≈≈≈≈≈≈≈≈...........≈≈≈≈≈.............≈≈≈≈≈≈≈
|
||||||
|
^^^^^^^^^...............≈≈≈≈≈≈≈≈≈............≈≈≈≈............≈≈≈≈≈≈≈≈
|
||||||
|
^^^^^^^^................≈≈≈≈≈≈≈≈≈............≈≈≈≈............≈≈≈≈≈≈≈≈
|
||||||
|
^^^^^^^..................≈≈≈≈≈≈≈≈≈...........≈≈≈.............≈≈≈≈≈≈≈≈
|
||||||
|
^^^^.....................≈≈≈≈≈≈≈≈≈≈≈........≈≈≈≈..............≈≈≈≈≈≈≈
|
||||||
|
^^.........................≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈..............≈≈≈≈≈≈≈
|
||||||
|
^^..............................≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈................≈≈≈≈≈≈
|
||||||
|
^.................................≈≈≈≈≈≈≈≈≈≈≈≈≈.................≈≈≈≈≈
|
||||||
|
^..................................≈≈≈≈≈≈≈≈≈≈≈≈.................≈≈≈≈≈
|
||||||
|
^....................................≈≈≈≈≈≈≈≈≈..................≈≈≈≈≈
|
||||||
|
^......................................≈≈≈≈≈≈...................≈≈≈≈≈
|
||||||
|
^........................................≈≈.....................≈≈≈≈≈
|
||||||
|
^..............................................................≈≈≈≈≈≈
|
||||||
|
^..............................................................≈≈≈≈≈≈
|
||||||
|
^^.............................................................≈≈≈≈≈≈
|
||||||
|
^^.............................................................≈≈≈≈≈≈
|
||||||
|
^^.............................................................≈≈≈≈≈≈
|
||||||
|
^^^............................................................≈≈≈≈≈≈
|
||||||
|
^^^^............................................................≈≈≈≈≈
|
||||||
|
^^^^^...........................................................≈≈≈≈≈
|
||||||
|
^^^^^^^^........................................................≈≈≈≈≈
|
||||||
|
^^^^^^^^^.......................................................≈≈≈≈≈
|
||||||
|
^^^^^^^^^..............................≈≈........................≈≈≈≈
|
||||||
|
^^^^^^^^^.............................≈≈≈≈≈≈≈≈≈...................≈≈≈
|
||||||
|
^^^^^^^^..............................≈≈≈≈≈≈≈≈≈≈......≈............≈≈
|
||||||
|
^^^^^^^..............................≈≈≈≈≈≈≈≈≈≈≈≈≈...≈≈..........≈..≈
|
||||||
|
^^^^^^^..........................≈≈.≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈....≈≈≈≈
|
||||||
|
^^^^^^^........................≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈.....≈
|
||||||
|
^^^^^^^^........@..............≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈....≈
|
||||||
|
^^^^^^^^..................≈...≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈...≈≈≈...≈≈≈≈≈≈≈≈.≈≈
|
||||||
|
^^^^^^^^^.................≈≈....≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈....≈≈......≈≈≈≈≈≈≈≈≈
|
||||||
|
^^^^^^^^^........≈≈≈≈...≈≈≈≈....≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈..≈≈≈......≈≈≈≈≈≈≈≈≈
|
||||||
|
^^^^^^^^^^......≈≈≈≈≈≈≈≈≈≈≈≈≈..≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈........≈≈≈≈≈≈≈≈
|
||||||
|
^^^^^^^^^^.....≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈........≈≈≈≈≈≈≈≈≈
|
||||||
|
^^^^^^^^^^....≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈....≈≈≈≈≈≈≈≈≈≈
|
||||||
|
^^^^^^^^^^^^.≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈≈";
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ pub fn town_builder(
|
||||||
initial_player_level: i32
|
initial_player_level: i32
|
||||||
) -> BuilderChain {
|
) -> BuilderChain {
|
||||||
rltk::console::log(format!("DEBUGINFO: Building town (ID:{}, DIFF:{})", new_id, difficulty));
|
rltk::console::log(format!("DEBUGINFO: Building town (ID:{}, DIFF:{})", new_id, difficulty));
|
||||||
let mut chain = BuilderChain::new(new_id, width, height, difficulty, "the town", initial_player_level);
|
let mut chain = BuilderChain::new(false, new_id, width, height, difficulty, "the town", initial_player_level);
|
||||||
chain.start_with(TownBuilder::new());
|
chain.start_with(TownBuilder::new());
|
||||||
|
|
||||||
return chain;
|
return chain;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{BuilderMap, Map, MetaMapBuilder, TileType};
|
use super::{ BuilderMap, Map, MetaMapBuilder, TileType };
|
||||||
use rltk::RandomNumberGenerator;
|
use rltk::RandomNumberGenerator;
|
||||||
mod common;
|
mod common;
|
||||||
use common::*;
|
use common::*;
|
||||||
|
|
@ -32,11 +32,12 @@ impl WaveFunctionCollapseBuilder {
|
||||||
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 = Map::new(
|
||||||
|
build_data.map.overmap,
|
||||||
build_data.map.id,
|
build_data.map.id,
|
||||||
build_data.map.width,
|
build_data.map.width,
|
||||||
build_data.map.height,
|
build_data.map.height,
|
||||||
build_data.map.difficulty,
|
build_data.map.difficulty,
|
||||||
&build_data.map.name,
|
&build_data.map.name
|
||||||
);
|
);
|
||||||
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);
|
||||||
|
|
@ -52,7 +53,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.width, build_data.height, 0, &build_data.map.name);
|
build_data.map = Map::new(false, 0, build_data.width, build_data.height, 0, &build_data.map.name);
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
let mut x = 1;
|
let mut x = 1;
|
||||||
let mut y = 1;
|
let mut y = 1;
|
||||||
|
|
@ -68,7 +69,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.width, build_data.height, 0, &build_data.map.name);
|
build_data.map = Map::new(false, 0, build_data.width, build_data.height, 0, &build_data.map.name);
|
||||||
|
|
||||||
x = 1;
|
x = 1;
|
||||||
y = 1;
|
y = 1;
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,11 @@ impl<'a> System<'a> for VisibilitySystem {
|
||||||
for (ent, viewshed, pos) in (&entities, &mut viewshed, &pos).join() {
|
for (ent, viewshed, pos) in (&entities, &mut viewshed, &pos).join() {
|
||||||
if viewshed.dirty {
|
if viewshed.dirty {
|
||||||
viewshed.dirty = false;
|
viewshed.dirty = false;
|
||||||
let range = if let Some(_is_blind) = blind_entities.get(ent) { 1 } else { viewshed.range };
|
let range = if let Some(_is_blind) = blind_entities.get(ent) {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
if map.overmap { viewshed.range / 2 } else { viewshed.range }
|
||||||
|
};
|
||||||
let origin = Point::new(pos.x, pos.y);
|
let origin = Point::new(pos.x, pos.y);
|
||||||
viewshed.visible_tiles = SymmetricShadowcasting.field_of_view(origin, range, &*map);
|
viewshed.visible_tiles = SymmetricShadowcasting.field_of_view(origin, range, &*map);
|
||||||
viewshed.visible_tiles.retain(|p| {
|
viewshed.visible_tiles.retain(|p| {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue