feat(chunk-gen): add mob spawn step
This commit is contained in:
parent
bec18d2443
commit
c23c7c429d
25
Cargo.lock
generated
25
Cargo.lock
generated
@ -348,9 +348,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.61"
|
version = "1.2.62"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d"
|
checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"find-msvc-tools",
|
"find-msvc-tools",
|
||||||
"jobserver",
|
"jobserver",
|
||||||
@ -1534,9 +1534,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.17.0"
|
version = "0.17.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
|
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"foldhash 0.2.0",
|
"foldhash 0.2.0",
|
||||||
"serde",
|
"serde",
|
||||||
@ -1867,7 +1867,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
|
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown 0.17.0",
|
"hashbrown 0.17.1",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
@ -2407,7 +2407,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b"
|
checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"hashbrown 0.17.0",
|
"hashbrown 0.17.1",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
@ -3028,6 +3028,7 @@ dependencies = [
|
|||||||
name = "pumpkin-world"
|
name = "pumpkin-world"
|
||||||
version = "0.1.0-dev+26.1"
|
version = "0.1.0-dev+26.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"arc-swap",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"bytes",
|
"bytes",
|
||||||
"criterion",
|
"criterion",
|
||||||
@ -3186,7 +3187,7 @@ checksum = "de2c52737737f8609e94f975dee22854a2d5c125772d4b1cf292120f4d45c186"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"allocator-api2",
|
"allocator-api2",
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"hashbrown 0.17.0",
|
"hashbrown 0.17.1",
|
||||||
"log",
|
"log",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
@ -3904,9 +3905,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.52.2"
|
version = "1.52.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "110a78583f19d5cdb2c5ccf321d1290344e71313c6c37d43520d386027d18386"
|
checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
@ -4516,7 +4517,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "8e6fb4c2bee46c5ea4d40f8cdb5c131725cd976718ec56f1c8e82fbde5fa2a80"
|
checksum = "8e6fb4c2bee46c5ea4d40f8cdb5c131725cd976718ec56f1c8e82fbde5fa2a80"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"hashbrown 0.17.0",
|
"hashbrown 0.17.1",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"semver",
|
"semver",
|
||||||
]
|
]
|
||||||
@ -4528,7 +4529,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "aa4439c5eee9df71ee0c6efb37f63b1fcb1fec38f85f5142c54e7ed05d33091a"
|
checksum = "aa4439c5eee9df71ee0c6efb37f63b1fcb1fec38f85f5142c54e7ed05d33091a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"hashbrown 0.17.0",
|
"hashbrown 0.17.1",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"semver",
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
@ -5408,7 +5409,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "8ffe4064318cdf3c08cb99343b44c039fcefe61ccdf58aa9975285f13d74d1fc"
|
checksum = "8ffe4064318cdf3c08cb99343b44c039fcefe61ccdf58aa9975285f13d74d1fc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"hashbrown 0.17.0",
|
"hashbrown 0.17.1",
|
||||||
"id-arena",
|
"id-arena",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"log",
|
"log",
|
||||||
|
|||||||
@ -34,6 +34,7 @@ crossbeam.workspace = true
|
|||||||
|
|
||||||
sha2.workspace = true
|
sha2.workspace = true
|
||||||
bitflags.workspace = true
|
bitflags.workspace = true
|
||||||
|
arc-swap.workspace = true
|
||||||
|
|
||||||
dashmap.workspace = true
|
dashmap.workspace = true
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use pumpkin_util::world_seed::Seed;
|
|||||||
use pumpkin_world::biome::hash_seed;
|
use pumpkin_world::biome::hash_seed;
|
||||||
use pumpkin_world::chunk_system::{StagedChunkEnum, generate_single_chunk};
|
use pumpkin_world::chunk_system::{StagedChunkEnum, generate_single_chunk};
|
||||||
use pumpkin_world::generation::get_world_gen;
|
use pumpkin_world::generation::get_world_gen;
|
||||||
use pumpkin_world::world::BlockRegistryExt;
|
use pumpkin_world::world::WorldPortalExt;
|
||||||
use std::hint::black_box;
|
use std::hint::black_box;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ fn bench_full_chunk_generation(c: &mut Criterion) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct BlockRegistry;
|
struct BlockRegistry;
|
||||||
impl BlockRegistryExt for BlockRegistry {
|
impl WorldPortalExt for BlockRegistry {
|
||||||
fn can_place_at(
|
fn can_place_at(
|
||||||
&self,
|
&self,
|
||||||
_block: &pumpkin_data::Block,
|
_block: &pumpkin_data::Block,
|
||||||
@ -42,6 +42,15 @@ impl BlockRegistryExt for BlockRegistry {
|
|||||||
) -> bool {
|
) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn spawn_mobs_for_chunk_generation(
|
||||||
|
&self,
|
||||||
|
_cache: &mut dyn pumpkin_world::generation::proto_chunk::GenerationCache,
|
||||||
|
_biome: &'static pumpkin_data::chunk::Biome,
|
||||||
|
_chunk_x: i32,
|
||||||
|
_chunk_z: i32,
|
||||||
|
) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
criterion_group!(benches, bench_full_chunk_generation,);
|
criterion_group!(benches, bench_full_chunk_generation,);
|
||||||
|
|||||||
@ -129,7 +129,7 @@ pub struct ChunkLoading {
|
|||||||
impl ChunkLoading {
|
impl ChunkLoading {
|
||||||
// pub const FULL_CHUNK_LEVEL: i8 = 33;
|
// pub const FULL_CHUNK_LEVEL: i8 = 33;
|
||||||
pub const FULL_CHUNK_LEVEL: i8 = 43;
|
pub const FULL_CHUNK_LEVEL: i8 = 43;
|
||||||
pub const MAX_LEVEL: i8 = 48; // level 48 will be unloaded.
|
pub const MAX_LEVEL: i8 = 49; // level 49 will be unloaded.
|
||||||
fn debug_check_error(&self) -> bool {
|
fn debug_check_error(&self) -> bool {
|
||||||
let mut temp = ChunkLevel::default();
|
let mut temp = ChunkLevel::default();
|
||||||
for (ticket_pos, levels) in &self.ticket {
|
for (ticket_pos, levels) in &self.ticket {
|
||||||
|
|||||||
@ -29,9 +29,11 @@ pub enum StagedChunkEnum {
|
|||||||
/// Chunk with carvers applied, ready for features and structures
|
/// Chunk with carvers applied, ready for features and structures
|
||||||
Carvers,
|
Carvers,
|
||||||
/// Chunk with features and structures, ready for lighting
|
/// Chunk with features and structures, ready for lighting
|
||||||
Features, // FEATURES SPAWN
|
Features, // FEATURES
|
||||||
/// Chunk with lighting calculated, ready for finalization
|
/// Chunk with lighting calculated, ready for spawning
|
||||||
Lighting, // INITIALIZE LIGHT
|
Lighting, // INITIALIZE LIGHT
|
||||||
|
/// Chunk with mobs spawned, ready for finalization
|
||||||
|
Spawn, // SPAWN
|
||||||
/// Fully generated chunk
|
/// Fully generated chunk
|
||||||
Full,
|
Full,
|
||||||
}
|
}
|
||||||
@ -48,7 +50,8 @@ impl From<u8> for StagedChunkEnum {
|
|||||||
7 => Self::Carvers,
|
7 => Self::Carvers,
|
||||||
8 => Self::Features,
|
8 => Self::Features,
|
||||||
9 => Self::Lighting,
|
9 => Self::Lighting,
|
||||||
10 => Self::Full,
|
10 => Self::Spawn,
|
||||||
|
11 => Self::Full,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,9 +68,9 @@ impl From<ChunkStatus> for StagedChunkEnum {
|
|||||||
ChunkStatus::Surface => Self::Surface,
|
ChunkStatus::Surface => Self::Surface,
|
||||||
ChunkStatus::Carvers => Self::Carvers,
|
ChunkStatus::Carvers => Self::Carvers,
|
||||||
ChunkStatus::Features => Self::Features,
|
ChunkStatus::Features => Self::Features,
|
||||||
ChunkStatus::Spawn => Self::Features,
|
|
||||||
ChunkStatus::InitializeLight => Self::Lighting,
|
ChunkStatus::InitializeLight => Self::Lighting,
|
||||||
ChunkStatus::Light => Self::Lighting,
|
ChunkStatus::Light => Self::Lighting,
|
||||||
|
ChunkStatus::Spawn => Self::Spawn,
|
||||||
ChunkStatus::Full => Self::Full,
|
ChunkStatus::Full => Self::Full,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,6 +88,7 @@ impl From<StagedChunkEnum> for ChunkStatus {
|
|||||||
StagedChunkEnum::Carvers => Self::Carvers,
|
StagedChunkEnum::Carvers => Self::Carvers,
|
||||||
StagedChunkEnum::Features => Self::Features,
|
StagedChunkEnum::Features => Self::Features,
|
||||||
StagedChunkEnum::Lighting => Self::Light,
|
StagedChunkEnum::Lighting => Self::Light,
|
||||||
|
StagedChunkEnum::Spawn => Self::Spawn,
|
||||||
StagedChunkEnum::Full => Self::Full,
|
StagedChunkEnum::Full => Self::Full,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
@ -97,22 +101,25 @@ impl StagedChunkEnum {
|
|||||||
if level <= 43 {
|
if level <= 43 {
|
||||||
Self::Full
|
Self::Full
|
||||||
} else if level <= 44 {
|
} else if level <= 44 {
|
||||||
Self::Lighting
|
Self::Spawn
|
||||||
} else if level <= 45 {
|
} else if level <= 45 {
|
||||||
Self::Features
|
Self::Lighting
|
||||||
} else if level <= 46 {
|
} else if level <= 46 {
|
||||||
Self::Carvers
|
Self::Features
|
||||||
} else if level <= 47 {
|
} else if level <= 47 {
|
||||||
|
Self::Carvers
|
||||||
|
} else if level <= 48 {
|
||||||
Self::Surface
|
Self::Surface
|
||||||
} else {
|
} else {
|
||||||
Self::None
|
Self::None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Total number of state values (0 = None … 10 = Full).
|
/// Total number of state values (0 = None … 11 = Full).
|
||||||
pub const COUNT: usize = Self::Full as usize + 1;
|
pub const COUNT: usize = Self::Full as usize + 1;
|
||||||
pub const FULL_DEPENDENCIES: &'static [Self] = &[
|
pub const FULL_DEPENDENCIES: &'static [Self] = &[
|
||||||
Self::Full,
|
Self::Full,
|
||||||
|
Self::Spawn,
|
||||||
Self::Lighting,
|
Self::Lighting,
|
||||||
Self::Features,
|
Self::Features,
|
||||||
Self::Carvers,
|
Self::Carvers,
|
||||||
@ -132,6 +139,7 @@ impl StagedChunkEnum {
|
|||||||
Self::Carvers => 0,
|
Self::Carvers => 0,
|
||||||
Self::Features => 1,
|
Self::Features => 1,
|
||||||
Self::Lighting => 1,
|
Self::Lighting => 1,
|
||||||
|
Self::Spawn => 1,
|
||||||
Self::Full => 1,
|
Self::Full => 1,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
@ -149,6 +157,7 @@ impl StagedChunkEnum {
|
|||||||
Self::Carvers => 0,
|
Self::Carvers => 0,
|
||||||
Self::Features => 1,
|
Self::Features => 1,
|
||||||
Self::Lighting => 1,
|
Self::Lighting => 1,
|
||||||
|
Self::Spawn => 1,
|
||||||
Self::Full => 0,
|
Self::Full => 0,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
@ -176,7 +185,8 @@ impl StagedChunkEnum {
|
|||||||
Self::Carvers => &[Self::Surface],
|
Self::Carvers => &[Self::Surface],
|
||||||
Self::Features => &[Self::Carvers, Self::Carvers],
|
Self::Features => &[Self::Carvers, Self::Carvers],
|
||||||
Self::Lighting => &[Self::Features, Self::Features],
|
Self::Lighting => &[Self::Features, Self::Features],
|
||||||
Self::Full => &[Self::Lighting, Self::Lighting],
|
Self::Spawn => &[Self::Lighting, Self::Lighting],
|
||||||
|
Self::Full => &[Self::Spawn, Self::Spawn],
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use pumpkin_data::dimension::Dimension;
|
|||||||
|
|
||||||
use crate::ProtoChunk;
|
use crate::ProtoChunk;
|
||||||
use crate::generation::generator::VanillaGenerator;
|
use crate::generation::generator::VanillaGenerator;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
use pumpkin_config::lighting::LightingEngineConfig;
|
use pumpkin_config::lighting::LightingEngineConfig;
|
||||||
|
|
||||||
use super::{Cache, Chunk, StagedChunkEnum};
|
use super::{Cache, Chunk, StagedChunkEnum};
|
||||||
@ -11,7 +11,7 @@ pub fn generate_single_chunk(
|
|||||||
_dimension: &Dimension,
|
_dimension: &Dimension,
|
||||||
_biome_mixer_seed: i64,
|
_biome_mixer_seed: i64,
|
||||||
generator: &VanillaGenerator,
|
generator: &VanillaGenerator,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk_x: i32,
|
chunk_x: i32,
|
||||||
chunk_z: i32,
|
chunk_z: i32,
|
||||||
target_stage: StagedChunkEnum,
|
target_stage: StagedChunkEnum,
|
||||||
@ -39,6 +39,7 @@ pub fn generate_single_chunk(
|
|||||||
StagedChunkEnum::Surface,
|
StagedChunkEnum::Surface,
|
||||||
StagedChunkEnum::Features,
|
StagedChunkEnum::Features,
|
||||||
StagedChunkEnum::Lighting,
|
StagedChunkEnum::Lighting,
|
||||||
|
StagedChunkEnum::Spawn,
|
||||||
StagedChunkEnum::Full,
|
StagedChunkEnum::Full,
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -64,13 +65,13 @@ mod tests {
|
|||||||
use crate::biome::hash_seed;
|
use crate::biome::hash_seed;
|
||||||
use crate::chunk_system::{StagedChunkEnum, generate_single_chunk};
|
use crate::chunk_system::{StagedChunkEnum, generate_single_chunk};
|
||||||
use crate::generation::get_world_gen;
|
use crate::generation::get_world_gen;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
use pumpkin_data::dimension::Dimension;
|
use pumpkin_data::dimension::Dimension;
|
||||||
use pumpkin_util::world_seed::Seed;
|
use pumpkin_util::world_seed::Seed;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
struct BlockRegistry;
|
struct BlockRegistry;
|
||||||
impl BlockRegistryExt for BlockRegistry {
|
impl WorldPortalExt for BlockRegistry {
|
||||||
fn can_place_at(
|
fn can_place_at(
|
||||||
&self,
|
&self,
|
||||||
_block: &pumpkin_data::Block,
|
_block: &pumpkin_data::Block,
|
||||||
@ -80,6 +81,15 @@ mod tests {
|
|||||||
) -> bool {
|
) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn spawn_mobs_for_chunk_generation(
|
||||||
|
&self,
|
||||||
|
_cache: &mut dyn crate::generation::proto_chunk::GenerationCache,
|
||||||
|
_biome: &'static pumpkin_data::chunk::Biome,
|
||||||
|
_chunk_x: i32,
|
||||||
|
_chunk_z: i32,
|
||||||
|
) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use crate::chunk::ChunkHeightmapType;
|
|||||||
use crate::generation::generator;
|
use crate::generation::generator;
|
||||||
use crate::generation::height_limit::HeightLimitView;
|
use crate::generation::height_limit::HeightLimitView;
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::{BlockAccessor, BlockRegistryExt};
|
use crate::world::{BlockAccessor, WorldPortalExt};
|
||||||
use crate::{BlockStateId, ProtoChunk};
|
use crate::{BlockStateId, ProtoChunk};
|
||||||
use pumpkin_config::lighting::LightingEngineConfig;
|
use pumpkin_config::lighting::LightingEngineConfig;
|
||||||
use pumpkin_data::biome::Biome;
|
use pumpkin_data::biome::Biome;
|
||||||
@ -360,7 +360,7 @@ impl Cache {
|
|||||||
&mut self,
|
&mut self,
|
||||||
stage: StagedChunkEnum,
|
stage: StagedChunkEnum,
|
||||||
generator: &generator::VanillaGenerator,
|
generator: &generator::VanillaGenerator,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
lighting_config: &LightingEngineConfig,
|
lighting_config: &LightingEngineConfig,
|
||||||
) {
|
) {
|
||||||
let mid = ((self.size * self.size) >> 1) as usize;
|
let mid = ((self.size * self.size) >> 1) as usize;
|
||||||
@ -407,9 +407,12 @@ impl Cache {
|
|||||||
// Engine's internal state is cleared by initialize_light() and will be dropped here
|
// Engine's internal state is cleared by initialize_light() and will be dropped here
|
||||||
drop(engine);
|
drop(engine);
|
||||||
}
|
}
|
||||||
|
StagedChunkEnum::Spawn => {
|
||||||
|
ProtoChunk::spawn_mobs(self, block_registry);
|
||||||
|
}
|
||||||
StagedChunkEnum::Full => {
|
StagedChunkEnum::Full => {
|
||||||
let chunk = self.chunks[mid].get_proto_chunk_mut();
|
let chunk = self.chunks[mid].get_proto_chunk_mut();
|
||||||
debug_assert_eq!(chunk.stage, StagedChunkEnum::Lighting);
|
debug_assert_eq!(chunk.stage, StagedChunkEnum::Spawn);
|
||||||
chunk.stage = StagedChunkEnum::Full;
|
chunk.stage = StagedChunkEnum::Full;
|
||||||
self.chunks[mid].upgrade_to_level_chunk(&generator.dimension, lighting_config);
|
self.chunks[mid].upgrade_to_level_chunk(&generator.dimension, lighting_config);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -721,14 +721,14 @@ impl GenerationSchedule {
|
|||||||
Chunk::Level(chunk) => {
|
Chunk::Level(chunk) => {
|
||||||
let mut holder = self.chunk_map.remove(&new_pos).unwrap();
|
let mut holder = self.chunk_map.remove(&new_pos).unwrap();
|
||||||
if new_pos == pos {
|
if new_pos == pos {
|
||||||
if holder.current_stage != StagedChunkEnum::Lighting {
|
if holder.current_stage != StagedChunkEnum::Spawn {
|
||||||
warn!(
|
warn!(
|
||||||
"receive_chunk(Level): holder at {:?} for pos {:?} expected {:?}; aligning",
|
"receive_chunk(Level): holder at {:?} for pos {:?} expected {:?}; aligning",
|
||||||
holder.current_stage,
|
holder.current_stage,
|
||||||
new_pos,
|
new_pos,
|
||||||
StagedChunkEnum::Lighting
|
StagedChunkEnum::Spawn
|
||||||
);
|
);
|
||||||
holder.current_stage = StagedChunkEnum::Lighting;
|
holder.current_stage = StagedChunkEnum::Spawn;
|
||||||
}
|
}
|
||||||
self.drop_node(holder.tasks[StagedChunkEnum::Full as usize]);
|
self.drop_node(holder.tasks[StagedChunkEnum::Full as usize]);
|
||||||
holder.tasks[StagedChunkEnum::Full as usize] = NodeKey::null();
|
holder.tasks[StagedChunkEnum::Full as usize] = NodeKey::null();
|
||||||
|
|||||||
@ -229,14 +229,11 @@ pub fn run_generation(
|
|||||||
level: &Level,
|
level: &Level,
|
||||||
_settings: &GenerationSettings,
|
_settings: &GenerationSettings,
|
||||||
) -> RecvChunk {
|
) -> RecvChunk {
|
||||||
|
let portal = level.world_portal.load_full();
|
||||||
|
let portal_ref = portal.as_deref().expect("Portal should be initialized");
|
||||||
// Run generation with panic catching
|
// Run generation with panic catching
|
||||||
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
||||||
cache.advance(
|
cache.advance(stage, &level.world_gen, portal_ref, &level.lighting_config);
|
||||||
stage,
|
|
||||||
&level.world_gen,
|
|
||||||
level.block_registry.as_ref(),
|
|
||||||
&level.lighting_config,
|
|
||||||
);
|
|
||||||
cache // Return cache on success
|
cache // Return cache on success
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@ -3,13 +3,12 @@ use std::{path::PathBuf, sync::Arc};
|
|||||||
use pumpkin_config::world::LevelConfig;
|
use pumpkin_config::world::LevelConfig;
|
||||||
use pumpkin_data::dimension::Dimension;
|
use pumpkin_data::dimension::Dimension;
|
||||||
|
|
||||||
use crate::{level::Level, world::BlockRegistryExt};
|
use crate::level::Level;
|
||||||
|
|
||||||
pub fn into_level(
|
pub fn into_level(
|
||||||
dimension: Dimension,
|
dimension: Dimension,
|
||||||
level_config: &LevelConfig,
|
level_config: &LevelConfig,
|
||||||
mut base_directory: PathBuf,
|
mut base_directory: PathBuf,
|
||||||
block_registry: Arc<dyn BlockRegistryExt>,
|
|
||||||
seed: i64,
|
seed: i64,
|
||||||
gen_pool: Option<Arc<rayon::ThreadPool>>,
|
gen_pool: Option<Arc<rayon::ThreadPool>>,
|
||||||
) -> Arc<Level> {
|
) -> Arc<Level> {
|
||||||
@ -19,12 +18,5 @@ pub fn into_level(
|
|||||||
} else if dimension == Dimension::THE_END {
|
} else if dimension == Dimension::THE_END {
|
||||||
base_directory.push("DIM1");
|
base_directory.push("DIM1");
|
||||||
}
|
}
|
||||||
Level::from_root_folder(
|
Level::from_root_folder(level_config, base_directory, seed, dimension, gen_pool)
|
||||||
level_config,
|
|
||||||
base_directory,
|
|
||||||
block_registry,
|
|
||||||
seed,
|
|
||||||
dimension,
|
|
||||||
gen_pool,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use pumpkin_util::math::{position::BlockPos, vector3::Vector3};
|
|||||||
|
|
||||||
use crate::block::RawBlockState;
|
use crate::block::RawBlockState;
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::{block::BlockStateCodec, world::BlockRegistryExt};
|
use crate::{block::BlockStateCodec, world::WorldPortalExt};
|
||||||
|
|
||||||
pub enum BlockPredicate {
|
pub enum BlockPredicate {
|
||||||
MatchingBlocks(MatchingBlocksBlockPredicate),
|
MatchingBlocks(MatchingBlocksBlockPredicate),
|
||||||
@ -28,7 +28,7 @@ pub enum BlockPredicate {
|
|||||||
impl BlockPredicate {
|
impl BlockPredicate {
|
||||||
pub fn test<T: GenerationCache>(
|
pub fn test<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
pos: &BlockPos,
|
pos: &BlockPos,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
@ -131,7 +131,7 @@ pub struct AnyOfBlockPredicate {
|
|||||||
impl AnyOfBlockPredicate {
|
impl AnyOfBlockPredicate {
|
||||||
pub fn test<T: GenerationCache>(
|
pub fn test<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
pos: &BlockPos,
|
pos: &BlockPos,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
@ -152,7 +152,7 @@ pub struct AllOfBlockPredicate {
|
|||||||
impl AllOfBlockPredicate {
|
impl AllOfBlockPredicate {
|
||||||
pub fn test<T: GenerationCache>(
|
pub fn test<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
pos: &BlockPos,
|
pos: &BlockPos,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
@ -173,7 +173,7 @@ pub struct NotBlockPredicate {
|
|||||||
impl NotBlockPredicate {
|
impl NotBlockPredicate {
|
||||||
pub fn test<T: GenerationCache>(
|
pub fn test<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
pos: &BlockPos,
|
pos: &BlockPos,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
@ -200,7 +200,7 @@ pub struct WouldSurviveBlockPredicate {
|
|||||||
impl WouldSurviveBlockPredicate {
|
impl WouldSurviveBlockPredicate {
|
||||||
pub fn test<T: GenerationCache>(
|
pub fn test<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
pos: &BlockPos,
|
pos: &BlockPos,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
|||||||
@ -13,7 +13,7 @@ use pumpkin_util::{
|
|||||||
use super::noise::perlin::DoublePerlinNoiseSampler;
|
use super::noise::perlin::DoublePerlinNoiseSampler;
|
||||||
use crate::generation::block_predicate::BlockPredicate;
|
use crate::generation::block_predicate::BlockPredicate;
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub enum BlockStateProvider {
|
pub enum BlockStateProvider {
|
||||||
Simple(SimpleStateProvider),
|
Simple(SimpleStateProvider),
|
||||||
@ -43,7 +43,7 @@ impl BlockStateProvider {
|
|||||||
|
|
||||||
pub fn get_with_context<T: GenerationCache>(
|
pub fn get_with_context<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
@ -56,7 +56,7 @@ impl BlockStateProvider {
|
|||||||
|
|
||||||
pub fn get_optional<T: GenerationCache>(
|
pub fn get_optional<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
@ -76,7 +76,7 @@ pub struct RuleBasedBlockStateProvider {
|
|||||||
impl RuleBasedBlockStateProvider {
|
impl RuleBasedBlockStateProvider {
|
||||||
pub fn get<T: GenerationCache>(
|
pub fn get<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
@ -88,7 +88,7 @@ impl RuleBasedBlockStateProvider {
|
|||||||
}
|
}
|
||||||
pub fn get_optional<T: GenerationCache>(
|
pub fn get_optional<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
|
|||||||
@ -69,7 +69,7 @@ use super::features::{
|
|||||||
weeping_vines::WeepingVinesFeature,
|
weeping_vines::WeepingVinesFeature,
|
||||||
};
|
};
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub static CONFIGURED_FEATURES: LazyLock<HashMap<String, ConfiguredFeature>> =
|
pub static CONFIGURED_FEATURES: LazyLock<HashMap<String, ConfiguredFeature>> =
|
||||||
LazyLock::new(build_configured_features);
|
LazyLock::new(build_configured_features);
|
||||||
@ -147,7 +147,7 @@ impl ConfiguredFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
min_y: i8,
|
min_y: i8,
|
||||||
height: u16,
|
height: u16,
|
||||||
feature_name: &str, // This placed feature
|
feature_name: &str, // This placed feature
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub struct BambooFeature {
|
pub struct BambooFeature {
|
||||||
pub probability: f32,
|
pub probability: f32,
|
||||||
@ -20,7 +20,7 @@ impl BambooFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
_min_y: i8,
|
_min_y: i8,
|
||||||
_height: u16,
|
_height: u16,
|
||||||
_feature: &str, // This placed feature
|
_feature: &str, // This placed feature
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use pumpkin_util::{
|
|||||||
random::{RandomGenerator, RandomImpl},
|
random::{RandomGenerator, RandomImpl},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{generation::proto_chunk::GenerationCache, world::BlockRegistryExt};
|
use crate::{generation::proto_chunk::GenerationCache, world::WorldPortalExt};
|
||||||
|
|
||||||
const LAVA_SEA_LEVEL: i32 = 32; // TODO: use getSeaLevel() instead of hardcoding this
|
const LAVA_SEA_LEVEL: i32 = 32; // TODO: use getSeaLevel() instead of hardcoding this
|
||||||
const CLUSTERED_REACH: i32 = 5;
|
const CLUSTERED_REACH: i32 = 5;
|
||||||
@ -22,7 +22,7 @@ impl BasaltColumnsFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
_min_y: i8,
|
_min_y: i8,
|
||||||
_height_limit: u16,
|
_height_limit: u16,
|
||||||
_feature: &str,
|
_feature: &str,
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use pumpkin_util::{
|
|||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::{
|
use crate::{
|
||||||
generation::{block_predicate::BlockPredicate, block_state_provider::BlockStateProvider},
|
generation::{block_predicate::BlockPredicate, block_state_provider::BlockStateProvider},
|
||||||
world::BlockRegistryExt,
|
world::WorldPortalExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct BlockColumnFeature {
|
pub struct BlockColumnFeature {
|
||||||
@ -27,7 +27,7 @@ impl BlockColumnFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
_min_y: i8,
|
_min_y: i8,
|
||||||
_height: u16,
|
_height: u16,
|
||||||
_feature: &str, // This placed feature
|
_feature: &str, // This placed feature
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use crate::generation::{
|
|||||||
block_predicate::BlockPredicate, block_state_provider::BlockStateProvider,
|
block_predicate::BlockPredicate, block_state_provider::BlockStateProvider,
|
||||||
proto_chunk::GenerationCache,
|
proto_chunk::GenerationCache,
|
||||||
};
|
};
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub struct DiskFeature {
|
pub struct DiskFeature {
|
||||||
pub state_provider: BlockStateProvider,
|
pub state_provider: BlockStateProvider,
|
||||||
@ -19,7 +19,7 @@ impl DiskFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
_min_y: i8,
|
_min_y: i8,
|
||||||
_height: u16,
|
_height: u16,
|
||||||
_feature: &str,
|
_feature: &str,
|
||||||
@ -55,7 +55,7 @@ impl DiskFeature {
|
|||||||
fn place_column<T: GenerationCache>(
|
fn place_column<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
top: i32,
|
top: i32,
|
||||||
bottom: i32,
|
bottom: i32,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub struct EndPlatformFeature;
|
pub struct EndPlatformFeature;
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ impl EndPlatformFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
_min_y: i8,
|
_min_y: i8,
|
||||||
_height: u16,
|
_height: u16,
|
||||||
_feature: &str, // This placed feature
|
_feature: &str, // This placed feature
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::{generation::section_coords, world::BlockRegistryExt};
|
use crate::{generation::section_coords, world::WorldPortalExt};
|
||||||
|
|
||||||
pub struct EndSpikeFeature {
|
pub struct EndSpikeFeature {
|
||||||
pub crystal_invulnerable: bool,
|
pub crystal_invulnerable: bool,
|
||||||
@ -37,7 +37,7 @@ impl EndSpikeFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
_min_y: i8,
|
_min_y: i8,
|
||||||
_height: u16,
|
_height: u16,
|
||||||
_feature: &str, // This placed feature
|
_feature: &str, // This placed feature
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use pumpkin_util::{
|
|||||||
|
|
||||||
use crate::generation::feature::features::spring_feature::BlockWrapper;
|
use crate::generation::feature::features::spring_feature::BlockWrapper;
|
||||||
use crate::{
|
use crate::{
|
||||||
block::BlockStateCodec, generation::proto_chunk::GenerationCache, world::BlockRegistryExt,
|
block::BlockStateCodec, generation::proto_chunk::GenerationCache, world::WorldPortalExt,
|
||||||
};
|
};
|
||||||
use pumpkin_util::random::RandomImpl;
|
use pumpkin_util::random::RandomImpl;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
@ -102,7 +102,7 @@ impl GeodeFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
_min_y: i8,
|
_min_y: i8,
|
||||||
_height: u16,
|
_height: u16,
|
||||||
_feature_name: &str,
|
_feature_name: &str,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::generation::{block_state_provider::BlockStateProvider, proto_chunk::GenerationCache};
|
use crate::generation::{block_state_provider::BlockStateProvider, proto_chunk::GenerationCache};
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub struct LakeFeature {
|
pub struct LakeFeature {
|
||||||
pub fluid: BlockStateProvider,
|
pub fluid: BlockStateProvider,
|
||||||
@ -15,7 +15,7 @@ pub struct LakeFeature {
|
|||||||
impl LakeFeature {
|
impl LakeFeature {
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::{generation::block_state_provider::BlockStateProvider, world::BlockRegistryExt};
|
use crate::{generation::block_state_provider::BlockStateProvider, world::WorldPortalExt};
|
||||||
|
|
||||||
pub struct NetherForestVegetationFeature {
|
pub struct NetherForestVegetationFeature {
|
||||||
pub state_provider: BlockStateProvider,
|
pub state_provider: BlockStateProvider,
|
||||||
@ -18,7 +18,7 @@ impl NetherForestVegetationFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
_min_y: i8,
|
_min_y: i8,
|
||||||
_height: u16,
|
_height: u16,
|
||||||
_feature: &str,
|
_feature: &str,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub struct ReplaceBlobsFeature {
|
pub struct ReplaceBlobsFeature {
|
||||||
pub target: &'static BlockState,
|
pub target: &'static BlockState,
|
||||||
@ -18,7 +18,7 @@ impl ReplaceBlobsFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
_min_y: i8,
|
_min_y: i8,
|
||||||
_height: u16,
|
_height: u16,
|
||||||
_feature: &str, // This placed feature
|
_feature: &str, // This placed feature
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{block::RawBlockState, generation::proto_chunk::GenerationCache};
|
use crate::{block::RawBlockState, generation::proto_chunk::GenerationCache};
|
||||||
use crate::{generation::rule::RuleTest, world::BlockRegistryExt};
|
use crate::{generation::rule::RuleTest, world::WorldPortalExt};
|
||||||
|
|
||||||
pub struct OreFeature {
|
pub struct OreFeature {
|
||||||
pub size: i32,
|
pub size: i32,
|
||||||
@ -25,7 +25,7 @@ impl OreFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
_min_y: i8,
|
_min_y: i8,
|
||||||
_height: u16,
|
_height: u16,
|
||||||
_feature: &str, // This placed feature
|
_feature: &str, // This placed feature
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::{generation::feature::placed_features::PlacedFeatureWrapper, world::BlockRegistryExt};
|
use crate::{generation::feature::placed_features::PlacedFeatureWrapper, world::WorldPortalExt};
|
||||||
|
|
||||||
pub struct RandomBooleanFeature {
|
pub struct RandomBooleanFeature {
|
||||||
pub feature_true: Box<PlacedFeatureWrapper>,
|
pub feature_true: Box<PlacedFeatureWrapper>,
|
||||||
@ -16,7 +16,7 @@ impl RandomBooleanFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
min_y: i8,
|
min_y: i8,
|
||||||
height: u16,
|
height: u16,
|
||||||
feature_name: &str, // This placed feature
|
feature_name: &str, // This placed feature
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::{generation::feature::placed_features::PlacedFeature, world::BlockRegistryExt};
|
use crate::{generation::feature::placed_features::PlacedFeature, world::WorldPortalExt};
|
||||||
|
|
||||||
pub struct RandomPatchFeature {
|
pub struct RandomPatchFeature {
|
||||||
pub tries: u8,
|
pub tries: u8,
|
||||||
@ -18,7 +18,7 @@ impl RandomPatchFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
min_y: i8,
|
min_y: i8,
|
||||||
height: u16,
|
height: u16,
|
||||||
feature: &str,
|
feature: &str,
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::{generation::feature::placed_features::PlacedFeatureWrapper, world::BlockRegistryExt};
|
use crate::{generation::feature::placed_features::PlacedFeatureWrapper, world::WorldPortalExt};
|
||||||
|
|
||||||
pub struct RandomFeature {
|
pub struct RandomFeature {
|
||||||
pub features: Vec<RandomFeatureEntry>,
|
pub features: Vec<RandomFeatureEntry>,
|
||||||
@ -21,7 +21,7 @@ impl RandomFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
min_y: i8,
|
min_y: i8,
|
||||||
height: u16,
|
height: u16,
|
||||||
feature_name: &str, // This placed feature
|
feature_name: &str, // This placed feature
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use pumpkin_util::{
|
|||||||
use crate::generation::block_predicate::BlockPredicate;
|
use crate::generation::block_predicate::BlockPredicate;
|
||||||
use crate::generation::block_state_provider::BlockStateProvider;
|
use crate::generation::block_state_provider::BlockStateProvider;
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub struct RootSystemFeature {
|
pub struct RootSystemFeature {
|
||||||
pub feature: Box<crate::generation::feature::placed_features::PlacedFeature>,
|
pub feature: Box<crate::generation::feature::placed_features::PlacedFeature>,
|
||||||
@ -29,7 +29,7 @@ impl RootSystemFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
min_y: i8,
|
min_y: i8,
|
||||||
height: u16,
|
height: u16,
|
||||||
feature_name: &str,
|
feature_name: &str,
|
||||||
@ -87,7 +87,7 @@ impl RootSystemFeature {
|
|||||||
fn place_roots<T: GenerationCache>(
|
fn place_roots<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
) {
|
) {
|
||||||
@ -98,7 +98,7 @@ impl RootSystemFeature {
|
|||||||
fn place_rooted_dirt<T: GenerationCache>(
|
fn place_rooted_dirt<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
) {
|
) {
|
||||||
@ -151,7 +151,7 @@ impl RootSystemFeature {
|
|||||||
fn place_hanging_roots<T: GenerationCache>(
|
fn place_hanging_roots<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
use super::ore::{OreFeature, OreTarget};
|
use super::ore::{OreFeature, OreTarget};
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ impl ScatteredOreFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
_min_y: i8,
|
_min_y: i8,
|
||||||
_height: u16,
|
_height: u16,
|
||||||
_feature: &str,
|
_feature: &str,
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub struct SculkPatchFeature {
|
pub struct SculkPatchFeature {
|
||||||
pub charge_count: i32,
|
pub charge_count: i32,
|
||||||
@ -21,7 +21,7 @@ pub struct SculkPatchFeature {
|
|||||||
impl SculkPatchFeature {
|
impl SculkPatchFeature {
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use pumpkin_util::{math::position::BlockPos, random::RandomGenerator};
|
|||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::{
|
use crate::{
|
||||||
generation::block_state_provider::BlockStateProvider,
|
generation::block_state_provider::BlockStateProvider,
|
||||||
world::{BlockAccessor, BlockRegistryExt},
|
world::{BlockAccessor, WorldPortalExt},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct SimpleBlockFeature {
|
pub struct SimpleBlockFeature {
|
||||||
@ -15,7 +15,7 @@ pub struct SimpleBlockFeature {
|
|||||||
impl SimpleBlockFeature {
|
impl SimpleBlockFeature {
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::{generation::feature::placed_features::PlacedFeature, world::BlockRegistryExt};
|
use crate::{generation::feature::placed_features::PlacedFeature, world::WorldPortalExt};
|
||||||
|
|
||||||
pub struct SimpleRandomFeature {
|
pub struct SimpleRandomFeature {
|
||||||
pub features: Vec<PlacedFeature>,
|
pub features: Vec<PlacedFeature>,
|
||||||
@ -15,7 +15,7 @@ impl SimpleRandomFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
min_y: i8,
|
min_y: i8,
|
||||||
height: u16,
|
height: u16,
|
||||||
feature_name: &str, // This placed feature
|
feature_name: &str, // This placed feature
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use pumpkin_data::{BlockDirection, BlockState};
|
|||||||
use pumpkin_util::{math::position::BlockPos, random::RandomGenerator};
|
use pumpkin_util::{math::position::BlockPos, random::RandomGenerator};
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub struct SpringFeatureFeature {
|
pub struct SpringFeatureFeature {
|
||||||
pub state: &'static BlockState,
|
pub state: &'static BlockState,
|
||||||
@ -30,7 +30,7 @@ impl BlockWrapper {
|
|||||||
impl SpringFeatureFeature {
|
impl SpringFeatureFeature {
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
_random: &mut RandomGenerator,
|
_random: &mut RandomGenerator,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use trunk::TrunkPlacer;
|
|||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::generation::{block_state_provider::BlockStateProvider, feature::size::FeatureSize};
|
use crate::generation::{block_state_provider::BlockStateProvider, feature::size::FeatureSize};
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub mod decorator;
|
pub mod decorator;
|
||||||
pub mod foliage;
|
pub mod foliage;
|
||||||
@ -35,7 +35,7 @@ impl TreeFeature {
|
|||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
min_y: i8,
|
min_y: i8,
|
||||||
height: u16,
|
height: u16,
|
||||||
@ -78,7 +78,7 @@ impl TreeFeature {
|
|||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
fn generate_main<T: GenerationCache>(
|
fn generate_main<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
_min_y: i8,
|
_min_y: i8,
|
||||||
_height: u16,
|
_height: u16,
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use crate::{
|
|||||||
block_state_provider::BlockStateProvider,
|
block_state_provider::BlockStateProvider,
|
||||||
feature::features::tree::{TreeNode, trunk::TrunkPlacer},
|
feature::features::tree::{TreeNode, trunk::TrunkPlacer},
|
||||||
},
|
},
|
||||||
world::BlockRegistryExt,
|
world::WorldPortalExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct BendingTrunkPlacer {
|
pub struct BendingTrunkPlacer {
|
||||||
@ -22,7 +22,7 @@ impl BendingTrunkPlacer {
|
|||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
placer: &TrunkPlacer,
|
placer: &TrunkPlacer,
|
||||||
height: u32,
|
height: u32,
|
||||||
start_pos: BlockPos,
|
start_pos: BlockPos,
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use super::TrunkPlacer;
|
|||||||
use crate::generation::block_state_provider::BlockStateProvider;
|
use crate::generation::block_state_provider::BlockStateProvider;
|
||||||
use crate::generation::feature::features::tree::TreeNode;
|
use crate::generation::feature::features::tree::TreeNode;
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
use pumpkin_data::block_properties::Axis;
|
use pumpkin_data::block_properties::Axis;
|
||||||
|
|
||||||
pub struct CherryTrunkPlacer {
|
pub struct CherryTrunkPlacer {
|
||||||
@ -21,7 +21,7 @@ impl CherryTrunkPlacer {
|
|||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
placer: &TrunkPlacer,
|
placer: &TrunkPlacer,
|
||||||
height: u32,
|
height: u32,
|
||||||
start_pos: BlockPos,
|
start_pos: BlockPos,
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use crate::{
|
|||||||
block_state_provider::BlockStateProvider,
|
block_state_provider::BlockStateProvider,
|
||||||
feature::features::tree::{TreeFeature, TreeNode, trunk::TrunkPlacer},
|
feature::features::tree::{TreeFeature, TreeNode, trunk::TrunkPlacer},
|
||||||
},
|
},
|
||||||
world::BlockRegistryExt,
|
world::WorldPortalExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct DarkOakTrunkPlacer;
|
pub struct DarkOakTrunkPlacer;
|
||||||
@ -18,7 +18,7 @@ pub struct DarkOakTrunkPlacer;
|
|||||||
impl DarkOakTrunkPlacer {
|
impl DarkOakTrunkPlacer {
|
||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
placer: &TrunkPlacer,
|
placer: &TrunkPlacer,
|
||||||
height: u32,
|
height: u32,
|
||||||
start_pos: BlockPos,
|
start_pos: BlockPos,
|
||||||
|
|||||||
@ -16,7 +16,7 @@ use crate::{
|
|||||||
block_state_provider::BlockStateProvider,
|
block_state_provider::BlockStateProvider,
|
||||||
feature::features::tree::{TreeFeature, TreeNode},
|
feature::features::tree::{TreeFeature, TreeNode},
|
||||||
},
|
},
|
||||||
world::BlockRegistryExt,
|
world::WorldPortalExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct FancyTrunkPlacer;
|
pub struct FancyTrunkPlacer;
|
||||||
@ -24,7 +24,7 @@ pub struct FancyTrunkPlacer;
|
|||||||
impl FancyTrunkPlacer {
|
impl FancyTrunkPlacer {
|
||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
placer: &TrunkPlacer,
|
placer: &TrunkPlacer,
|
||||||
height: u32,
|
height: u32,
|
||||||
start_pos: BlockPos,
|
start_pos: BlockPos,
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use super::TrunkPlacer;
|
|||||||
use crate::generation::block_state_provider::BlockStateProvider;
|
use crate::generation::block_state_provider::BlockStateProvider;
|
||||||
use crate::generation::feature::features::tree::TreeNode;
|
use crate::generation::feature::features::tree::TreeNode;
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
use pumpkin_data::BlockDirection;
|
use pumpkin_data::BlockDirection;
|
||||||
|
|
||||||
pub struct ForkingTrunkPlacer;
|
pub struct ForkingTrunkPlacer;
|
||||||
@ -14,7 +14,7 @@ pub struct ForkingTrunkPlacer;
|
|||||||
impl ForkingTrunkPlacer {
|
impl ForkingTrunkPlacer {
|
||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
placer: &TrunkPlacer,
|
placer: &TrunkPlacer,
|
||||||
height: u32,
|
height: u32,
|
||||||
start_pos: BlockPos,
|
start_pos: BlockPos,
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use crate::{
|
|||||||
block_state_provider::BlockStateProvider,
|
block_state_provider::BlockStateProvider,
|
||||||
feature::features::tree::{TreeNode, trunk::TrunkPlacer},
|
feature::features::tree::{TreeNode, trunk::TrunkPlacer},
|
||||||
},
|
},
|
||||||
world::BlockRegistryExt,
|
world::WorldPortalExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct GiantTrunkPlacer;
|
pub struct GiantTrunkPlacer;
|
||||||
@ -15,7 +15,7 @@ pub struct GiantTrunkPlacer;
|
|||||||
impl GiantTrunkPlacer {
|
impl GiantTrunkPlacer {
|
||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
placer: &TrunkPlacer,
|
placer: &TrunkPlacer,
|
||||||
height: u32,
|
height: u32,
|
||||||
start_pos: BlockPos,
|
start_pos: BlockPos,
|
||||||
|
|||||||
@ -15,7 +15,7 @@ use crate::{
|
|||||||
trunk::{TrunkPlacer, giant::GiantTrunkPlacer},
|
trunk::{TrunkPlacer, giant::GiantTrunkPlacer},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
world::BlockRegistryExt,
|
world::WorldPortalExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct MegaJungleTrunkPlacer;
|
pub struct MegaJungleTrunkPlacer;
|
||||||
@ -23,7 +23,7 @@ pub struct MegaJungleTrunkPlacer;
|
|||||||
impl MegaJungleTrunkPlacer {
|
impl MegaJungleTrunkPlacer {
|
||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
placer: &TrunkPlacer,
|
placer: &TrunkPlacer,
|
||||||
height: u32,
|
height: u32,
|
||||||
start_pos: BlockPos,
|
start_pos: BlockPos,
|
||||||
|
|||||||
@ -15,7 +15,7 @@ use crate::generation::feature::features::tree::trunk::{
|
|||||||
upwards_branching::UpwardsBranchingTrunkPlacer,
|
upwards_branching::UpwardsBranchingTrunkPlacer,
|
||||||
};
|
};
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub mod bending;
|
pub mod bending;
|
||||||
pub mod cherry;
|
pub mod cherry;
|
||||||
@ -43,7 +43,7 @@ impl TrunkPlacer {
|
|||||||
|
|
||||||
pub fn set_dirt<T: GenerationCache>(
|
pub fn set_dirt<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
pos: &BlockPos,
|
pos: &BlockPos,
|
||||||
@ -85,7 +85,7 @@ impl TrunkPlacer {
|
|||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
height: u32,
|
height: u32,
|
||||||
start_pos: BlockPos,
|
start_pos: BlockPos,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
@ -122,7 +122,7 @@ impl TrunkType {
|
|||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
placer: &TrunkPlacer,
|
placer: &TrunkPlacer,
|
||||||
height: u32,
|
height: u32,
|
||||||
start_pos: BlockPos,
|
start_pos: BlockPos,
|
||||||
|
|||||||
@ -6,14 +6,14 @@ use super::TrunkPlacer;
|
|||||||
use crate::generation::block_state_provider::BlockStateProvider;
|
use crate::generation::block_state_provider::BlockStateProvider;
|
||||||
use crate::generation::feature::features::tree::TreeNode;
|
use crate::generation::feature::features::tree::TreeNode;
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub struct StraightTrunkPlacer;
|
pub struct StraightTrunkPlacer;
|
||||||
|
|
||||||
impl StraightTrunkPlacer {
|
impl StraightTrunkPlacer {
|
||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
placer: &TrunkPlacer,
|
placer: &TrunkPlacer,
|
||||||
height: u32,
|
height: u32,
|
||||||
start_pos: BlockPos,
|
start_pos: BlockPos,
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use super::TrunkPlacer;
|
|||||||
use crate::generation::block_state_provider::BlockStateProvider;
|
use crate::generation::block_state_provider::BlockStateProvider;
|
||||||
use crate::generation::feature::features::tree::{TreeFeature, TreeNode};
|
use crate::generation::feature::features::tree::{TreeFeature, TreeNode};
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
use pumpkin_data::BlockDirection;
|
use pumpkin_data::BlockDirection;
|
||||||
|
|
||||||
pub struct UpwardsBranchingTrunkPlacer {
|
pub struct UpwardsBranchingTrunkPlacer {
|
||||||
@ -21,7 +21,7 @@ impl UpwardsBranchingTrunkPlacer {
|
|||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
placer: &TrunkPlacer,
|
placer: &TrunkPlacer,
|
||||||
height: u32,
|
height: u32,
|
||||||
start_pos: BlockPos,
|
start_pos: BlockPos,
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use pumpkin_util::{
|
|||||||
use crate::generation::block_predicate::BlockPredicate;
|
use crate::generation::block_predicate::BlockPredicate;
|
||||||
use crate::generation::block_state_provider::BlockStateProvider;
|
use crate::generation::block_state_provider::BlockStateProvider;
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub struct VegetationPatchFeature {
|
pub struct VegetationPatchFeature {
|
||||||
pub replaceable: BlockPredicate,
|
pub replaceable: BlockPredicate,
|
||||||
@ -41,7 +41,7 @@ impl VegetationPatchFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
min_y: i8,
|
min_y: i8,
|
||||||
height: u16,
|
height: u16,
|
||||||
feature_name: &str,
|
feature_name: &str,
|
||||||
@ -79,7 +79,7 @@ impl VegetationPatchFeature {
|
|||||||
pub(crate) fn place_ground_patch<T: GenerationCache>(
|
pub(crate) fn place_ground_patch<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
origin: BlockPos,
|
origin: BlockPos,
|
||||||
replaceable: &BlockPredicate,
|
replaceable: &BlockPredicate,
|
||||||
@ -166,7 +166,7 @@ impl VegetationPatchFeature {
|
|||||||
fn place_ground<T: GenerationCache>(
|
fn place_ground<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
replaceable: &BlockPredicate,
|
replaceable: &BlockPredicate,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
mut below_pos: BlockPos,
|
mut below_pos: BlockPos,
|
||||||
@ -196,7 +196,7 @@ impl VegetationPatchFeature {
|
|||||||
pub(crate) fn distribute_vegetation<T: GenerationCache>(
|
pub(crate) fn distribute_vegetation<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
min_y: i8,
|
min_y: i8,
|
||||||
height: u16,
|
height: u16,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use pumpkin_data::{Block, BlockDirection, BlockState, block_properties::BlockPro
|
|||||||
use pumpkin_util::{math::position::BlockPos, random::RandomGenerator};
|
use pumpkin_util::{math::position::BlockPos, random::RandomGenerator};
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
pub struct VinesFeature;
|
pub struct VinesFeature;
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ impl VinesFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
_min_y: i8,
|
_min_y: i8,
|
||||||
_height: u16,
|
_height: u16,
|
||||||
_feature: &str,
|
_feature: &str,
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
use pumpkin_data::BlockDirection;
|
use pumpkin_data::BlockDirection;
|
||||||
|
|
||||||
use super::vegetation_patch::VegetationPatchFeature;
|
use super::vegetation_patch::VegetationPatchFeature;
|
||||||
@ -20,7 +20,7 @@ impl WaterloggedVegetationPatchFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
min_y: i8,
|
min_y: i8,
|
||||||
height: u16,
|
height: u16,
|
||||||
feature_name: &str,
|
feature_name: &str,
|
||||||
@ -64,7 +64,7 @@ impl WaterloggedVegetationPatchFeature {
|
|||||||
fn place_ground_patch<T: GenerationCache>(
|
fn place_ground_patch<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
origin: BlockPos,
|
origin: BlockPos,
|
||||||
replaceable: &crate::generation::block_predicate::BlockPredicate,
|
replaceable: &crate::generation::block_predicate::BlockPredicate,
|
||||||
@ -98,7 +98,7 @@ impl WaterloggedVegetationPatchFeature {
|
|||||||
fn place_vegetation<T: GenerationCache>(
|
fn place_vegetation<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
min_y: i8,
|
min_y: i8,
|
||||||
height: u16,
|
height: u16,
|
||||||
feature_name: &str,
|
feature_name: &str,
|
||||||
|
|||||||
@ -15,7 +15,7 @@ use crate::block::RawBlockState;
|
|||||||
use crate::generation::block_predicate::BlockPredicate;
|
use crate::generation::block_predicate::BlockPredicate;
|
||||||
use crate::generation::height_provider::HeightProvider;
|
use crate::generation::height_provider::HeightProvider;
|
||||||
use crate::generation::proto_chunk::GenerationCache;
|
use crate::generation::proto_chunk::GenerationCache;
|
||||||
use crate::world::BlockRegistryExt;
|
use crate::world::WorldPortalExt;
|
||||||
|
|
||||||
use super::configured_features::{CONFIGURED_FEATURES, ConfiguredFeature};
|
use super::configured_features::{CONFIGURED_FEATURES, ConfiguredFeature};
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ impl PlacedFeature {
|
|||||||
pub fn generate<T: GenerationCache>(
|
pub fn generate<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &mut T,
|
chunk: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
min_y: i8,
|
min_y: i8,
|
||||||
height: u16,
|
height: u16,
|
||||||
feature_name: &str, // This placed feature
|
feature_name: &str, // This placed feature
|
||||||
@ -129,7 +129,7 @@ impl PlacementModifier {
|
|||||||
pub fn get_positions<T: GenerationCache>(
|
pub fn get_positions<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
min_y: i8,
|
min_y: i8,
|
||||||
height: u16,
|
height: u16,
|
||||||
feature: &str,
|
feature: &str,
|
||||||
@ -213,7 +213,7 @@ impl EnvironmentScanPlacementModifier {
|
|||||||
pub fn get_positions<T: GenerationCache>(
|
pub fn get_positions<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
) -> Box<dyn Iterator<Item = BlockPos>> {
|
) -> Box<dyn Iterator<Item = BlockPos>> {
|
||||||
let allowed_search_condition = self
|
let allowed_search_condition = self
|
||||||
@ -339,7 +339,7 @@ pub struct BlockFilterPlacementModifier {
|
|||||||
impl ConditionalPlacementModifier for BlockFilterPlacementModifier {
|
impl ConditionalPlacementModifier for BlockFilterPlacementModifier {
|
||||||
fn should_place<T: GenerationCache>(
|
fn should_place<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
_feature: &str,
|
_feature: &str,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
_random: &mut RandomGenerator,
|
_random: &mut RandomGenerator,
|
||||||
@ -358,7 +358,7 @@ pub struct SurfaceThresholdFilterPlacementModifier {
|
|||||||
impl ConditionalPlacementModifier for SurfaceThresholdFilterPlacementModifier {
|
impl ConditionalPlacementModifier for SurfaceThresholdFilterPlacementModifier {
|
||||||
fn should_place<T: GenerationCache>(
|
fn should_place<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
_feature: &str,
|
_feature: &str,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
_random: &mut RandomGenerator,
|
_random: &mut RandomGenerator,
|
||||||
@ -378,7 +378,7 @@ pub struct RarityFilterPlacementModifier {
|
|||||||
impl ConditionalPlacementModifier for RarityFilterPlacementModifier {
|
impl ConditionalPlacementModifier for RarityFilterPlacementModifier {
|
||||||
fn should_place<T: GenerationCache>(
|
fn should_place<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
_feature: &str,
|
_feature: &str,
|
||||||
_chunk: &T,
|
_chunk: &T,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
@ -418,7 +418,7 @@ pub struct SurfaceWaterDepthFilterPlacementModifier {
|
|||||||
impl ConditionalPlacementModifier for SurfaceWaterDepthFilterPlacementModifier {
|
impl ConditionalPlacementModifier for SurfaceWaterDepthFilterPlacementModifier {
|
||||||
fn should_place<T: GenerationCache>(
|
fn should_place<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
_feature: &str,
|
_feature: &str,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
_random: &mut RandomGenerator,
|
_random: &mut RandomGenerator,
|
||||||
@ -435,7 +435,7 @@ pub struct BiomePlacementModifier;
|
|||||||
impl ConditionalPlacementModifier for BiomePlacementModifier {
|
impl ConditionalPlacementModifier for BiomePlacementModifier {
|
||||||
fn should_place<T: GenerationCache>(
|
fn should_place<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
_block_registry: &dyn BlockRegistryExt,
|
_block_registry: &dyn WorldPortalExt,
|
||||||
this_feature: &str,
|
this_feature: &str,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
_random: &mut RandomGenerator,
|
_random: &mut RandomGenerator,
|
||||||
@ -510,7 +510,7 @@ pub trait CountPlacementModifierBase {
|
|||||||
pub trait ConditionalPlacementModifier {
|
pub trait ConditionalPlacementModifier {
|
||||||
fn get_positions<T: GenerationCache>(
|
fn get_positions<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
feature: &str,
|
feature: &str,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
@ -525,7 +525,7 @@ pub trait ConditionalPlacementModifier {
|
|||||||
|
|
||||||
fn should_place<T: GenerationCache>(
|
fn should_place<T: GenerationCache>(
|
||||||
&self,
|
&self,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
feature: &str,
|
feature: &str,
|
||||||
chunk: &T,
|
chunk: &T,
|
||||||
random: &mut RandomGenerator,
|
random: &mut RandomGenerator,
|
||||||
|
|||||||
@ -42,6 +42,7 @@ use crate::generation::noise::perlin::DoublePerlinNoiseSampler;
|
|||||||
use crate::generation::noise::router::multi_noise_sampler::MultiNoiseSamplerBuilderOptions;
|
use crate::generation::noise::router::multi_noise_sampler::MultiNoiseSamplerBuilderOptions;
|
||||||
use crate::generation::noise::router::surface_height_sampler::SurfaceHeightSamplerBuilderOptions;
|
use crate::generation::noise::router::surface_height_sampler::SurfaceHeightSamplerBuilderOptions;
|
||||||
use crate::generation::noise::{CHUNK_DIM, ChunkNoiseGenerator, LAVA_BLOCK, WATER_BLOCK};
|
use crate::generation::noise::{CHUNK_DIM, ChunkNoiseGenerator, LAVA_BLOCK, WATER_BLOCK};
|
||||||
|
use crate::generation::section_coords::section_to_block;
|
||||||
use crate::generation::structure::lazily_generate_structure;
|
use crate::generation::structure::lazily_generate_structure;
|
||||||
use crate::generation::structure::placement::should_generate_structure;
|
use crate::generation::structure::placement::should_generate_structure;
|
||||||
use crate::generation::structure::structures::{
|
use crate::generation::structure::structures::{
|
||||||
@ -54,7 +55,7 @@ use crate::{
|
|||||||
block::RawBlockState,
|
block::RawBlockState,
|
||||||
chunk::CHUNK_AREA,
|
chunk::CHUNK_AREA,
|
||||||
generation::{biome, positions::chunk_pos},
|
generation::{biome, positions::chunk_pos},
|
||||||
world::{BlockAccessor, BlockRegistryExt},
|
world::{BlockAccessor, WorldPortalExt},
|
||||||
};
|
};
|
||||||
use pumpkin_data::tag::get_tag_ids;
|
use pumpkin_data::tag::get_tag_ids;
|
||||||
use pumpkin_nbt::compound::NbtCompound;
|
use pumpkin_nbt::compound::NbtCompound;
|
||||||
@ -777,6 +778,23 @@ impl ProtoChunk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn spawn_mobs<T: GenerationCache>(cache: &mut T, block_registry: &dyn WorldPortalExt) {
|
||||||
|
let chunk = cache.get_center_chunk();
|
||||||
|
debug_assert_eq!(chunk.stage, StagedChunkEnum::Lighting);
|
||||||
|
|
||||||
|
let biome = chunk.get_terrain_gen_biome(
|
||||||
|
section_to_block(chunk.x),
|
||||||
|
chunk.bottom_y() as i32 + chunk.height() as i32 - 1,
|
||||||
|
section_to_block(chunk.z),
|
||||||
|
);
|
||||||
|
let x = chunk.x;
|
||||||
|
let z = chunk.z;
|
||||||
|
|
||||||
|
block_registry.spawn_mobs_for_chunk_generation(cache, biome, x, z);
|
||||||
|
|
||||||
|
cache.get_center_chunk_mut().stage = StagedChunkEnum::Spawn;
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_terrain_gen_biome_id(&self, x: i32, y: i32, z: i32) -> u8 {
|
pub fn get_terrain_gen_biome_id(&self, x: i32, y: i32, z: i32) -> u8 {
|
||||||
// TODO: See if we can cache this value
|
// TODO: See if we can cache this value
|
||||||
@ -943,7 +961,7 @@ impl ProtoChunk {
|
|||||||
/// 2. Then, using the second file, we determine **how** to generate the feature.
|
/// 2. Then, using the second file, we determine **how** to generate the feature.
|
||||||
pub fn generate_features_and_structure<T: GenerationCache>(
|
pub fn generate_features_and_structure<T: GenerationCache>(
|
||||||
cache: &mut T,
|
cache: &mut T,
|
||||||
block_registry: &dyn BlockRegistryExt,
|
block_registry: &dyn WorldPortalExt,
|
||||||
random_config: &GlobalRandomConfig,
|
random_config: &GlobalRandomConfig,
|
||||||
) {
|
) {
|
||||||
let (center_x, center_z, min_y, height, biomes_in_chunk) = {
|
let (center_x, center_z, min_y, height, biomes_in_chunk) = {
|
||||||
|
|||||||
@ -14,8 +14,9 @@ use crate::{
|
|||||||
},
|
},
|
||||||
generation::get_world_gen,
|
generation::get_world_gen,
|
||||||
tick::{OrderedTick, ScheduledTick, TickPriority},
|
tick::{OrderedTick, ScheduledTick, TickPriority},
|
||||||
world::BlockRegistryExt,
|
world::WorldPortalExt,
|
||||||
};
|
};
|
||||||
|
use arc_swap::ArcSwap;
|
||||||
use dashmap::{DashMap, Entry};
|
use dashmap::{DashMap, Entry};
|
||||||
use pumpkin_config::{chunk::ChunkConfig, lighting::LightingEngineConfig, world::LevelConfig};
|
use pumpkin_config::{chunk::ChunkConfig, lighting::LightingEngineConfig, world::LevelConfig};
|
||||||
use pumpkin_data::biome::Biome;
|
use pumpkin_data::biome::Biome;
|
||||||
@ -24,14 +25,11 @@ use pumpkin_data::{Block, block_properties::has_random_ticks, fluid::Fluid};
|
|||||||
use pumpkin_util::math::{position::BlockPos, vector2::Vector2};
|
use pumpkin_util::math::{position::BlockPos, vector2::Vector2};
|
||||||
use pumpkin_util::world_seed::Seed;
|
use pumpkin_util::world_seed::Seed;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use std::sync::Mutex;
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{
|
use std::{
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
sync::{
|
sync::atomic::{AtomicBool, AtomicU64, Ordering},
|
||||||
Arc,
|
|
||||||
atomic::{AtomicBool, AtomicU64, Ordering},
|
|
||||||
},
|
|
||||||
thread,
|
thread,
|
||||||
};
|
};
|
||||||
use tokio::time::timeout;
|
use tokio::time::timeout;
|
||||||
@ -62,7 +60,7 @@ pub type SyncEntityChunk = Arc<ChunkEntityData>;
|
|||||||
/// For more details on world generation, refer to the `WorldGenerator` module.
|
/// For more details on world generation, refer to the `WorldGenerator` module.
|
||||||
pub struct Level {
|
pub struct Level {
|
||||||
pub seed: Seed,
|
pub seed: Seed,
|
||||||
pub block_registry: Arc<dyn BlockRegistryExt>,
|
pub world_portal: ArcSwap<Option<Arc<dyn WorldPortalExt>>>,
|
||||||
pub level_folder: LevelFolder,
|
pub level_folder: LevelFolder,
|
||||||
pub lighting_config: LightingEngineConfig,
|
pub lighting_config: LightingEngineConfig,
|
||||||
|
|
||||||
@ -143,7 +141,6 @@ impl Level {
|
|||||||
pub fn from_root_folder(
|
pub fn from_root_folder(
|
||||||
level_config: &LevelConfig,
|
level_config: &LevelConfig,
|
||||||
root_folder: PathBuf,
|
root_folder: PathBuf,
|
||||||
block_registry: Arc<dyn BlockRegistryExt>,
|
|
||||||
seed: i64,
|
seed: i64,
|
||||||
dimension: Dimension,
|
dimension: Dimension,
|
||||||
gen_pool: Option<Arc<rayon::ThreadPool>>,
|
gen_pool: Option<Arc<rayon::ThreadPool>>,
|
||||||
@ -187,7 +184,7 @@ impl Level {
|
|||||||
|
|
||||||
let level_ref = Arc::new(Self {
|
let level_ref = Arc::new(Self {
|
||||||
seed,
|
seed,
|
||||||
block_registry,
|
world_portal: ArcSwap::new(Arc::new(None)),
|
||||||
world_gen,
|
world_gen,
|
||||||
level_folder,
|
level_folder,
|
||||||
lighting_config: level_config.lighting,
|
lighting_config: level_config.lighting,
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
|
||||||
use crate::BlockStateId;
|
use crate::{BlockStateId, generation::proto_chunk::GenerationCache};
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use pumpkin_data::{Block, BlockState};
|
use pumpkin_data::{Block, BlockState, chunk::Biome};
|
||||||
use pumpkin_util::math::position::BlockPos;
|
use pumpkin_util::math::position::BlockPos;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ impl std::fmt::Display for GetBlockError {
|
|||||||
|
|
||||||
pub type WorldFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
|
pub type WorldFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
|
||||||
|
|
||||||
pub trait BlockRegistryExt: Send + Sync {
|
pub trait WorldPortalExt: Send + Sync {
|
||||||
fn can_place_at(
|
fn can_place_at(
|
||||||
&self,
|
&self,
|
||||||
block: &Block,
|
block: &Block,
|
||||||
@ -63,6 +63,14 @@ pub trait BlockRegistryExt: Send + Sync {
|
|||||||
block_accessor: &dyn BlockAccessor,
|
block_accessor: &dyn BlockAccessor,
|
||||||
block_pos: &BlockPos,
|
block_pos: &BlockPos,
|
||||||
) -> bool;
|
) -> bool;
|
||||||
|
|
||||||
|
fn spawn_mobs_for_chunk_generation(
|
||||||
|
&self,
|
||||||
|
cache: &mut dyn GenerationCache,
|
||||||
|
biome: &'static Biome,
|
||||||
|
chunk_x: i32,
|
||||||
|
chunk_z: i32,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait BlockAccessor: Send + Sync {
|
pub trait BlockAccessor: Send + Sync {
|
||||||
|
|||||||
@ -139,7 +139,7 @@ use pumpkin_protocol::java::server::play::SUseItemOn;
|
|||||||
use pumpkin_util::math::boundingbox::BoundingBox;
|
use pumpkin_util::math::boundingbox::BoundingBox;
|
||||||
use pumpkin_util::math::position::BlockPos;
|
use pumpkin_util::math::position::BlockPos;
|
||||||
use pumpkin_world::BlockStateId;
|
use pumpkin_world::BlockStateId;
|
||||||
use pumpkin_world::world::{BlockAccessor, BlockFlags, BlockRegistryExt};
|
use pumpkin_world::world::{BlockAccessor, BlockFlags};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
@ -372,31 +372,6 @@ pub struct BlockRegistry {
|
|||||||
fluids: FxHashMap<u16, Arc<dyn FluidBehaviour>>,
|
fluids: FxHashMap<u16, Arc<dyn FluidBehaviour>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockRegistryExt for BlockRegistry {
|
|
||||||
fn can_place_at(
|
|
||||||
&self,
|
|
||||||
block: &pumpkin_data::Block,
|
|
||||||
state: &BlockState,
|
|
||||||
block_accessor: &dyn BlockAccessor,
|
|
||||||
block_pos: &BlockPos,
|
|
||||||
) -> bool {
|
|
||||||
futures::executor::block_on(async move {
|
|
||||||
self.can_place_at(
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
block_accessor,
|
|
||||||
None,
|
|
||||||
block,
|
|
||||||
state,
|
|
||||||
block_pos,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BlockRegistry {
|
impl BlockRegistry {
|
||||||
pub fn register<T: BlockBehaviour + BlockMetadata + 'static>(&mut self, block: T) {
|
pub fn register<T: BlockBehaviour + BlockMetadata + 'static>(&mut self, block: T) {
|
||||||
let ids = T::ids();
|
let ids = T::ids();
|
||||||
|
|||||||
@ -11,6 +11,7 @@ use crate::plugin::PluginManager;
|
|||||||
use crate::plugin::player::player_login::PlayerLoginEvent;
|
use crate::plugin::player::player_login::PlayerLoginEvent;
|
||||||
use crate::plugin::server::server_broadcast::ServerBroadcastEvent;
|
use crate::plugin::server::server_broadcast::ServerBroadcastEvent;
|
||||||
use crate::server::tick_rate_manager::ServerTickRateManager;
|
use crate::server::tick_rate_manager::ServerTickRateManager;
|
||||||
|
use crate::world::WorldPortal;
|
||||||
use crate::world::custom_bossbar::CustomBossbars;
|
use crate::world::custom_bossbar::CustomBossbars;
|
||||||
use crate::{
|
use crate::{
|
||||||
command::node::dispatcher::CommandDispatcher, entity::player::Player, world::World,
|
command::node::dispatcher::CommandDispatcher, entity::player::Player, world::World,
|
||||||
@ -25,6 +26,7 @@ use pumpkin_data::entity::EntityType;
|
|||||||
use pumpkin_util::permission::{PermissionManager, PermissionRegistry};
|
use pumpkin_util::permission::{PermissionManager, PermissionRegistry};
|
||||||
use pumpkin_util::text::color::NamedColor;
|
use pumpkin_util::text::color::NamedColor;
|
||||||
use pumpkin_world::dimension::into_level;
|
use pumpkin_world::dimension::into_level;
|
||||||
|
use pumpkin_world::world::WorldPortalExt;
|
||||||
use tracing::{debug, error, info, warn};
|
use tracing::{debug, error, info, warn};
|
||||||
|
|
||||||
use crate::command::CommandSender;
|
use crate::command::CommandSender;
|
||||||
@ -284,13 +286,14 @@ impl Server {
|
|||||||
.color_named(NamedColor::DarkGreen)
|
.color_named(NamedColor::DarkGreen)
|
||||||
.to_pretty_console()
|
.to_pretty_console()
|
||||||
);
|
);
|
||||||
World::load(
|
let level = into_level(dim, &config, path, seed, Some(pool));
|
||||||
into_level(dim, &config, path, registry.clone(), seed, Some(pool)),
|
let world = Arc::new(World::load(level.clone(), l_info, dim, registry, weak));
|
||||||
l_info,
|
let portal: Arc<dyn WorldPortalExt> = Arc::new(WorldPortal(
|
||||||
dim,
|
world.clone(),
|
||||||
registry,
|
tokio::runtime::Handle::current(),
|
||||||
weak,
|
));
|
||||||
)
|
level.world_portal.store(Arc::new(Some(portal)));
|
||||||
|
world
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -303,9 +306,9 @@ impl Server {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let worlds_vec = vec![
|
let worlds_vec = vec![
|
||||||
Arc::new(overworld.expect("Overworld panicked")),
|
overworld.expect("Overworld panicked"),
|
||||||
Arc::new(nether.expect("Nether panicked")),
|
nether.expect("Nether panicked"),
|
||||||
Arc::new(end.expect("End panicked")),
|
end.expect("End panicked"),
|
||||||
];
|
];
|
||||||
server.worlds.store(Arc::new(worlds_vec));
|
server.worlds.store(Arc::new(worlds_vec));
|
||||||
if let Ok(k) = keys {
|
if let Ok(k) = keys {
|
||||||
@ -380,27 +383,21 @@ impl Server {
|
|||||||
let seed = server.level_info.load().world_gen_settings.seed;
|
let seed = server.level_info.load().world_gen_settings.seed;
|
||||||
|
|
||||||
// TODO: gen_pool should be reused
|
// TODO: gen_pool should be reused
|
||||||
let world = World::load(
|
let level =
|
||||||
pumpkin_world::dimension::into_level(
|
pumpkin_world::dimension::into_level(dimension, &config, world_path, seed, None);
|
||||||
dimension,
|
let world: World = World::load(level.clone(), l_info, dimension, registry, weak);
|
||||||
&config,
|
let world = Arc::new(world);
|
||||||
world_path,
|
let portal: Arc<dyn WorldPortalExt> = Arc::new(WorldPortal(
|
||||||
registry.clone(),
|
world.clone(),
|
||||||
seed,
|
tokio::runtime::Handle::current(),
|
||||||
None,
|
));
|
||||||
),
|
level.world_portal.store(Arc::new(Some(portal)));
|
||||||
l_info,
|
|
||||||
dimension,
|
|
||||||
registry,
|
|
||||||
weak,
|
|
||||||
);
|
|
||||||
let world_arc = Arc::new(world);
|
|
||||||
server.worlds.rcu(|worlds| {
|
server.worlds.rcu(|worlds| {
|
||||||
let mut new_worlds = (**worlds).clone();
|
let mut new_worlds = (**worlds).clone();
|
||||||
new_worlds.push(world_arc.clone());
|
new_worlds.push(world.clone());
|
||||||
new_worlds
|
new_worlds
|
||||||
});
|
});
|
||||||
world_arc
|
world
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.expect("World creation panicked")
|
.expect("World creation panicked")
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
use crate::block::entities::BlockEntity;
|
use crate::block::entities::BlockEntity;
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
|
use pumpkin_data::chunk::Biome;
|
||||||
use pumpkin_protocol::bedrock::client::level_event::{CLevelEvent, LevelEvent};
|
use pumpkin_protocol::bedrock::client::level_event::{CLevelEvent, LevelEvent};
|
||||||
use pumpkin_protocol::codec::data_component::data_to_proto_sound;
|
use pumpkin_protocol::codec::data_component::data_to_proto_sound;
|
||||||
|
use pumpkin_world::generation::proto_chunk::GenerationCache;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::sync::atomic::Ordering::Relaxed;
|
use std::sync::atomic::Ordering::Relaxed;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
@ -9,6 +11,7 @@ use std::{
|
|||||||
collections::{BTreeMap, HashMap},
|
collections::{BTreeMap, HashMap},
|
||||||
sync::atomic::Ordering,
|
sync::atomic::Ordering,
|
||||||
};
|
};
|
||||||
|
use tokio::runtime::Handle;
|
||||||
use tracing::{debug, error, info, trace, warn};
|
use tracing::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
pub mod chunker;
|
pub mod chunker;
|
||||||
@ -121,7 +124,7 @@ use pumpkin_util::{
|
|||||||
random::{RandomImpl, get_seed, xoroshiro128::Xoroshiro},
|
random::{RandomImpl, get_seed, xoroshiro128::Xoroshiro},
|
||||||
};
|
};
|
||||||
use pumpkin_world::inventory::Clearable;
|
use pumpkin_world::inventory::Clearable;
|
||||||
use pumpkin_world::world::GetBlockError;
|
use pumpkin_world::world::{GetBlockError, WorldPortalExt};
|
||||||
use pumpkin_world::{
|
use pumpkin_world::{
|
||||||
BlockStateId, CURRENT_BEDROCK_MC_VERSION, biome, chunk::io::Dirtiable, inventory::Inventory,
|
BlockStateId, CURRENT_BEDROCK_MC_VERSION, biome, chunk::io::Dirtiable, inventory::Inventory,
|
||||||
};
|
};
|
||||||
@ -3187,12 +3190,7 @@ impl World {
|
|||||||
pub async fn add_entity_silent(&self, entity: Arc<dyn EntityBase>) {
|
pub async fn add_entity_silent(&self, entity: Arc<dyn EntityBase>) {
|
||||||
let base_entity = entity.get_entity();
|
let base_entity = entity.get_entity();
|
||||||
|
|
||||||
// Update biome
|
|
||||||
let block_pos = base_entity.block_pos.load();
|
let block_pos = base_entity.block_pos.load();
|
||||||
let biome = self.level.get_rough_biome(&block_pos).await;
|
|
||||||
base_entity.current_biome.store(Arc::new(biome));
|
|
||||||
base_entity.last_biome_update_pos.store(block_pos);
|
|
||||||
|
|
||||||
let chunk_coordinate = block_pos.chunk_position();
|
let chunk_coordinate = block_pos.chunk_position();
|
||||||
let mut nbt = PNbtCompound::new();
|
let mut nbt = PNbtCompound::new();
|
||||||
entity.write_nbt(&mut nbt).await;
|
entity.write_nbt(&mut nbt).await;
|
||||||
@ -4303,3 +4301,52 @@ impl BlockAccessor for World {
|
|||||||
Box::pin(async move { self.get_block_and_state(position).await })
|
Box::pin(async move { self.get_block_and_state(position).await })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct WorldPortal(pub Arc<World>, pub Handle);
|
||||||
|
|
||||||
|
// Pure Beauty :cap:
|
||||||
|
impl WorldPortalExt for WorldPortal {
|
||||||
|
fn can_place_at(
|
||||||
|
&self,
|
||||||
|
block: &pumpkin_data::Block,
|
||||||
|
state: &BlockState,
|
||||||
|
block_accessor: &dyn BlockAccessor,
|
||||||
|
block_pos: &BlockPos,
|
||||||
|
) -> bool {
|
||||||
|
let handle = &self.1;
|
||||||
|
|
||||||
|
handle.block_on(async move {
|
||||||
|
self.0
|
||||||
|
.block_registry
|
||||||
|
.can_place_at(
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
block_accessor,
|
||||||
|
None,
|
||||||
|
block,
|
||||||
|
state,
|
||||||
|
block_pos,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn_mobs_for_chunk_generation(
|
||||||
|
&self,
|
||||||
|
cache: &mut dyn GenerationCache,
|
||||||
|
biome: &'static Biome,
|
||||||
|
chunk_x: i32,
|
||||||
|
chunk_z: i32,
|
||||||
|
) {
|
||||||
|
let handle = &self.1;
|
||||||
|
|
||||||
|
handle.block_on(async move {
|
||||||
|
natural_spawner::spawn_mobs_for_chunk_generation(
|
||||||
|
&self.0, cache, biome, chunk_x, chunk_z,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use crate::entity::r#type::from_type;
|
|||||||
use crate::world::World;
|
use crate::world::World;
|
||||||
use arc_swap::ArcSwap;
|
use arc_swap::ArcSwap;
|
||||||
use pumpkin_data::biome::Spawner;
|
use pumpkin_data::biome::Spawner;
|
||||||
|
use pumpkin_data::chunk::Biome;
|
||||||
use pumpkin_data::entity::{EntityType, MobCategory, SpawnLocation};
|
use pumpkin_data::entity::{EntityType, MobCategory, SpawnLocation};
|
||||||
use pumpkin_data::tag::Block::MINECRAFT_PREVENT_MOB_SPAWNING_INSIDE;
|
use pumpkin_data::tag::Block::MINECRAFT_PREVENT_MOB_SPAWNING_INSIDE;
|
||||||
use pumpkin_data::tag::Fluid::{MINECRAFT_LAVA, MINECRAFT_WATER};
|
use pumpkin_data::tag::Fluid::{MINECRAFT_LAVA, MINECRAFT_WATER};
|
||||||
@ -20,6 +21,7 @@ use pumpkin_util::random::xoroshiro128::Xoroshiro;
|
|||||||
use pumpkin_util::random::{RandomImpl, get_seed};
|
use pumpkin_util::random::{RandomImpl, get_seed};
|
||||||
use pumpkin_world::chunk::io::Dirtiable;
|
use pumpkin_world::chunk::io::Dirtiable;
|
||||||
use pumpkin_world::chunk::{ChunkData, ChunkHeightmapType};
|
use pumpkin_world::chunk::{ChunkData, ChunkHeightmapType};
|
||||||
|
use pumpkin_world::generation::proto_chunk::GenerationCache;
|
||||||
use rand::seq::IndexedRandom;
|
use rand::seq::IndexedRandom;
|
||||||
use rand::{RngExt, rng};
|
use rand::{RngExt, rng};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -503,6 +505,126 @@ pub fn get_random_pos_within(
|
|||||||
BlockPos::new(x, y, z)
|
BlockPos::new(x, y, z)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn spawn_mobs_for_chunk_generation(
|
||||||
|
world: &Arc<World>,
|
||||||
|
cache: &mut dyn GenerationCache,
|
||||||
|
biome: &'static Biome,
|
||||||
|
chunk_x: i32,
|
||||||
|
chunk_z: i32,
|
||||||
|
) {
|
||||||
|
let mob_settings = &biome.spawners;
|
||||||
|
let creatures = &mob_settings.creature;
|
||||||
|
|
||||||
|
if creatures.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let xo = chunk_x << 4;
|
||||||
|
let zo = chunk_z << 4;
|
||||||
|
|
||||||
|
while rand::random::<f32>() < biome.creature_spawn_probability {
|
||||||
|
let Some(spawner_data) = creatures.choose(&mut rand::rng()) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let count = spawner_data.min_count
|
||||||
|
+ rand::random_range(0..(1 + spawner_data.max_count - spawner_data.min_count).max(1));
|
||||||
|
let entity_type = EntityType::from_name(
|
||||||
|
spawner_data
|
||||||
|
.r#type
|
||||||
|
.strip_prefix("minecraft:")
|
||||||
|
.unwrap_or(spawner_data.r#type),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut x = xo + rand::random_range(0..16);
|
||||||
|
let mut z = zo + rand::random_range(0..16);
|
||||||
|
let start_x = x;
|
||||||
|
let start_z = z;
|
||||||
|
|
||||||
|
for _ in 0..count {
|
||||||
|
let mut success = false;
|
||||||
|
|
||||||
|
// Try 4 times to find a valid spot in the immediate area
|
||||||
|
for _ in 0..4 {
|
||||||
|
if success {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pos = get_top_non_colliding_pos(world, cache, entity_type, x, z);
|
||||||
|
|
||||||
|
if is_spawn_position_ok_cache(cache, &pos, entity_type) {
|
||||||
|
let spawn_pos_f64 = Vector3::new(
|
||||||
|
f64::from(pos.0.x) + 0.5,
|
||||||
|
f64::from(pos.0.y),
|
||||||
|
f64::from(pos.0.z) + 0.5,
|
||||||
|
);
|
||||||
|
|
||||||
|
let entity = from_type(entity_type, spawn_pos_f64, world, Uuid::new_v4()).await;
|
||||||
|
entity
|
||||||
|
.get_entity()
|
||||||
|
.set_rotation(rand::random::<f32>() * 360., 0.);
|
||||||
|
world.spawn_entity(entity).await;
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Random jitter for the next mob in the group
|
||||||
|
x += rand::random_range(0..5) - rand::random_range(0..5);
|
||||||
|
z += rand::random_range(0..5) - rand::random_range(0..5);
|
||||||
|
|
||||||
|
// Keep group within the chunk bounds
|
||||||
|
if x < xo || x >= xo + 16 || z < zo || z >= zo + 16 {
|
||||||
|
x = start_x;
|
||||||
|
z = start_z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_top_non_colliding_pos(
|
||||||
|
world: &World,
|
||||||
|
cache: &dyn GenerationCache,
|
||||||
|
entity_type: &'static EntityType,
|
||||||
|
x: i32,
|
||||||
|
z: i32,
|
||||||
|
) -> BlockPos {
|
||||||
|
let mut y = cache.get_top_y(&entity_type.spawn_restriction.heightmap, x, z);
|
||||||
|
let mut pos_vec = Vector3::new(x, y, z);
|
||||||
|
let min_y = world.min_y;
|
||||||
|
|
||||||
|
if world.dimension.has_ceiling {
|
||||||
|
loop {
|
||||||
|
y -= 1;
|
||||||
|
pos_vec.y = y;
|
||||||
|
// Use UFCS to avoid the ambiguity error from earlier
|
||||||
|
if GenerationCache::get_block_state(cache, &pos_vec)
|
||||||
|
.to_state()
|
||||||
|
.is_air()
|
||||||
|
|| y <= min_y
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loop {
|
||||||
|
y -= 1;
|
||||||
|
pos_vec.y = y;
|
||||||
|
if !GenerationCache::get_block_state(cache, &pos_vec)
|
||||||
|
.to_state()
|
||||||
|
.is_air()
|
||||||
|
|| y <= min_y
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let pos = BlockPos::new(x, y, z);
|
||||||
|
|
||||||
|
adjust_spawn_position_cache(cache, pos, entity_type)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn spawn_category_for_position(
|
pub async fn spawn_category_for_position(
|
||||||
category: &'static MobCategory,
|
category: &'static MobCategory,
|
||||||
world: &Arc<World>,
|
world: &Arc<World>,
|
||||||
@ -768,6 +890,69 @@ pub async fn is_spawn_position_ok(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cache-based version of `is_spawn_position_ok` used during world generation.
|
||||||
|
pub fn is_spawn_position_ok_cache(
|
||||||
|
cache: &dyn GenerationCache,
|
||||||
|
block_pos: &BlockPos,
|
||||||
|
entity_type: &'static EntityType,
|
||||||
|
) -> bool {
|
||||||
|
let pos_vec = block_pos.0;
|
||||||
|
let state = GenerationCache::get_block_state(cache, &pos_vec).to_state();
|
||||||
|
|
||||||
|
match entity_type.spawn_restriction.location {
|
||||||
|
SpawnLocation::InLava => {
|
||||||
|
// During generation, we check the block state's liquid property and tag
|
||||||
|
state.is_liquid() && Block::from_state_id(state.id).has_tag(&MINECRAFT_LAVA)
|
||||||
|
}
|
||||||
|
SpawnLocation::InWater => {
|
||||||
|
let above_pos = block_pos.up().0;
|
||||||
|
let above_state = GenerationCache::get_block_state(cache, &above_pos).to_state();
|
||||||
|
|
||||||
|
state.is_liquid()
|
||||||
|
&& Block::from_state_id(state.id).has_tag(&MINECRAFT_WATER)
|
||||||
|
&& !above_state.is_full_cube()
|
||||||
|
}
|
||||||
|
SpawnLocation::OnGround => {
|
||||||
|
let down_pos = block_pos.down().0;
|
||||||
|
let up_pos = block_pos.up().0;
|
||||||
|
|
||||||
|
let down = GenerationCache::get_block_state(cache, &down_pos).to_state();
|
||||||
|
let up = GenerationCache::get_block_state(cache, &up_pos).to_state();
|
||||||
|
|
||||||
|
// Logic: solid surface below and low enough light level (if applicable in generation)
|
||||||
|
let is_valid_spawn_below =
|
||||||
|
down.is_side_solid(BlockDirection::Up) && down.luminance < 14;
|
||||||
|
|
||||||
|
if is_valid_spawn_below {
|
||||||
|
is_valid_empty_spawn_block(state) && is_valid_empty_spawn_block(up)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SpawnLocation::Unrestricted => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cache-based version of `adjust_spawn_position` used during world generation.
|
||||||
|
pub fn adjust_spawn_position_cache(
|
||||||
|
cache: &dyn GenerationCache,
|
||||||
|
pos: BlockPos,
|
||||||
|
entity_type: &'static EntityType,
|
||||||
|
) -> BlockPos {
|
||||||
|
if matches!(
|
||||||
|
entity_type.spawn_restriction.location,
|
||||||
|
SpawnLocation::OnGround
|
||||||
|
) {
|
||||||
|
let below = pos.down();
|
||||||
|
let state = GenerationCache::get_block_state(cache, &below.0).to_state();
|
||||||
|
|
||||||
|
if !state.is_full_cube() && !state.is_liquid() {
|
||||||
|
return below;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn adjust_spawn_position(
|
pub async fn adjust_spawn_position(
|
||||||
world: &World,
|
world: &World,
|
||||||
pos: BlockPos,
|
pos: BlockPos,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user