mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'aweinstock/lava' into 'master'
Lava See merge request veloren/veloren!2482
This commit is contained in:
commit
8356e2ffca
assets/world/style
common
world/src/layer
@ -64,6 +64,7 @@
|
|||||||
cave_roof: (38, 21, 79),
|
cave_roof: (38, 21, 79),
|
||||||
dirt: (69, 48, 15),
|
dirt: (69, 48, 15),
|
||||||
scaffold: (195, 190, 212),
|
scaffold: (195, 190, 212),
|
||||||
|
lava: (184, 39, 0),
|
||||||
vein: (222, 140, 39),
|
vein: (222, 140, 39),
|
||||||
),
|
),
|
||||||
site: (
|
site: (
|
||||||
|
@ -557,7 +557,7 @@ impl<const AVERAGE_PALETTE: bool> VoxelImageDecoding for TriPngEncoding<AVERAGE_
|
|||||||
} else {
|
} else {
|
||||||
use BlockKind::*;
|
use BlockKind::*;
|
||||||
match kind {
|
match kind {
|
||||||
Air | Water => Rgb { r: 0, g: 0, b: 0 },
|
Air | Water | Lava => Rgb { r: 0, g: 0, b: 0 },
|
||||||
Rock => Rgb {
|
Rock => Rgb {
|
||||||
r: 93,
|
r: 93,
|
||||||
g: 110,
|
g: 110,
|
||||||
|
@ -2,18 +2,45 @@
|
|||||||
use super::body::{object, Body};
|
use super::body::{object, Body};
|
||||||
use super::{Density, Ori, Vel};
|
use super::{Density, Ori, Vel};
|
||||||
use crate::{
|
use crate::{
|
||||||
consts::{AIR_DENSITY, WATER_DENSITY},
|
consts::{AIR_DENSITY, LAVA_DENSITY, WATER_DENSITY},
|
||||||
util::{Dir, Plane, Projection},
|
util::{Dir, Plane, Projection},
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum LiquidKind {
|
||||||
|
Water,
|
||||||
|
Lava,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LiquidKind {
|
||||||
|
/// If an entity is in multiple overlapping liquid blocks, which one takes
|
||||||
|
/// precedence? (should be a rare edge case, since checkerboard patterns of
|
||||||
|
/// water and lava shouldn't show up in worldgen)
|
||||||
|
pub fn merge(self, other: LiquidKind) -> LiquidKind {
|
||||||
|
use LiquidKind::{Lava, Water};
|
||||||
|
match (self, other) {
|
||||||
|
(Water, Water) => Water,
|
||||||
|
(Water, Lava) => Lava,
|
||||||
|
(Lava, _) => Lava,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Fluid medium in which the entity exists
|
/// Fluid medium in which the entity exists
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum Fluid {
|
pub enum Fluid {
|
||||||
Air { vel: Vel, elevation: f32 },
|
Air {
|
||||||
Water { vel: Vel, depth: f32 },
|
vel: Vel,
|
||||||
|
elevation: f32,
|
||||||
|
},
|
||||||
|
Liquid {
|
||||||
|
kind: LiquidKind,
|
||||||
|
vel: Vel,
|
||||||
|
depth: f32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fluid {
|
impl Fluid {
|
||||||
@ -21,7 +48,14 @@ impl Fluid {
|
|||||||
pub fn density(&self) -> Density {
|
pub fn density(&self) -> Density {
|
||||||
match self {
|
match self {
|
||||||
Self::Air { .. } => Density(AIR_DENSITY),
|
Self::Air { .. } => Density(AIR_DENSITY),
|
||||||
Self::Water { .. } => Density(WATER_DENSITY),
|
Self::Liquid {
|
||||||
|
kind: LiquidKind::Water,
|
||||||
|
..
|
||||||
|
} => Density(WATER_DENSITY),
|
||||||
|
Self::Liquid {
|
||||||
|
kind: LiquidKind::Lava,
|
||||||
|
..
|
||||||
|
} => Density(LAVA_DENSITY),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,14 +87,14 @@ impl Fluid {
|
|||||||
pub fn flow_vel(&self) -> Vel {
|
pub fn flow_vel(&self) -> Vel {
|
||||||
match self {
|
match self {
|
||||||
Self::Air { vel, .. } => *vel,
|
Self::Air { vel, .. } => *vel,
|
||||||
Self::Water { vel, .. } => *vel,
|
Self::Liquid { vel, .. } => *vel,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Very simple but useful in reducing mental overhead
|
// Very simple but useful in reducing mental overhead
|
||||||
pub fn relative_flow(&self, vel: &Vel) -> Vel { Vel(self.flow_vel().0 - vel.0) }
|
pub fn relative_flow(&self, vel: &Vel) -> Vel { Vel(self.flow_vel().0 - vel.0) }
|
||||||
|
|
||||||
pub fn is_liquid(&self) -> bool { matches!(self, Fluid::Water { .. }) }
|
pub fn is_liquid(&self) -> bool { matches!(self, Fluid::Liquid { .. }) }
|
||||||
|
|
||||||
pub fn elevation(&self) -> Option<f32> {
|
pub fn elevation(&self) -> Option<f32> {
|
||||||
match self {
|
match self {
|
||||||
@ -71,7 +105,7 @@ impl Fluid {
|
|||||||
|
|
||||||
pub fn depth(&self) -> Option<f32> {
|
pub fn depth(&self) -> Option<f32> {
|
||||||
match self {
|
match self {
|
||||||
Fluid::Water { depth, .. } => Some(*depth),
|
Fluid::Liquid { depth, .. } => Some(*depth),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,9 @@ pub const FRIC_GROUND: f32 = 0.15;
|
|||||||
// kg/m³
|
// kg/m³
|
||||||
pub const AIR_DENSITY: f32 = 1.225;
|
pub const AIR_DENSITY: f32 = 1.225;
|
||||||
pub const WATER_DENSITY: f32 = 999.1026;
|
pub const WATER_DENSITY: f32 = 999.1026;
|
||||||
|
// LAVA_DENSITY is unsourced, estimated as "roughly three times higher" than
|
||||||
|
// water
|
||||||
|
pub const LAVA_DENSITY: f32 = 3000.0;
|
||||||
pub const IRON_DENSITY: f32 = 7870.0;
|
pub const IRON_DENSITY: f32 = 7870.0;
|
||||||
// pub const HUMAN_DENSITY: f32 = 1010.0; // real value
|
// pub const HUMAN_DENSITY: f32 = 1010.0; // real value
|
||||||
pub const HUMAN_DENSITY: f32 = 990.0; // value we use to make humanoids gently float
|
pub const HUMAN_DENSITY: f32 = 990.0; // value we use to make humanoids gently float
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use super::SpriteKind;
|
use super::SpriteKind;
|
||||||
use crate::{comp::tool::ToolKind, make_case_elim};
|
use crate::{
|
||||||
|
comp::{fluid_dynamics::LiquidKind, tool::ToolKind},
|
||||||
|
make_case_elim,
|
||||||
|
};
|
||||||
use enum_iterator::IntoEnumIterator;
|
use enum_iterator::IntoEnumIterator;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
@ -33,6 +36,7 @@ make_case_elim!(
|
|||||||
// being *very* fast).
|
// being *very* fast).
|
||||||
Rock = 0x10,
|
Rock = 0x10,
|
||||||
WeakRock = 0x11, // Explodable
|
WeakRock = 0x11, // Explodable
|
||||||
|
Lava = 0x12,
|
||||||
// 0x12 <= x < 0x20 is reserved for future rocks
|
// 0x12 <= x < 0x20 is reserved for future rocks
|
||||||
Grass = 0x20, // Note: *not* the same as grass sprites
|
Grass = 0x20, // Note: *not* the same as grass sprites
|
||||||
Snow = 0x21,
|
Snow = 0x21,
|
||||||
@ -63,6 +67,15 @@ impl BlockKind {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub const fn is_liquid(&self) -> bool { self.is_fluid() && !self.is_air() }
|
pub const fn is_liquid(&self) -> bool { self.is_fluid() && !self.is_air() }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub const fn liquid_kind(&self) -> Option<LiquidKind> {
|
||||||
|
Some(match self {
|
||||||
|
BlockKind::Water => LiquidKind::Water,
|
||||||
|
BlockKind::Lava => LiquidKind::Lava,
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Determine whether the block is filled (i.e: fully solid). Right now,
|
/// Determine whether the block is filled (i.e: fully solid). Right now,
|
||||||
/// this is the opposite of being a fluid.
|
/// this is the opposite of being a fluid.
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -168,6 +181,9 @@ impl Block {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_glow(&self) -> Option<u8> {
|
pub fn get_glow(&self) -> Option<u8> {
|
||||||
|
if matches!(self.kind, BlockKind::Lava) {
|
||||||
|
return Some(24);
|
||||||
|
}
|
||||||
match self.get_sprite()? {
|
match self.get_sprite()? {
|
||||||
SpriteKind::StreetLamp | SpriteKind::StreetLampTall => Some(24),
|
SpriteKind::StreetLamp | SpriteKind::StreetLampTall => Some(24),
|
||||||
SpriteKind::Ember => Some(20),
|
SpriteKind::Ember => Some(20),
|
||||||
@ -217,7 +233,7 @@ impl Block {
|
|||||||
pub fn is_solid(&self) -> bool {
|
pub fn is_solid(&self) -> bool {
|
||||||
self.get_sprite()
|
self.get_sprite()
|
||||||
.map(|s| s.solid_height().is_some())
|
.map(|s| s.solid_height().is_some())
|
||||||
.unwrap_or(true)
|
.unwrap_or(!matches!(self.kind, BlockKind::Lava))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Can this block be exploded? If so, what 'power' is required to do so?
|
/// Can this block be exploded? If so, what 'power' is required to do so?
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
fluid_dynamics::Fluid, Buff, BuffCategory, BuffChange, BuffEffect, BuffId, BuffKind,
|
fluid_dynamics::{Fluid, LiquidKind},
|
||||||
BuffSource, Buffs, Energy, Health, HealthChange, HealthSource, Inventory, ModifierKind,
|
Buff, BuffCategory, BuffChange, BuffData, BuffEffect, BuffId, BuffKind, BuffSource, Buffs,
|
||||||
PhysicsState, Stats,
|
Energy, Health, HealthChange, HealthSource, Inventory, ModifierKind, PhysicsState, Stats,
|
||||||
},
|
},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
resources::DeltaTime,
|
resources::DeltaTime,
|
||||||
@ -45,34 +45,47 @@ impl<'a> System<'a> for Sys {
|
|||||||
// Set to false to avoid spamming server
|
// Set to false to avoid spamming server
|
||||||
buffs.set_event_emission(false);
|
buffs.set_event_emission(false);
|
||||||
stats.set_event_emission(false);
|
stats.set_event_emission(false);
|
||||||
for (entity, mut buff_comp, energy, mut stat, health) in (
|
for (entity, mut buff_comp, energy, mut stat, health, physics_state) in (
|
||||||
&read_data.entities,
|
&read_data.entities,
|
||||||
&mut buffs,
|
&mut buffs,
|
||||||
&read_data.energies,
|
&read_data.energies,
|
||||||
&mut stats,
|
&mut stats,
|
||||||
&read_data.healths,
|
&read_data.healths,
|
||||||
|
read_data.physics_states.maybe(),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
{
|
{
|
||||||
|
let in_fluid = physics_state.and_then(|p| p.in_fluid);
|
||||||
|
|
||||||
|
if matches!(
|
||||||
|
in_fluid,
|
||||||
|
Some(Fluid::Liquid {
|
||||||
|
kind: LiquidKind::Lava,
|
||||||
|
..
|
||||||
|
})
|
||||||
|
) && !buff_comp.contains(BuffKind::Burning)
|
||||||
|
{
|
||||||
|
server_emitter.emit(ServerEvent::Buff {
|
||||||
|
entity,
|
||||||
|
buff_change: BuffChange::Add(Buff::new(
|
||||||
|
BuffKind::Burning,
|
||||||
|
BuffData::new(200.0, None),
|
||||||
|
vec![BuffCategory::Natural],
|
||||||
|
BuffSource::World,
|
||||||
|
)),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let (buff_comp_kinds, buff_comp_buffs): (
|
let (buff_comp_kinds, buff_comp_buffs): (
|
||||||
&HashMap<BuffKind, Vec<BuffId>>,
|
&HashMap<BuffKind, Vec<BuffId>>,
|
||||||
&mut HashMap<BuffId, Buff>,
|
&mut HashMap<BuffId, Buff>,
|
||||||
) = buff_comp.parts();
|
) = buff_comp.parts();
|
||||||
let mut expired_buffs = Vec::<BuffId>::new();
|
let mut expired_buffs = Vec::<BuffId>::new();
|
||||||
|
|
||||||
// For each buff kind present on entity, if the buff kind queues, only ticks
|
// For each buff kind present on entity, if the buff kind queues, only ticks
|
||||||
// duration of strongest buff of that kind, else it ticks durations of all buffs
|
// duration of strongest buff of that kind, else it ticks durations of all buffs
|
||||||
// of that kind. Any buffs whose durations expire are marked expired.
|
// of that kind. Any buffs whose durations expire are marked expired.
|
||||||
for (kind, ids) in buff_comp_kinds.iter() {
|
for (kind, ids) in buff_comp_kinds.iter() {
|
||||||
// Only get the physics state component if the entity has the burning buff, as
|
|
||||||
// we don't need it for any other conditions yet
|
|
||||||
let in_fluid = if matches!(kind, BuffKind::Burning) {
|
|
||||||
read_data
|
|
||||||
.physics_states
|
|
||||||
.get(entity)
|
|
||||||
.and_then(|p| p.in_fluid)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
if kind.queues() {
|
if kind.queues() {
|
||||||
if let Some((Some(buff), id)) =
|
if let Some((Some(buff), id)) =
|
||||||
ids.get(0).map(|id| (buff_comp_buffs.get_mut(id), id))
|
ids.get(0).map(|id| (buff_comp_buffs.get_mut(id), id))
|
||||||
@ -257,7 +270,15 @@ fn tick_buff(
|
|||||||
}
|
}
|
||||||
if let Some(remaining_time) = &mut buff.time {
|
if let Some(remaining_time) = &mut buff.time {
|
||||||
// Extinguish Burning buff when in water
|
// Extinguish Burning buff when in water
|
||||||
if matches!(buff.kind, BuffKind::Burning) && matches!(in_fluid, Some(Fluid::Water { .. })) {
|
if matches!(buff.kind, BuffKind::Burning)
|
||||||
|
&& matches!(
|
||||||
|
in_fluid,
|
||||||
|
Some(Fluid::Liquid {
|
||||||
|
kind: LiquidKind::Water,
|
||||||
|
..
|
||||||
|
})
|
||||||
|
)
|
||||||
|
{
|
||||||
*remaining_time = Duration::default();
|
*remaining_time = Duration::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
body::ship::figuredata::{VoxelCollider, VOXEL_COLLIDER_MANIFEST},
|
body::ship::figuredata::{VoxelCollider, VOXEL_COLLIDER_MANIFEST},
|
||||||
fluid_dynamics::{Fluid, Wings},
|
fluid_dynamics::{Fluid, LiquidKind, Wings},
|
||||||
BeamSegment, Body, CharacterState, Collider, Density, Mass, Mounting, Ori, PhysicsState,
|
BeamSegment, Body, CharacterState, Collider, Density, Mass, Mounting, Ori, PhysicsState,
|
||||||
Pos, PosVelDefer, PreviousPhysCache, Projectile, Scale, Shockwave, Stats, Sticky, Vel,
|
Pos, PosVelDefer, PreviousPhysCache, Projectile, Scale, Shockwave, Stats, Sticky, Vel,
|
||||||
},
|
},
|
||||||
@ -905,13 +905,15 @@ impl<'a> PhysicsData<'a> {
|
|||||||
.terrain
|
.terrain
|
||||||
.get(pos.0.map(|e| e.floor() as i32))
|
.get(pos.0.map(|e| e.floor() as i32))
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|vox| vox.is_liquid().then_some(1.0))
|
.and_then(|vox| {
|
||||||
.map(|depth| Fluid::Water {
|
vox.liquid_kind().map(|kind| Fluid::Liquid {
|
||||||
depth,
|
kind,
|
||||||
vel: Vel::zero(),
|
depth: 1.0,
|
||||||
|
vel: Vel::zero(),
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.or_else(|| match physics_state.in_fluid {
|
.or_else(|| match physics_state.in_fluid {
|
||||||
Some(Fluid::Water { .. }) | None => Some(Fluid::Air {
|
Some(Fluid::Liquid { .. }) | None => Some(Fluid::Air {
|
||||||
elevation: pos.0.z,
|
elevation: pos.0.z,
|
||||||
vel: Vel::default(),
|
vel: Vel::default(),
|
||||||
}),
|
}),
|
||||||
@ -1541,24 +1543,27 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Find liquid immersion and wall collision all in one round of iteration
|
// Find liquid immersion and wall collision all in one round of iteration
|
||||||
let mut max_liquid_z = None::<f32>;
|
let mut liquid = None::<(LiquidKind, f32)>;
|
||||||
let mut wall_dir_collisions = [false; 4];
|
let mut wall_dir_collisions = [false; 4];
|
||||||
near_iter.for_each(|(i, j, k)| {
|
near_iter.for_each(|(i, j, k)| {
|
||||||
let block_pos = player_voxel_pos + Vec3::new(i, j, k);
|
let block_pos = player_voxel_pos + Vec3::new(i, j, k);
|
||||||
|
|
||||||
if let Some(block) = terrain.get(block_pos).ok().copied() {
|
if let Some(block) = terrain.get(block_pos).ok().copied() {
|
||||||
// Check for liquid blocks
|
// Check for liquid blocks
|
||||||
if block.is_liquid() {
|
if let Some(block_liquid) = block.liquid_kind() {
|
||||||
let liquid_aabb = Aabb {
|
let liquid_aabb = Aabb {
|
||||||
min: block_pos.map(|e| e as f32),
|
min: block_pos.map(|e| e as f32),
|
||||||
// The liquid part of a liquid block always extends 1 block high.
|
// The liquid part of a liquid block always extends 1 block high.
|
||||||
max: block_pos.map(|e| e as f32) + Vec3::one(),
|
max: block_pos.map(|e| e as f32) + Vec3::one(),
|
||||||
};
|
};
|
||||||
if player_aabb.collides_with_aabb(liquid_aabb) {
|
if player_aabb.collides_with_aabb(liquid_aabb) {
|
||||||
max_liquid_z = Some(match max_liquid_z {
|
liquid = match liquid {
|
||||||
Some(z) => z.max(liquid_aabb.max.z),
|
Some((kind, max_liquid_z)) => Some((
|
||||||
None => liquid_aabb.max.z,
|
kind.merge(block_liquid),
|
||||||
});
|
max_liquid_z.max(liquid_aabb.max.z),
|
||||||
|
)),
|
||||||
|
None => Some((block_liquid, liquid_aabb.max.z)),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check for walls
|
// Check for walls
|
||||||
@ -1594,23 +1599,24 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
physics_state.ground_vel = ground_vel;
|
physics_state.ground_vel = ground_vel;
|
||||||
}
|
}
|
||||||
|
|
||||||
physics_state.in_fluid = max_liquid_z
|
physics_state.in_fluid = liquid
|
||||||
.map(|max_z| max_z - pos.0.z) // NOTE: assumes min_z == 0.0
|
.map(|(kind, max_z)| (kind, max_z - pos.0.z)) // NOTE: assumes min_z == 0.0
|
||||||
.map(|depth| {
|
.map(|(kind, depth)| {
|
||||||
physics_state
|
(kind, physics_state
|
||||||
.in_liquid()
|
.in_liquid()
|
||||||
// This is suboptimal because it doesn't check for true depth,
|
// This is suboptimal because it doesn't check for true depth,
|
||||||
// so it can cause problems for situations like swimming down
|
// so it can cause problems for situations like swimming down
|
||||||
// a river and spawning or teleporting in(/to) water
|
// a river and spawning or teleporting in(/to) water
|
||||||
.map(|old_depth| (old_depth + old_pos.z - pos.0.z).max(depth))
|
.map(|old_depth| (old_depth + old_pos.z - pos.0.z).max(depth))
|
||||||
.unwrap_or(depth)
|
.unwrap_or(depth))
|
||||||
})
|
})
|
||||||
.map(|depth| Fluid::Water {
|
.map(|(kind, depth)| Fluid::Liquid {
|
||||||
|
kind,
|
||||||
depth,
|
depth,
|
||||||
vel: Vel::zero(),
|
vel: Vel::zero(),
|
||||||
})
|
})
|
||||||
.or_else(|| match physics_state.in_fluid {
|
.or_else(|| match physics_state.in_fluid {
|
||||||
Some(Fluid::Water { .. }) | None => Some(Fluid::Air {
|
Some(Fluid::Liquid { .. }) | None => Some(Fluid::Air {
|
||||||
elevation: pos.0.z,
|
elevation: pos.0.z,
|
||||||
vel: Vel::default(),
|
vel: Vel::default(),
|
||||||
}),
|
}),
|
||||||
|
@ -34,6 +34,7 @@ pub struct Colors {
|
|||||||
pub cave_roof: (u8, u8, u8),
|
pub cave_roof: (u8, u8, u8),
|
||||||
pub dirt: (u8, u8, u8),
|
pub dirt: (u8, u8, u8),
|
||||||
pub scaffold: (u8, u8, u8),
|
pub scaffold: (u8, u8, u8),
|
||||||
|
pub lava: (u8, u8, u8),
|
||||||
pub vein: (u8, u8, u8),
|
pub vein: (u8, u8, u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,12 +211,14 @@ pub fn apply_caves_to(canvas: &mut Canvas, rng: &mut impl Rng) {
|
|||||||
//make pits
|
//make pits
|
||||||
for z in cave_base - pit_depth..cave_base {
|
for z in cave_base - pit_depth..cave_base {
|
||||||
if pit_condition && (cave_roof - cave_base) > 10 {
|
if pit_condition && (cave_roof - cave_base) > 10 {
|
||||||
|
let kind = if z < (cave_base - pit_depth) + (3 * pit_depth / 4) {
|
||||||
|
BlockKind::Lava
|
||||||
|
} else {
|
||||||
|
BlockKind::Air
|
||||||
|
};
|
||||||
canvas.set(
|
canvas.set(
|
||||||
Vec3::new(wpos2d.x, wpos2d.y, z),
|
Vec3::new(wpos2d.x, wpos2d.y, z),
|
||||||
Block::new(
|
Block::new(kind, noisy_color(info.index().colors.layer.lava.into(), 8)),
|
||||||
BlockKind::Air,
|
|
||||||
noisy_color(info.index().colors.layer.scaffold.into(), 8),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user