mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Improved terrain in sites
This commit is contained in:
parent
56eff72670
commit
692855198e
@ -1,6 +1,7 @@
|
||||
use crate::{
|
||||
all::ForestKind,
|
||||
sim::{local_cells, Cave, Path, RiverKind, SimChunk, WorldSim},
|
||||
site::SpawnRules,
|
||||
util::{RandomField, Sampler},
|
||||
IndexRef, CONFIG,
|
||||
};
|
||||
@ -109,6 +110,11 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
let neighbor_chunk = sim.get(neighbor_pos)?;
|
||||
Some((neighbor_pos, neighbor_chunk, &neighbor_chunk.river))
|
||||
});
|
||||
let spawn_rules = sim_chunk
|
||||
.sites
|
||||
.iter()
|
||||
.map(|site| index.sites[*site].spawn_rules(wpos))
|
||||
.fold(SpawnRules::default(), |a, b| a.combine(b));
|
||||
|
||||
let gradient = sim.get_gradient_approx(chunk_pos);
|
||||
|
||||
@ -829,12 +835,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
// NOTE: To disable warp, uncomment this line.
|
||||
// let warp_factor = 0.0;
|
||||
|
||||
let warp_factor = warp_factor
|
||||
* sim_chunk
|
||||
.sites
|
||||
.iter()
|
||||
.map(|site| index.sites[*site].spawn_rules(wpos).max_warp)
|
||||
.fold(1.0f32, |a, b| a.min(b));
|
||||
let warp_factor = warp_factor * spawn_rules.max_warp;
|
||||
|
||||
let riverless_alt_delta = Lerp::lerp(0.0, riverless_alt_delta, warp_factor);
|
||||
let alt = alt + riverless_alt_delta;
|
||||
@ -1120,7 +1121,11 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
// dirt
|
||||
let ground = Lerp::lerp(ground, sub_surface_color, marble_mid * tree_density);
|
||||
|
||||
let path = sim.get_nearest_path(wpos);
|
||||
let path = if spawn_rules.paths {
|
||||
sim.get_nearest_path(wpos)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let cave = sim.get_nearest_cave(wpos);
|
||||
|
||||
let ice_depth = if snow_factor < -0.25
|
||||
@ -1168,11 +1173,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
// No growing directly on bedrock.
|
||||
// And, no growing on sites that don't want them TODO: More precise than this when we
|
||||
// apply trees as a post-processing layer
|
||||
tree_density: if sim_chunk
|
||||
.sites
|
||||
.iter()
|
||||
.all(|site| index.sites[*site].spawn_rules(wpos).trees)
|
||||
{
|
||||
tree_density: if spawn_rules.trees {
|
||||
Lerp::lerp(0.0, tree_density, alt.sub(2.0).sub(basement).mul(0.5))
|
||||
} else {
|
||||
0.0
|
||||
|
@ -26,6 +26,18 @@ pub struct Colors {
|
||||
pub struct SpawnRules {
|
||||
pub trees: bool,
|
||||
pub max_warp: f32,
|
||||
pub paths: bool,
|
||||
}
|
||||
|
||||
impl SpawnRules {
|
||||
pub fn combine(self, other: Self) -> Self {
|
||||
// Should be commutative
|
||||
Self {
|
||||
trees: self.trees && other.trees,
|
||||
max_warp: self.max_warp.min(other.max_warp),
|
||||
paths: self.paths && other.paths,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SpawnRules {
|
||||
@ -33,6 +45,7 @@ impl Default for SpawnRules {
|
||||
Self {
|
||||
trees: true,
|
||||
max_warp: 1.0,
|
||||
paths: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,13 +60,26 @@ impl Site {
|
||||
}
|
||||
|
||||
pub fn spawn_rules(&self, wpos: Vec2<i32>) -> SpawnRules {
|
||||
let not_near_things = SQUARE_9.iter().all(|&rpos| {
|
||||
self.wpos_tile(wpos + rpos * tile::TILE_SIZE as i32)
|
||||
.is_empty()
|
||||
});
|
||||
let tile_pos = self.wpos_tile_pos(wpos);
|
||||
let max_warp = SQUARE_9
|
||||
.iter()
|
||||
.filter_map(|rpos| {
|
||||
let tile_pos = tile_pos + rpos;
|
||||
if self.tiles.get(tile_pos).is_natural() {
|
||||
None
|
||||
} else {
|
||||
let clamped =
|
||||
wpos.clamped(self.tile_wpos(tile_pos), self.tile_wpos(tile_pos + 1) - 1);
|
||||
Some(clamped.distance_squared(wpos) as f32)
|
||||
}
|
||||
})
|
||||
.min_by_key(|d2| *d2 as i32)
|
||||
.map(|d2| d2.sqrt() as f32 / TILE_SIZE as f32)
|
||||
.unwrap_or(1.0);
|
||||
SpawnRules {
|
||||
trees: not_near_things,
|
||||
max_warp: if not_near_things { 1.0 } else { 0.0 },
|
||||
trees: max_warp == 1.0,
|
||||
max_warp,
|
||||
paths: max_warp > std::f32::EPSILON,
|
||||
}
|
||||
}
|
||||
|
||||
@ -698,14 +711,10 @@ impl Site {
|
||||
let alt = canvas.col(wpos2d).map_or(0, |col| col.alt as i32);
|
||||
(-8..6).for_each(|z| {
|
||||
canvas.map(Vec3::new(wpos2d.x, wpos2d.y, alt + z), |b| {
|
||||
if z >= 0 {
|
||||
if b.is_filled() {
|
||||
Block::empty()
|
||||
} else {
|
||||
b.with_sprite(SpriteKind::Empty)
|
||||
}
|
||||
} else {
|
||||
if b.is_filled() {
|
||||
Block::new(BlockKind::Earth, Rgb::new(0x6A, 0x47, 0x24))
|
||||
} else {
|
||||
b.into_vacant()
|
||||
}
|
||||
})
|
||||
});
|
||||
@ -761,21 +770,19 @@ impl Site {
|
||||
|
||||
if min_dist.is_some() {
|
||||
let alt = /*avg_hard_alt.map(|(sum, weight)| sum / weight).unwrap_or_else(||*/ canvas.col(wpos2d).map_or(0.0, |col| col.alt)/*)*/ as i32;
|
||||
let mut underground = true;
|
||||
(-6..4).for_each(|z| canvas.map(
|
||||
Vec3::new(wpos2d.x, wpos2d.y, alt + z),
|
||||
|b| if z > 0 {
|
||||
let sprite = if z == 1 && self.tile_wpos(tpos) == wpos2d && (tpos + tpos.yx() / 2) % 2 == Vec2::zero() {
|
||||
|b| if b.is_filled() {
|
||||
Block::new(BlockKind::Earth, Rgb::new(0x6A, 0x47, 0x24))
|
||||
} else {
|
||||
let sprite = if underground && self.tile_wpos(tpos) == wpos2d && (tpos + tpos.yx() / 2) % 2 == Vec2::zero() {
|
||||
SpriteKind::StreetLamp
|
||||
} else {
|
||||
SpriteKind::Empty
|
||||
};
|
||||
if b.is_filled() {
|
||||
Block::air(sprite)
|
||||
} else {
|
||||
b.with_sprite(sprite)
|
||||
}
|
||||
} else {
|
||||
Block::new(BlockKind::Earth, Rgb::new(0x6A, 0x47, 0x24))
|
||||
underground = false;
|
||||
b.with_sprite(sprite)
|
||||
},
|
||||
));
|
||||
}
|
||||
|
@ -216,6 +216,8 @@ impl Tile {
|
||||
|
||||
pub fn is_empty(&self) -> bool { self.kind == TileKind::Empty }
|
||||
|
||||
pub fn is_natural(&self) -> bool { matches!(self.kind, TileKind::Empty | TileKind::Hazard(_)) }
|
||||
|
||||
pub fn is_road(&self) -> bool { matches!(self.kind, TileKind::Plaza | TileKind::Road { .. }) }
|
||||
|
||||
pub fn is_obstacle(&self) -> bool {
|
||||
|
Loading…
Reference in New Issue
Block a user