mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add Primitive::Prefab
and Fill::Prefab
for coloring dungeon entrances.
This commit is contained in:
parent
95214649db
commit
c6bb61f2e6
@ -11,7 +11,7 @@ use vek::*;
|
||||
|
||||
make_case_elim!(
|
||||
structure_block,
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
#[repr(u32)]
|
||||
pub enum StructureBlock {
|
||||
None = 0,
|
||||
@ -40,12 +40,13 @@ pub enum StructureError {
|
||||
OutOfBounds,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Structure {
|
||||
center: Vec3<i32>,
|
||||
base: Arc<BaseStructure>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct BaseStructure {
|
||||
vol: Dyna<StructureBlock, ()>,
|
||||
default_kind: BlockKind,
|
||||
|
@ -140,6 +140,7 @@ pub trait Access {
|
||||
fn idx(pos: Vec3<i32>, sz: Vec3<u32>) -> usize;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct ColumnAccess;
|
||||
|
||||
impl Access for ColumnAccess {
|
||||
|
@ -7,8 +7,7 @@ mod tree;
|
||||
|
||||
// Reexports
|
||||
pub use self::{
|
||||
block_mask::BlockMask, castle::Castle, economy::Economy,
|
||||
settlement::Settlement, tree::Tree,
|
||||
block_mask::BlockMask, castle::Castle, economy::Economy, settlement::Settlement, tree::Tree,
|
||||
};
|
||||
|
||||
use crate::{column::ColumnSample, site2, Canvas};
|
||||
@ -155,7 +154,8 @@ impl Site {
|
||||
};
|
||||
s.apply_supplement(dynamic_rng, wpos2d, get_column, supplement, economy)
|
||||
},
|
||||
SiteKind::Dungeon(d) => {}, //d.apply_supplement(dynamic_rng, wpos2d, get_column, supplement),
|
||||
SiteKind::Dungeon(d) => {}, /* d.apply_supplement(dynamic_rng, wpos2d, get_column,
|
||||
* supplement), */
|
||||
SiteKind::Castle(c) => c.apply_supplement(dynamic_rng, wpos2d, get_column, supplement),
|
||||
SiteKind::Refactor(_) => {},
|
||||
SiteKind::Tree(_) => {},
|
||||
|
@ -1,8 +1,15 @@
|
||||
use super::*;
|
||||
use crate::util::{RandomField, Sampler};
|
||||
use crate::{
|
||||
block::block_from_structure,
|
||||
util::{RandomField, Sampler},
|
||||
};
|
||||
use common::{
|
||||
store::{Id, Store},
|
||||
terrain::{Block, BlockKind},
|
||||
terrain::{
|
||||
structure::{Structure as PrefabStructure, StructureBlock},
|
||||
Block, BlockKind,
|
||||
},
|
||||
vol::ReadVol,
|
||||
};
|
||||
use vek::*;
|
||||
|
||||
@ -18,6 +25,7 @@ pub enum Primitive {
|
||||
Sphere(Aabb<i32>),
|
||||
Plane(Aabr<i32>, Vec3<i32>, Vec2<f32>),
|
||||
Sampling(Box<dyn Fn(Vec3<i32>) -> bool>),
|
||||
Prefab(PrefabStructure),
|
||||
|
||||
// Combinators
|
||||
And(Id<Primitive>, Id<Primitive>),
|
||||
@ -34,6 +42,10 @@ pub enum Primitive {
|
||||
pub enum Fill {
|
||||
Block(Block),
|
||||
Brick(BlockKind, Rgb<u8>, u8),
|
||||
// TODO: the offset field for Prefab is a hack that breaks the compositionality of Translate,
|
||||
// we probably need an evaluator for the primitive tree that gets which point is queried at
|
||||
// leaf nodes given an input point to make Translate/Rotate work generally
|
||||
Prefab(PrefabStructure, Vec3<i32>, u32),
|
||||
}
|
||||
|
||||
impl Fill {
|
||||
@ -99,6 +111,7 @@ impl Fill {
|
||||
.dot(*gradient) as i32)
|
||||
},
|
||||
Primitive::Sampling(f) => f(pos),
|
||||
Primitive::Prefab(p) => !matches!(p.get(pos), Err(_) | Ok(StructureBlock::None)),
|
||||
Primitive::And(a, b) => {
|
||||
self.contains_at(tree, *a, pos) && self.contains_at(tree, *b, pos)
|
||||
},
|
||||
@ -118,7 +131,7 @@ impl Fill {
|
||||
},
|
||||
Primitive::Translate(prim, vec) => {
|
||||
self.contains_at(tree, *prim, pos.map2(*vec, i32::saturating_sub))
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,6 +140,7 @@ impl Fill {
|
||||
tree: &Store<Primitive>,
|
||||
prim: Id<Primitive>,
|
||||
pos: Vec3<i32>,
|
||||
canvas: &Canvas,
|
||||
) -> Option<Block> {
|
||||
if self.contains_at(tree, prim, pos) {
|
||||
match self {
|
||||
@ -137,6 +151,19 @@ impl Fill {
|
||||
.get((pos + Vec3::new(pos.z, pos.z, 0)) / Vec3::new(2, 2, 1))
|
||||
% *range as u32) as u8,
|
||||
)),
|
||||
Fill::Prefab(p, tr, seed) => p.get(pos - tr).ok().and_then(|sb| {
|
||||
let info = canvas.info;
|
||||
let col_sample = info.col(info.wpos)?;
|
||||
block_from_structure(
|
||||
canvas.index,
|
||||
*sb,
|
||||
pos - tr,
|
||||
info.wpos,
|
||||
*seed,
|
||||
col_sample,
|
||||
Block::air,
|
||||
)
|
||||
}),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
@ -180,6 +207,7 @@ impl Fill {
|
||||
min: Vec3::broadcast(std::i32::MIN),
|
||||
max: Vec3::broadcast(std::i32::MAX),
|
||||
},
|
||||
Primitive::Prefab(p) => p.get_bounds(),
|
||||
Primitive::And(a, b) => or_zip_with(
|
||||
self.get_bounds_inner(tree, *a),
|
||||
self.get_bounds_inner(tree, *b),
|
||||
|
@ -276,18 +276,19 @@ impl Site {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
pub fn name(&self) -> &str { &self.name }
|
||||
|
||||
pub fn difficulty(&self) -> Option<u32> {
|
||||
self.plots.iter().filter_map(|(_, plot)| {
|
||||
if let PlotKind::Dungeon(d) = &plot.kind {
|
||||
Some(d.difficulty())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).max()
|
||||
self.plots
|
||||
.iter()
|
||||
.filter_map(|(_, plot)| {
|
||||
if let PlotKind::Dungeon(d) = &plot.kind {
|
||||
Some(d.difficulty())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.max()
|
||||
}
|
||||
|
||||
pub fn generate_dungeon(land: &Land, rng: &mut impl Rng, origin: Vec2<i32>) -> Self {
|
||||
@ -763,9 +764,14 @@ impl Site {
|
||||
PlotKind::Castle(castle) => castle.render_collect(self),
|
||||
PlotKind::Dungeon(dungeon) => {
|
||||
let (prim_tree, fills) = dungeon.render_collect(self);
|
||||
tracing::info!("{:?}: {:?} {:?}", dungeon.name(), prim_tree.ids().count(), fills.len());
|
||||
tracing::info!(
|
||||
"{:?}: {:?} {:?}",
|
||||
dungeon.name(),
|
||||
prim_tree.ids().count(),
|
||||
fills.len()
|
||||
);
|
||||
(prim_tree, fills)
|
||||
}
|
||||
},
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
@ -777,7 +783,7 @@ impl Site {
|
||||
for z in aabb.min.z..aabb.max.z {
|
||||
let pos = Vec3::new(x, y, z);
|
||||
|
||||
if let Some(block) = fill.sample_at(&prim_tree, prim, pos) {
|
||||
if let Some(block) = fill.sample_at(&prim_tree, prim, pos, &canvas) {
|
||||
canvas.set(pos, block);
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,8 @@ use common::{
|
||||
generation::{ChunkSupplement, EntityInfo},
|
||||
store::{Id, Store},
|
||||
terrain::{
|
||||
Block, BlockKind, SpriteKind, Structure, structure::StructureBlock, StructuresGroup, TerrainChunkSize,
|
||||
structure::StructureBlock, Block, BlockKind, SpriteKind, Structure, StructuresGroup,
|
||||
TerrainChunkSize,
|
||||
},
|
||||
vol::{BaseVol, ReadVol, RectSizedVol, RectVolSize, WriteVol},
|
||||
};
|
||||
@ -1245,9 +1246,10 @@ impl SiteStructure for Dungeon {
|
||||
TILE_SIZE as f32 / 2.0,
|
||||
tweak!(27.0),
|
||||
)));
|
||||
let stairs_radius = 7;
|
||||
let bounding_box = prim(Primitive::Aabb(Aabb {
|
||||
min: origin - Vec3::new(8, 8, self.alt - 1),
|
||||
max: origin + Vec3::new(8, 8, 400),
|
||||
min: origin - Vec3::new(stairs_radius, stairs_radius, self.alt - 1),
|
||||
max: origin + Vec3::new(stairs_radius, stairs_radius, 400),
|
||||
}));
|
||||
//let stairs_inf = prim(Primitive::Sampling(Box::new(|_| true)));
|
||||
let stairs = prim(Primitive::And(bounding_box, stairs_inf));
|
||||
@ -1269,7 +1271,7 @@ impl SiteStructure for Dungeon {
|
||||
let entrances = ENTRANCES.read();
|
||||
let entrance = entrances[self.seed as usize % entrances.len()].clone();
|
||||
|
||||
let entrance_aabb = prim(Primitive::Aabb(entrance.get_bounds()));
|
||||
/*let entrance_aabb = prim(Primitive::Aabb(entrance.get_bounds()));
|
||||
let entrance = prim(Primitive::Sampling(Box::new(move |pos| {
|
||||
entrance
|
||||
.get(pos)
|
||||
@ -1277,7 +1279,12 @@ impl SiteStructure for Dungeon {
|
||||
})));
|
||||
let entrance = prim(Primitive::And(entrance, entrance_aabb));
|
||||
let entrance = prim(Primitive::Translate(entrance, origin));
|
||||
fill(entrance, Fill::Block(stone_red));
|
||||
fill(entrance, Fill::Block(stone_red));*/
|
||||
let entrance_prim = prim(Primitive::Prefab(entrance.clone()));
|
||||
let entrance_prim = prim(Primitive::Translate(entrance_prim, origin));
|
||||
let entrance_prim = prim(Primitive::Diff(entrance_prim, bounding_box));
|
||||
//fill(entrance_prim, Fill::Block(stone_red));
|
||||
fill(entrance_prim, Fill::Prefab(entrance, origin, self.seed));
|
||||
|
||||
/*let make_staircase = move |kind: &StairsKind,
|
||||
pos: Vec3<i32>,
|
||||
|
Loading…
Reference in New Issue
Block a user