Slippery ice

This commit is contained in:
Joshua Barretto 2021-12-09 14:53:33 +00:00
parent d6d55764c4
commit 6e97e3179d
10 changed files with 60 additions and 15 deletions

View File

@ -621,6 +621,11 @@ impl<const AVERAGE_PALETTE: bool> VoxelImageDecoding for TriPngEncoding<AVERAGE_
g: 255,
b: 255,
},
Ice => Rgb {
r: 150,
g: 190,
b: 255,
},
Earth => Rgb {
r: 200,
g: 140,

View File

@ -305,8 +305,9 @@ pub fn handle_move(data: &JoinData<'_>, update: &mut StateUpdate, efficiency: f3
fn basic_move(data: &JoinData<'_>, update: &mut StateUpdate, efficiency: f32) {
let efficiency = efficiency * data.stats.move_speed_modifier * data.stats.friction_modifier;
let accel = if data.physics.on_ground.is_some() {
data.body.base_accel()
let accel = if let Some(block) = data.physics.on_ground {
// FRIC_GROUND temporarily used to normalize things around expected values
data.body.base_accel() * block.get_friction() / FRIC_GROUND
} else {
data.body.air_accel()
} * efficiency;
@ -351,7 +352,10 @@ pub fn handle_forced_movement(
match movement {
ForcedMovement::Forward { strength } => {
let strength = strength * data.stats.move_speed_modifier * data.stats.friction_modifier;
if let Some(accel) = data.physics.on_ground.map(|_| data.body.base_accel()) {
if let Some(accel) = data.physics.on_ground.map(|block| {
// FRIC_GROUND temporarily used to normalize things around expected values
data.body.base_accel() * block.get_friction() / FRIC_GROUND
}) {
update.vel.0 += Vec2::broadcast(data.dt.0)
* accel
* (data.inputs.move_dir + Vec2::from(update.ori))

View File

@ -1,6 +1,7 @@
use super::SpriteKind;
use crate::{
comp::{fluid_dynamics::LiquidKind, tool::ToolKind},
consts::FRIC_GROUND,
make_case_elim,
};
use num_derive::FromPrimitive;
@ -49,6 +50,7 @@ make_case_elim!(
Wood = 0x40,
Leaves = 0x41,
GlowingMushroom = 0x42,
Ice = 0x43,
// 0x43 <= x < 0x50 is reserved for future tree parts
// Covers all other cases (we sometimes have bizarrely coloured misc blocks, and also we
// often want to experiment with new kinds of block without allocating them a
@ -226,6 +228,7 @@ impl Block {
BlockKind::Leaves => (9, 255),
BlockKind::Wood => (6, 2),
BlockKind::Snow => (6, 2),
BlockKind::Ice => (4, 2),
_ if self.is_opaque() => (0, 255),
_ => (0, 0),
}
@ -251,6 +254,7 @@ impl Block {
BlockKind::Grass => Some(0.5),
BlockKind::WeakRock => Some(0.75),
BlockKind::Snow => Some(0.1),
BlockKind::Ice => Some(0.5),
BlockKind::Lava => None,
_ => self.get_sprite().and_then(|sprite| match sprite {
sprite if sprite.is_container() => None,
@ -291,7 +295,9 @@ impl Block {
#[inline]
pub fn mine_tool(&self) -> Option<ToolKind> {
match self.kind() {
BlockKind::WeakRock | BlockKind::GlowingWeakRock => Some(ToolKind::Pick),
BlockKind::WeakRock | BlockKind::Ice | BlockKind::GlowingWeakRock => {
Some(ToolKind::Pick)
},
_ => self.get_sprite().and_then(|s| s.mine_tool()),
}
}
@ -306,6 +312,15 @@ impl Block {
.unwrap_or(1.0)
}
// Used to calculate surface friction when walking. Currently has no units.
#[inline]
pub fn get_friction(&self) -> f32 {
match self.kind() {
BlockKind::Ice => FRIC_GROUND * 0.1,
_ => FRIC_GROUND,
}
}
#[inline]
pub fn kind(&self) -> BlockKind { self.kind }

View File

@ -588,7 +588,7 @@ impl<'a> MapConfig<'a> {
let b_water = 64.0 * water_color_factor;
if has_river {
// Rudimentary ice check
if !rgb.map(|e| e > 0.6).reduce_and() {
if !rgb.map(|e| e > 0.35).reduce_and() {
let water_rgb = Rgb::new(0, ((g_water) * 1.0) as u8, ((b_water) * 1.0) as u8)
.map(|e| e as f64 / 255.0);
rgb = water_rgb;

View File

@ -1692,8 +1692,18 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
physics_state.on_wall = on_wall;
let fric_mod = read.stats.get(entity).map_or(1.0, |s| s.friction_modifier);
if physics_state.on_ground.is_some() || (physics_state.on_wall.is_some() && climbing) {
vel.0 *= (1.0 - FRIC_GROUND.min(1.0) * fric_mod).powf(dt.0 * 60.0);
let ground_fric = physics_state
.on_ground
.map(|b| b.get_friction())
.unwrap_or(0.0);
let wall_fric = if physics_state.on_wall.is_some() && climbing {
FRIC_GROUND
} else {
0.0
};
let fric = ground_fric.max(wall_fric);
if fric > 0.0 {
vel.0 *= (1.0 - fric.min(1.0) * fric_mod).powf(dt.0 * 60.0);
physics_state.ground_vel = ground_vel;
}

View File

@ -206,7 +206,9 @@ impl MovementEventMapper {
} else {
match underfoot_block_kind {
BlockKind::Snow => SfxEvent::Run(BlockKind::Snow),
BlockKind::Rock | BlockKind::WeakRock => SfxEvent::Run(BlockKind::Rock),
BlockKind::Rock | BlockKind::WeakRock | BlockKind::Ice => {
SfxEvent::Run(BlockKind::Rock)
},
BlockKind::Sand => SfxEvent::Run(BlockKind::Sand),
BlockKind::Air => SfxEvent::Idle,
_ => SfxEvent::Run(BlockKind::Grass),

View File

@ -210,8 +210,7 @@ impl<'a> BlockGen<'a> {
let over_water = height < water_height;
// Water
if over_water && (wposf.z as f32 - water_height).abs() < ice_depth {
// TODO: Ice block
Some(Block::new(BlockKind::WeakRock, CONFIG.ice_color))
Some(Block::new(BlockKind::Ice, CONFIG.ice_color))
} else if (wposf.z as f32) < water_height {
// Ocean
Some(water)

View File

@ -91,7 +91,13 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
wpos,
|chunk| if chunk.river.near_water() { 1.0 } else { 0.0 },
)?;
let water_vel = sim.get_interpolated(wpos, |chunk| chunk.river.velocity)?;
let water_vel = sim.get_interpolated(wpos, |chunk| {
if chunk.river.river_kind.is_some() {
chunk.river.velocity
} else {
Vec3::zero()
}
})?;
let alt = sim.get_interpolated_monotone(wpos, |chunk| chunk.alt)?;
let surface_veg = sim.get_interpolated_monotone(wpos, |chunk| chunk.surface_veg)?;
let sim_chunk = sim.get(chunk_pos)?;

View File

@ -74,7 +74,7 @@ pub const CONFIG: Config = Config {
river_max_width: 2.0,
river_min_height: 0.25,
river_width_to_depth: 8.0,
ice_color: Rgb::new(175, 200, 255),
ice_color: Rgb::new(140, 175, 255),
};
#[derive(Deserialize)]

View File

@ -26,7 +26,7 @@ impl Tree {
alt: land.get_alt_approx(origin) as i32,
seed: rng.gen(),
tree: {
let config = TreeConfig::giant(rng, 4.0, false);
let config = TreeConfig::giant(rng, 4.0, true);
ProceduralTree::generate(config, rng)
},
}
@ -60,7 +60,7 @@ impl Tree {
let wpos = wpos2d.with_z(self.alt + z);
let rposf = (wpos - self.origin.with_z(self.alt)).map(|e| e as f32 + 0.5);
let (branch, leaves, _, _) = self.tree.is_branch_or_leaves_at(rposf);
let (branch, leaves, platform, air) = self.tree.is_branch_or_leaves_at(rposf);
if (branch || leaves) && above && col.snow_cover {
canvas.set(
@ -69,7 +69,9 @@ impl Tree {
);
}
let block = if leaves {
let block = if air {
Some(Block::empty())
} else if leaves {
if above && dynamic_rng.gen_bool(0.0005) {
canvas.spawn(
EntityInfo::at(wpos.map(|e| e as f32) + Vec3::unit_z())
@ -96,6 +98,8 @@ impl Tree {
Some(Block::new(BlockKind::Leaves, leaf_col.map(|e| e as u8)))
} else if branch {
Some(Block::new(BlockKind::Wood, Rgb::new(80, 32, 0)))
} else if platform {
Some(Block::new(BlockKind::Wood, Rgb::new(180, 130, 50)))
} else {
None
};