diff --git a/CHANGELOG.md b/CHANGELOG.md index 1782eff3de..ee13ff795a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `/sudo` command - Added a Level of Detail (LoD) system for terrain sprites and entities - Added owl, hyena, parrot npcs +- Added dungeon entrances ### Changed diff --git a/assets/world/manifests/dungeon_entrances.ron b/assets/world/manifests/dungeon_entrances.ron new file mode 100644 index 0000000000..a90c39e368 --- /dev/null +++ b/assets/world/manifests/dungeon_entrances.ron @@ -0,0 +1,48 @@ +( + [ ( + specifier: "world.structure.dungeon.jungle_temple.entrance.1", + center: (50, 40, 10) + ), + ( + specifier: "world.structure.dungeon.pillar_entrance.round.1", + center: (21, 17, 28) + ), + ( + specifier: "world.structure.dungeon.pillar_entrance.round.2", + center: (20, 28, 15) + ), + ( + specifier: "world.structure.dungeon.pillar_entrance.1", + center: (18, 16, 17) + ), + ( + specifier: "world.structure.dungeon.pillar_entrance.2", + center: (18, 16, 17) + ), + ( + specifier: "world.structure.dungeon.pillar_entrance.3", + center: (18, 16, 17) + ), + ( + specifier: "world.structure.dungeon.pillar_entrance.4", + center: (18, 16, 17) + ), + ( + specifier: "world.structure.dungeon.pillar_entrance.5", + center: (18, 16, 17) + ), + ( + specifier: "world.structure.dungeon.pillar_entrance.6", + center: (18, 16, 17) + ), + ( + specifier: "world.structure.dungeon.temperate_entrance.ruins_4", + center: (13, 11, 14) + ), + ( + specifier: "world.structure.dungeon.misc_entrance.tower-ruin", + center: (13, 16, 9) + ), + + ] +) diff --git a/assets/world/manifests/quirky.ron b/assets/world/manifests/quirky.ron index 487c05d9c1..762845cdfb 100644 --- a/assets/world/manifests/quirky.ron +++ b/assets/world/manifests/quirky.ron @@ -1,9 +1,5 @@ ( - [ - ( - specifier: "world.structure.natural.tower-ruin", - center: (11, 14, 5) - ), + [ ( specifier: "world.structure.natural.witch-hut", center: (10, 13, 9) diff --git a/assets/world/module/human/balcony_upstairs.vox b/assets/world/module/human/balcony_upstairs.vox deleted file mode 100644 index e06d2de363..0000000000 Binary files a/assets/world/module/human/balcony_upstairs.vox and /dev/null differ diff --git a/assets/world/module/human/chimney_roof.vox b/assets/world/module/human/chimney_roof.vox deleted file mode 100644 index e8e49926a4..0000000000 Binary files a/assets/world/module/human/chimney_roof.vox and /dev/null differ diff --git a/assets/world/module/human/corner_ground.vox b/assets/world/module/human/corner_ground.vox deleted file mode 100644 index 7bcfc40923..0000000000 Binary files a/assets/world/module/human/corner_ground.vox and /dev/null differ diff --git a/assets/world/module/human/corner_roof.vox b/assets/world/module/human/corner_roof.vox deleted file mode 100644 index dea1a89941..0000000000 Binary files a/assets/world/module/human/corner_roof.vox and /dev/null differ diff --git a/assets/world/module/human/corner_upstairs.vox b/assets/world/module/human/corner_upstairs.vox deleted file mode 100644 index 3d153c18a2..0000000000 Binary files a/assets/world/module/human/corner_upstairs.vox and /dev/null differ diff --git a/assets/world/module/human/door_big.vox b/assets/world/module/human/door_big.vox deleted file mode 100644 index 74f233010e..0000000000 Binary files a/assets/world/module/human/door_big.vox and /dev/null differ diff --git a/assets/world/module/human/door_ground.vox b/assets/world/module/human/door_ground.vox deleted file mode 100644 index f5465e94b3..0000000000 Binary files a/assets/world/module/human/door_ground.vox and /dev/null differ diff --git a/assets/world/module/human/floor_ground.vox b/assets/world/module/human/floor_ground.vox deleted file mode 100644 index d231795f22..0000000000 Binary files a/assets/world/module/human/floor_ground.vox and /dev/null differ diff --git a/assets/world/module/human/floor_roof.vox b/assets/world/module/human/floor_roof.vox deleted file mode 100644 index e55181a790..0000000000 Binary files a/assets/world/module/human/floor_roof.vox and /dev/null differ diff --git a/assets/world/module/human/floor_upstairs.vox b/assets/world/module/human/floor_upstairs.vox deleted file mode 100644 index 9a4a55bad6..0000000000 Binary files a/assets/world/module/human/floor_upstairs.vox and /dev/null differ diff --git a/assets/world/module/human/stair_ground.vox b/assets/world/module/human/stair_ground.vox deleted file mode 100644 index cb742e0dbe..0000000000 Binary files a/assets/world/module/human/stair_ground.vox and /dev/null differ diff --git a/assets/world/module/human/wall_ground.vox b/assets/world/module/human/wall_ground.vox deleted file mode 100644 index 89844fe485..0000000000 Binary files a/assets/world/module/human/wall_ground.vox and /dev/null differ diff --git a/assets/world/module/human/wall_roof.vox b/assets/world/module/human/wall_roof.vox deleted file mode 100644 index de7dbfbc77..0000000000 Binary files a/assets/world/module/human/wall_roof.vox and /dev/null differ diff --git a/assets/world/module/human/wall_upstairs.vox b/assets/world/module/human/wall_upstairs.vox deleted file mode 100644 index bbcf8d6110..0000000000 Binary files a/assets/world/module/human/wall_upstairs.vox and /dev/null differ diff --git a/assets/world/module/human/window_corner_ground.vox b/assets/world/module/human/window_corner_ground.vox deleted file mode 100644 index ce4da8b6d4..0000000000 Binary files a/assets/world/module/human/window_corner_ground.vox and /dev/null differ diff --git a/assets/world/module/human/window_corner_upstairs.vox b/assets/world/module/human/window_corner_upstairs.vox deleted file mode 100644 index 1094c36bd1..0000000000 Binary files a/assets/world/module/human/window_corner_upstairs.vox and /dev/null differ diff --git a/assets/world/module/human/window_ground.vox b/assets/world/module/human/window_ground.vox deleted file mode 100644 index e7879dda46..0000000000 Binary files a/assets/world/module/human/window_ground.vox and /dev/null differ diff --git a/assets/world/module/human/window_upstairs.vox b/assets/world/module/human/window_upstairs.vox deleted file mode 100644 index 309fc417ec..0000000000 Binary files a/assets/world/module/human/window_upstairs.vox and /dev/null differ diff --git a/assets/world/module/wall/corner_ground.vox b/assets/world/module/wall/corner_ground.vox deleted file mode 100644 index b59950d418..0000000000 Binary files a/assets/world/module/wall/corner_ground.vox and /dev/null differ diff --git a/assets/world/module/wall/corner_mid.vox b/assets/world/module/wall/corner_mid.vox deleted file mode 100644 index 02a545ac05..0000000000 Binary files a/assets/world/module/wall/corner_mid.vox and /dev/null differ diff --git a/assets/world/module/wall/corner_top.vox b/assets/world/module/wall/corner_top.vox deleted file mode 100644 index 6a88adced1..0000000000 Binary files a/assets/world/module/wall/corner_top.vox and /dev/null differ diff --git a/assets/world/module/wall/edge_ground.vox b/assets/world/module/wall/edge_ground.vox deleted file mode 100644 index c10a129d23..0000000000 Binary files a/assets/world/module/wall/edge_ground.vox and /dev/null differ diff --git a/assets/world/module/wall/edge_mid.vox b/assets/world/module/wall/edge_mid.vox deleted file mode 100644 index 1c86d6ddb9..0000000000 Binary files a/assets/world/module/wall/edge_mid.vox and /dev/null differ diff --git a/assets/world/module/wall/edge_top.vox b/assets/world/module/wall/edge_top.vox deleted file mode 100644 index fcfeff9c7b..0000000000 Binary files a/assets/world/module/wall/edge_top.vox and /dev/null differ diff --git a/assets/world/module/wall/end_top.vox b/assets/world/module/wall/end_top.vox deleted file mode 100644 index 8d76ad09f3..0000000000 Binary files a/assets/world/module/wall/end_top.vox and /dev/null differ diff --git a/assets/world/module/wall/single_top.vox b/assets/world/module/wall/single_top.vox deleted file mode 100644 index bfa78a6c44..0000000000 Binary files a/assets/world/module/wall/single_top.vox and /dev/null differ diff --git a/assets/world/structure/dungeon/jungle_temple/entrance/1.vox b/assets/world/structure/dungeon/jungle_temple/entrance/1.vox new file mode 100644 index 0000000000..a39150f0ad Binary files /dev/null and b/assets/world/structure/dungeon/jungle_temple/entrance/1.vox differ diff --git a/assets/world/structure/natural/tower-ruin.vox b/assets/world/structure/dungeon/misc_entrance/tower-ruin.vox similarity index 100% rename from assets/world/structure/natural/tower-ruin.vox rename to assets/world/structure/dungeon/misc_entrance/tower-ruin.vox diff --git a/assets/world/structure/dungeon/pillar_entrance/1.vox b/assets/world/structure/dungeon/pillar_entrance/1.vox new file mode 100644 index 0000000000..31d5884569 Binary files /dev/null and b/assets/world/structure/dungeon/pillar_entrance/1.vox differ diff --git a/assets/world/structure/dungeon/pillar_entrance/2.vox b/assets/world/structure/dungeon/pillar_entrance/2.vox new file mode 100644 index 0000000000..19c95a3fcc Binary files /dev/null and b/assets/world/structure/dungeon/pillar_entrance/2.vox differ diff --git a/assets/world/structure/dungeon/pillar_entrance/3.vox b/assets/world/structure/dungeon/pillar_entrance/3.vox new file mode 100644 index 0000000000..11de3d7243 Binary files /dev/null and b/assets/world/structure/dungeon/pillar_entrance/3.vox differ diff --git a/assets/world/structure/dungeon/pillar_entrance/4.vox b/assets/world/structure/dungeon/pillar_entrance/4.vox new file mode 100644 index 0000000000..9752e62ccd Binary files /dev/null and b/assets/world/structure/dungeon/pillar_entrance/4.vox differ diff --git a/assets/world/structure/dungeon/pillar_entrance/5.vox b/assets/world/structure/dungeon/pillar_entrance/5.vox new file mode 100644 index 0000000000..0561c55082 Binary files /dev/null and b/assets/world/structure/dungeon/pillar_entrance/5.vox differ diff --git a/assets/world/structure/dungeon/pillar_entrance/6.vox b/assets/world/structure/dungeon/pillar_entrance/6.vox new file mode 100644 index 0000000000..203724017e Binary files /dev/null and b/assets/world/structure/dungeon/pillar_entrance/6.vox differ diff --git a/assets/world/structure/dungeon/pillar_entrance/round/1.vox b/assets/world/structure/dungeon/pillar_entrance/round/1.vox new file mode 100644 index 0000000000..23c5566ebc Binary files /dev/null and b/assets/world/structure/dungeon/pillar_entrance/round/1.vox differ diff --git a/assets/world/structure/dungeon/pillar_entrance/round/2.vox b/assets/world/structure/dungeon/pillar_entrance/round/2.vox new file mode 100644 index 0000000000..888473496b Binary files /dev/null and b/assets/world/structure/dungeon/pillar_entrance/round/2.vox differ diff --git a/assets/world/structure/dungeon/temperate_entrance/ruins_4.vox b/assets/world/structure/dungeon/temperate_entrance/ruins_4.vox new file mode 100644 index 0000000000..d52cbb55e4 Binary files /dev/null and b/assets/world/structure/dungeon/temperate_entrance/ruins_4.vox differ diff --git a/assets/world/tree/desert_palm_old/1.vox b/assets/world/tree/desert_palm_old/1.vox deleted file mode 100644 index 319c8d8996..0000000000 Binary files a/assets/world/tree/desert_palm_old/1.vox and /dev/null differ diff --git a/assets/world/tree/desert_palm_old/10.vox b/assets/world/tree/desert_palm_old/10.vox deleted file mode 100644 index 477a8bff82..0000000000 Binary files a/assets/world/tree/desert_palm_old/10.vox and /dev/null differ diff --git a/assets/world/tree/desert_palm_old/2.vox b/assets/world/tree/desert_palm_old/2.vox deleted file mode 100644 index 1818004e00..0000000000 Binary files a/assets/world/tree/desert_palm_old/2.vox and /dev/null differ diff --git a/assets/world/tree/desert_palm_old/3.vox b/assets/world/tree/desert_palm_old/3.vox deleted file mode 100644 index 5e4db856a9..0000000000 Binary files a/assets/world/tree/desert_palm_old/3.vox and /dev/null differ diff --git a/assets/world/tree/desert_palm_old/4.vox b/assets/world/tree/desert_palm_old/4.vox deleted file mode 100644 index deb8db5523..0000000000 Binary files a/assets/world/tree/desert_palm_old/4.vox and /dev/null differ diff --git a/assets/world/tree/desert_palm_old/5.vox b/assets/world/tree/desert_palm_old/5.vox deleted file mode 100644 index 2926cc3b8c..0000000000 Binary files a/assets/world/tree/desert_palm_old/5.vox and /dev/null differ diff --git a/assets/world/tree/desert_palm_old/6.vox b/assets/world/tree/desert_palm_old/6.vox deleted file mode 100644 index f5fe355481..0000000000 Binary files a/assets/world/tree/desert_palm_old/6.vox and /dev/null differ diff --git a/assets/world/tree/desert_palm_old/7.vox b/assets/world/tree/desert_palm_old/7.vox deleted file mode 100644 index af6beef2e5..0000000000 Binary files a/assets/world/tree/desert_palm_old/7.vox and /dev/null differ diff --git a/assets/world/tree/desert_palm_old/8.vox b/assets/world/tree/desert_palm_old/8.vox deleted file mode 100644 index c3a3bf33e0..0000000000 Binary files a/assets/world/tree/desert_palm_old/8.vox and /dev/null differ diff --git a/assets/world/tree/desert_palm_old/9.vox b/assets/world/tree/desert_palm_old/9.vox deleted file mode 100644 index d5207d1022..0000000000 Binary files a/assets/world/tree/desert_palm_old/9.vox and /dev/null differ diff --git a/common/src/terrain/structure.rs b/common/src/terrain/structure.rs index 8bdf71586e..14ea9806be 100644 --- a/common/src/terrain/structure.rs +++ b/common/src/terrain/structure.rs @@ -5,12 +5,13 @@ use crate::{ volumes::dyna::{Dyna, DynaError}, }; use dot_vox::DotVoxData; -use std::{fs::File, io::BufReader}; +use std::{fs::File, io::BufReader, sync::Arc}; use vek::*; #[derive(Copy, Clone, PartialEq)] pub enum StructureBlock { None, + Grass, TemperateLeaves, PineLeaves, Acacia, @@ -50,6 +51,21 @@ pub struct Structure { } impl Structure { + pub fn load_group(specifier: &str) -> Vec> { + let spec = assets::load::(&["world.manifests.", specifier].concat()); + return spec + .unwrap() + .0 + .iter() + .map(|sp| { + assets::load_map(&sp.specifier[..], |s: Structure| { + s.with_center(Vec3::from(sp.center)) + }) + .unwrap() + }) + .collect(); + } + pub fn with_center(mut self, center: Vec3) -> Self { self.center = center; self @@ -113,6 +129,7 @@ impl Asset for Structure { 5 => StructureBlock::Mangrove, 6 => StructureBlock::GreenSludge, 7 => StructureBlock::Fruit, + 8 => StructureBlock::Grass, 9 => StructureBlock::Liana, 10 => StructureBlock::Chest, 11 => StructureBlock::Coconut, @@ -150,3 +167,19 @@ impl Asset for Structure { } } } + +#[derive(Deserialize)] +struct StructureSpec { + specifier: String, + center: [i32; 3], +} +#[derive(Deserialize)] +struct StructuresSpec(Vec); + +impl Asset for StructuresSpec { + const ENDINGS: &'static [&'static str] = &["ron"]; + + fn parse(buf_reader: BufReader) -> Result { + ron::de::from_reader(buf_reader).map_err(assets::Error::parse_error) + } +} diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 8aa8020af6..fdcd9f1307 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -538,7 +538,6 @@ impl StructureInfo { .and_then(|b| { block_from_structure( *b, - volume.default_kind(), block_pos, self.pos.into(), self.seed, @@ -552,11 +551,10 @@ impl StructureInfo { pub fn block_from_structure( sblock: StructureBlock, - default_kind: BlockKind, pos: Vec3, structure_pos: Vec2, structure_seed: u32, - _sample: &ColumnSample, + sample: &ColumnSample, ) -> Option { let field = RandomField::new(structure_seed + 0); @@ -565,6 +563,10 @@ pub fn block_from_structure( match sblock { StructureBlock::None => None, + StructureBlock::Grass => Some(Block::new( + BlockKind::Normal, + sample.surface_color.map(|e| (e * 255.0) as u8), + )), StructureBlock::TemperateLeaves => Some(Block::new( BlockKind::Leaves, Lerp::lerp( @@ -639,7 +641,7 @@ pub fn block_from_structure( )), StructureBlock::Hollow => Some(Block::empty()), StructureBlock::Normal(color) => { - Some(Block::new(default_kind, color)).filter(|block| !block.is_empty()) + Some(Block::new(BlockKind::Normal, color)).filter(|block| !block.is_empty()) }, } } diff --git a/world/src/block/natural.rs b/world/src/block/natural.rs index 232708dad6..1ea1103ae9 100644 --- a/world/src/block/natural.rs +++ b/world/src/block/natural.rs @@ -5,11 +5,9 @@ use crate::{ util::{RandomPerm, Sampler, SmallCache, UnitChooser}, CONFIG, }; -use common::{assets, assets::Asset, terrain::Structure}; +use common::terrain::Structure; use lazy_static::lazy_static; -use ron; -use serde::Deserialize; -use std::{fs::File, io::BufReader, sync::Arc, u32}; +use std::{sync::Arc, u32}; use vek::*; static VOLUME_RAND: RandomPerm = RandomPerm::new(0xDB21C052); @@ -76,47 +74,16 @@ pub fn structure_gen<'a>( }) } -#[derive(Deserialize)] -struct StructureSpec { - specifier: String, - center: [i32; 3], -} -#[derive(Deserialize)] -struct StructuresSpec(Vec); - -impl Asset for StructuresSpec { - const ENDINGS: &'static [&'static str] = &["ron"]; - - fn parse(buf_reader: BufReader) -> Result { - ron::de::from_reader(buf_reader).map_err(assets::Error::parse_error) - } -} - -fn load_structures(specifier: &str) -> Vec> { - let spec = assets::load::(&["world.manifests.", specifier].concat()); - return spec - .unwrap() - .0 - .iter() - .map(|sp| { - assets::load_map(&sp.specifier[..], |s: Structure| { - s.with_center(Vec3::from(sp.center)) - }) - .unwrap() - }) - .collect(); -} - lazy_static! { - pub static ref OAKS: Vec> = load_structures("oaks"); - pub static ref OAK_STUMPS: Vec> = load_structures("oak_stumps"); - pub static ref PINES: Vec> = load_structures("pines"); - pub static ref PALMS: Vec> = load_structures("palms"); - pub static ref SNOW_PINES: Vec> = load_structures("snow_pines"); - pub static ref ACACIAS: Vec> = load_structures("acacias"); - pub static ref FRUIT_TREES: Vec> = load_structures("fruit_trees"); - pub static ref BIRCHES: Vec> = load_structures("birch"); - pub static ref MANGROVE_TREES: Vec> = load_structures("mangrove_trees"); - pub static ref QUIRKY: Vec> = load_structures("quirky"); - pub static ref QUIRKY_DRY: Vec> = load_structures("quirky_dry"); + pub static ref OAKS: Vec> = Structure::load_group("oaks"); + pub static ref OAK_STUMPS: Vec> = Structure::load_group("oak_stumps"); + pub static ref PINES: Vec> = Structure::load_group("pines"); + pub static ref PALMS: Vec> = Structure::load_group("palms"); + pub static ref SNOW_PINES: Vec> = Structure::load_group("snow_pines"); + pub static ref ACACIAS: Vec> = Structure::load_group("acacias"); + pub static ref FRUIT_TREES: Vec> = Structure::load_group("fruit_trees"); + pub static ref BIRCHES: Vec> = Structure::load_group("birch"); + pub static ref MANGROVE_TREES: Vec> = Structure::load_group("mangrove_trees"); + pub static ref QUIRKY: Vec> = Structure::load_group("quirky"); + pub static ref QUIRKY_DRY: Vec> = Structure::load_group("quirky_dry"); } diff --git a/world/src/civ/mod.rs b/world/src/civ/mod.rs index 1d1515159a..750e17322a 100644 --- a/world/src/civ/mod.rs +++ b/world/src/civ/mod.rs @@ -95,21 +95,26 @@ impl Civs { // Flatten ground around sites for site in this.sites.iter() { - if let SiteKind::Settlement = &site.kind { - } else { - continue; - } - let radius = 48i32; + let wpos = site.center * Vec2::from(TerrainChunkSize::RECT_SIZE).map(|e: u32| e as i32); + let flatten_radius = match &site.kind { + SiteKind::Settlement => 10.0, + SiteKind::Dungeon => 2.0, + }; + + let (raise, raise_dist): (f32, i32) = match &site.kind { + SiteKind::Settlement => (10.0, 6), + _ => (0.0, 0), + }; + // Flatten ground - let flatten_radius = 10.0; if let Some(center_alt) = ctx.sim.get_alt_approx(wpos) { for offs in Spiral2d::new().take(radius.pow(2) as usize) { let center_alt = center_alt - + if offs.magnitude_squared() <= 6i32.pow(2) { - 16.0 + + if offs.magnitude_squared() <= raise_dist.pow(2) { + raise } else { 0.0 }; // Raise the town centre up a little @@ -335,7 +340,7 @@ impl Civs { let site = self.sites.insert(site_fn(place)); // Find neighbors - const MAX_NEIGHBOR_DISTANCE: f32 = 250.0; + const MAX_NEIGHBOR_DISTANCE: f32 = 500.0; let mut nearby = self .sites .iter_ids() diff --git a/world/src/site/dungeon/mod.rs b/world/src/site/dungeon/mod.rs index a696907e7a..9a19332ff4 100644 --- a/world/src/site/dungeon/mod.rs +++ b/world/src/site/dungeon/mod.rs @@ -1,5 +1,6 @@ use super::SpawnRules; use crate::{ + block::block_from_structure, column::ColumnSample, sim::WorldSim, site::BlockMask, @@ -11,11 +12,12 @@ use common::{ comp, generation::{ChunkSupplement, EntityInfo}, store::{Id, Store}, - terrain::{Block, BlockKind, TerrainChunkSize}, + terrain::{Block, BlockKind, Structure, TerrainChunkSize}, vol::{BaseVol, ReadVol, RectSizedVol, RectVolSize, Vox, WriteVol}, }; +use lazy_static::lazy_static; use rand::prelude::*; -use std::f32; +use std::{f32, sync::Arc}; use vek::*; impl WorldSim { @@ -34,6 +36,7 @@ impl WorldSim { pub struct Dungeon { origin: Vec2, alt: i32, + seed: u32, #[allow(dead_code)] noise: RandomField, floors: Vec, @@ -44,16 +47,19 @@ pub struct GenCtx<'a, R: Rng> { rng: &'a mut R, } +const ALT_OFFSET: i32 = -2; + impl Dungeon { pub fn generate(wpos: Vec2, sim: Option<&WorldSim>, rng: &mut impl Rng) -> Self { let mut ctx = GenCtx { sim, rng }; let this = Self { - origin: wpos, + origin: wpos - TILE_SIZE / 2, alt: ctx .sim .and_then(|sim| sim.get_alt_approx(wpos)) .unwrap_or(0.0) as i32 + 6, + seed: ctx.rng.gen(), noise: RandomField::new(ctx.rng.gen()), floors: (0..6) .scan(Vec2::zero(), |stair_tile, level| { @@ -71,8 +77,9 @@ impl Dungeon { pub fn radius(&self) -> f32 { 1200.0 } - pub fn spawn_rules(&self, _wpos: Vec2) -> SpawnRules { + pub fn spawn_rules(&self, wpos: Vec2) -> SpawnRules { SpawnRules { + trees: wpos.distance_squared(self.origin) > 64i32.pow(2), ..SpawnRules::default() } } @@ -80,9 +87,16 @@ impl Dungeon { pub fn apply_to<'a>( &'a self, wpos2d: Vec2, - _get_column: impl FnMut(Vec2) -> Option<&'a ColumnSample<'a>>, + mut get_column: impl FnMut(Vec2) -> Option<&'a ColumnSample<'a>>, vol: &mut (impl BaseVol + RectSizedVol + ReadVol + WriteVol), ) { + lazy_static! { + pub static ref ENTRANCES: Vec> = + Structure::load_group("dungeon_entrances"); + } + + let entrance = &ENTRANCES[self.seed as usize % ENTRANCES.len()]; + for y in 0..vol.size_xy().y as i32 { for x in 0..vol.size_xy().x as i32 { let offs = Vec2::new(x, y); @@ -90,7 +104,30 @@ impl Dungeon { let wpos2d = wpos2d + offs; let rpos = wpos2d - self.origin; - let mut z = self.alt; + // Apply the dungeon entrance + let col_sample = if let Some(col) = get_column(offs) { + col + } else { + continue; + }; + for z in entrance.get_bounds().min.z..entrance.get_bounds().max.z { + let wpos = Vec3::new(offs.x, offs.y, self.alt + z + ALT_OFFSET); + let spos = Vec3::new(rpos.x - TILE_SIZE / 2, rpos.y - TILE_SIZE / 2, z); + if let Some(block) = entrance + .get(spos) + .ok() + .copied() + .map(|sb| { + block_from_structure(sb, spos, self.origin, self.seed, col_sample) + }) + .unwrap_or(None) + { + let _ = vol.set(wpos, block); + } + } + + // Apply the dungeon internals + let mut z = self.alt + ALT_OFFSET; for floor in &self.floors { z -= floor.total_depth(); @@ -123,17 +160,17 @@ impl Dungeon { let offs = Vec2::new(rng.gen_range(-1.0, 1.0), rng.gen_range(-1.0, 1.0)) .try_normalized() .unwrap_or(Vec2::unit_y()) - * 16.0; + * 12.0; supplement.add_entity( EntityInfo::at( - Vec3::new(self.origin.x, self.origin.y, self.alt + 4).map(|e| e as f32) + Vec3::new(self.origin.x, self.origin.y, self.alt + 16).map(|e| e as f32) + Vec3::from(offs), ) .into_waypoint(), ); } - let mut z = self.alt; + let mut z = self.alt + ALT_OFFSET; for floor in &self.floors { z -= floor.total_depth(); let origin = Vec3::new(self.origin.x, self.origin.y, z);