mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added dungeon entrances
This commit is contained in:
parent
00f0a011de
commit
d0b1c9eb6f
45
assets/world/manifests/dungeon_entrances.ron
Normal file
45
assets/world/manifests/dungeon_entrances.ron
Normal file
@ -0,0 +1,45 @@
|
||||
(
|
||||
[
|
||||
(
|
||||
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)
|
||||
),
|
||||
// Pfau's dungeon entrance
|
||||
//(
|
||||
// specifier: "world.structure.dungeon.entrance.1",
|
||||
// center: (13, 11, 12)
|
||||
//),
|
||||
]
|
||||
)
|
BIN
assets/world/structure/dungeon/jungle_temple/entrance/1.vox
(Stored with Git LFS)
Normal file
BIN
assets/world/structure/dungeon/jungle_temple/entrance/1.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/world/structure/dungeon/pillar_entrance/1.vox
(Stored with Git LFS)
Normal file
BIN
assets/world/structure/dungeon/pillar_entrance/1.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/world/structure/dungeon/pillar_entrance/2.vox
(Stored with Git LFS)
Normal file
BIN
assets/world/structure/dungeon/pillar_entrance/2.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/world/structure/dungeon/pillar_entrance/3.vox
(Stored with Git LFS)
Normal file
BIN
assets/world/structure/dungeon/pillar_entrance/3.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/world/structure/dungeon/pillar_entrance/4.vox
(Stored with Git LFS)
Normal file
BIN
assets/world/structure/dungeon/pillar_entrance/4.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/world/structure/dungeon/pillar_entrance/5.vox
(Stored with Git LFS)
Normal file
BIN
assets/world/structure/dungeon/pillar_entrance/5.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/world/structure/dungeon/pillar_entrance/6.vox
(Stored with Git LFS)
Normal file
BIN
assets/world/structure/dungeon/pillar_entrance/6.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/world/structure/dungeon/pillar_entrance/round/1.vox
(Stored with Git LFS)
Normal file
BIN
assets/world/structure/dungeon/pillar_entrance/round/1.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/world/structure/dungeon/pillar_entrance/round/2.vox
(Stored with Git LFS)
Normal file
BIN
assets/world/structure/dungeon/pillar_entrance/round/2.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -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<Arc<Structure>> {
|
||||
let spec = assets::load::<StructuresSpec>(&["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<i32>) -> 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<StructureSpec>);
|
||||
|
||||
impl Asset for StructuresSpec {
|
||||
const ENDINGS: &'static [&'static str] = &["ron"];
|
||||
|
||||
fn parse(buf_reader: BufReader<File>) -> Result<Self, assets::Error> {
|
||||
ron::de::from_reader(buf_reader).map_err(assets::Error::parse_error)
|
||||
}
|
||||
}
|
||||
|
@ -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<i32>,
|
||||
structure_pos: Vec2<i32>,
|
||||
structure_seed: u32,
|
||||
_sample: &ColumnSample,
|
||||
sample: &ColumnSample,
|
||||
) -> Option<Block> {
|
||||
let field = RandomField::new(structure_seed + 0);
|
||||
|
||||
@ -565,6 +563,7 @@ 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 +638,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())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -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<StructureSpec>);
|
||||
|
||||
impl Asset for StructuresSpec {
|
||||
const ENDINGS: &'static [&'static str] = &["ron"];
|
||||
|
||||
fn parse(buf_reader: BufReader<File>) -> Result<Self, assets::Error> {
|
||||
ron::de::from_reader(buf_reader).map_err(assets::Error::parse_error)
|
||||
}
|
||||
}
|
||||
|
||||
fn load_structures(specifier: &str) -> Vec<Arc<Structure>> {
|
||||
let spec = assets::load::<StructuresSpec>(&["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<Arc<Structure>> = load_structures("oaks");
|
||||
pub static ref OAK_STUMPS: Vec<Arc<Structure>> = load_structures("oak_stumps");
|
||||
pub static ref PINES: Vec<Arc<Structure>> = load_structures("pines");
|
||||
pub static ref PALMS: Vec<Arc<Structure>> = load_structures("palms");
|
||||
pub static ref SNOW_PINES: Vec<Arc<Structure>> = load_structures("snow_pines");
|
||||
pub static ref ACACIAS: Vec<Arc<Structure>> = load_structures("acacias");
|
||||
pub static ref FRUIT_TREES: Vec<Arc<Structure>> = load_structures("fruit_trees");
|
||||
pub static ref BIRCHES: Vec<Arc<Structure>> = load_structures("birch");
|
||||
pub static ref MANGROVE_TREES: Vec<Arc<Structure>> = load_structures("mangrove_trees");
|
||||
pub static ref QUIRKY: Vec<Arc<Structure>> = load_structures("quirky");
|
||||
pub static ref QUIRKY_DRY: Vec<Arc<Structure>> = load_structures("quirky_dry");
|
||||
pub static ref OAKS: Vec<Arc<Structure>> = Structure::load_group("oaks");
|
||||
pub static ref OAK_STUMPS: Vec<Arc<Structure>> = Structure::load_group("oak_stumps");
|
||||
pub static ref PINES: Vec<Arc<Structure>> = Structure::load_group("pines");
|
||||
pub static ref PALMS: Vec<Arc<Structure>> = Structure::load_group("palms");
|
||||
pub static ref SNOW_PINES: Vec<Arc<Structure>> = Structure::load_group("snow_pines");
|
||||
pub static ref ACACIAS: Vec<Arc<Structure>> = Structure::load_group("acacias");
|
||||
pub static ref FRUIT_TREES: Vec<Arc<Structure>> = Structure::load_group("fruit_trees");
|
||||
pub static ref BIRCHES: Vec<Arc<Structure>> = Structure::load_group("birch");
|
||||
pub static ref MANGROVE_TREES: Vec<Arc<Structure>> = Structure::load_group("mangrove_trees");
|
||||
pub static ref QUIRKY: Vec<Arc<Structure>> = Structure::load_group("quirky");
|
||||
pub static ref QUIRKY_DRY: Vec<Arc<Structure>> = Structure::load_group("quirky_dry");
|
||||
}
|
||||
|
@ -95,16 +95,16 @@ 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);
|
||||
|
||||
// Flatten ground
|
||||
let flatten_radius = 10.0;
|
||||
let flatten_radius = match &site.kind {
|
||||
SiteKind::Settlement => 10.0,
|
||||
SiteKind::Dungeon => 2.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
|
||||
@ -335,7 +335,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()
|
||||
|
@ -4,6 +4,7 @@ use crate::{
|
||||
sim::WorldSim,
|
||||
site::BlockMask,
|
||||
util::{attempt, Grid, RandomField, Sampler, CARDINALS, DIRS},
|
||||
block::block_from_structure,
|
||||
};
|
||||
use common::{
|
||||
assets,
|
||||
@ -11,11 +12,12 @@ use common::{
|
||||
comp,
|
||||
generation::{ChunkSupplement, EntityInfo},
|
||||
store::{Id, Store},
|
||||
terrain::{Block, BlockKind, TerrainChunkSize},
|
||||
terrain::{Block, BlockKind, TerrainChunkSize, Structure},
|
||||
vol::{BaseVol, ReadVol, RectSizedVol, RectVolSize, Vox, WriteVol},
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use rand::prelude::*;
|
||||
use std::f32;
|
||||
use std::{sync::Arc, f32};
|
||||
use vek::*;
|
||||
|
||||
impl WorldSim {
|
||||
@ -34,6 +36,7 @@ impl WorldSim {
|
||||
pub struct Dungeon {
|
||||
origin: Vec2<i32>,
|
||||
alt: i32,
|
||||
seed: u32,
|
||||
#[allow(dead_code)]
|
||||
noise: RandomField,
|
||||
floors: Vec<Floor>,
|
||||
@ -44,6 +47,8 @@ pub struct GenCtx<'a, R: Rng> {
|
||||
rng: &'a mut R,
|
||||
}
|
||||
|
||||
const ALT_OFFSET: i32 = 2;
|
||||
|
||||
impl Dungeon {
|
||||
pub fn generate(wpos: Vec2<i32>, sim: Option<&WorldSim>, rng: &mut impl Rng) -> Self {
|
||||
let mut ctx = GenCtx { sim, rng };
|
||||
@ -54,6 +59,7 @@ impl Dungeon {
|
||||
.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<i32>) -> SpawnRules {
|
||||
pub fn spawn_rules(&self, wpos: Vec2<i32>) -> SpawnRules {
|
||||
SpawnRules {
|
||||
trees: wpos.distance_squared(self.origin) > 64i32.pow(2),
|
||||
..SpawnRules::default()
|
||||
}
|
||||
}
|
||||
@ -80,9 +87,15 @@ impl Dungeon {
|
||||
pub fn apply_to<'a>(
|
||||
&'a self,
|
||||
wpos2d: Vec2<i32>,
|
||||
_get_column: impl FnMut(Vec2<i32>) -> Option<&'a ColumnSample<'a>>,
|
||||
mut get_column: impl FnMut(Vec2<i32>) -> Option<&'a ColumnSample<'a>>,
|
||||
vol: &mut (impl BaseVol<Vox = Block> + RectSizedVol + ReadVol + WriteVol),
|
||||
) {
|
||||
lazy_static! {
|
||||
pub static ref ENTRANCES: Vec<Arc<Structure>> = 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 +103,28 @@ 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();
|
||||
|
||||
@ -133,7 +167,7 @@ impl Dungeon {
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user