feat(chunk-gen): add lake feature
This commit is contained in:
parent
f5397dd85a
commit
ed12db09ce
@ -613,7 +613,14 @@ pub fn value_to_configured_feature(v: &Value) -> TokenStream {
|
|||||||
quote! { ConfiguredFeature::Fossil(crate::generation::feature::features::fossil::FossilFeature {}) }
|
quote! { ConfiguredFeature::Fossil(crate::generation::feature::features::fossil::FossilFeature {}) }
|
||||||
}
|
}
|
||||||
"minecraft:lake" => {
|
"minecraft:lake" => {
|
||||||
quote! { ConfiguredFeature::Lake(crate::generation::feature::features::lake::LakeFeature {}) }
|
let fluid = value_to_block_state_provider(&config["fluid"]);
|
||||||
|
let barrier = value_to_block_state_provider(&config["barrier"]);
|
||||||
|
quote! {
|
||||||
|
ConfiguredFeature::Lake(crate::generation::feature::features::lake::LakeFeature {
|
||||||
|
fluid: #fluid,
|
||||||
|
barrier: #barrier,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"minecraft:huge_brown_mushroom" => {
|
"minecraft:huge_brown_mushroom" => {
|
||||||
quote! { ConfiguredFeature::HugeBrownMushroom(crate::generation::feature::features::huge_brown_mushroom::HugeBrownMushroomFeature {}) }
|
quote! { ConfiguredFeature::HugeBrownMushroom(crate::generation::feature::features::huge_brown_mushroom::HugeBrownMushroomFeature {}) }
|
||||||
|
|||||||
@ -2305,7 +2305,22 @@ fn build_configured_features() -> std::collections::HashMap<String, ConfiguredFe
|
|||||||
);
|
);
|
||||||
map.insert(
|
map.insert(
|
||||||
"lake_lava".to_string(),
|
"lake_lava".to_string(),
|
||||||
ConfiguredFeature::Lake(crate::generation::feature::features::lake::LakeFeature {}),
|
ConfiguredFeature::Lake(crate::generation::feature::features::lake::LakeFeature {
|
||||||
|
fluid: BlockStateProvider::Simple(SimpleStateProvider {
|
||||||
|
state: {
|
||||||
|
let mut props = std::collections::HashMap::new();
|
||||||
|
props.insert("level".to_string(), "0".to_string());
|
||||||
|
BlockStateCodec {
|
||||||
|
name: &pumpkin_data::Block::LAVA,
|
||||||
|
properties: Some(props),
|
||||||
|
}
|
||||||
|
.get_state()
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
barrier: BlockStateProvider::Simple(SimpleStateProvider {
|
||||||
|
state: pumpkin_data::Block::STONE.default_state,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
map.insert(
|
map.insert(
|
||||||
"large_basalt_columns".to_string(),
|
"large_basalt_columns".to_string(),
|
||||||
|
|||||||
@ -359,6 +359,7 @@ impl ConfiguredFeature {
|
|||||||
random,
|
random,
|
||||||
pos,
|
pos,
|
||||||
),
|
),
|
||||||
|
Self::Lake(feature) => feature.generate(block_registry, chunk, random, pos),
|
||||||
Self::BasaltColumns(feature) => feature.generate(
|
Self::BasaltColumns(feature) => feature.generate(
|
||||||
chunk,
|
chunk,
|
||||||
block_registry,
|
block_registry,
|
||||||
|
|||||||
@ -1,3 +1,174 @@
|
|||||||
|
use pumpkin_data::{Block, BlockState, tag};
|
||||||
|
use pumpkin_util::{
|
||||||
|
math::position::BlockPos,
|
||||||
|
random::{RandomGenerator, RandomImpl},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::generation::{block_state_provider::BlockStateProvider, proto_chunk::GenerationCache};
|
||||||
|
use crate::world::BlockRegistryExt;
|
||||||
|
|
||||||
pub struct LakeFeature {
|
pub struct LakeFeature {
|
||||||
// TODO
|
pub fluid: BlockStateProvider,
|
||||||
|
pub barrier: BlockStateProvider,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LakeFeature {
|
||||||
|
pub fn generate<T: GenerationCache>(
|
||||||
|
&self,
|
||||||
|
block_registry: &dyn BlockRegistryExt,
|
||||||
|
chunk: &mut T,
|
||||||
|
random: &mut RandomGenerator,
|
||||||
|
pos: BlockPos,
|
||||||
|
) -> bool {
|
||||||
|
if pos.0.y <= chunk.bottom_y() as i32 + 4 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let origin = pos.add(-8, -4, -8);
|
||||||
|
let mut grid = [false; 2048];
|
||||||
|
let spots = random.next_bounded_i32(4) + 4;
|
||||||
|
|
||||||
|
for _ in 0..spots {
|
||||||
|
let xr = random.next_f64() * 6.0 + 3.0;
|
||||||
|
let yr = random.next_f64() * 4.0 + 2.0;
|
||||||
|
let zr = random.next_f64() * 6.0 + 3.0;
|
||||||
|
let xp = random.next_f64() * (16.0 - xr - 2.0) + 1.0 + xr / 2.0;
|
||||||
|
let yp = random.next_f64() * (8.0 - yr - 4.0) + 2.0 + yr / 2.0;
|
||||||
|
let zp = random.next_f64() * (16.0 - zr - 2.0) + 1.0 + zr / 2.0;
|
||||||
|
|
||||||
|
for xx in 1..15 {
|
||||||
|
for zz in 1..15 {
|
||||||
|
for yy in 1..7 {
|
||||||
|
let xd = (xx as f64 - xp) / (xr / 2.0);
|
||||||
|
let yd = (yy as f64 - yp) / (yr / 2.0);
|
||||||
|
let zd = (zz as f64 - zp) / (zr / 2.0);
|
||||||
|
let d = xd * xd + yd * yd + zd * zd;
|
||||||
|
if d < 1.0 {
|
||||||
|
grid[(xx * 16 + zz) * 8 + yy] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let fluid_state = self
|
||||||
|
.fluid
|
||||||
|
.get_with_context(block_registry, chunk, random, origin);
|
||||||
|
|
||||||
|
for xx in 0..16 {
|
||||||
|
for zz in 0..16 {
|
||||||
|
for yyx in 0..8 {
|
||||||
|
let check = !grid[(xx * 16 + zz) * 8 + yyx]
|
||||||
|
&& (xx < 15 && grid[((xx + 1) * 16 + zz) * 8 + yyx]
|
||||||
|
|| xx > 0 && grid[((xx - 1) * 16 + zz) * 8 + yyx]
|
||||||
|
|| zz < 15 && grid[(xx * 16 + zz + 1) * 8 + yyx]
|
||||||
|
|| zz > 0 && grid[(xx * 16 + (zz - 1)) * 8 + yyx]
|
||||||
|
|| yyx < 7 && grid[(xx * 16 + zz) * 8 + yyx + 1]
|
||||||
|
|| yyx > 0 && grid[(xx * 16 + zz) * 8 + (yyx - 1)]);
|
||||||
|
|
||||||
|
if check {
|
||||||
|
let check_pos = origin.add(xx as i32, yyx as i32, zz as i32);
|
||||||
|
let block_state =
|
||||||
|
GenerationCache::get_block_state(chunk, &check_pos.0).to_state();
|
||||||
|
|
||||||
|
if yyx >= 4 && block_state.is_liquid() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if yyx < 4 && !block_state.is_solid() && block_state != fluid_state {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let air_state = Block::CAVE_AIR.default_state;
|
||||||
|
|
||||||
|
for xx in 0..16 {
|
||||||
|
for zz in 0..16 {
|
||||||
|
for yyx in 0..8 {
|
||||||
|
if grid[(xx * 16 + zz) * 8 + yyx] {
|
||||||
|
let place_pos = origin.add(xx as i32, yyx as i32, zz as i32);
|
||||||
|
let current_state =
|
||||||
|
GenerationCache::get_block_state(chunk, &place_pos.0).to_state();
|
||||||
|
if self.can_replace_block(current_state) {
|
||||||
|
let place_air = yyx >= 4;
|
||||||
|
chunk.set_block_state(
|
||||||
|
&place_pos.0,
|
||||||
|
if place_air { air_state } else { fluid_state },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let barrier_state = self
|
||||||
|
.barrier
|
||||||
|
.get_with_context(block_registry, chunk, random, origin);
|
||||||
|
if !barrier_state.is_air() {
|
||||||
|
for xx in 0..16 {
|
||||||
|
for zz in 0..16 {
|
||||||
|
for yyx in 0..8 {
|
||||||
|
let check = !grid[(xx * 16 + zz) * 8 + yyx]
|
||||||
|
&& (xx < 15 && grid[((xx + 1) * 16 + zz) * 8 + yyx]
|
||||||
|
|| xx > 0 && grid[((xx - 1) * 16 + zz) * 8 + yyx]
|
||||||
|
|| zz < 15 && grid[(xx * 16 + zz + 1) * 8 + yyx]
|
||||||
|
|| zz > 0 && grid[(xx * 16 + (zz - 1)) * 8 + yyx]
|
||||||
|
|| yyx < 7 && grid[(xx * 16 + zz) * 8 + yyx + 1]
|
||||||
|
|| yyx > 0 && grid[(xx * 16 + zz) * 8 + (yyx - 1)]);
|
||||||
|
|
||||||
|
if check && (yyx < 4 || random.next_bounded_i32(2) != 0) {
|
||||||
|
let barrier_pos = origin.add(xx as i32, yyx as i32, zz as i32);
|
||||||
|
let block_state =
|
||||||
|
GenerationCache::get_block_state(chunk, &barrier_pos.0).to_state();
|
||||||
|
if block_state.is_solid()
|
||||||
|
&& !tag::Block::MINECRAFT_LAVA_POOL_STONE_CANNOT_REPLACE
|
||||||
|
.1
|
||||||
|
.contains(&block_state.id)
|
||||||
|
{
|
||||||
|
chunk.set_block_state(&barrier_pos.0, barrier_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Freeze top layer
|
||||||
|
if Block::from_state_id(fluid_state.id).id == Block::WATER.id {
|
||||||
|
for xx in 0..16 {
|
||||||
|
for zz in 0..16 {
|
||||||
|
let freeze_pos = origin.add(xx as i32, 4, zz as i32);
|
||||||
|
let biome = chunk.get_biome_for_terrain_gen(
|
||||||
|
freeze_pos.0.x,
|
||||||
|
freeze_pos.0.y,
|
||||||
|
freeze_pos.0.z,
|
||||||
|
);
|
||||||
|
if biome.weather.compute_temperature(
|
||||||
|
freeze_pos.0.x as f64,
|
||||||
|
freeze_pos.0.y,
|
||||||
|
freeze_pos.0.z as f64,
|
||||||
|
63,
|
||||||
|
) < 0.15
|
||||||
|
{
|
||||||
|
let current_state =
|
||||||
|
GenerationCache::get_block_state(chunk, &freeze_pos.0).to_state();
|
||||||
|
if self.can_replace_block(current_state) {
|
||||||
|
chunk.set_block_state(&freeze_pos.0, Block::ICE.default_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn can_replace_block(&self, state: &BlockState) -> bool {
|
||||||
|
!tag::Block::MINECRAFT_FEATURES_CANNOT_REPLACE
|
||||||
|
.1
|
||||||
|
.contains(&state.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user