Merge branch 'depths_to_ids'

This commit is contained in:
Llywelwyn 2023-07-27 17:59:54 +01:00
commit 5f091bc2ab
20 changed files with 164 additions and 204 deletions

View file

@ -28,7 +28,7 @@
"effects": { "ranged": "10", "damage": "15", "aoe": "3" }
},
{
"id": "scroll_fireball_cursed",
"id": "scroll_fireball_c",
"name": { "name": "cursed scroll of fireball", "plural": "cursed scrolls of fireball" },
"renderable": { "glyph": "?", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "CURSED"],
@ -49,7 +49,7 @@
"effects": { "magicmapper": "" }
},
{
"id": "scroll_magicmap_cursed",
"id": "scroll_magicmap_c",
"name": { "name": "cursed scroll of magic mapping", "plural": "cursed scrolls of magic mapping" },
"renderable": { "glyph": "?", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "CURSED"],

View file

@ -2,70 +2,74 @@
{
"id": "equipment",
"table": [
{ "id": "equip_dagger", "weight": 4, "min": 0, "max": 100 },
{ "id": "equip_shortsword", "weight": 2, "min": 0, "max": 100 },
{ "id": "equip_longsword", "weight": 1, "min": 3, "max": 100 },
{ "id": "equip_smallshield", "weight": 4, "min": 0, "max": 100 },
{ "id": "equip_mediumshield", "weight": 2, "min": 0, "max": 100 },
{ "id": "equip_largeshield", "weight": 1, "min": 3, "max": 100 }
{ "id": "equip_dagger", "weight": 4, "difficulty": 1},
{ "id": "equip_shortsword", "weight": 2, "difficulty": 1},
{ "id": "equip_smallshield", "weight": 4, "difficulty": 1},
{ "id": "equip_mediumshield", "weight": 2, "difficulty": 1},
{ "id": "equip_longsword", "weight": 1, "difficulty": 3},
{ "id": "equip_largeshield", "weight": 1, "difficulty": 3}
]
},
{
"id": "potions",
"table": [
{ "id": "potion_health_weak", "weight": 6, "min": 0, "max": 100 },
{ "id": "potion_health", "weight": 3, "min": 0, "max": 100 }
{ "id": "potion_health_weak", "weight": 6, "difficulty": 1},
{ "id": "potion_health", "weight": 3, "difficulty": 1}
]
},
{
"id": "scrolls",
"table": [
{ "id": "scroll_fireball", "weight": 2, "min": 3, "max": 100 },
{ "id": "scroll_fireball_cursed", "weight": 2, "min": 3, "max": 100 },
{ "id": "scroll_confusion", "weight": 2, "min": 0, "max": 100 },
{ "id": "scroll_magicmap_cursed", "weight": 2, "min": 0, "max": 100 },
{ "id": "scroll_magicmap", "weight": 2, "min": 0, "max": 100 }
{ "id": "scroll_confusion", "weight": 2, "difficulty": 1},
{ "id": "scroll_magicmap_c", "weight": 2, "difficulty": 1},
{ "id": "scroll_magicmap", "weight": 2, "difficulty": 1},
{ "id": "scroll_fireball", "weight": 2, "difficulty": 2},
{ "id": "scroll_fireball_c", "weight": 2, "difficulty": 2}
]
},
{
"id": "wands",
"table": [
{ "id": "wand_magicmissile", "weight": 1, "min": 0, "max": 100 },
{ "id": "wand_fireball", "weight": 1, "min": 3, "max": 100 },
{ "id": "wand_confusion", "weight": 1, "min": 0, "max": 100 },
{ "id": "wand_digging", "weight": 1, "min": 0, "max": 100 }
{ "id": "wand_magicmissile", "weight": 1, "difficulty": 1},
{ "id": "wand_confusion", "weight": 1, "difficulty": 1},
{ "id": "wand_digging", "weight": 1, "difficulty": 1},
{ "id": "wand_fireball", "weight": 1, "difficulty": 2}
]
},
{
"id": "food",
"table": [
{ "id": "food_rations", "weight": 1, "min": 0, "max": 100 },
{ "id": "food_apple", "weight": 1, "min": 0, "max": 100 }
{ "id": "food_rations", "weight": 1, "difficulty": 1},
{ "id": "food_apple", "weight": 1, "difficulty": 1}
]
},
{
"id": "mobs",
"table": [
{ "id": "dog_little", "weight": 5, "min": 0, "max": 100 },
{ "id": "dog", "weight": 5, "min": 2, "max": 100 },
{ "id": "dog_large", "weight": 5, "min": 3, "max": 100 },
{ "id": "goblin", "weight": 50, "min": 0, "max": 100 },
{ "id": "kobold", "weight": 100, "min": 0, "max": 3 },
{ "id": "jackal", "weight": 100, "min": 0, "max": 100 },
{ "id": "fox", "weight": 6, "min": 0, "max": 100 },
{ "id": "coyote", "weight": 6, "min": 0, "max": 100 },
{ "id": "orc", "weight": 30, "min": 3, "max": 100 },
{ "id": "orc_large", "weight": 10, "min": 3, "max": 100 },
{ "id": "goblin_chieftain", "weight": 5, "min": 3, "max": 100 },
{ "id": "ogre", "weight": 2, "min": 4, "max": 100 }
{ "id": "goblin", "weight": 3, "difficulty": 1},
{ "id": "kobold", "weight": 1, "difficulty": 1},
{ "id": "fox", "weight": 1, "difficulty": 1},
{ "id": "jackal", "weight": 4, "difficulty": 1},
{ "id": "coyote", "weight": 4, "difficulty": 2},
{ "id": "dog_little", "weight": 1, "difficulty": 3},
{ "id": "orc", "weight": 2, "difficulty": 3},
{ "id": "orc_large", "weight": 1, "difficulty": 3},
{ "id": "goblin_chieftain", "weight": 1, "difficulty": 3},
{ "id": "dog", "weight": 1, "difficulty": 4},
{ "id": "ogre", "weight": 1, "difficulty": 4},
{ "id": "dog_large", "weight": 1, "difficulty": 5}
]
},
{
"id": "traps",
"table": [
{ "id": "trap_bear", "weight": 2, "min": 0, "max": 100 },
{ "id": "trap_confusion", "weight": 1, "min": 0, "max": 100 },
{ "id": "trap_stonefall", "weight": 1, "min": 3, "max": 100 }
{ "id": "trap_bear", "weight": 2, "difficulty": 1},
{ "id": "trap_confusion", "weight": 1, "difficulty": 1},
{ "id": "trap_stonefall", "weight": 1, "difficulty": 3}
]
}
]

View file

@ -37,10 +37,10 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
// Render the message log at [1, 46], descending, with 6 lines.
gamelog::print_log(&mut rltk::BACKEND_INTERNAL.lock().consoles[0].console, Point::new(1, 44), true, 6);
// Render depth
// Render id
let map = ecs.fetch::<Map>();
let depth = format!(" D{} ", map.depth);
ctx.print_color_right(78, 43, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), &depth);
let id = format!(" D{} ", map.id);
ctx.print_color_right(78, 43, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), &id);
// Render turn
ctx.print_color_right(

View file

@ -76,13 +76,13 @@ pub struct State {
}
impl State {
fn generate_world_map(&mut self, new_depth: i32) {
fn generate_world_map(&mut self, new_id: i32) {
// Visualisation stuff
self.mapgen_index = 0;
self.mapgen_timer = 0.0;
self.mapgen_history.clear();
let mut rng = self.ecs.write_resource::<rltk::RandomNumberGenerator>();
let mut builder = map_builders::level_builder(new_depth, &mut rng, 80, 50);
let mut builder = map_builders::level_builder(new_id, &mut rng, 80, 50);
builder.build_map(&mut rng);
std::mem::drop(rng);
self.mapgen_history = builder.build_data.history.clone();
@ -197,13 +197,13 @@ impl State {
}
// Build new map + place player
let current_depth;
let current_id;
{
let worldmap_resource = self.ecs.fetch::<Map>();
current_depth = worldmap_resource.depth;
current_id = worldmap_resource.id;
}
gamelog::record_event("descended", 1);
self.generate_world_map(current_depth + 1);
self.generate_world_map(current_id + 1);
// Notify player, restore health up to a point.
let player_entity = self.ecs.fetch::<Entity>();
@ -547,7 +547,7 @@ fn main() -> rltk::BError {
raws::load_raws();
let player_entity = spawner::player(&mut gs.ecs, 0, 0);
gs.ecs.insert(Map::new(1, 64, 64));
gs.ecs.insert(Map::new(1, 64, 64, 0));
gs.ecs.insert(Point::new(0, 0));
gs.ecs.insert(player_entity);
gs.ecs.insert(rltk::RandomNumberGenerator::new());

View file

@ -23,7 +23,8 @@ pub struct Map {
pub colour_offset: Vec<(f32, f32, f32)>,
pub additional_fg_offset: rltk::RGB,
pub blocked: Vec<bool>,
pub depth: i32,
pub id: i32,
pub difficulty: i32,
pub bloodstains: HashSet<usize>,
pub view_blocked: HashSet<usize>,
@ -37,7 +38,7 @@ impl Map {
(y as usize) * (self.width as usize) + (x as usize)
}
pub fn new(new_depth: i32, width: i32, height: i32) -> Map {
pub fn new(new_id: i32, width: i32, height: i32, difficulty: i32) -> Map {
let map_tile_count = (width * height) as usize;
let mut map = Map {
tiles: vec![TileType::Wall; map_tile_count],
@ -50,7 +51,8 @@ impl Map {
colour_offset: vec![(1.0, 1.0, 1.0); map_tile_count],
additional_fg_offset: rltk::RGB::from_u8(HALF_OFFSET, HALF_OFFSET, HALF_OFFSET),
blocked: vec![false; map_tile_count],
depth: new_depth,
id: new_id,
difficulty: difficulty,
bloodstains: HashSet::new(),
view_blocked: HashSet::new(),
tile_content: vec![Vec::new(); map_tile_count],

View file

@ -55,7 +55,7 @@ pub fn get_tile_glyph(idx: usize, map: &Map) -> (rltk::FontCharType, RGB, RGB) {
bg = RGB::from_u8(39, 39, 54);
}
TileType::Road => {
glyph = rltk::to_cp437('~');
glyph = rltk::to_cp437('.');
//fg = RGB::from_u8(112, 105, 94);
bg = RGB::from_u8(29, 45, 46);
}

View file

@ -1,4 +1,4 @@
use super::{BuilderMap, MetaMapBuilder, Position, TileType};
use super::{BuilderMap, MetaMapBuilder, Position};
use rltk::RandomNumberGenerator;
#[allow(dead_code)]

View file

@ -92,13 +92,13 @@ pub struct BuilderChain {
}
impl BuilderChain {
pub fn new(new_depth: i32, width: i32, height: i32) -> BuilderChain {
pub fn new(new_id: i32, width: i32, height: i32, difficulty: i32) -> BuilderChain {
BuilderChain {
starter: None,
builders: Vec::new(),
build_data: BuilderMap {
spawn_list: Vec::new(),
map: Map::new(new_depth, width, height),
map: Map::new(new_id, width, height, difficulty),
starting_position: None,
rooms: None,
corridors: None,
@ -136,9 +136,12 @@ impl BuilderChain {
}
pub fn spawn_entities(&mut self, ecs: &mut World) {
let mut spawned_entities = Vec::new();
for entity in self.build_data.spawn_list.iter() {
spawned_entities.push(&entity.1);
spawner::spawn_entity(ecs, &(&entity.0, &entity.1));
}
rltk::console::log(format!("DEBUGINFO: SPAWNED ENTITIES = {:?}", spawned_entities));
}
}
@ -279,8 +282,15 @@ fn random_shape_builder(rng: &mut rltk::RandomNumberGenerator, builder: &mut Bui
builder.with(DistantExit::new());
}
pub fn random_builder(new_depth: i32, rng: &mut rltk::RandomNumberGenerator, width: i32, height: i32) -> BuilderChain {
let mut builder = BuilderChain::new(new_depth, width, height);
pub fn random_builder(
new_id: i32,
rng: &mut rltk::RandomNumberGenerator,
width: i32,
height: i32,
difficulty: i32,
) -> BuilderChain {
rltk::console::log(format!("DEBUGINFO: Building random (ID:{}, DIFF:{})", new_id, difficulty));
let mut builder = BuilderChain::new(new_id, width, height, difficulty);
let type_roll = rng.roll_dice(1, 2);
match type_roll {
1 => random_room_builder(rng, &mut builder),
@ -317,10 +327,10 @@ pub fn random_builder(new_depth: i32, rng: &mut rltk::RandomNumberGenerator, wid
builder
}
pub fn level_builder(new_depth: i32, rng: &mut rltk::RandomNumberGenerator, width: i32, height: i32) -> BuilderChain {
rltk::console::log(format!("DEBUGINFO: Depth: {}", new_depth));
match new_depth {
1 => town_builder(new_depth, rng, width, height),
_ => random_builder(new_depth, rng, width, height),
pub fn level_builder(new_id: i32, rng: &mut rltk::RandomNumberGenerator, width: i32, height: i32) -> BuilderChain {
let difficulty = new_id;
match new_id {
1 => town_builder(new_id, rng, width, height),
_ => random_builder(new_id, rng, width, height, difficulty),
}
}

View file

@ -102,23 +102,23 @@ impl PrefabBuilder {
}
'%' => {
build_data.map.tiles[idx] = TileType::Floor;
build_data.spawn_list.push((idx, spawner::food_table(build_data.map.depth).roll(rng)));
build_data.spawn_list.push((idx, spawner::food_table(build_data.map.difficulty).roll(rng)));
}
'!' => {
build_data.map.tiles[idx] = TileType::Floor;
build_data.spawn_list.push((idx, spawner::potion_table(build_data.map.depth).roll(rng)));
build_data.spawn_list.push((idx, spawner::potion_table(build_data.map.difficulty).roll(rng)));
}
'/' => {
build_data.map.tiles[idx] = TileType::Floor;
build_data.spawn_list.push((idx, spawner::wand_table(build_data.map.depth).roll(rng)));
build_data.spawn_list.push((idx, spawner::wand_table(build_data.map.difficulty).roll(rng)));
}
'?' => {
build_data.map.tiles[idx] = TileType::Floor;
build_data.spawn_list.push((idx, spawner::scroll_table(build_data.map.depth).roll(rng)));
build_data.spawn_list.push((idx, spawner::scroll_table(build_data.map.difficulty).roll(rng)));
}
')' => {
build_data.map.tiles[idx] = TileType::Floor;
build_data.spawn_list.push((idx, spawner::equipment_table(build_data.map.depth).roll(rng)));
build_data.spawn_list.push((idx, spawner::equipment_table(build_data.map.difficulty).roll(rng)));
}
_ => {
rltk::console::log(format!("Unknown glyph '{}' when loading prefab", (ch as u8) as char));
@ -255,7 +255,7 @@ impl PrefabBuilder {
self.apply_previous_iteration(|_x, _y| true, rng, build_data);
// Do we want a vault at all?
let vault_roll = rng.roll_dice(1, 6) + build_data.map.depth;
let vault_roll = rng.roll_dice(1, 6) + build_data.map.difficulty;
if vault_roll < 4 {
return;
}
@ -276,10 +276,10 @@ impl PrefabBuilder {
ORC_HOUSE_8X8,
];
// Filter the vault list down to ones that are applicable to the current depth
// Filter the vault list down to ones that are applicable to the current id
let mut possible_vaults: Vec<&PrefabVault> = master_vault_list
.iter()
.filter(|v| build_data.map.depth >= v.first_depth && build_data.map.depth <= v.last_depth)
.filter(|v| build_data.map.id >= v.first_id && build_data.map.id <= v.last_id)
.collect();
if possible_vaults.is_empty() {

View file

@ -12,8 +12,8 @@ pub struct PrefabVault {
pub template: &'static str,
pub width: usize,
pub height: usize,
pub first_depth: i32,
pub last_depth: i32,
pub first_id: i32,
pub last_id: i32,
pub can_flip: Flipping,
}
@ -21,8 +21,8 @@ pub const CLASSIC_TRAP_5X5: PrefabVault = PrefabVault {
template: CLASSIC_TRAP_5X5_V,
width: 5,
height: 5,
first_depth: 0,
last_depth: 100,
first_id: 0,
last_id: 100,
can_flip: Flipping::None,
};
const CLASSIC_TRAP_5X5_V: &str = "
@ -37,8 +37,8 @@ pub const CLASSIC_TRAP_CARDINALGAP_5X5: PrefabVault = PrefabVault {
template: CLASSIC_TRAP_CARDINALGAP_5X5_V,
width: 5,
height: 5,
first_depth: 0,
last_depth: 100,
first_id: 0,
last_id: 100,
can_flip: Flipping::Both,
};
const CLASSIC_TRAP_CARDINALGAP_5X5_V: &str = "
@ -53,8 +53,8 @@ pub const CLASSIC_TRAP_DIAGONALGAP_5X5: PrefabVault = PrefabVault {
template: CLASSIC_TRAP_DIAGONALGAP_5X5_V,
width: 5,
height: 5,
first_depth: 0,
last_depth: 100,
first_id: 0,
last_id: 100,
can_flip: Flipping::Both,
};
const CLASSIC_TRAP_DIAGONALGAP_5X5_V: &str = "
@ -65,14 +65,8 @@ const CLASSIC_TRAP_DIAGONALGAP_5X5_V: &str = "
     
";
pub const GOBLINS_4X4: PrefabVault = PrefabVault {
template: GOBLINS_4X4_V,
width: 4,
height: 4,
first_depth: 0,
last_depth: 100,
can_flip: Flipping::Both,
};
pub const GOBLINS_4X4: PrefabVault =
PrefabVault { template: GOBLINS_4X4_V, width: 4, height: 4, first_id: 0, last_id: 100, can_flip: Flipping::Both };
const GOBLINS_4X4_V: &str = "
#^  
#G#
@ -80,14 +74,8 @@ const GOBLINS_4X4_V: &str = "
^g^
";
pub const GOBLINS2_4X4: PrefabVault = PrefabVault {
template: GOBLINS2_4X4_V,
width: 4,
height: 4,
first_depth: 0,
last_depth: 100,
can_flip: Flipping::Both,
};
pub const GOBLINS2_4X4: PrefabVault =
PrefabVault { template: GOBLINS2_4X4_V, width: 4, height: 4, first_id: 0, last_id: 100, can_flip: Flipping::Both };
const GOBLINS2_4X4_V: &str = "
#^#g
G# #
@ -95,14 +83,8 @@ G# #
# g^
";
pub const GOBLINS_5X5: PrefabVault = PrefabVault {
template: GOBLINS_5X5_V,
width: 5,
height: 5,
first_depth: 0,
last_depth: 100,
can_flip: Flipping::Both,
};
pub const GOBLINS_5X5: PrefabVault =
PrefabVault { template: GOBLINS_5X5_V, width: 5, height: 5, first_id: 0, last_id: 100, can_flip: Flipping::Both };
const GOBLINS_5X5_V: &str = "
 ^#g 
G#?#^
@ -111,14 +93,8 @@ G#?#^
^# # 
";
pub const GOBLINS_6X6: PrefabVault = PrefabVault {
template: GOBLINS_6X6_V,
width: 6,
height: 6,
first_depth: 0,
last_depth: 100,
can_flip: Flipping::Both,
};
pub const GOBLINS_6X6: PrefabVault =
PrefabVault { template: GOBLINS_6X6_V, width: 6, height: 6, first_id: 0, last_id: 100, can_flip: Flipping::Both };
const GOBLINS_6X6_V: &str = "
   #  
 #^#g 
@ -128,28 +104,16 @@ g##$^
 ^ # ^
";
pub const FLUFF_6X3: PrefabVault = PrefabVault {
template: FLUFF_6X3_V,
width: 6,
height: 3,
first_depth: 0,
last_depth: 100,
can_flip: Flipping::Both,
};
pub const FLUFF_6X3: PrefabVault =
PrefabVault { template: FLUFF_6X3_V, width: 6, height: 3, first_id: 0, last_id: 100, can_flip: Flipping::Both };
const FLUFF_6X3_V: &str = "
###^ 
 ^ #
 ## 
";
pub const FLUFF2_6X3: PrefabVault = PrefabVault {
template: FLUFF2_6X3_V,
width: 6,
height: 3,
first_depth: 0,
last_depth: 100,
can_flip: Flipping::Both,
};
pub const FLUFF2_6X3: PrefabVault =
PrefabVault { template: FLUFF2_6X3_V, width: 6, height: 3, first_id: 0, last_id: 100, can_flip: Flipping::Both };
const FLUFF2_6X3_V: &str = "
 ^###
# ^ 
@ -160,8 +124,8 @@ pub const HOUSE_NOTRAP_7X7: PrefabVault = PrefabVault {
template: HOUSE_NOTRAP_7X7_V,
width: 7,
height: 7,
first_depth: 0,
last_depth: 100,
first_id: 0,
last_id: 100,
can_flip: Flipping::Both,
};
const HOUSE_NOTRAP_7X7_V: &str = "
@ -178,8 +142,8 @@ pub const HOUSE_TRAP_7X7: PrefabVault = PrefabVault {
template: HOUSE_TRAP_7X7_V,
width: 7,
height: 7,
first_depth: 0,
last_depth: 100,
first_id: 0,
last_id: 100,
can_flip: Flipping::Both,
};
const HOUSE_TRAP_7X7_V: &str = "
@ -192,14 +156,8 @@ const HOUSE_TRAP_7X7_V: &str = "
##   ##
";
pub const ORC_HOUSE_8X8: PrefabVault = PrefabVault {
template: ORC_HOUSE_8X8_V,
width: 8,
height: 8,
first_depth: 0,
last_depth: 100,
can_flip: Flipping::Both,
};
pub const ORC_HOUSE_8X8: PrefabVault =
PrefabVault { template: ORC_HOUSE_8X8_V, width: 8, height: 8, first_id: 0, last_id: 100, can_flip: Flipping::Both };
const ORC_HOUSE_8X8_V: &str = "
######

View file

@ -18,7 +18,7 @@ impl RoomBasedSpawner {
fn build(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
if let Some(rooms) = &build_data.rooms {
for room in rooms.iter().skip(1) {
spawner::spawn_room(&build_data.map, rng, room, build_data.map.depth, &mut build_data.spawn_list);
spawner::spawn_room(&build_data.map, rng, room, &mut build_data.spawn_list);
}
} else {
panic!("RoomBasedSpawner only works after rooms have been created");

View file

@ -18,8 +18,7 @@ impl CorridorSpawner {
fn build(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
if let Some(corridors) = &build_data.corridors {
for corridor in corridors.iter() {
let depth = build_data.map.depth;
spawner::spawn_region(&build_data.map, rng, &corridor, depth, &mut build_data.spawn_list);
spawner::spawn_region(&build_data.map, rng, &corridor, &mut build_data.spawn_list);
}
} else {
panic!("CorridorSpawner only works after corridors have been created");

View file

@ -9,7 +9,7 @@ use std::collections::HashMap;
pub struct MazeBuilder {
map: Map,
starting_position: Position,
depth: i32,
id: i32,
history: Vec<Map>,
noise_areas: HashMap<i32, Vec<usize>>,
}
@ -20,7 +20,7 @@ impl MapBuilder for MazeBuilder {
}
fn spawn_entities(&mut self, ecs: &mut World) {
for area in self.noise_areas.iter() {
spawner::spawn_region(ecs, area.1, self.depth);
spawner::spawn_region(ecs, area.1, self.id);
}
}
// Getters
@ -46,11 +46,11 @@ impl MapBuilder for MazeBuilder {
}
impl MazeBuilder {
pub fn new(new_depth: i32) -> MazeBuilder {
pub fn new(new_id: i32) -> MazeBuilder {
MazeBuilder {
map: Map::new(new_depth),
map: Map::new(new_id),
starting_position: Position { x: 0, y: 0 },
depth: new_depth,
id: new_id,
history: Vec::new(),
noise_areas: HashMap::new(),
}

View file

@ -1,8 +1,10 @@
use super::{BuilderChain, BuilderMap, InitialMapBuilder, Position, TileType};
use std::collections::HashSet;
pub fn town_builder(new_depth: i32, _rng: &mut rltk::RandomNumberGenerator, width: i32, height: i32) -> BuilderChain {
let mut chain = BuilderChain::new(new_depth, width, height);
pub fn town_builder(new_id: i32, _rng: &mut rltk::RandomNumberGenerator, width: i32, height: i32) -> BuilderChain {
let difficulty = 0;
rltk::console::log(format!("DEBUGINFO: Building town (ID:{}, DIFF:{})", new_id, difficulty));
let mut chain = BuilderChain::new(new_id, width, height, difficulty);
chain.start_with(TownBuilder::new());
return chain;
@ -13,7 +15,7 @@ pub struct TownBuilder {}
impl InitialMapBuilder for TownBuilder {
#[allow(dead_code)]
fn build_map(&mut self, rng: &mut rltk::RandomNumberGenerator, build_data: &mut BuilderMap) {
self.build_rooms(rng, build_data);
self.build_map(rng, build_data);
}
}
@ -22,26 +24,19 @@ impl TownBuilder {
return Box::new(TownBuilder {});
}
pub fn build_rooms(&mut self, rng: &mut rltk::RandomNumberGenerator, build_data: &mut BuilderMap) {
pub fn build_map(&mut self, rng: &mut rltk::RandomNumberGenerator, build_data: &mut BuilderMap) {
// Make visible for snapshot
for t in build_data.map.visible_tiles.iter_mut() {
*t = true;
}
self.grass_layer(build_data);
rltk::console::log("Placed grass.");
let piers = self.water_and_piers(rng, build_data);
rltk::console::log("Placed water and piers.");
let (mut available_building_tiles, wall_gap_y) = self.town_walls(rng, build_data);
rltk::console::log("Placed walls.");
let mut buildings = self.buildings(rng, build_data, &mut available_building_tiles);
rltk::console::log("Placed buildings.");
let doors = self.add_doors(rng, build_data, &mut buildings, wall_gap_y);
rltk::console::log("Placed doors.");
self.path_from_tiles_to_nearest_tiletype(build_data, &doors, TileType::Road, TileType::Road, true);
rltk::console::log("Placed path from doors to road.");
self.path_from_tiles_to_nearest_tiletype(build_data, &piers, TileType::Road, TileType::Road, false);
rltk::console::log("Placed path from piers to road.");
build_data.take_snapshot();
@ -107,7 +102,6 @@ impl TownBuilder {
loop {
y = rng.roll_dice(1, build_data.height - 3) - 1;
if !(placed_piers.contains(&y) || placed_piers.contains(&(y + pier_width))) {
rltk::console::log(format!("Placing pier at y {}-{}", y, y + 3));
break;
}
}
@ -166,7 +160,6 @@ impl TownBuilder {
let wall_gap_y =
(build_data.height / 2) + rng.roll_dice(1, PATH_OFFSET_FROM_CENTRE * 2) - 1 - PATH_OFFSET_FROM_CENTRE;
rltk::console::log(format!("Placing road centred at y {}", wall_gap_y));
for y in BORDER..build_data.height - BORDER {
if !(y > wall_gap_y - HALF_PATH_THICKNESS && y < wall_gap_y + HALF_PATH_THICKNESS) {
@ -193,7 +186,7 @@ impl TownBuilder {
}
}
} else {
for x in OFFSET_FROM_LEFT - 1..build_data.width {
for x in OFFSET_FROM_LEFT - 3..build_data.width {
let road_idx = build_data.map.xy_idx(x, y);
build_data.map.tiles[road_idx] = TileType::Road;
}
@ -260,7 +253,6 @@ impl TownBuilder {
}
}
build_data.take_snapshot();
rltk::console::log(format!("Placed building {}", n_buildings));
}
}

View file

@ -42,7 +42,7 @@ impl VoronoiSpawning {
// Spawn the entities
for area in noise_areas.iter() {
spawner::spawn_region(&build_data.map, rng, area.1, build_data.map.depth, &mut build_data.spawn_list);
spawner::spawn_region(&build_data.map, rng, area.1, &mut build_data.spawn_list);
}
}
}

View file

@ -31,7 +31,8 @@ impl WaveFunctionCollapseBuilder {
let constraints = patterns_to_constraints(patterns, CHUNK_SIZE);
self.render_tile_gallery(&constraints, CHUNK_SIZE, build_data);
build_data.map = Map::new(build_data.map.depth, build_data.map.width, build_data.map.height);
build_data.map =
Map::new(build_data.map.id, build_data.map.width, build_data.map.height, build_data.map.difficulty);
loop {
let mut solver = Solver::new(constraints.clone(), CHUNK_SIZE, &build_data.map);
while !solver.iteration(&mut build_data.map, rng) {
@ -46,7 +47,7 @@ impl WaveFunctionCollapseBuilder {
}
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);
build_data.map = Map::new(0, build_data.width, build_data.height, 0);
let mut counter = 0;
let mut x = 1;
let mut y = 1;
@ -62,7 +63,7 @@ impl WaveFunctionCollapseBuilder {
if y + chunk_size > build_data.map.height {
// Move to the next page
build_data.take_snapshot();
build_data.map = Map::new(0, build_data.width, build_data.height);
build_data.map = Map::new(0, build_data.width, build_data.height, 0);
x = 1;
y = 1;

View file

@ -413,7 +413,7 @@ pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState {
VirtualKeyCode::Numpad7 | VirtualKeyCode::Y => result = try_move_player(-1, -1, &mut gs.ecs),
VirtualKeyCode::Numpad3 | VirtualKeyCode::N => result = try_move_player(1, 1, &mut gs.ecs),
VirtualKeyCode::Numpad1 | VirtualKeyCode::B => result = try_move_player(-1, 1, &mut gs.ecs),
// Depth
// id
VirtualKeyCode::Period => {
if ctx.shift {
if !try_next_level(&mut gs.ecs) {

View file

@ -249,14 +249,20 @@ fn get_renderable_component(renderable: &super::item_structs::Renderable) -> cra
}
}
pub fn table_by_name(raws: &RawMaster, key: &str, depth: i32) -> RandomTable {
pub fn table_by_name(raws: &RawMaster, key: &str, difficulty: i32) -> RandomTable {
if raws.table_index.contains_key(key) {
let spawn_table = &raws.raws.spawn_tables[raws.table_index[key]];
use super::SpawnTableEntry;
let available_options: Vec<&SpawnTableEntry> =
spawn_table.table.iter().filter(|a| depth >= a.min && depth <= a.max).collect();
let upper_bound = difficulty;
let lower_bound = 1;
let available_options: Vec<&SpawnTableEntry> = spawn_table
.table
.iter()
.filter(|entry| entry.difficulty >= lower_bound && entry.difficulty <= upper_bound)
.collect();
let mut rt = RandomTable::new();
for e in available_options.iter() {

View file

@ -10,6 +10,5 @@ pub struct SpawnTable {
pub struct SpawnTableEntry {
pub id: String,
pub weight: i32,
pub min: i32,
pub max: i32,
pub difficulty: i32,
}

View file

@ -39,13 +39,7 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
const MAX_ENTITIES: i32 = 3;
/// Fills a room with stuff!
pub fn spawn_room(
map: &Map,
rng: &mut RandomNumberGenerator,
room: &Rect,
map_depth: i32,
spawn_list: &mut Vec<(usize, String)>,
) {
pub fn spawn_room(map: &Map, rng: &mut RandomNumberGenerator, room: &Rect, spawn_list: &mut Vec<(usize, String)>) {
let mut possible_targets: Vec<usize> = Vec::new();
{
// Borrow scope - to keep access to the map separated
@ -59,18 +53,13 @@ pub fn spawn_room(
}
}
spawn_region(map, rng, &possible_targets, map_depth, spawn_list);
spawn_region(map, rng, &possible_targets, spawn_list);
}
pub fn spawn_region(
_map: &Map,
rng: &mut RandomNumberGenerator,
area: &[usize],
map_depth: i32,
spawn_list: &mut Vec<(usize, String)>,
) {
pub fn spawn_region(map: &Map, rng: &mut RandomNumberGenerator, area: &[usize], spawn_list: &mut Vec<(usize, String)>) {
let mut spawn_points: HashMap<usize, String> = HashMap::new();
let mut areas: Vec<usize> = Vec::from(area);
let difficulty = map.difficulty;
let num_spawns = i32::min(areas.len() as i32, rng.roll_dice(1, MAX_ENTITIES + 2) - 2);
if num_spawns <= 0 {
@ -81,19 +70,19 @@ pub fn spawn_region(
let category = category_table().roll(rng);
let spawn_table;
match category.as_ref() {
"mob" => spawn_table = mob_table(map_depth),
"mob" => spawn_table = mob_table(difficulty),
"item" => {
let item_category = item_category_table().roll(rng);
match item_category.as_ref() {
"equipment" => spawn_table = equipment_table(map_depth),
"potion" => spawn_table = potion_table(map_depth),
"scroll" => spawn_table = scroll_table(map_depth),
"wand" => spawn_table = wand_table(map_depth),
"equipment" => spawn_table = equipment_table(difficulty),
"potion" => spawn_table = potion_table(difficulty),
"scroll" => spawn_table = scroll_table(difficulty),
"wand" => spawn_table = wand_table(difficulty),
_ => spawn_table = debug_table(),
}
}
"food" => spawn_table = food_table(map_depth),
"trap" => spawn_table = trap_table(map_depth),
"food" => spawn_table = food_table(difficulty),
"trap" => spawn_table = trap_table(difficulty),
_ => spawn_table = debug_table(),
}
let array_idx = if areas.len() == 1 { 0usize } else { (rng.roll_dice(1, areas.len() as i32) - 1) as usize };
@ -143,30 +132,30 @@ fn debug_table() -> RandomTable {
return RandomTable::new().add("debug", 1);
}
pub fn equipment_table(map_depth: i32) -> RandomTable {
raws::table_by_name(&raws::RAWS.lock().unwrap(), "equipment", map_depth)
pub fn equipment_table(difficulty: i32) -> RandomTable {
raws::table_by_name(&raws::RAWS.lock().unwrap(), "equipment", difficulty)
}
pub fn potion_table(map_depth: i32) -> RandomTable {
raws::table_by_name(&raws::RAWS.lock().unwrap(), "potions", map_depth)
pub fn potion_table(difficulty: i32) -> RandomTable {
raws::table_by_name(&raws::RAWS.lock().unwrap(), "potions", difficulty)
}
pub fn scroll_table(map_depth: i32) -> RandomTable {
raws::table_by_name(&raws::RAWS.lock().unwrap(), "scrolls", map_depth)
pub fn scroll_table(difficulty: i32) -> RandomTable {
raws::table_by_name(&raws::RAWS.lock().unwrap(), "scrolls", difficulty)
}
pub fn wand_table(map_depth: i32) -> RandomTable {
raws::table_by_name(&raws::RAWS.lock().unwrap(), "wands", map_depth)
pub fn wand_table(difficulty: i32) -> RandomTable {
raws::table_by_name(&raws::RAWS.lock().unwrap(), "wands", difficulty)
}
pub fn food_table(map_depth: i32) -> RandomTable {
raws::table_by_name(&raws::RAWS.lock().unwrap(), "food", map_depth)
pub fn food_table(difficulty: i32) -> RandomTable {
raws::table_by_name(&raws::RAWS.lock().unwrap(), "food", difficulty)
}
pub fn mob_table(map_depth: i32) -> RandomTable {
raws::table_by_name(&raws::RAWS.lock().unwrap(), "mobs", map_depth)
pub fn mob_table(difficulty: i32) -> RandomTable {
raws::table_by_name(&raws::RAWS.lock().unwrap(), "mobs", difficulty)
}
pub fn trap_table(map_depth: i32) -> RandomTable {
raws::table_by_name(&raws::RAWS.lock().unwrap(), "traps", map_depth)
pub fn trap_table(difficulty: i32) -> RandomTable {
raws::table_by_name(&raws::RAWS.lock().unwrap(), "traps", difficulty)
}