Refactor block default state

This commit is contained in:
Alexander Medvedev 2025-06-22 21:28:14 +02:00
parent 2e78b9fdca
commit 8ebc9ee494
74 changed files with 594 additions and 534 deletions

View File

@ -308,7 +308,7 @@ impl ToTokens for BlockPropertyStruct {
if !Self::handles_block_id(block.id) { if !Self::handles_block_id(block.id) {
panic!("{} is not a valid block for {}", &block.name, #struct_name); panic!("{} is not a valid block for {}", &block.name, #struct_name);
} }
Self::from_state_id(block.default_state_id, block) Self::from_state_id(block.default_state.id, block)
} }
#[allow(clippy::vec_init_then_push)] #[allow(clippy::vec_init_then_push)]
@ -506,15 +506,14 @@ pub struct OptimizedBlock {
pub experience: Option<Experience>, pub experience: Option<Experience>,
} }
impl ToTokens for OptimizedBlock { impl OptimizedBlock {
fn to_tokens(&self, tokens: &mut TokenStream) { fn to_tokens(&self, tokens: &mut TokenStream, all_states: &[BlockState]) {
let id = LitInt::new(&self.id.to_string(), Span::call_site()); let id = LitInt::new(&self.id.to_string(), Span::call_site());
let name = LitStr::new(&self.name, Span::call_site()); let name = LitStr::new(&self.name, Span::call_site());
let translation_key = LitStr::new(&self.translation_key, Span::call_site()); let translation_key = LitStr::new(&self.translation_key, Span::call_site());
let hardness = &self.hardness; let hardness = &self.hardness;
let blast_resistance = &self.blast_resistance; let blast_resistance = &self.blast_resistance;
let item_id = LitInt::new(&self.item_id.to_string(), Span::call_site()); let item_id = LitInt::new(&self.item_id.to_string(), Span::call_site());
let default_state_id = LitInt::new(&self.default_state_id.to_string(), Span::call_site());
let slipperiness = &self.slipperiness; let slipperiness = &self.slipperiness;
let velocity_multiplier = &self.velocity_multiplier; let velocity_multiplier = &self.velocity_multiplier;
let jump_velocity_multiplier = &self.jump_velocity_multiplier; let jump_velocity_multiplier = &self.jump_velocity_multiplier;
@ -535,6 +534,14 @@ impl ToTokens for OptimizedBlock {
None => quote! { None }, None => quote! { None },
}; };
let default_state_ref: &BlockStateRef = self
.states
.iter()
.find(|state| state.id == self.default_state_id)
.unwrap();
let mut default_state = all_states[default_state_ref.state_idx as usize].clone();
default_state.id = default_state_ref.id;
let default_state = default_state.to_tokens();
tokens.extend(quote! { tokens.extend(quote! {
Block { Block {
id: #id, id: #id,
@ -546,7 +553,7 @@ impl ToTokens for OptimizedBlock {
velocity_multiplier: #velocity_multiplier, velocity_multiplier: #velocity_multiplier,
jump_velocity_multiplier: #jump_velocity_multiplier, jump_velocity_multiplier: #jump_velocity_multiplier,
item_id: #item_id, item_id: #item_id,
default_state_id: #default_state_id, default_state: #default_state,
states: &[#(#states),*], states: &[#(#states),*],
loot_table: #loot_table, loot_table: #loot_table,
experience: #experience, experience: #experience,
@ -787,7 +794,7 @@ pub(crate) fn build() -> TokenStream {
.iter() .iter()
.map(|shape| shape.to_token_stream()); .map(|shape| shape.to_token_stream());
let unique_states = unique_states.iter().map(|state| state.to_tokens()); let unique_states_tokens = unique_states.iter().map(|state| state.to_tokens());
let block_props = block_properties.iter().map(|prop| prop.to_token_stream()); let block_props = block_properties.iter().map(|prop| prop.to_token_stream());
let properties = property_enums.values().map(|prop| prop.to_token_stream()); let properties = property_enums.values().map(|prop| prop.to_token_stream());
@ -801,7 +808,8 @@ pub(crate) fn build() -> TokenStream {
// Generate constants and `match` arms for each block. // Generate constants and `match` arms for each block.
for (name, block) in optimized_blocks { for (name, block) in optimized_blocks {
let const_ident = format_ident!("{}", const_block_name_from_block_name(&name)); let const_ident = format_ident!("{}", const_block_name_from_block_name(&name));
let block_tokens = block.to_token_stream(); let mut block_tokens = TokenStream::new();
block.to_tokens(&mut block_tokens, &unique_states);
let id_lit = LitInt::new(&block.id.to_string(), Span::call_site()); let id_lit = LitInt::new(&block.id.to_string(), Span::call_site());
let state_start = block.states.iter().map(|state| state.id).min().unwrap(); let state_start = block.states.iter().map(|state| state.id).min().unwrap();
let state_end = block.states.iter().map(|state| state.id).max().unwrap(); let state_end = block.states.iter().map(|state| state.id).max().unwrap();
@ -882,7 +890,7 @@ pub(crate) fn build() -> TokenStream {
]; ];
pub static BLOCK_STATES: &[BlockState] = &[ pub static BLOCK_STATES: &[BlockState] = &[
#(#unique_states),* #(#unique_states_tokens),*
]; ];
pub static BLOCK_ENTITY_TYPES: &[&str] = &[ pub static BLOCK_ENTITY_TYPES: &[&str] = &[
@ -924,39 +932,6 @@ pub(crate) fn build() -> TokenStream {
Block::from_item_id(item_id) Block::from_item_id(item_id)
} }
pub fn get_block_collision_shapes(state_id: u16) -> Option<Vec<CollisionShape>> {
let state = get_state_by_state_id(state_id)?;
let shapes: Vec<CollisionShape> = state.collision_shapes
.iter()
.map(|&id| COLLISION_SHAPES[id as usize])
.collect();
Some(shapes)
}
pub fn get_block_outline_shapes(state_id: u16) -> Option<Vec<CollisionShape>> {
let state = get_state_by_state_id(state_id)?;
let mut shapes: Vec<CollisionShape> = state.outline_shapes
.iter()
.map(|&id| COLLISION_SHAPES[id as usize])
.collect();
let block = get_block_by_state_id(state_id)?;
if block.properties(state.id).and_then(|properties| {
properties
.to_props()
.into_iter()
.find(|p| p.0 == "waterlogged")
.map(|(_, value)| value == true.to_string())
}) == Some(true)
{
// If the block is waterlogged, add a water shape
let shape =
&CollisionShape::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(1.0, 0.875, 1.0));
shapes.push(*shape);
}
Some(shapes)
}
pub fn blocks_movement(block_state: &BlockState) -> bool { pub fn blocks_movement(block_state: &BlockState) -> bool {
if block_state.is_solid() { if block_state.is_solid() {
if let Some(block) = get_block_by_state_id(block_state.id) { if let Some(block) = get_block_by_state_id(block_state.id) {

View File

@ -79,7 +79,7 @@ pub fn write_generated_file(content: TokenStream, out_file: &str) {
let mut file = fs::File::create(&path).unwrap(); let mut file = fs::File::create(&path).unwrap();
if let Err(e) = file.write_all(code.as_bytes()) { if let Err(e) = file.write_all(code.as_bytes()) {
println!("cargo::error={}", e); println!("cargo::error={e}");
} }
// Try to format the output for debugging purposes. // Try to format the output for debugging purposes.

View File

@ -1,5 +1,7 @@
use crate::BlockDirection; use pumpkin_util::math::vector3::Vector3;
use crate::block_properties::Instrument;
use crate::block_properties::{COLLISION_SHAPES, Instrument, get_block_by_state_id};
use crate::{Block, BlockDirection, CollisionShape};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct BlockState { pub struct BlockState {
@ -18,6 +20,12 @@ pub struct BlockState {
pub block_entity_type: u16, pub block_entity_type: u16,
} }
impl PartialEq for BlockState {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
#[repr(u8)] #[repr(u8)]
pub enum PistonBehavior { pub enum PistonBehavior {
@ -83,6 +91,41 @@ impl BlockState {
_ => unreachable!(), _ => unreachable!(),
} }
} }
pub fn block(&self) -> Block {
get_block_by_state_id(self.id).unwrap()
}
pub fn get_block_collision_shapes(&self) -> Vec<CollisionShape> {
self.collision_shapes
.iter()
.map(|&id| COLLISION_SHAPES[id as usize])
.collect()
}
pub fn get_block_outline_shapes(&self) -> Option<Vec<CollisionShape>> {
let mut shapes: Vec<CollisionShape> = self
.outline_shapes
.iter()
.map(|&id| COLLISION_SHAPES[id as usize])
.collect();
let block = get_block_by_state_id(self.id)?;
if block.properties(self.id).and_then(|properties| {
properties
.to_props()
.into_iter()
.find(|p| p.0 == "waterlogged")
.map(|(_, value)| value == true.to_string())
}) == Some(true)
{
// If the block is waterlogged, add a water shape
let shape =
&CollisionShape::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(1.0, 0.875, 1.0));
shapes.push(*shape);
}
Some(shapes)
}
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]

View File

@ -1,5 +1,6 @@
use crate::{ use crate::{
BlockStateRef, BlockState, BlockStateRef,
block_properties::get_state_by_state_id,
tag::{RegistryKey, Tagable}, tag::{RegistryKey, Tagable},
}; };
use pumpkin_util::{loot_table::LootTable, math::experience::Experience}; use pumpkin_util::{loot_table::LootTable, math::experience::Experience};
@ -15,7 +16,7 @@ pub struct Block {
pub velocity_multiplier: f32, pub velocity_multiplier: f32,
pub jump_velocity_multiplier: f32, pub jump_velocity_multiplier: f32,
pub item_id: u16, pub item_id: u16,
pub default_state_id: u16, pub default_state: BlockState,
pub states: &'static [BlockStateRef], pub states: &'static [BlockStateRef],
pub loot_table: Option<LootTable>, pub loot_table: Option<LootTable>,
pub experience: Option<Experience>, pub experience: Option<Experience>,

View File

@ -150,7 +150,7 @@ impl PlayerInventory {
&*self.get_stack(Self::OFF_HAND_SLOT).await.lock().await, &*self.get_stack(Self::OFF_HAND_SLOT).await.lock().await,
stack, stack,
) { ) {
return Self::OFF_HAND_SLOT as i16; Self::OFF_HAND_SLOT as i16
} else { } else {
for i in 0..Self::MAIN_SIZE { for i in 0..Self::MAIN_SIZE {
if self.can_stack_add_more(&*self.main_inventory[i].lock().await, stack) { if self.can_stack_add_more(&*self.main_inventory[i].lock().await, stack) {
@ -158,7 +158,7 @@ impl PlayerInventory {
} }
} }
return -1; -1
} }
} }

View File

@ -1,27 +0,0 @@
use pumpkin_data::Block;
use quote::quote;
pub(crate) fn default_block_state_impl(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input_string = item.to_string();
let registry_id = input_string.trim_matches('"');
let state = Block::from_registry_key(registry_id).expect("Invalid registry id");
let default_state_id = state.default_state_id;
if std::env::var("CARGO_PKG_NAME").unwrap() == "pumpkin-world" {
quote! {
crate::block::RawBlockState {
state_id: #default_state_id,
}
}
.into()
} else {
quote! {
pumpkin_world::block::RawBlockState {
state_id: #default_state_id,
}
}
.into()
}
}

View File

@ -352,9 +352,3 @@ pub fn block_property(input: TokenStream, item: TokenStream) -> TokenStream {
code.into() code.into()
} }
mod block_state;
#[proc_macro]
pub fn default_block_state(item: TokenStream) -> TokenStream {
block_state::default_block_state_impl(item)
}

View File

@ -361,8 +361,7 @@ impl<'de, R: Read> de::EnumAccess<'de> for &mut Deserializer<R> {
let variant_index_i32 = self.inner.get_var_int()?.0; let variant_index_i32 = self.inner.get_var_int()?.0;
let variant_index_u32: u32 = variant_index_i32.try_into().map_err(|_| { let variant_index_u32: u32 = variant_index_i32.try_into().map_err(|_| {
ReadingError::Message(format!( ReadingError::Message(format!(
"Invalid variant index {} for enum, cannot convert to u32", "Invalid variant index {variant_index_i32} for enum, cannot convert to u32"
variant_index_i32
)) ))
})?; })?;
let val = seed.deserialize(variant_index_u32.into_deserializer())?; let val = seed.deserialize(variant_index_u32.into_deserializer())?;

View File

@ -6,11 +6,7 @@ use crate::random::{RandomGenerator, RandomImpl};
pub struct Pool; pub struct Pool;
impl Pool { impl Pool {
pub fn get<E: Clone>( pub fn get<E: Clone>(distribution: &[Weighted<E>], random: &mut RandomGenerator) -> Option<E> {
&self,
distribution: &[Weighted<E>],
random: &mut RandomGenerator,
) -> Option<E> {
let mut total_weight = 0; let mut total_weight = 0;
for dist in distribution { for dist in distribution {
total_weight += dist.weight; total_weight += dist.weight;

View File

@ -172,7 +172,7 @@ impl PermissionManager {
// Check wildcard permissions at each level // Check wildcard permissions at each level
let mut current_node = namespace.to_string(); let mut current_node = namespace.to_string();
if let Some(value) = attachment.has_permission_set(&format!("{}:*", current_node)) { if let Some(value) = attachment.has_permission_set(&format!("{current_node}:*")) {
return value; return value;
} }
@ -186,7 +186,7 @@ impl PermissionManager {
if i < key_parts.len() - 1 { if i < key_parts.len() - 1 {
if let Some(value) = if let Some(value) =
attachment.has_permission_set(&format!("{}.*", current_node)) attachment.has_permission_set(&format!("{current_node}.*"))
{ {
return value; return value;
} }
@ -240,7 +240,7 @@ pub enum PermissionLvl {
impl PartialOrd for PermissionLvl { impl PartialOrd for PermissionLvl {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some((*self as u8).cmp(&(*other as u8))) Some(self.cmp(other))
} }
} }

View File

@ -39,7 +39,7 @@ impl<'de> Deserialize<'de> for Color {
let b = u8::from_str_radix(&hex[4..6], 16) let b = u8::from_str_radix(&hex[4..6], 16)
.map_err(|_| serde::de::Error::custom("Invalid blue component in hex color"))?; .map_err(|_| serde::de::Error::custom("Invalid blue component in hex color"))?;
return Ok(Color::Rgb(RGBColor::new(r, g, b))); Ok(Color::Rgb(RGBColor::new(r, g, b)))
} else { } else {
Ok(Color::Named(NamedColor::try_from(s.as_str()).map_err( Ok(Color::Named(NamedColor::try_from(s.as_str()).map_err(
|_| serde::de::Error::custom("Invalid named color"), |_| serde::de::Error::custom("Invalid named color"),

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,10 +2,7 @@ use std::sync::Arc;
use async_trait::async_trait; use async_trait::async_trait;
use crossbeam::atomic::AtomicCell; use crossbeam::atomic::AtomicCell;
use pumpkin_data::{ use pumpkin_data::{Block, BlockDirection, BlockState, block_properties::get_block_by_state_id};
Block, BlockDirection, BlockState,
block_properties::{get_block_by_state_id, get_state_by_state_id},
};
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
@ -32,7 +29,7 @@ impl PistonBlockEntity {
world.remove_block_entity(&pos).await; world.remove_block_entity(&pos).await;
if world.get_block(&pos).await == Block::MOVING_PISTON { if world.get_block(&pos).await == Block::MOVING_PISTON {
let state = if self.source { let state = if self.source {
Block::AIR.default_state_id Block::AIR.default_state.id
} else { } else {
self.pushed_block_state.id self.pushed_block_state.id
}; };
@ -109,7 +106,7 @@ impl BlockEntity for PistonBlockEntity {
Self: Sized, Self: Sized,
{ {
// TODO // TODO
let pushed_block_state = get_state_by_state_id(Block::AIR.default_state_id).unwrap(); let pushed_block_state = Block::AIR.default_state;
let facing = nbt.get_byte(FACING).unwrap_or(0); let facing = nbt.get_byte(FACING).unwrap_or(0);
let last_progress = nbt.get_float(LAST_PROGRESS).unwrap_or(0.0); let last_progress = nbt.get_float(LAST_PROGRESS).unwrap_or(0.0);
let extending = nbt.get_bool(EXTENDING).unwrap_or(false); let extending = nbt.get_bool(EXTENDING).unwrap_or(false);

View File

@ -22,24 +22,20 @@ pub struct BlockStateCodec {
impl BlockStateCodec { impl BlockStateCodec {
pub fn get_state(&self) -> Option<BlockState> { pub fn get_state(&self) -> Option<BlockState> {
let block = get_block(self.name.as_str()); let block = get_block(self.name.as_str())?;
if let Some(block) = block { let mut state_id = block.default_state.id;
let mut state_id = block.default_state_id;
if let Some(properties) = &self.properties { if let Some(properties) = &self.properties {
let mut properties_vec: Vec<(&str, &str)> = Vec::with_capacity(properties.len()); let properties_vec: Vec<(&str, &str)> = properties
for (key, value) in properties { .iter()
properties_vec.push((key, value)); .map(|(key, value)| (key.as_str(), value.as_str()))
} .collect();
let block_properties = block.from_properties(properties_vec).unwrap(); let block_properties = block.from_properties(properties_vec).unwrap();
state_id = block_properties.to_state_id(&block); state_id = block_properties.to_state_id(&block);
} }
return get_state_by_state_id(state_id); get_state_by_state_id(state_id)
}
None
} }
} }

View File

@ -4,27 +4,25 @@ use crate::BlockStateId;
/// Instead of using a memory heavy normal BlockState This is used for internal representation in chunks to save memory /// Instead of using a memory heavy normal BlockState This is used for internal representation in chunks to save memory
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct RawBlockState { pub struct RawBlockState(pub BlockStateId);
pub state_id: BlockStateId,
}
impl RawBlockState { impl RawBlockState {
pub const AIR: RawBlockState = RawBlockState { state_id: 0 }; pub const AIR: RawBlockState = RawBlockState(0);
/// Get a Block from the Vanilla Block registry at Runtime /// Get a Block from the Vanilla Block registry at Runtime
pub fn new(registry_id: &str) -> Option<Self> { pub fn new(registry_id: &str) -> Option<Self> {
let block = get_block(registry_id); let block = get_block(registry_id);
block.map(|block| Self { block.map(|block| Self(block.default_state.id))
state_id: block.default_state_id,
})
} }
#[inline]
pub fn to_state(&self) -> pumpkin_data::BlockState { pub fn to_state(&self) -> pumpkin_data::BlockState {
get_state_by_state_id(self.state_id).unwrap() get_state_by_state_id(self.0).unwrap()
} }
#[inline]
pub fn to_block(&self) -> pumpkin_data::Block { pub fn to_block(&self) -> pumpkin_data::Block {
get_block_by_state_id(self.state_id).unwrap() get_block_by_state_id(self.0).unwrap()
} }
} }

View File

@ -1,11 +1,10 @@
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use pumpkin_data::{Block, BlockState};
use pumpkin_util::{ use pumpkin_util::{
math::{clamped_map, floor_div, vector2::Vector2, vector3::Vector3}, math::{clamped_map, floor_div, vector2::Vector2, vector3::Vector3},
random::{RandomDeriver, RandomDeriverImpl, RandomImpl}, random::{RandomDeriver, RandomDeriverImpl, RandomImpl},
}; };
use crate::block::RawBlockState;
use super::{ use super::{
chunk_noise::{LAVA_BLOCK, WATER_BLOCK}, chunk_noise::{LAVA_BLOCK, WATER_BLOCK},
noise_router::{ noise_router::{
@ -22,23 +21,23 @@ use super::{
#[derive(Clone)] #[derive(Clone)]
pub struct FluidLevel { pub struct FluidLevel {
max_y: i32, max_y: i32,
state: RawBlockState, block: Block,
} }
impl FluidLevel { impl FluidLevel {
pub fn new(max_y: i32, state: RawBlockState) -> Self { pub fn new(max_y: i32, block: Block) -> Self {
Self { max_y, state } Self { max_y, block }
} }
pub fn max_y_exclusive(&self) -> i32 { pub fn max_y_exclusive(&self) -> i32 {
self.max_y self.max_y
} }
fn get_block_state(&self, y: i32) -> RawBlockState { fn get_block(&self, y: i32) -> Block {
if y < self.max_y { if y < self.max_y {
self.state self.block.clone()
} else { } else {
RawBlockState::AIR Block::AIR
} }
} }
} }
@ -51,18 +50,18 @@ pub enum FluidLevelSampler {
pub struct StaticFluidLevelSampler { pub struct StaticFluidLevelSampler {
y: i32, y: i32,
state: RawBlockState, block: Block,
} }
impl StaticFluidLevelSampler { impl StaticFluidLevelSampler {
pub fn new(y: i32, state: RawBlockState) -> Self { pub fn new(y: i32, block: Block) -> Self {
Self { y, state } Self { y, block }
} }
} }
impl FluidLevelSamplerImpl for StaticFluidLevelSampler { impl FluidLevelSamplerImpl for StaticFluidLevelSampler {
fn get_fluid_level(&self, _x: i32, _y: i32, _z: i32) -> FluidLevel { fn get_fluid_level(&self, _x: i32, _y: i32, _z: i32) -> FluidLevel {
FluidLevel::new(self.y, self.state) FluidLevel::new(self.y, self.block.clone())
} }
} }
@ -196,11 +195,11 @@ impl WorldAquiferSampler {
level_2: FluidLevel, level_2: FluidLevel,
) -> f64 { ) -> f64 {
let y = pos.y(); let y = pos.y();
let block_state1 = level_1.get_block_state(y).to_block(); let block_state1 = level_1.get_block(y);
let block_state2 = level_2.get_block_state(y).to_block(); let block_state2 = level_2.get_block(y);
if (block_state1 != LAVA_BLOCK.to_block() || block_state2 != WATER_BLOCK.to_block()) if (block_state1 != LAVA_BLOCK || block_state2 != WATER_BLOCK)
&& (block_state1 != WATER_BLOCK.to_block() || block_state2 != LAVA_BLOCK.to_block()) && (block_state1 != WATER_BLOCK || block_state2 != LAVA_BLOCK)
{ {
let level_diff = (level_1.max_y - level_2.max_y).abs(); let level_diff = (level_1.max_y - level_2.max_y).abs();
if level_diff == 0 { if level_diff == 0 {
@ -287,7 +286,7 @@ impl WorldAquiferSampler {
let bl3 = j > o; let bl3 = j > o;
if bl3 || bl2 { if bl3 || bl2 {
let fluid_level = self.fluid_level.get_fluid_level(x, o, z); let fluid_level = self.fluid_level.get_fluid_level(x, o, z);
if !fluid_level.get_block_state(o).to_state().is_air() { if !fluid_level.get_block(o).default_state.is_air() {
if bl2 { if bl2 {
bl = true; bl = true;
} }
@ -411,11 +410,8 @@ impl WorldAquiferSampler {
level: i32, level: i32,
router: &mut ChunkNoiseRouter, router: &mut ChunkNoiseRouter,
sample_options: &ChunkNoiseFunctionSampleOptions, sample_options: &ChunkNoiseFunctionSampleOptions,
) -> RawBlockState { ) -> Block {
if level <= -10 if level <= -10 && level != MIN_HEIGHT_CELL && default_level.block != LAVA_BLOCK {
&& level != MIN_HEIGHT_CELL
&& default_level.state.to_block() != LAVA_BLOCK.to_block()
{
let x = floor_div(block_x, 64); let x = floor_div(block_x, 64);
let y = floor_div(block_y, 40); let y = floor_div(block_y, 40);
let z = floor_div(block_z, 64); let z = floor_div(block_z, 64);
@ -427,7 +423,7 @@ impl WorldAquiferSampler {
} }
} }
default_level.state default_level.block
} }
fn apply_internal( fn apply_internal(
@ -437,7 +433,7 @@ impl WorldAquiferSampler {
sample_options: &ChunkNoiseFunctionSampleOptions, sample_options: &ChunkNoiseFunctionSampleOptions,
height_estimator: &mut SurfaceHeightEstimateSampler, height_estimator: &mut SurfaceHeightEstimateSampler,
density: f64, density: f64,
) -> Option<RawBlockState> { ) -> Option<BlockState> {
if density > 0f64 { if density > 0f64 {
None None
} else { } else {
@ -446,8 +442,8 @@ impl WorldAquiferSampler {
let k = pos.z(); let k = pos.z();
let fluid_level = self.fluid_level.get_fluid_level(i, j, k); let fluid_level = self.fluid_level.get_fluid_level(i, j, k);
if fluid_level.get_block_state(j).to_block() == LAVA_BLOCK.to_block() { if fluid_level.get_block(j) == LAVA_BLOCK {
Some(LAVA_BLOCK) Some(LAVA_BLOCK.default_state)
} else { } else {
let scaled_x = floor_div(i - 5, 16); let scaled_x = floor_div(i - 5, 16);
let scaled_y = floor_div(j + 1, 12); let scaled_y = floor_div(j + 1, 12);
@ -501,21 +497,20 @@ impl WorldAquiferSampler {
); );
let d = let d =
Self::max_distance(packed_block_and_hypots[0].1, packed_block_and_hypots[1].1); Self::max_distance(packed_block_and_hypots[0].1, packed_block_and_hypots[1].1);
let block_state = fluid_level2.get_block_state(j); let block_state = fluid_level2.get_block(j);
if d <= 0f64 { if d <= 0f64 {
// TODO: Handle fluid tick // TODO: Handle fluid tick
Some(block_state) Some(block_state.default_state)
} else if block_state.to_block() == WATER_BLOCK.to_block() } else if block_state == WATER_BLOCK
&& self && self
.fluid_level .fluid_level
.get_fluid_level(i, j - 1, k) .get_fluid_level(i, j - 1, k)
.get_block_state(j - 1) .get_block(j - 1)
.to_block() == LAVA_BLOCK
== LAVA_BLOCK.to_block()
{ {
Some(block_state) Some(block_state.default_state)
} else { } else {
let barrier_sample = router.barrier_noise(pos, sample_options); let barrier_sample = router.barrier_noise(pos, sample_options);
let fluid_level3 = self.get_water_level( let fluid_level3 = self.get_water_level(
@ -578,7 +573,7 @@ impl WorldAquiferSampler {
//TODO Handle fluid tick //TODO Handle fluid tick
Some(block_state) Some(block_state.default_state)
} }
} }
} }
@ -594,7 +589,7 @@ impl AquiferSamplerImpl for WorldAquiferSampler {
pos: &impl NoisePos, pos: &impl NoisePos,
sample_options: &ChunkNoiseFunctionSampleOptions, sample_options: &ChunkNoiseFunctionSampleOptions,
height_estimator: &mut SurfaceHeightEstimateSampler, height_estimator: &mut SurfaceHeightEstimateSampler,
) -> Option<RawBlockState> { ) -> Option<BlockState> {
let density = router.final_density(pos, sample_options); let density = router.final_density(pos, sample_options);
self.apply_internal(router, pos, sample_options, height_estimator, density) self.apply_internal(router, pos, sample_options, height_estimator, density)
} }
@ -617,7 +612,7 @@ impl AquiferSamplerImpl for SeaLevelAquiferSampler {
pos: &impl NoisePos, pos: &impl NoisePos,
sample_options: &ChunkNoiseFunctionSampleOptions, sample_options: &ChunkNoiseFunctionSampleOptions,
_height_estimator: &mut SurfaceHeightEstimateSampler, _height_estimator: &mut SurfaceHeightEstimateSampler,
) -> Option<RawBlockState> { ) -> Option<BlockState> {
let sample = router.final_density(pos, sample_options); let sample = router.final_density(pos, sample_options);
//log::debug!("Aquifer sample {:?}: {}", &pos, sample); //log::debug!("Aquifer sample {:?}: {}", &pos, sample);
if sample > 0f64 { if sample > 0f64 {
@ -626,7 +621,8 @@ impl AquiferSamplerImpl for SeaLevelAquiferSampler {
Some( Some(
self.level_sampler self.level_sampler
.get_fluid_level(pos.x(), pos.y(), pos.z()) .get_fluid_level(pos.x(), pos.y(), pos.z())
.get_block_state(pos.y()), .get_block(pos.y())
.default_state,
) )
} }
} }
@ -640,7 +636,7 @@ pub trait AquiferSamplerImpl {
pos: &impl NoisePos, pos: &impl NoisePos,
sample_options: &ChunkNoiseFunctionSampleOptions, sample_options: &ChunkNoiseFunctionSampleOptions,
height_estimator: &mut SurfaceHeightEstimateSampler, height_estimator: &mut SurfaceHeightEstimateSampler,
) -> Option<RawBlockState>; ) -> Option<BlockState>;
} }
#[cfg(test)] #[cfg(test)]
@ -728,7 +724,7 @@ mod test {
BlockStateSampler::Aquifer(aquifer) => aquifer, BlockStateSampler::Aquifer(aquifer) => aquifer,
_ => unreachable!(), _ => unreachable!(),
}; };
let aquifer = match sampler { let aquifer = match *sampler {
AquiferSampler::Aquifer(aquifer) => aquifer, AquiferSampler::Aquifer(aquifer) => aquifer,
_ => unreachable!(), _ => unreachable!(),
}; };
@ -1445,7 +1441,7 @@ mod test {
for ((x, y, z), (y1, state)) in values { for ((x, y, z), (y1, state)) in values {
let level = aquifer.get_fluid_level(x, y, z, &mut router, &mut height_estimator, &env); let level = aquifer.get_fluid_level(x, y, z, &mut router, &mut height_estimator, &env);
assert_eq!(level.max_y, y1); assert_eq!(level.max_y, y1);
assert_eq!(level.state, state); assert_eq!(level.block, state);
} }
} }
@ -1720,8 +1716,14 @@ mod test {
((114, -20, 70, 0.11121282163190734), None), ((114, -20, 70, 0.11121282163190734), None),
((114, -20, 72, 0.11433776346079558), None), ((114, -20, 72, 0.11433776346079558), None),
((114, -20, 74, 0.11770444723497474), None), ((114, -20, 74, 0.11770444723497474), None),
((114, 0, 64, -0.0026209759846139574), Some(WATER_BLOCK)), (
((114, 0, 66, -0.0011869543056835608), Some(WATER_BLOCK)), (114, 0, 64, -0.0026209759846139574),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(114, 0, 66, -0.0011869543056835608),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
((114, 0, 68, 3.9347454816496854E-4), None), ((114, 0, 68, 3.9347454816496854E-4), None),
((114, 0, 70, 0.002068623223791626), None), ((114, 0, 70, 0.002068623223791626), None),
((114, 0, 72, 0.0038193250297024243), None), ((114, 0, 72, 0.0038193250297024243), None),
@ -1807,9 +1809,18 @@ mod test {
((116, -20, 70, 0.11589560860382501), None), ((116, -20, 70, 0.11589560860382501), None),
((116, -20, 72, 0.11889599517563405), None), ((116, -20, 72, 0.11889599517563405), None),
((116, -20, 74, 0.12214992807094607), None), ((116, -20, 74, 0.12214992807094607), None),
((116, 0, 64, -0.003764380972543319), Some(WATER_BLOCK)), (
((116, 0, 66, -0.002339168705169207), Some(WATER_BLOCK)), (116, 0, 64, -0.003764380972543319),
((116, 0, 68, -7.530784033722614E-4), Some(WATER_BLOCK)), Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(116, 0, 66, -0.002339168705169207),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(116, 0, 68, -7.530784033722614E-4),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
((116, 0, 70, 9.517226455286942E-4), None), ((116, 0, 70, 9.517226455286942E-4), None),
((116, 0, 72, 0.0027605740566328273), None), ((116, 0, 72, 0.0027605740566328273), None),
((116, 0, 74, 0.0046712919320928475), None), ((116, 0, 74, 0.0046712919320928475), None),
@ -1906,10 +1917,22 @@ mod test {
((118, -20, 70, 0.12038440430256446), None), ((118, -20, 70, 0.12038440430256446), None),
((118, -20, 72, 0.12325317705242089), None), ((118, -20, 72, 0.12325317705242089), None),
((118, -20, 74, 0.12637678353248477), None), ((118, -20, 74, 0.12637678353248477), None),
((118, 0, 64, -0.00501589634392619), Some(WATER_BLOCK)), (
((118, 0, 66, -0.003601631485605401), Some(WATER_BLOCK)), (118, 0, 64, -0.00501589634392619),
((118, 0, 68, -0.0020166185756455924), Some(WATER_BLOCK)), Some(RawBlockState(WATER_BLOCK.default_state.id)),
((118, 0, 70, -2.901294172670075E-4), Some(WATER_BLOCK)), ),
(
(118, 0, 66, -0.003601631485605401),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(118, 0, 68, -0.0020166185756455924),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(118, 0, 70, -2.901294172670075E-4),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
((118, 0, 72, 0.0015704124446037308), None), ((118, 0, 72, 0.0015704124446037308), None),
((118, 0, 74, 0.0035605198020311826), None), ((118, 0, 74, 0.0035605198020311826), None),
((118, 20, 64, 0.040232966220497414), None), ((118, 20, 64, 0.040232966220497414), None),
@ -2017,10 +2040,22 @@ mod test {
((120, -20, 70, 0.12469970986670785), None), ((120, -20, 70, 0.12469970986670785), None),
((120, -20, 72, 0.1274266324562779), None), ((120, -20, 72, 0.1274266324562779), None),
((120, -20, 74, 0.13039812171785095), None), ((120, -20, 74, 0.13039812171785095), None),
((120, 0, 64, -0.006329576321547214), Some(WATER_BLOCK)), (
((120, 0, 66, -0.004930192503238298), Some(WATER_BLOCK)), (120, 0, 64, -0.006329576321547214),
((120, 0, 68, -0.003355964670343278), Some(WATER_BLOCK)), Some(RawBlockState(WATER_BLOCK.default_state.id)),
((120, 0, 70, -0.0016206542469077872), Some(WATER_BLOCK)), ),
(
(120, 0, 66, -0.004930192503238298),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(120, 0, 68, -0.003355964670343278),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(120, 0, 70, -0.0016206542469077872),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
((120, 0, 72, 2.77535008128212E-4), None), ((120, 0, 72, 2.77535008128212E-4), None),
((120, 0, 74, 0.002332419553726638), None), ((120, 0, 74, 0.002332419553726638), None),
((120, 20, 64, 0.04783863627983937), None), ((120, 20, 64, 0.04783863627983937), None),
@ -2050,12 +2085,30 @@ mod test {
(120, 40, 74, -0.013001583733654043), (120, 40, 74, -0.013001583733654043),
Some(RawBlockState::AIR), Some(RawBlockState::AIR),
), ),
((120, 60, 64, -0.010805185122555435), Some(WATER_BLOCK)), (
((120, 60, 66, -0.011684313707812422), Some(WATER_BLOCK)), (120, 60, 64, -0.010805185122555435),
((120, 60, 68, -0.007705484690135335), Some(WATER_BLOCK)), Some(RawBlockState(WATER_BLOCK.default_state.id)),
((120, 60, 70, -0.012326309226980426), Some(WATER_BLOCK)), ),
((120, 60, 72, -0.019043795741958334), Some(WATER_BLOCK)), (
((120, 60, 74, -0.023185441889689514), Some(WATER_BLOCK)), (120, 60, 66, -0.011684313707812422),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(120, 60, 68, -0.007705484690135335),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(120, 60, 70, -0.012326309226980426),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(120, 60, 72, -0.019043795741958334),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(120, 60, 74, -0.023185441889689514),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
((120, 80, 64, -0.3611328625547435), Some(RawBlockState::AIR)), ((120, 80, 64, -0.3611328625547435), Some(RawBlockState::AIR)),
((120, 80, 66, -0.3586517592327399), Some(RawBlockState::AIR)), ((120, 80, 66, -0.3586517592327399), Some(RawBlockState::AIR)),
((120, 80, 68, -0.3524534485283812), Some(RawBlockState::AIR)), ((120, 80, 68, -0.3524534485283812), Some(RawBlockState::AIR)),
@ -2122,11 +2175,26 @@ mod test {
((122, -20, 70, 0.12884021810202248), None), ((122, -20, 70, 0.12884021810202248), None),
((122, -20, 72, 0.13141636494496137), None), ((122, -20, 72, 0.13141636494496137), None),
((122, -20, 74, 0.13421609155559988), None), ((122, -20, 74, 0.13421609155559988), None),
((122, 0, 64, -0.007667256303541582), Some(WATER_BLOCK)), (
((122, 0, 66, -0.006288822820341533), Some(WATER_BLOCK)), (122, 0, 64, -0.007667256303541582),
((122, 0, 68, -0.004737470102527975), Some(WATER_BLOCK)), Some(RawBlockState(WATER_BLOCK.default_state.id)),
((122, 0, 70, -0.0030099389619020873), Some(WATER_BLOCK)), ),
((122, 0, 72, -0.0010942861750551764), Some(WATER_BLOCK)), (
(122, 0, 66, -0.006288822820341533),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(122, 0, 68, -0.004737470102527975),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(122, 0, 70, -0.0030099389619020873),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(122, 0, 72, -0.0010942861750551764),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
((122, 0, 74, 0.001001992078975999), None), ((122, 0, 74, 0.001001992078975999), None),
((122, 20, 64, 0.05535892661135848), None), ((122, 20, 64, 0.05535892661135848), None),
((122, 20, 66, 0.05444413322973901), None), ((122, 20, 66, 0.05444413322973901), None),
@ -2152,12 +2220,30 @@ mod test {
Some(RawBlockState::AIR), Some(RawBlockState::AIR),
), ),
((122, 40, 74, -0.02133677750482264), None), ((122, 40, 74, -0.02133677750482264), None),
((122, 60, 64, -0.02580014098083049), Some(WATER_BLOCK)), (
((122, 60, 66, -0.027410062228040422), Some(WATER_BLOCK)), (122, 60, 64, -0.02580014098083049),
((122, 60, 68, -0.02425659570836858), Some(WATER_BLOCK)), Some(RawBlockState(WATER_BLOCK.default_state.id)),
((122, 60, 70, -0.03261718168256943), Some(WATER_BLOCK)), ),
((122, 60, 72, -0.04369665936638442), Some(WATER_BLOCK)), (
((122, 60, 74, -0.04490159197647781), Some(WATER_BLOCK)), (122, 60, 66, -0.027410062228040422),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(122, 60, 68, -0.02425659570836858),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(122, 60, 70, -0.03261718168256943),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(122, 60, 72, -0.04369665936638442),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(122, 60, 74, -0.04490159197647781),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
( (
(122, 80, 64, -0.37247525946547166), (122, 80, 64, -0.37247525946547166),
Some(RawBlockState::AIR), Some(RawBlockState::AIR),
@ -2224,11 +2310,26 @@ mod test {
((124, -20, 70, 0.1327707947453995), None), ((124, -20, 70, 0.1327707947453995), None),
((124, -20, 72, 0.13519345838131658), None), ((124, -20, 72, 0.13519345838131658), None),
((124, -20, 74, 0.13781110986582973), None), ((124, -20, 74, 0.13781110986582973), None),
((124, 0, 64, -0.009009809178163559), Some(WATER_BLOCK)), (
((124, 0, 66, -0.007660237459532607), Some(WATER_BLOCK)), (124, 0, 64, -0.009009809178163559),
((124, 0, 68, -0.0061446463166489424), Some(WATER_BLOCK)), Some(RawBlockState(WATER_BLOCK.default_state.id)),
((124, 0, 70, -0.004442459854201204), Some(WATER_BLOCK)), ),
((124, 0, 72, -0.0025318494505197223), Some(WATER_BLOCK)), (
(124, 0, 66, -0.007660237459532607),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(124, 0, 68, -0.0061446463166489424),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(124, 0, 70, -0.004442459854201204),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(124, 0, 72, -0.0025318494505197223),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
((124, 0, 74, -4.216225767843497E-4), None), ((124, 0, 74, -4.216225767843497E-4), None),
((124, 20, 64, 0.06277697412858188), None), ((124, 20, 64, 0.06277697412858188), None),
((124, 20, 66, 0.06182400117210263), None), ((124, 20, 66, 0.06182400117210263), None),
@ -2239,15 +2340,42 @@ mod test {
((124, 40, 64, -0.004596793013348681), None), ((124, 40, 64, -0.004596793013348681), None),
((124, 40, 66, -0.007881293688553023), None), ((124, 40, 66, -0.007881293688553023), None),
((124, 40, 68, -0.010851313478373932), None), ((124, 40, 68, -0.010851313478373932), None),
((124, 40, 70, -0.013513605008223933), Some(WATER_BLOCK)), (
((124, 40, 72, -0.015880866729427373), Some(WATER_BLOCK)), (124, 40, 70, -0.013513605008223933),
((124, 40, 74, -0.017978317799117856), Some(WATER_BLOCK)), Some(RawBlockState(WATER_BLOCK.default_state.id)),
((124, 60, 64, -0.033729060298063454), Some(WATER_BLOCK)), ),
((124, 60, 66, -0.04062740064249005), Some(WATER_BLOCK)), (
((124, 60, 68, -0.03660634922712756), Some(WATER_BLOCK)), (124, 40, 72, -0.015880866729427373),
((124, 60, 70, -0.04106936165998065), Some(WATER_BLOCK)), Some(RawBlockState(WATER_BLOCK.default_state.id)),
((124, 60, 72, -0.048715160337165046), Some(WATER_BLOCK)), ),
((124, 60, 74, -0.053817378732386144), Some(WATER_BLOCK)), (
(124, 40, 74, -0.017978317799117856),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(124, 60, 64, -0.033729060298063454),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(124, 60, 66, -0.04062740064249005),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(124, 60, 68, -0.03660634922712756),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(124, 60, 70, -0.04106936165998065),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(124, 60, 72, -0.048715160337165046),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(124, 60, 74, -0.053817378732386144),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
((124, 80, 64, -0.378513110274629), Some(RawBlockState::AIR)), ((124, 80, 64, -0.378513110274629), Some(RawBlockState::AIR)),
( (
(124, 80, 66, -0.37887533037235366), (124, 80, 66, -0.37887533037235366),
@ -2317,12 +2445,30 @@ mod test {
((126, -20, 70, 0.13641807828631622), None), ((126, -20, 70, 0.13641807828631622), None),
((126, -20, 72, 0.13869641277763253), None), ((126, -20, 72, 0.13869641277763253), None),
((126, -20, 74, 0.1411390651002113), None), ((126, -20, 74, 0.1411390651002113), None),
((126, 0, 64, -0.010355206926252296), Some(WATER_BLOCK)), (
((126, 0, 66, -0.009043874021560911), Some(WATER_BLOCK)), (126, 0, 64, -0.010355206926252296),
((126, 0, 68, -0.007576245457331987), Some(WATER_BLOCK)), Some(RawBlockState(WATER_BLOCK.default_state.id)),
((126, 0, 70, -0.005915269354878528), Some(WATER_BLOCK)), ),
((126, 0, 72, -0.0040306175772153365), Some(WATER_BLOCK)), (
((126, 0, 74, -0.0019328609472880898), Some(WATER_BLOCK)), (126, 0, 66, -0.009043874021560911),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(126, 0, 68, -0.007576245457331987),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(126, 0, 70, -0.005915269354878528),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(126, 0, 72, -0.0040306175772153365),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(126, 0, 74, -0.0019328609472880898),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
((126, 20, 64, 0.0700499260773044), None), ((126, 20, 64, 0.0700499260773044), None),
((126, 20, 66, 0.06908003164862005), None), ((126, 20, 66, 0.06908003164862005), None),
((126, 20, 68, 0.0681425614589177), None), ((126, 20, 68, 0.0681425614589177), None),
@ -2331,16 +2477,46 @@ mod test {
((126, 20, 74, 0.06551116407146489), None), ((126, 20, 74, 0.06551116407146489), None),
((126, 40, 64, 0.004497597038868666), None), ((126, 40, 64, 0.004497597038868666), None),
((126, 40, 66, 0.0013502912778844962), None), ((126, 40, 66, 0.0013502912778844962), None),
((126, 40, 68, -0.0015191728313191184), Some(WATER_BLOCK)), (
((126, 40, 70, -0.0041188588354404134), Some(WATER_BLOCK)), (126, 40, 68, -0.0015191728313191184),
((126, 40, 72, -0.006463772144671846), Some(WATER_BLOCK)), Some(RawBlockState(WATER_BLOCK.default_state.id)),
((126, 40, 74, -0.008581034519921562), Some(WATER_BLOCK)), ),
((126, 60, 64, -0.03471424652823008), Some(WATER_BLOCK)), (
((126, 60, 66, -0.04732045558891548), Some(WATER_BLOCK)), (126, 40, 70, -0.0041188588354404134),
((126, 60, 68, -0.04568337003176991), Some(WATER_BLOCK)), Some(RawBlockState(WATER_BLOCK.default_state.id)),
((126, 60, 70, -0.0428377824231183), Some(WATER_BLOCK)), ),
((126, 60, 72, -0.04738820166968918), Some(WATER_BLOCK)), (
((126, 60, 74, -0.05663750895047857), Some(WATER_BLOCK)), (126, 40, 72, -0.006463772144671846),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(126, 40, 74, -0.008581034519921562),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(126, 60, 64, -0.03471424652823008),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(126, 60, 66, -0.04732045558891548),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(126, 60, 68, -0.04568337003176991),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(126, 60, 70, -0.0428377824231183),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(126, 60, 72, -0.04738820166968918),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(126, 60, 74, -0.05663750895047857),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
( (
(126, 80, 64, -0.37931742687180287), (126, 80, 64, -0.37931742687180287),
Some(RawBlockState::AIR), Some(RawBlockState::AIR),
@ -2386,7 +2562,7 @@ mod test {
let pos = UnblendedNoisePos::new(x, y, z); let pos = UnblendedNoisePos::new(x, y, z);
assert_eq!( assert_eq!(
aquifer.apply_internal(&mut router, &pos, &env, &mut height_estimator, sample), aquifer.apply_internal(&mut router, &pos, &env, &mut height_estimator, sample),
result result.map(|r| r.to_state())
); );
} }
} }

View File

@ -131,7 +131,7 @@ pub struct WeightedBlockStateProvider {
impl WeightedBlockStateProvider { impl WeightedBlockStateProvider {
pub fn get(&self, random: &mut RandomGenerator) -> BlockState { pub fn get(&self, random: &mut RandomGenerator) -> BlockState {
Pool.get(&self.entries, random) Pool::get(&self.entries, random)
.unwrap() .unwrap()
.get_state() .get_state()
.unwrap() .unwrap()

View File

@ -1,7 +1,7 @@
use pumpkin_macros::default_block_state; use pumpkin_data::{Block, BlockState};
use pumpkin_util::math::{floor_div, floor_mod, vector2::Vector2, vector3::Vector3}; use pumpkin_util::math::{floor_div, floor_mod, vector2::Vector2, vector3::Vector3};
use crate::{block::RawBlockState, generation::section_coords}; use crate::generation::section_coords;
use super::{ use super::{
GlobalRandomConfig, GlobalRandomConfig,
@ -24,13 +24,13 @@ use super::{
settings::GenerationShapeConfig, settings::GenerationShapeConfig,
}; };
pub const LAVA_BLOCK: RawBlockState = default_block_state!("lava"); pub const LAVA_BLOCK: Block = Block::LAVA;
pub const WATER_BLOCK: RawBlockState = default_block_state!("water"); pub const WATER_BLOCK: Block = Block::WATER;
pub const CHUNK_DIM: u8 = 16; pub const CHUNK_DIM: u8 = 16;
pub enum BlockStateSampler { pub enum BlockStateSampler {
Aquifer(AquiferSampler), Aquifer(Box<AquiferSampler>),
Ore(OreVeinSampler), Ore(OreVeinSampler),
Chained(ChainedBlockStateSampler), Chained(ChainedBlockStateSampler),
} }
@ -42,7 +42,7 @@ impl BlockStateSampler {
pos: &impl NoisePos, pos: &impl NoisePos,
sample_options: &ChunkNoiseFunctionSampleOptions, sample_options: &ChunkNoiseFunctionSampleOptions,
height_estimator: &mut SurfaceHeightEstimateSampler, height_estimator: &mut SurfaceHeightEstimateSampler,
) -> Option<RawBlockState> { ) -> Option<BlockState> {
match self { match self {
Self::Aquifer(aquifer) => aquifer.apply(router, pos, sample_options, height_estimator), Self::Aquifer(aquifer) => aquifer.apply(router, pos, sample_options, height_estimator),
Self::Ore(ore) => ore.sample(router, pos, sample_options), Self::Ore(ore) => ore.sample(router, pos, sample_options),
@ -66,7 +66,7 @@ impl ChainedBlockStateSampler {
pos: &impl NoisePos, pos: &impl NoisePos,
sample_options: &ChunkNoiseFunctionSampleOptions, sample_options: &ChunkNoiseFunctionSampleOptions,
height_estimator: &mut SurfaceHeightEstimateSampler, height_estimator: &mut SurfaceHeightEstimateSampler,
) -> Option<RawBlockState> { ) -> Option<BlockState> {
self.samplers self.samplers
.iter_mut() .iter_mut()
.map(|sampler| sampler.sample(router, pos, sample_options, height_estimator)) .map(|sampler| sampler.sample(router, pos, sample_options, height_estimator))
@ -221,7 +221,7 @@ impl<'a> ChunkNoiseGenerator<'a> {
AquiferSampler::SeaLevel(SeaLevelAquiferSampler::new(level_sampler)) AquiferSampler::SeaLevel(SeaLevelAquiferSampler::new(level_sampler))
}; };
let mut samplers = vec![BlockStateSampler::Aquifer(aquifer_sampler)]; let mut samplers = vec![BlockStateSampler::Aquifer(Box::new(aquifer_sampler))];
if ore_veins { if ore_veins {
let ore_sampler = OreVeinSampler::new(random_config.ore_random_deriver.clone()); let ore_sampler = OreVeinSampler::new(random_config.ore_random_deriver.clone());
@ -370,7 +370,7 @@ impl<'a> ChunkNoiseGenerator<'a> {
start_pos: Vector3<i32>, start_pos: Vector3<i32>,
cell_pos: Vector3<i32>, cell_pos: Vector3<i32>,
height_estimator: &mut SurfaceHeightEstimateSampler, height_estimator: &mut SurfaceHeightEstimateSampler,
) -> Option<RawBlockState> { ) -> Option<BlockState> {
//TODO: Fix this when Blender is added //TODO: Fix this when Blender is added
let pos = UnblendedNoisePos::new( let pos = UnblendedNoisePos::new(
start_pos.x + cell_pos.x, start_pos.x + cell_pos.x,

View File

@ -50,15 +50,12 @@ impl BambooFeature {
if !block.to_block().is_tagged_with("minecraft:dirt").unwrap() { if !block.to_block().is_tagged_with("minecraft:dirt").unwrap() {
continue; continue;
} }
chunk.set_block_state( chunk.set_block_state(&block_below.0, &Block::PODZOL.default_state);
&block_below.0,
&get_state_by_state_id(Block::PODZOL.id).unwrap(),
);
} }
} }
} }
let mut bpos = pos; let mut bpos = pos;
let bamboo = get_state_by_state_id(Block::BAMBOO.default_state_id).unwrap(); let bamboo = Block::BAMBOO.default_state;
for _ in 0..height { for _ in 0..height {
if chunk.is_air(&bpos.0) { if chunk.is_air(&bpos.0) {
chunk.set_block_state(&bpos.0, &bamboo); chunk.set_block_state(&bpos.0, &bamboo);

View File

@ -57,7 +57,7 @@ impl CoralFeature {
} }
let wall_coral = Self::get_random_tag_entry_block("minecraft:wall_corals", random); let wall_coral = Self::get_random_tag_entry_block("minecraft:wall_corals", random);
let original_props = &wall_coral let original_props = &wall_coral
.properties(wall_coral.default_state_id) .properties(wall_coral.default_state.id)
.unwrap() .unwrap()
.to_props(); .to_props();
let facing = dir.to_facing(); let facing = dir.to_facing();
@ -89,7 +89,7 @@ impl CoralFeature {
pub fn get_random_tag_entry(tag: &str, random: &mut RandomGenerator) -> BlockState { pub fn get_random_tag_entry(tag: &str, random: &mut RandomGenerator) -> BlockState {
let block = Self::get_random_tag_entry_block(tag, random); let block = Self::get_random_tag_entry_block(tag, random);
get_state_by_state_id(block.default_state_id).unwrap() block.default_state
} }
pub fn get_random_tag_entry_block(tag: &str, random: &mut RandomGenerator) -> Block { pub fn get_random_tag_entry_block(tag: &str, random: &mut RandomGenerator) -> Block {

View File

@ -1,5 +1,4 @@
use pumpkin_data::BlockDirection; use pumpkin_data::{Block, BlockDirection};
use pumpkin_macros::default_block_state;
use pumpkin_util::{ use pumpkin_util::{
math::{position::BlockPos, vector3::Vector3}, math::{position::BlockPos, vector3::Vector3},
random::RandomGenerator, random::RandomGenerator,
@ -8,7 +7,6 @@ use serde::Deserialize;
use crate::{ use crate::{
ProtoChunk, ProtoChunk,
block::RawBlockState,
generation::{chunk_noise::WATER_BLOCK, height_limit::HeightLimitView}, generation::{chunk_noise::WATER_BLOCK, height_limit::HeightLimitView},
}; };
@ -18,10 +16,10 @@ use crate::{
pub struct DesertWellFeature; pub struct DesertWellFeature;
impl DesertWellFeature { impl DesertWellFeature {
const CAN_GENERATE: RawBlockState = default_block_state!("sand"); const CAN_GENERATE: Block = Block::SAND;
const SAND: RawBlockState = default_block_state!("sand"); const SAND: Block = Block::SAND;
const SLAB: RawBlockState = default_block_state!("sandstone_slab"); const SLAB: Block = Block::SANDSTONE_SLAB;
const WALL: RawBlockState = default_block_state!("sandstone"); const WALL: Block = Block::SANDSTONE;
pub fn generate( pub fn generate(
&self, &self,
@ -37,8 +35,8 @@ impl DesertWellFeature {
block_pos = block_pos.down(); block_pos = block_pos.down();
} }
let block = chunk.get_block_state(&pos.0).to_block(); let block = chunk.get_block_state(&pos.0).to_block();
const CAN_GENERATE: RawBlockState = default_block_state!("sand"); const CAN_GENERATE: Block = Block::SAND;
if CAN_GENERATE.to_block().id != block.id { if CAN_GENERATE.id != block.id {
return false; return false;
} }
@ -58,28 +56,28 @@ impl DesertWellFeature {
for k in -2..=2 { for k in -2..=2 {
chunk.set_block_state( chunk.set_block_state(
&block_pos.0.add(&Vector3::new(j2, i, k)), &block_pos.0.add(&Vector3::new(j2, i, k)),
&Self::WALL.to_state(), &Self::WALL.default_state,
); );
} }
} }
} }
chunk.set_block_state(&block_pos.0, &WATER_BLOCK.to_state()); chunk.set_block_state(&block_pos.0, &WATER_BLOCK.default_state);
for direction in BlockDirection::horizontal().iter() { for direction in BlockDirection::horizontal().iter() {
chunk.set_block_state( chunk.set_block_state(
&block_pos.0.add(&direction.to_offset()), &block_pos.0.add(&direction.to_offset()),
&WATER_BLOCK.to_state(), &WATER_BLOCK.default_state,
); );
} }
let block_pos2 = &block_pos.0.add(&Vector3::new(0, -1, 0)); let block_pos2 = &block_pos.0.add(&Vector3::new(0, -1, 0));
chunk.set_block_state(block_pos2, &Self::SAND.to_state()); chunk.set_block_state(block_pos2, &Self::SAND.default_state);
for direction2 in BlockDirection::horizontal().iter() { for direction2 in BlockDirection::horizontal().iter() {
chunk.set_block_state( chunk.set_block_state(
&block_pos2.add(&direction2.to_offset()), &block_pos2.add(&direction2.to_offset()),
&Self::SAND.to_state(), &Self::SAND.default_state,
); );
} }
@ -90,26 +88,26 @@ impl DesertWellFeature {
} }
chunk.set_block_state( chunk.set_block_state(
&block_pos.0.add(&Vector3::new(j, 1, k)), &block_pos.0.add(&Vector3::new(j, 1, k)),
&Self::WALL.to_state(), &Self::WALL.default_state,
); );
} }
} }
chunk.set_block_state( chunk.set_block_state(
&block_pos.0.add(&Vector3::new(2, 1, 0)), &block_pos.0.add(&Vector3::new(2, 1, 0)),
&Self::SLAB.to_state(), &Self::SLAB.default_state,
); );
chunk.set_block_state( chunk.set_block_state(
&block_pos.0.add(&Vector3::new(-2, 1, 0)), &block_pos.0.add(&Vector3::new(-2, 1, 0)),
&Self::SLAB.to_state(), &Self::SLAB.default_state,
); );
chunk.set_block_state( chunk.set_block_state(
&block_pos.0.add(&Vector3::new(0, 1, 2)), &block_pos.0.add(&Vector3::new(0, 1, 2)),
&Self::SLAB.to_state(), &Self::SLAB.default_state,
); );
chunk.set_block_state( chunk.set_block_state(
&block_pos.0.add(&Vector3::new(0, 1, -2)), &block_pos.0.add(&Vector3::new(0, 1, -2)),
&Self::SLAB.to_state(), &Self::SLAB.default_state,
); );
for j in -1..=1 { for j in -1..=1 {
@ -117,13 +115,13 @@ impl DesertWellFeature {
if j == 0 && k == 0 { if j == 0 && k == 0 {
chunk.set_block_state( chunk.set_block_state(
&block_pos.0.add(&Vector3::new(j, 4, k)), &block_pos.0.add(&Vector3::new(j, 4, k)),
&Self::WALL.to_state(), &Self::WALL.default_state,
); );
continue; continue;
} }
chunk.set_block_state( chunk.set_block_state(
&block_pos.0.add(&Vector3::new(j, 4, k)), &block_pos.0.add(&Vector3::new(j, 4, k)),
&Self::SLAB.to_state(), &Self::SLAB.default_state,
); );
} }
} }
@ -131,19 +129,19 @@ impl DesertWellFeature {
for j in 1..=3 { for j in 1..=3 {
chunk.set_block_state( chunk.set_block_state(
&block_pos.0.add(&Vector3::new(-1, j, -1)), &block_pos.0.add(&Vector3::new(-1, j, -1)),
&Self::WALL.to_state(), &Self::WALL.default_state,
); );
chunk.set_block_state( chunk.set_block_state(
&block_pos.0.add(&Vector3::new(-1, j, 1)), &block_pos.0.add(&Vector3::new(-1, j, 1)),
&Self::WALL.to_state(), &Self::WALL.default_state,
); );
chunk.set_block_state( chunk.set_block_state(
&block_pos.0.add(&Vector3::new(1, j, -1)), &block_pos.0.add(&Vector3::new(1, j, -1)),
&Self::WALL.to_state(), &Self::WALL.default_state,
); );
chunk.set_block_state( chunk.set_block_state(
&block_pos.0.add(&Vector3::new(1, j, 1)), &block_pos.0.add(&Vector3::new(1, j, 1)),
&Self::WALL.to_state(), &Self::WALL.default_state,
); );
} }

View File

@ -1,4 +1,4 @@
use pumpkin_data::{Block, block_properties::get_state_by_state_id, tag::Tagable}; use pumpkin_data::{Block, tag::Tagable};
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use crate::ProtoChunk; use crate::ProtoChunk;
@ -20,10 +20,7 @@ pub(super) fn gen_dripstone(chunk: &mut ProtoChunk, pos: BlockPos) -> bool {
.is_tagged_with("minecraft:dripstone_replaceable_blocks") .is_tagged_with("minecraft:dripstone_replaceable_blocks")
.unwrap() .unwrap()
{ {
chunk.set_block_state( chunk.set_block_state(&pos.0, &Block::DRIPSTONE_BLOCK.default_state);
&pos.0,
&get_state_by_state_id(Block::DRIPSTONE_BLOCK.default_state_id).unwrap(),
);
return true; return true;
} }
false false

View File

@ -1,4 +1,4 @@
use pumpkin_data::{Block, block_properties::get_state_by_state_id}; use pumpkin_data::Block;
use pumpkin_util::{math::position::BlockPos, random::RandomGenerator}; use pumpkin_util::{math::position::BlockPos, random::RandomGenerator};
use serde::Deserialize; use serde::Deserialize;
@ -22,13 +22,12 @@ impl EndPlatformFeature {
for _ in -2..2 { for _ in -2..2 {
for _ in -2..2 { for _ in -2..2 {
for t in -1..3 { for t in -1..3 {
let block = if t == -1 { let state = if t == -1 {
Block::OBSIDIAN.default_state_id Block::OBSIDIAN.default_state
} else { } else {
Block::AIR.default_state_id Block::AIR.default_state
}; };
let state = get_state_by_state_id(block).unwrap(); if chunk.get_block_state(&pos.0).0 == state.id {
if chunk.get_block_state(&pos.0).state_id == state.id {
continue; continue;
} }
chunk.set_block_state(&pos.0, &state); chunk.set_block_state(&pos.0, &state);

View File

@ -1,4 +1,4 @@
use pumpkin_data::{Block, block_properties::get_state_by_state_id}; use pumpkin_data::Block;
use pumpkin_util::{ use pumpkin_util::{
math::position::BlockPos, math::position::BlockPos,
random::{RandomGenerator, RandomImpl}, random::{RandomGenerator, RandomImpl},
@ -98,19 +98,13 @@ impl EndSpikeFeature {
<= (radius * radius + 1) <= (radius * radius + 1)
&& pos.0.y < spike.height && pos.0.y < spike.height
{ {
chunk.set_block_state( chunk.set_block_state(&pos.0, &Block::OBSIDIAN.default_state);
&pos.0,
&get_state_by_state_id(Block::OBSIDIAN.default_state_id).unwrap(),
);
continue; continue;
} }
if pos.0.y <= 65 { if pos.0.y <= 65 {
continue; continue;
} }
chunk.set_block_state( chunk.set_block_state(&pos.0, &Block::AIR.default_state);
&pos.0,
&get_state_by_state_id(Block::AIR.default_state_id).unwrap(),
);
} }
// TODO // TODO
} }

View File

@ -38,20 +38,14 @@ impl SeagrassFeature {
if chunk.get_block_state(&tall_pos.0).to_block() == Block::WATER { if chunk.get_block_state(&tall_pos.0).to_block() == Block::WATER {
let mut props = TallSeagrassLikeProperties::default(&Block::TALL_SEAGRASS); let mut props = TallSeagrassLikeProperties::default(&Block::TALL_SEAGRASS);
props.half = DoubleBlockHalf::Upper; props.half = DoubleBlockHalf::Upper;
chunk.set_block_state( chunk.set_block_state(&top_pos.0, &Block::TALL_SEAGRASS.default_state);
&top_pos.0,
&get_state_by_state_id(Block::TALL_SEAGRASS.default_state_id).unwrap(),
);
chunk.set_block_state( chunk.set_block_state(
&tall_pos.0, &tall_pos.0,
&get_state_by_state_id(props.to_state_id(&Block::TALL_SEAGRASS)).unwrap(), &get_state_by_state_id(props.to_state_id(&Block::TALL_SEAGRASS)).unwrap(),
); );
} }
} else { } else {
chunk.set_block_state( chunk.set_block_state(&top_pos.0, &Block::SEAGRASS.default_state);
&top_pos.0,
&get_state_by_state_id(Block::SEAGRASS.default_state_id).unwrap(),
);
} }
return true; return true;
} }

View File

@ -108,7 +108,7 @@ impl WorldGenerator for VanillaGenerator {
let absolute_y = generation_settings.shape.min_y as i32 + y as i32; let absolute_y = generation_settings.shape.min_y as i32 + y as i32;
let block = let block =
proto_chunk.get_block_state(&Vector3::new(x as i32, absolute_y, z as i32)); proto_chunk.get_block_state(&Vector3::new(x as i32, absolute_y, z as i32));
sections.set_relative_block(x, y as usize, z, block.state_id); sections.set_relative_block(x, y as usize, z, block.0);
} }
} }
} }

View File

@ -1,9 +1,10 @@
use pumpkin_data::{Block, BlockState};
use pumpkin_util::{ use pumpkin_util::{
math::clamped_map, math::clamped_map,
random::{RandomDeriver, RandomDeriverImpl, RandomImpl}, random::{RandomDeriver, RandomDeriverImpl, RandomImpl},
}; };
use crate::{block::RawBlockState, generation::noise_router::chunk_noise_router::ChunkNoiseRouter}; use crate::generation::noise_router::chunk_noise_router::ChunkNoiseRouter;
use super::noise_router::{ use super::noise_router::{
chunk_density_function::ChunkNoiseFunctionSampleOptions, density_function::NoisePos, chunk_density_function::ChunkNoiseFunctionSampleOptions, density_function::NoisePos,
@ -23,7 +24,7 @@ impl OreVeinSampler {
router: &mut ChunkNoiseRouter, router: &mut ChunkNoiseRouter,
pos: &impl NoisePos, pos: &impl NoisePos,
sample_options: &ChunkNoiseFunctionSampleOptions, sample_options: &ChunkNoiseFunctionSampleOptions,
) -> Option<RawBlockState> { ) -> Option<BlockState> {
let vein_toggle = router.vein_toggle(pos, sample_options); let vein_toggle = router.vein_toggle(pos, sample_options);
let vein_type: &VeinType = if vein_toggle > 0f64 { let vein_type: &VeinType = if vein_toggle > 0f64 {
&vein_type::COPPER &vein_type::COPPER
@ -56,12 +57,12 @@ impl OreVeinSampler {
&& vein_gap > (-0.3f32 as f64) && vein_gap > (-0.3f32 as f64)
{ {
Some(if random.next_f32() < 0.02f32 { Some(if random.next_f32() < 0.02f32 {
vein_type.raw_ore vein_type.raw_ore.default_state.clone()
} else { } else {
vein_type.ore vein_type.ore.default_state.clone()
}) })
} else { } else {
Some(vein_type.stone) Some(vein_type.stone.default_state.clone())
}; };
} }
} }
@ -71,29 +72,29 @@ impl OreVeinSampler {
} }
pub struct VeinType { pub struct VeinType {
ore: RawBlockState, ore: Block,
raw_ore: RawBlockState, raw_ore: Block,
stone: RawBlockState, stone: Block,
min_y: i32, min_y: i32,
max_y: i32, max_y: i32,
} }
// One of the victims of removing compile time blocks // One of the victims of removing compile time blocks
pub mod vein_type { pub mod vein_type {
use pumpkin_macros::default_block_state; use pumpkin_data::Block;
use super::*; use super::*;
pub const COPPER: VeinType = VeinType { pub const COPPER: VeinType = VeinType {
ore: default_block_state!("copper_ore"), ore: Block::COPPER_ORE,
raw_ore: default_block_state!("raw_copper_block"), raw_ore: Block::RAW_COPPER_BLOCK,
stone: default_block_state!("granite"), stone: Block::GRANITE,
min_y: 0, min_y: 0,
max_y: 50, max_y: 50,
}; };
pub const IRON: VeinType = VeinType { pub const IRON: VeinType = VeinType {
ore: default_block_state!("deepslate_iron_ore"), ore: Block::DEEPSLATE_IRON_ORE,
raw_ore: default_block_state!("raw_iron_block"), raw_ore: Block::RAW_IRON_BLOCK,
stone: default_block_state!("tuff"), stone: Block::TUFF,
min_y: -60, min_y: -60,
max_y: -8, max_y: -8,
}; };

View File

@ -3,21 +3,18 @@ use std::sync::Arc;
use async_trait::async_trait; use async_trait::async_trait;
use pumpkin_data::{ use pumpkin_data::{
Block, BlockState, Block, BlockState,
block_properties::{ block_properties::{blocks_movement, get_block_and_state_by_state_id, get_block_by_state_id},
blocks_movement, get_block_and_state_by_state_id, get_block_by_state_id,
get_state_by_state_id,
},
chunk::Biome, chunk::Biome,
tag::Tagable, tag::Tagable,
}; };
use pumpkin_macros::default_block_state;
use pumpkin_util::{ use pumpkin_util::{
HeightMap, HeightMap,
math::{position::BlockPos, vector2::Vector2, vector3::Vector3}, math::{position::BlockPos, vector2::Vector2, vector3::Vector3},
random::{RandomGenerator, get_decorator_seed, xoroshiro128::Xoroshiro}, random::{RandomGenerator, RandomImpl, get_decorator_seed, xoroshiro128::Xoroshiro},
}; };
use crate::{ use crate::{
BlockStateId,
biome::{BiomeSupplier, MultiNoiseBiomeSupplier, end::TheEndBiomeSupplier, hash_seed}, biome::{BiomeSupplier, MultiNoiseBiomeSupplier, end::TheEndBiomeSupplier, hash_seed},
block::RawBlockState, block::RawBlockState,
chunk::CHUNK_AREA, chunk::CHUNK_AREA,
@ -47,7 +44,7 @@ use super::{
surface::{MaterialRuleContext, estimate_surface_height, terrain::SurfaceTerrainBuilder}, surface::{MaterialRuleContext, estimate_surface_height, terrain::SurfaceTerrainBuilder},
}; };
const AIR_BLOCK: RawBlockState = default_block_state!("air"); const AIR_BLOCK: Block = Block::AIR;
pub struct StandardChunkFluidLevelSampler { pub struct StandardChunkFluidLevelSampler {
top_fluid: FluidLevel, top_fluid: FluidLevel,
@ -110,12 +107,12 @@ pub struct ProtoChunk<'a> {
// TODO: These can technically go to an even higher level and we can reuse them across chunks // TODO: These can technically go to an even higher level and we can reuse them across chunks
pub multi_noise_sampler: MultiNoiseSampler<'a>, pub multi_noise_sampler: MultiNoiseSampler<'a>,
pub surface_height_estimate_sampler: SurfaceHeightEstimateSampler<'a>, pub surface_height_estimate_sampler: SurfaceHeightEstimateSampler<'a>,
pub default_block: BlockState,
random_config: &'a GlobalRandomConfig, random_config: &'a GlobalRandomConfig,
settings: &'a GenerationSettings, settings: &'a GenerationSettings,
default_block: RawBlockState,
biome_mixer_seed: i64, biome_mixer_seed: i64,
// These are local positions // These are local positions
flat_block_map: Box<[RawBlockState]>, flat_block_map: Box<[BlockStateId]>,
flat_biome_map: Box<[&'static Biome]>, flat_biome_map: Box<[&'static Biome]>,
/// HEIGHTMAPS /// HEIGHTMAPS
/// ///
@ -141,9 +138,7 @@ impl<'a> ProtoChunk<'a> {
let sampler = FluidLevelSampler::Chunk(StandardChunkFluidLevelSampler::new( let sampler = FluidLevelSampler::Chunk(StandardChunkFluidLevelSampler::new(
FluidLevel::new( FluidLevel::new(
settings.sea_level, settings.sea_level,
RawBlockState { settings.default_fluid.get_state().unwrap().block(),
state_id: settings.default_fluid.get_state().unwrap().id,
},
), ),
FluidLevel::new(-54, LAVA_BLOCK), // this is always the same for every dimension FluidLevel::new(-54, LAVA_BLOCK), // this is always the same for every dimension
)); ));
@ -190,7 +185,7 @@ impl<'a> ProtoChunk<'a> {
let surface_height_estimate_sampler = let surface_height_estimate_sampler =
SurfaceHeightEstimateSampler::generate(&base_router.surface_estimator, &surface_config); SurfaceHeightEstimateSampler::generate(&base_router.surface_estimator, &surface_config);
let default_block = RawBlockState::new(&settings.default_block.name).unwrap(); let default_block = settings.default_block.get_state().unwrap();
let default_heightmap = vec![i64::MIN; CHUNK_AREA].into_boxed_slice(); let default_heightmap = vec![i64::MIN; CHUNK_AREA].into_boxed_slice();
Self { Self {
chunk_pos, chunk_pos,
@ -200,8 +195,7 @@ impl<'a> ProtoChunk<'a> {
noise_sampler: sampler, noise_sampler: sampler,
multi_noise_sampler, multi_noise_sampler,
surface_height_estimate_sampler, surface_height_estimate_sampler,
flat_block_map: vec![RawBlockState::AIR; CHUNK_AREA * height as usize] flat_block_map: vec![0; CHUNK_AREA * height as usize].into_boxed_slice(),
.into_boxed_slice(),
flat_biome_map: vec![ flat_biome_map: vec![
&Biome::PLAINS; &Biome::PLAINS;
biome_coords::from_block(CHUNK_DIM as usize) biome_coords::from_block(CHUNK_DIM as usize)
@ -364,7 +358,7 @@ impl<'a> ProtoChunk<'a> {
return RawBlockState::AIR; return RawBlockState::AIR;
} }
let index = self.local_pos_to_block_index(&local_pos); let index = self.local_pos_to_block_index(&local_pos);
self.flat_block_map[index] RawBlockState(self.flat_block_map[index])
} }
pub fn set_block_state(&mut self, pos: &Vector3<i32>, block_state: &BlockState) { pub fn set_block_state(&mut self, pos: &Vector3<i32>, block_state: &BlockState) {
@ -384,15 +378,15 @@ impl<'a> ProtoChunk<'a> {
self.maybe_update_motion_blocking_height_map(pos); self.maybe_update_motion_blocking_height_map(pos);
if let Some(block) = get_block_by_state_id(block_state.id) { if let Some(block) = get_block_by_state_id(block_state.id) {
if !block.is_tagged_with("minecraft:leaves").unwrap() { if !block.is_tagged_with("minecraft:leaves").unwrap() {
{
self.maybe_update_motion_blocking_no_leaves_height_map(pos); self.maybe_update_motion_blocking_no_leaves_height_map(pos);
} }
} }
} }
}
let index = self.local_pos_to_block_index(&local_pos); let index = self.local_pos_to_block_index(&local_pos);
self.flat_block_map[index] = RawBlockState { self.flat_block_map[index] = block_state.id;
state_id: block_state.id,
};
} }
#[inline] #[inline]
@ -537,10 +531,10 @@ impl<'a> ProtoChunk<'a> {
Vector3::new(cell_offset_x, cell_offset_y, cell_offset_z), Vector3::new(cell_offset_x, cell_offset_y, cell_offset_z),
&mut self.surface_height_estimate_sampler, &mut self.surface_height_estimate_sampler,
) )
.unwrap_or(self.default_block); .unwrap_or(self.default_block.clone());
self.set_block_state( self.set_block_state(
&Vector3::new(block_x, block_y, block_z), &Vector3::new(block_x, block_y, block_z),
&block_state.to_state(), &block_state,
); );
} }
} }
@ -558,15 +552,13 @@ impl<'a> ProtoChunk<'a> {
let population_seed = let population_seed =
Xoroshiro::get_population_seed(self.random_config.seed, start_x, start_z); Xoroshiro::get_population_seed(self.random_config.seed, start_x, start_z);
let _random = RandomGenerator::Xoroshiro(Xoroshiro::from_seed(population_seed)); let mut random = RandomGenerator::Xoroshiro(Xoroshiro::from_seed(population_seed));
let _biome = self.get_biome(&Vector3::new( let biome = self.get_biome(&Vector3::new(
start_x, start_x,
self.bottom_section_coord() as i32 + self.height() as i32 - 1, self.bottom_section_coord() as i32 + self.height() as i32 - 1,
start_z, start_z,
)); ));
// while random.next_f32() < biome.creature_spawn_probability { while random.next_f32() < biome.creature_spawn_probability {}
// }
todo!() todo!()
} }
@ -616,13 +608,7 @@ impl<'a> ProtoChunk<'a> {
let this_biome = self.get_biome_for_terrain_gen(&Vector3::new(x, biome_y, z)); let this_biome = self.get_biome_for_terrain_gen(&Vector3::new(x, biome_y, z));
if this_biome == &Biome::ERODED_BADLANDS { if this_biome == &Biome::ERODED_BADLANDS {
terrain_builder.place_badlands_pillar( terrain_builder.place_badlands_pillar(self, x, z, top_block);
self,
x,
z,
top_block,
self.default_block,
);
// Get the top block again if we placed a pillar! // Get the top block again if we placed a pillar!
top_block = top_block =
@ -663,9 +649,7 @@ impl<'a> ProtoChunk<'a> {
.to_block(); .to_block();
// TODO: Is there a better way to check that its not a fluid? // TODO: Is there a better way to check that its not a fluid?
if !(state != AIR_BLOCK.to_block() if !(state != AIR_BLOCK && state != WATER_BLOCK && state != LAVA_BLOCK)
&& state != WATER_BLOCK.to_block()
&& state != LAVA_BLOCK.to_block())
{ {
min = search_y + 1; min = search_y + 1;
break; break;
@ -679,7 +663,7 @@ impl<'a> ProtoChunk<'a> {
context.init_vertical(stone_depth_above, stone_depth_below, y, fluid_height); context.init_vertical(stone_depth_above, stone_depth_below, y, fluid_height);
// panic!("Blending with biome {:?} at: {:?}", biome, biome_pos); // panic!("Blending with biome {:?} at: {:?}", biome, biome_pos);
if state.id == self.default_block.state_id { if state.id == self.default_block.id {
context.biome = self.get_biome_for_terrain_gen(&context.block_pos); context.biome = self.get_biome_for_terrain_gen(&context.block_pos);
let new_state = self.settings.surface_rule.try_apply(self, &mut context); let new_state = self.settings.surface_rule.try_apply(self, &mut context);
@ -789,11 +773,8 @@ impl BlockAccessor for ProtoChunk<'_> {
&self, &self,
position: &BlockPos, position: &BlockPos,
) -> (pumpkin_data::Block, pumpkin_data::BlockState) { ) -> (pumpkin_data::Block, pumpkin_data::BlockState) {
let id = self.get_block_state(&position.0).state_id; let id = self.get_block_state(&position.0);
get_block_and_state_by_state_id(id).unwrap_or(( get_block_and_state_by_state_id(id.0).unwrap_or((Block::AIR, Block::AIR.default_state))
Block::AIR,
get_state_by_state_id(Block::AIR.default_state_id).unwrap(),
))
} }
} }
@ -881,8 +862,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!("{} vs {} ({})", expected, actual.state_id, index); panic!("{} vs {} ({})", expected, actual, index);
} }
}); });
} }
@ -938,8 +919,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!("{} vs {} ({})", expected, actual.state_id, index); panic!("{} vs {} ({})", expected, actual, index);
} }
}); });
} }
@ -995,8 +976,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!("{} vs {} ({})", expected, actual.state_id, index); panic!("{} vs {} ({})", expected, actual, index);
} }
}); });
} }
@ -1052,8 +1033,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!("{} vs {} ({})", expected, actual.state_id, index); panic!("{} vs {} ({})", expected, actual, index);
} }
}); });
} }
@ -1109,8 +1090,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!("{} vs {} ({})", expected, actual.state_id, index); panic!("{} vs {} ({})", expected, actual, index);
} }
}); });
} }
@ -1132,11 +1113,7 @@ mod test {
assert_eq!( assert_eq!(
expected_data, expected_data,
chunk chunk.flat_block_map.into_iter().collect::<Vec<u16>>()
.flat_block_map
.into_iter()
.map(|state| state.state_id)
.collect::<Vec<u16>>()
); );
} }
@ -1157,11 +1134,7 @@ mod test {
assert_eq!( assert_eq!(
expected_data, expected_data,
chunk chunk.flat_block_map.into_iter().collect::<Vec<u16>>()
.flat_block_map
.into_iter()
.map(|state| state.state_id)
.collect::<Vec<u16>>()
); );
} }
@ -1185,11 +1158,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!( panic!("expected {}, was {} (at {})", expected, actual, index);
"expected {}, was {} (at {})",
expected, actual.state_id, index
);
} }
}); });
} }
@ -1214,11 +1184,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!( panic!("expected {}, was {} (at {})", expected, actual, index);
"expected {}, was {} (at {})",
expected, actual.state_id, index
);
} }
}); });
} }
@ -1243,11 +1210,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!( panic!("expected {}, was {} (at {})", expected, actual, index);
"expected {}, was {} (at {})",
expected, actual.state_id, index
);
} }
}); });
} }
@ -1272,11 +1236,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!( panic!("expected {}, was {} (at {})", expected, actual, index);
"expected {}, was {} (at {})",
expected, actual.state_id, index
);
} }
}); });
} }
@ -1304,11 +1265,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!( panic!("expected {}, was {} (at {})", expected, actual, index);
"expected {}, was {} (at {})",
expected, actual.state_id, index
);
} }
}); });
} }
@ -1336,11 +1294,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!( panic!("expected {}, was {} (at {})", expected, actual, index);
"expected {}, was {} (at {})",
expected, actual.state_id, index
);
} }
}); });
} }
@ -1368,11 +1323,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!( panic!("expected {}, was {} (at {})", expected, actual, index);
"expected {}, was {} (at {})",
expected, actual.state_id, index
);
} }
}); });
} }
@ -1400,11 +1352,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!( panic!("expected {}, was {} (at {})", expected, actual, index);
"expected {}, was {} (at {})",
expected, actual.state_id, index
);
} }
}); });
} }
@ -1432,11 +1381,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!( panic!("expected {}, was {} (at {})", expected, actual, index);
"expected {}, was {} (at {})",
expected, actual.state_id, index
);
} }
}); });
} }
@ -1465,11 +1411,8 @@ mod test {
.zip(chunk.flat_block_map) .zip(chunk.flat_block_map)
.enumerate() .enumerate()
.for_each(|(index, (expected, actual))| { .for_each(|(index, (expected, actual))| {
if expected != actual.state_id { if expected != actual {
panic!( panic!("expected {}, was {} (at {})", expected, actual, index);
"expected {}, was {} (at {})",
expected, actual.state_id, index
);
} }
}); });
} }

View File

@ -1,5 +1,4 @@
use pumpkin_data::{BlockState, chunk::Biome}; use pumpkin_data::{Block, BlockState, block_properties::get_block_by_state_id, chunk::Biome};
use pumpkin_macros::default_block_state;
use pumpkin_util::{ use pumpkin_util::{
math::vector3::Vector3, math::vector3::Vector3,
random::{RandomDeriver, RandomDeriverImpl, RandomGenerator, RandomImpl}, random::{RandomDeriver, RandomDeriverImpl, RandomGenerator, RandomImpl},
@ -50,13 +49,16 @@ impl SurfaceTerrainBuilder {
} }
} }
const ORANGE_TERRACOTTA: RawBlockState = default_block_state!("orange_terracotta"); const ORANGE_TERRACOTTA: RawBlockState =
const YELLOW_TERRACOTTA: RawBlockState = default_block_state!("yellow_terracotta"); RawBlockState(Block::ORANGE_TERRACOTTA.default_state.id);
const BROWN_TERRACOTTA: RawBlockState = default_block_state!("brown_terracotta"); const YELLOW_TERRACOTTA: RawBlockState =
const RED_TERRACOTTA: RawBlockState = default_block_state!("red_terracotta"); RawBlockState(Block::YELLOW_TERRACOTTA.default_state.id);
const WHITE_TERRACOTTA: RawBlockState = default_block_state!("white_terracotta"); const BROWN_TERRACOTTA: RawBlockState = RawBlockState(Block::BROWN_TERRACOTTA.default_state.id);
const LIGHT_GRAY_TERRACOTTA: RawBlockState = default_block_state!("light_gray_terracotta"); const RED_TERRACOTTA: RawBlockState = RawBlockState(Block::RED_TERRACOTTA.default_state.id);
const TERRACOTTA: RawBlockState = default_block_state!("terracotta"); const WHITE_TERRACOTTA: RawBlockState = RawBlockState(Block::WHITE_TERRACOTTA.default_state.id);
const LIGHT_GRAY_TERRACOTTA: RawBlockState =
RawBlockState(Block::LIGHT_GRAY_TERRACOTTA.default_state.id);
const TERRACOTTA: RawBlockState = RawBlockState(Block::TERRACOTTA.default_state.id);
fn create_terracotta_bands(mut random: RandomGenerator) -> Box<[RawBlockState]> { fn create_terracotta_bands(mut random: RandomGenerator) -> Box<[RawBlockState]> {
let mut block_states = [Self::TERRACOTTA; 192]; let mut block_states = [Self::TERRACOTTA; 192];
@ -125,7 +127,6 @@ impl SurfaceTerrainBuilder {
global_x: i32, global_x: i32,
global_z: i32, global_z: i32,
surface_y: i32, surface_y: i32,
default_state: RawBlockState,
) { ) {
let surface_noise = let surface_noise =
(self (self
@ -156,11 +157,11 @@ impl SurfaceTerrainBuilder {
for y in (chunk.bottom_y() as i32..=elevation_y).rev() { for y in (chunk.bottom_y() as i32..=elevation_y).rev() {
let pos = Vector3::new(global_x, y, global_z); let pos = Vector3::new(global_x, y, global_z);
let block_state = chunk.get_block_state(&pos).to_block(); let block_state = chunk.get_block_state(&pos).to_block();
if block_state == default_state.to_block() { if block_state == get_block_by_state_id(chunk.default_block.id).unwrap() {
break; break;
} }
if block_state == WATER_BLOCK.to_block() { if block_state == WATER_BLOCK {
return; return;
} }
} }
@ -172,14 +173,15 @@ impl SurfaceTerrainBuilder {
break; break;
} }
chunk.set_block_state(&pos, &default_state.to_state()); let default_block = &chunk.default_block;
chunk.set_block_state(&pos, &default_block.clone());
} }
} }
} }
} }
const SNOW_BLOCK: RawBlockState = default_block_state!("snow_block"); const SNOW_BLOCK: Block = Block::SNOW;
const PACKED_ICE: RawBlockState = default_block_state!("packed_ice"); const PACKED_ICE: Block = Block::PACKED_ICE;
#[expect(clippy::too_many_arguments)] #[expect(clippy::too_many_arguments)]
pub fn place_iceberg( pub fn place_iceberg(
@ -240,17 +242,17 @@ impl SurfaceTerrainBuilder {
let pos = Vector3::new(x, y, z); let pos = Vector3::new(x, y, z);
let block_state = chunk.get_block_state(&pos); let block_state = chunk.get_block_state(&pos);
if (block_state.to_state().is_air() && y < top_block && rand.next_f64() > 0.01) if (block_state.to_state().is_air() && y < top_block && rand.next_f64() > 0.01)
|| (block_state.to_block() == WATER_BLOCK.to_block() || (block_state.to_block() == WATER_BLOCK
&& y > bottom_block && y > bottom_block
&& y < sea_level && y < sea_level
&& bottom_block != 0 && bottom_block != 0
&& rand.next_f64() > 0.15) && rand.next_f64() > 0.15)
{ {
if snow_blocks <= snow_block_count && y > snow_bottom { if snow_blocks <= snow_block_count && y > snow_bottom {
chunk.set_block_state(&pos, &Self::SNOW_BLOCK.to_state()); chunk.set_block_state(&pos, &Self::SNOW_BLOCK.default_state);
snow_blocks += 1; snow_blocks += 1;
} else { } else {
chunk.set_block_state(&pos, &Self::PACKED_ICE.to_state()); chunk.set_block_state(&pos, &Self::PACKED_ICE.default_state);
} }
} }
} }

View File

@ -379,12 +379,10 @@ impl Level {
relative.y, relative.y,
relative.z as usize, relative.z as usize,
) else { ) else {
return RawBlockState { return RawBlockState(Block::AIR.default_state.id);
state_id: Block::AIR.default_state_id,
};
}; };
RawBlockState { state_id: id } RawBlockState(id)
} }
pub async fn set_block_state( pub async fn set_block_state(

View File

@ -53,6 +53,6 @@ pub trait WallMountedBlock {
) -> Option<BlockStateId> { ) -> Option<BlockStateId> {
(self.get_direction(state_id, block).opposite() == direction (self.get_direction(state_id, block).opposite() == direction
&& !self.can_place_at(world, pos, direction).await) && !self.can_place_at(world, pos, direction).await)
.then(|| Block::AIR.default_state_id) .then(|| Block::AIR.default_state.id)
} }
} }

View File

@ -24,7 +24,7 @@ impl PumpkinBlock for DirtPathBlock {
async fn on_scheduled_tick(&self, world: &Arc<World>, _block: &Block, pos: &BlockPos) { async fn on_scheduled_tick(&self, world: &Arc<World>, _block: &Block, pos: &BlockPos) {
// TODO: push up entities // TODO: push up entities
world world
.set_block_state(pos, Block::DIRT.default_state_id, BlockFlags::NOTIFY_ALL) .set_block_state(pos, Block::DIRT.default_state.id, BlockFlags::NOTIFY_ALL)
.await; .await;
} }
@ -40,10 +40,10 @@ impl PumpkinBlock for DirtPathBlock {
_use_item_on: &SUseItemOn, _use_item_on: &SUseItemOn,
) -> BlockStateId { ) -> BlockStateId {
if !can_place_at(world, block_pos).await { if !can_place_at(world, block_pos).await {
return Block::DIRT.default_state_id; return Block::DIRT.default_state.id;
} }
block.default_state_id block.default_state.id
} }
async fn get_state_for_neighbor_update( async fn get_state_for_neighbor_update(

View File

@ -24,7 +24,7 @@ impl PumpkinBlock for FarmLandBlock {
async fn on_scheduled_tick(&self, world: &Arc<World>, _block: &Block, pos: &BlockPos) { async fn on_scheduled_tick(&self, world: &Arc<World>, _block: &Block, pos: &BlockPos) {
// TODO: push up entities // TODO: push up entities
world world
.set_block_state(pos, Block::DIRT.default_state_id, BlockFlags::NOTIFY_ALL) .set_block_state(pos, Block::DIRT.default_state.id, BlockFlags::NOTIFY_ALL)
.await; .await;
} }
@ -40,9 +40,9 @@ impl PumpkinBlock for FarmLandBlock {
_use_item_on: &SUseItemOn, _use_item_on: &SUseItemOn,
) -> BlockStateId { ) -> BlockStateId {
if !can_place_at(world, pos).await { if !can_place_at(world, pos).await {
return Block::DIRT.default_state_id; return Block::DIRT.default_state.id;
} }
block.default_state_id block.default_state.id
} }
async fn get_state_for_neighbor_update( async fn get_state_for_neighbor_update(

View File

@ -108,7 +108,7 @@ impl PumpkinBlock for FireBlock {
_neighbor_state: BlockStateId, _neighbor_state: BlockStateId,
) -> BlockStateId { ) -> BlockStateId {
if !FireBlockBase::can_place_on(&world.get_block(&block_pos.down()).await) { if !FireBlockBase::can_place_on(&world.get_block(&block_pos.down()).await) {
return Block::AIR.default_state_id; return Block::AIR.default_state.id;
} }
state_id state_id

View File

@ -41,7 +41,7 @@ impl PumpkinBlock for SoulFireBlock {
_neighbor_state: BlockStateId, _neighbor_state: BlockStateId,
) -> BlockStateId { ) -> BlockStateId {
if !Self::is_soul_base(&world.get_block(&block_pos.down()).await) { if !Self::is_soul_base(&world.get_block(&block_pos.down()).await) {
return Block::AIR.default_state_id; return Block::AIR.default_state.id;
} }
state_id state_id

View File

@ -33,7 +33,7 @@ impl PumpkinBlock for GrindstoneBlock {
_replacing: BlockIsReplacing, _replacing: BlockIsReplacing,
_use_item_on: &SUseItemOn, _use_item_on: &SUseItemOn,
) -> BlockStateId { ) -> BlockStateId {
let mut props = GrindstoneLikeProperties::from_state_id(block.default_state_id, block); let mut props = GrindstoneLikeProperties::from_state_id(block.default_state.id, block);
(props.face, props.facing) = WallMountedBlock::get_placement_face(self, player, direction); (props.face, props.facing) = WallMountedBlock::get_placement_face(self, player, direction);
props.to_state_id(block) props.to_state_id(block)

View File

@ -58,7 +58,7 @@ impl PumpkinBlock for NetherPortalBlock {
{ {
return state; return state;
} }
Block::AIR.default_state_id Block::AIR.default_state.id
} }
async fn on_entity_collision( async fn on_entity_collision(

View File

@ -162,7 +162,7 @@ impl PumpkinBlock for NoteBlock {
_replacing: BlockIsReplacing, _replacing: BlockIsReplacing,
_use_item_on: &SUseItemOn, _use_item_on: &SUseItemOn,
) -> BlockStateId { ) -> BlockStateId {
Self::get_state_with_instrument(world, pos, Block::NOTE_BLOCK.default_state_id, block).await Self::get_state_with_instrument(world, pos, Block::NOTE_BLOCK.default_state.id, block).await
} }
async fn get_state_for_neighbor_update( async fn get_state_for_neighbor_update(

View File

@ -248,7 +248,7 @@ impl PumpkinBlock for PistonBlock {
world world
.set_block_state( .set_block_state(
&extended_pos, &extended_pos,
Block::AIR.default_state_id, Block::AIR.default_state.id,
BlockFlags::NOTIFY_ALL, BlockFlags::NOTIFY_ALL,
) )
.await; .await;
@ -259,7 +259,7 @@ impl PumpkinBlock for PistonBlock {
world world
.set_block_state( .set_block_state(
&extended_pos, &extended_pos,
Block::AIR.default_state_id, Block::AIR.default_state.id,
BlockFlags::NOTIFY_ALL, BlockFlags::NOTIFY_ALL,
) )
.await; .await;
@ -351,7 +351,7 @@ async fn move_piston(
world world
.set_block_state( .set_block_state(
&extended_pos, &extended_pos,
Block::AIR.default_state_id, Block::AIR.default_state.id,
BlockFlags::FORCE_STATE, BlockFlags::FORCE_STATE,
) )
.await; .await;
@ -453,7 +453,7 @@ async fn move_piston(
.await; .await;
} }
let air_state = Block::AIR.default_state_id; let air_state = Block::AIR.default_state.id;
for &pos in moved_blocks_map.keys() { for &pos in moved_blocks_map.keys() {
world world
.set_block_state( .set_block_state(

View File

@ -32,7 +32,7 @@ impl crate::block::pumpkin_block::PumpkinBlock for PumpkinBlock {
world world
.set_block_state( .set_block_state(
&pos, &pos,
Block::CARVED_PUMPKIN.default_state_id, Block::CARVED_PUMPKIN.default_state.id,
BlockFlags::NOTIFY_ALL, BlockFlags::NOTIFY_ALL,
) )
.await; .await;

View File

@ -85,7 +85,7 @@ pub trait RedstoneGateBlock<T: Send + BlockProperties + RedstoneGateBlockPropert
return; return;
} }
world world
.set_block_state(pos, Block::AIR.default_state_id, BlockFlags::NOTIFY_ALL) .set_block_state(pos, Block::AIR.default_state.id, BlockFlags::NOTIFY_ALL)
.await; .await;
for dir in BlockDirection::all() { for dir in BlockDirection::all() {
world world

View File

@ -161,7 +161,7 @@ impl PumpkinBlock for ButtonBlock {
_replacing: BlockIsReplacing, _replacing: BlockIsReplacing,
_use_item_on: &SUseItemOn, _use_item_on: &SUseItemOn,
) -> BlockStateId { ) -> BlockStateId {
let mut props = ButtonLikeProperties::from_state_id(block.default_state_id, block); let mut props = ButtonLikeProperties::from_state_id(block.default_state.id, block);
(props.face, props.facing) = WallMountedBlock::get_placement_face(self, player, direction); (props.face, props.facing) = WallMountedBlock::get_placement_face(self, player, direction);
props.to_state_id(block) props.to_state_id(block)

View File

@ -154,7 +154,7 @@ impl PumpkinBlock for ComparatorBlock {
if !RedstoneGateBlock::can_place_above(self, world, *neighbor_pos, &neighbor_state) if !RedstoneGateBlock::can_place_above(self, world, *neighbor_pos, &neighbor_state)
.await .await
{ {
return Block::AIR.default_state_id; return Block::AIR.default_state.id;
} }
} }
} }

View File

@ -133,7 +133,7 @@ impl PumpkinBlock for LeverBlock {
_replacing: BlockIsReplacing, _replacing: BlockIsReplacing,
_use_item_on: &SUseItemOn, _use_item_on: &SUseItemOn,
) -> BlockStateId { ) -> BlockStateId {
let mut props = LeverLikeProperties::from_state_id(block.default_state_id, block); let mut props = LeverLikeProperties::from_state_id(block.default_state.id, block);
(props.face, props.facing) = WallMountedBlock::get_placement_face(self, player, direction); (props.face, props.facing) = WallMountedBlock::get_placement_face(self, player, direction);
props.to_state_id(block) props.to_state_id(block)

View File

@ -55,7 +55,7 @@ impl PumpkinBlock for RedstoneTorchBlock {
if face == BlockDirection::Down { if face == BlockDirection::Down {
let support_block = world.get_block_state(&block_pos.down()).await; let support_block = world.get_block_state(&block_pos.down()).await;
if support_block.is_center_solid(BlockDirection::Up) { if support_block.is_center_solid(BlockDirection::Up) {
return block.default_state_id; return block.default_state.id;
} }
} }
let mut directions = player.get_entity().get_entity_facing_order(); let mut directions = player.get_entity().get_entity_facing_order();
@ -74,7 +74,7 @@ impl PumpkinBlock for RedstoneTorchBlock {
} else if directions[0] == Facing::Down { } else if directions[0] == Facing::Down {
let support_block = world.get_block_state(&block_pos.down()).await; let support_block = world.get_block_state(&block_pos.down()).await;
if support_block.is_center_solid(BlockDirection::Up) { if support_block.is_center_solid(BlockDirection::Up) {
return block.default_state_id; return block.default_state.id;
} }
} }
@ -95,7 +95,7 @@ impl PumpkinBlock for RedstoneTorchBlock {
let support_block = world.get_block_state(&block_pos.down()).await; let support_block = world.get_block_state(&block_pos.down()).await;
if support_block.is_center_solid(BlockDirection::Up) { if support_block.is_center_solid(BlockDirection::Up) {
block.default_state_id block.default_state.id
} else { } else {
0 0
} }

View File

@ -229,7 +229,7 @@ impl PumpkinBlock for RepeaterBlock {
if !RedstoneGateBlock::can_place_above(self, world, *neighbor_pos, &neighbor_state) if !RedstoneGateBlock::can_place_above(self, world, *neighbor_pos, &neighbor_state)
.await .await
{ {
return Block::AIR.default_state_id; return Block::AIR.default_state.id;
} }
} }
} }

View File

@ -78,7 +78,7 @@ impl PumpkinBlock for TripwireBlock {
Self::should_connect_to(state_id, dir) Self::should_connect_to(state_id, dir)
}); });
let mut props = TripwireProperties::from_state_id(block.default_state_id, block); let mut props = TripwireProperties::from_state_id(block.default_state.id, block);
props.north = connect_north.await; props.north = connect_north.await;
props.south = connect_south.await; props.south = connect_south.await;

View File

@ -49,7 +49,7 @@ impl PumpkinBlock for TripwireHookBlock {
props.facing = face.opposite().to_cardinal_direction(); props.facing = face.opposite().to_cardinal_direction();
return props.to_state_id(block); return props.to_state_id(block);
} }
block.default_state_id block.default_state.id
} }
async fn can_place_at( async fn can_place_at(
@ -97,7 +97,7 @@ impl PumpkinBlock for TripwireHookBlock {
facing.opposite() == props.facing facing.opposite() == props.facing
}) && !Self::can_place_at(world, pos, direction).await }) && !Self::can_place_at(world, pos, direction).await
{ {
Block::AIR.default_state_id Block::AIR.default_state.id
} else { } else {
state state
} }

View File

@ -50,7 +50,7 @@ impl PumpkinBlock for TorchBlock {
if face == BlockDirection::Down { if face == BlockDirection::Down {
let support_block = world.get_block_state(&block_pos.down()).await; let support_block = world.get_block_state(&block_pos.down()).await;
if support_block.is_center_solid(BlockDirection::Up) { if support_block.is_center_solid(BlockDirection::Up) {
return block.default_state_id; return block.default_state.id;
} }
} }
let mut directions = player.get_entity().get_entity_facing_order(); let mut directions = player.get_entity().get_entity_facing_order();
@ -69,7 +69,7 @@ impl PumpkinBlock for TorchBlock {
} else if directions[0] == Facing::Down { } else if directions[0] == Facing::Down {
let support_block = world.get_block_state(&block_pos.down()).await; let support_block = world.get_block_state(&block_pos.down()).await;
if support_block.is_center_solid(BlockDirection::Up) { if support_block.is_center_solid(BlockDirection::Up) {
return block.default_state_id; return block.default_state.id;
} }
} }
@ -95,7 +95,7 @@ impl PumpkinBlock for TorchBlock {
let support_block = world.get_block_state(&block_pos.down()).await; let support_block = world.get_block_state(&block_pos.down()).await;
if support_block.is_center_solid(BlockDirection::Up) { if support_block.is_center_solid(BlockDirection::Up) {
block.default_state_id block.default_state.id
} else { } else {
0 0
} }

View File

@ -133,7 +133,7 @@ pub trait FlowingFluid {
world world
.set_block_state( .set_block_state(
block_pos, block_pos,
Block::AIR.default_state_id, Block::AIR.default_state.id,
BlockFlags::NOTIFY_ALL, BlockFlags::NOTIFY_ALL,
) )
.await; .await;

View File

@ -30,7 +30,7 @@ impl FlowingLava {
.get_block(&block_pos.offset(BlockDirection::Down.to_offset())) .get_block(&block_pos.offset(BlockDirection::Down.to_offset()))
.await .await
== Block::SOUL_SOIL; == Block::SOUL_SOIL;
let is_still = world.get_block_state_id(block_pos).await == Block::LAVA.default_state_id; let is_still = world.get_block_state_id(block_pos).await == Block::LAVA.default_state.id;
for dir in BlockDirection::flow_directions() { for dir in BlockDirection::flow_directions() {
let neighbor_pos = block_pos.offset(dir.opposite().to_offset()); let neighbor_pos = block_pos.offset(dir.opposite().to_offset());
@ -43,7 +43,7 @@ impl FlowingLava {
world world
.set_block_state( .set_block_state(
block_pos, block_pos,
block.default_state_id, block.default_state.id,
BlockFlags::NOTIFY_NEIGHBORS, BlockFlags::NOTIFY_NEIGHBORS,
) )
.await; .await;
@ -56,7 +56,7 @@ impl FlowingLava {
world world
.set_block_state( .set_block_state(
block_pos, block_pos,
Block::BASALT.default_state_id, Block::BASALT.default_state.id,
BlockFlags::NOTIFY_NEIGHBORS, BlockFlags::NOTIFY_NEIGHBORS,
) )
.await; .await;
@ -146,7 +146,7 @@ impl FlowingFluid for FlowingLava {
// STONE creation // STONE creation
if world.get_block(pos).await == Block::WATER { if world.get_block(pos).await == Block::WATER {
world world
.set_block_state(pos, Block::STONE.default_state_id, BlockFlags::NOTIFY_ALL) .set_block_state(pos, Block::STONE.default_state.id, BlockFlags::NOTIFY_ALL)
.await; .await;
world world
.sync_world_event(WorldEvent::LavaExtinguished, *pos, 0) .sync_world_event(WorldEvent::LavaExtinguished, *pos, 0)

View File

@ -93,7 +93,7 @@ pub trait PumpkinBlock: Send + Sync {
_replacing: BlockIsReplacing, _replacing: BlockIsReplacing,
_use_item_on: &SUseItemOn, _use_item_on: &SUseItemOn,
) -> BlockStateId { ) -> BlockStateId {
block.default_state_id block.default_state.id
} }
async fn random_tick(&self, _block: &Block, _world: &Arc<World>, _pos: &BlockPos) {} async fn random_tick(&self, _block: &Block, _world: &Arc<World>, _pos: &BlockPos) {}

View File

@ -247,7 +247,7 @@ impl BlockRegistry {
) )
.await; .await;
} }
block.default_state_id block.default_state.id
} }
pub async fn player_placed( pub async fn player_placed(

View File

@ -58,7 +58,7 @@ pub trait ArgumentConsumer: Sync + GetClientSideArgParser {
args: &mut RawArgs<'a>, args: &mut RawArgs<'a>,
) -> Option<Arg>; ) -> Option<Arg>;
/// Used for tab completion (but only if argument suggestion type is "minecraft:ask_server"!). /// Used for tab completion (but only if argument suggestion type is "`minecraft:ask_server`"!).
/// ///
/// NOTE: This is called after this consumer's [`ArgumentConsumer::consume`] method returned None, so if args is used here, make sure [`ArgumentConsumer::consume`] never returns None after mutating args. /// NOTE: This is called after this consumer's [`ArgumentConsumer::consume`] method returned None, so if args is used here, make sure [`ArgumentConsumer::consume`] never returns None after mutating args.
async fn suggest<'a>( async fn suggest<'a>(

View File

@ -46,7 +46,7 @@ impl CommandExecutor for Executor {
args: &ConsumedArgs<'a>, args: &ConsumedArgs<'a>,
) -> Result<(), CommandError> { ) -> Result<(), CommandError> {
let block = BlockArgumentConsumer::find_arg(args, ARG_BLOCK)?; let block = BlockArgumentConsumer::find_arg(args, ARG_BLOCK)?;
let block_state_id = block.default_state_id; let block_state_id = block.default_state.id;
let from = BlockPosArgumentConsumer::find_arg(args, ARG_FROM)?; let from = BlockPosArgumentConsumer::find_arg(args, ARG_FROM)?;
let to = BlockPosArgumentConsumer::find_arg(args, ARG_TO)?; let to = BlockPosArgumentConsumer::find_arg(args, ARG_TO)?;
let mode = self.0; let mode = self.0;

View File

@ -82,7 +82,7 @@ impl CommandExecutor for Executor {
let targets = if let Ok(players) = PlayersArgumentConsumer::find_arg(args, ARG_TARGETS) { let targets = if let Ok(players) = PlayersArgumentConsumer::find_arg(args, ARG_TARGETS) {
players players
} else if let Some(player) = sender.as_player() { } else if let Some(player) = sender.as_player() {
&[player.clone()] &[player]
} else { } else {
return Ok(()); return Ok(());
}; };

View File

@ -39,7 +39,7 @@ impl CommandExecutor for Executor {
args: &ConsumedArgs<'a>, args: &ConsumedArgs<'a>,
) -> Result<(), CommandError> { ) -> Result<(), CommandError> {
let block = BlockArgumentConsumer::find_arg(args, ARG_BLOCK)?; let block = BlockArgumentConsumer::find_arg(args, ARG_BLOCK)?;
let block_state_id = block.default_state_id; let block_state_id = block.default_state.id;
let pos = BlockPosArgumentConsumer::find_arg(args, ARG_BLOCK_POS)?; let pos = BlockPosArgumentConsumer::find_arg(args, ARG_BLOCK_POS)?;
let mode = self.0; let mode = self.0;
let world = match sender { let world = match sender {

View File

@ -1,4 +1,3 @@
use pumpkin_data::block_properties::get_block_collision_shapes;
use pumpkin_protocol::client::play::CUpdateEntityPos; use pumpkin_protocol::client::play::CUpdateEntityPos;
use pumpkin_util::math::{position::BlockPos, vector3::Vector3}; use pumpkin_util::math::{position::BlockPos, vector3::Vector3};
@ -48,13 +47,10 @@ impl Navigator {
goal.current_progress.y, goal.current_progress.y,
goal.current_progress.z + z, goal.current_progress.z + z,
); );
let shapes = get_block_collision_shapes( let state = world
world
.get_block_state(&BlockPos(potential_pos.to_i32())) .get_block_state(&BlockPos(potential_pos.to_i32()))
.await .await;
.id, let shapes = state.get_block_collision_shapes();
)
.unwrap();
if !shapes.is_empty() { if !shapes.is_empty() {
continue; continue;
} }

View File

@ -6,7 +6,7 @@ use crossbeam::atomic::AtomicCell;
use living::LivingEntity; use living::LivingEntity;
use player::Player; use player::Player;
use pumpkin_data::{ use pumpkin_data::{
block_properties::{Facing, HorizontalFacing, get_block_outline_shapes}, block_properties::{Facing, HorizontalFacing},
damage::DamageType, damage::DamageType,
entity::{EntityPose, EntityType}, entity::{EntityPose, EntityType},
sound::{Sound, SoundCategory}, sound::{Sound, SoundCategory},
@ -673,7 +673,7 @@ impl Entity {
for z in blockpos.0.z..=blockpos1.0.z { for z in blockpos.0.z..=blockpos1.0.z {
let pos = BlockPos::new(x, y, z); let pos = BlockPos::new(x, y, z);
let (block, state) = world.get_block_and_block_state(&pos).await; let (block, state) = world.get_block_and_block_state(&pos).await;
let block_outlines = get_block_outline_shapes(state.id); let block_outlines = state.get_block_outline_shapes();
if let Some(outlines) = block_outlines { if let Some(outlines) = block_outlines {
if outlines.is_empty() { if outlines.is_empty() {

View File

@ -65,7 +65,7 @@ impl EntityBase for TNTEntity {
Metadata::new( Metadata::new(
9, 9,
MetaDataType::BlockState, MetaDataType::BlockState,
VarInt(i32::from(Block::TNT.default_state_id)), VarInt(i32::from(Block::TNT.default_state.id)),
), ),
]) ])
.await; .await;

View File

@ -46,8 +46,8 @@ impl PumpkinItem for AxeItem {
// First we try to strip the block. by getting his equivalent and applying it the axis. // First we try to strip the block. by getting his equivalent and applying it the axis.
// If there is a strip equivalent. // If there is a strip equivalent.
if replacement_block.is_some() { if let Some(replacement_block) = replacement_block {
let new_block = Block::from_id(replacement_block.unwrap()); let new_block = Block::from_id(replacement_block);
let new_block = &new_block.unwrap(); let new_block = &new_block.unwrap();
let new_state_id = if block.is_tagged_with("#minecraft:logs") == Some(true) { let new_state_id = if block.is_tagged_with("#minecraft:logs") == Some(true) {
let log_information = world.get_block_state_id(&location).await; let log_information = world.get_block_state_id(&location).await;
@ -78,7 +78,7 @@ impl PumpkinItem for AxeItem {
new_door_properties.powered = door_props.powered; new_door_properties.powered = door_props.powered;
new_door_properties.to_state_id(new_block) new_door_properties.to_state_id(new_block)
} else { } else {
new_block.default_state_id new_block.default_state.id
}; };
// TODO Implements trapdoors when It's implemented // TODO Implements trapdoors when It's implemented
world world

View File

@ -102,13 +102,13 @@ impl PumpkinItem for EmptyBucketItem {
let block = Block::from_state_id(state_id).unwrap(); let block = Block::from_state_id(state_id).unwrap();
if state_id == Block::AIR.default_state_id { if state_id == Block::AIR.default_state.id {
return false; return false;
} }
(block.id != Block::WATER.id && block.id != Block::LAVA.id) (block.id != Block::WATER.id && block.id != Block::LAVA.id)
|| ((block.id == Block::WATER.id && state_id == Block::WATER.default_state_id) || ((block.id == Block::WATER.id && state_id == Block::WATER.default_state.id)
|| (block.id == Block::LAVA.id && state_id == Block::LAVA.default_state_id)) || (block.id == Block::LAVA.id && state_id == Block::LAVA.default_state.id))
}; };
let Some((block_pos, direction)) = world.raycast(start_pos, end_pos, checker).await else { let Some((block_pos, direction)) = world.raycast(start_pos, end_pos, checker).await else {
@ -133,8 +133,8 @@ impl PumpkinItem for EmptyBucketItem {
.set_block_state(&block_pos, state_id, BlockFlags::NOTIFY_NEIGHBORS) .set_block_state(&block_pos, state_id, BlockFlags::NOTIFY_NEIGHBORS)
.await; .await;
world.schedule_fluid_tick(block.id, block_pos, 5).await; world.schedule_fluid_tick(block.id, block_pos, 5).await;
} else if state.id == Block::LAVA.default_state_id } else if state.id == Block::LAVA.default_state.id
|| state.id == Block::WATER.default_state_id || state.id == Block::WATER.default_state.id
{ {
world world
.break_block(&block_pos, None, BlockFlags::NOTIFY_NEIGHBORS) .break_block(&block_pos, None, BlockFlags::NOTIFY_NEIGHBORS)
@ -142,7 +142,7 @@ impl PumpkinItem for EmptyBucketItem {
world world
.set_block_state( .set_block_state(
&block_pos, &block_pos,
Block::AIR.default_state_id, Block::AIR.default_state.id,
BlockFlags::NOTIFY_NEIGHBORS, BlockFlags::NOTIFY_NEIGHBORS,
) )
.await; .await;
@ -167,7 +167,7 @@ impl PumpkinItem for EmptyBucketItem {
} }
} }
let item = if state.id == Block::LAVA.default_state_id { let item = if state.id == Block::LAVA.default_state.id {
&Item::LAVA_BUCKET &Item::LAVA_BUCKET
} else { } else {
&Item::WATER_BUCKET &Item::WATER_BUCKET
@ -255,14 +255,14 @@ impl PumpkinItem for FilledBucketItem {
world world
.schedule_fluid_tick(block.id, pos.offset(direction.to_offset()), 5) .schedule_fluid_tick(block.id, pos.offset(direction.to_offset()), 5)
.await; .await;
} else if state.id == Block::AIR.default_state_id || state.is_liquid() { } else if state.id == Block::AIR.default_state.id || state.is_liquid() {
world world
.set_block_state( .set_block_state(
&pos.offset(direction.to_offset()), &pos.offset(direction.to_offset()),
if item.id == Item::LAVA_BUCKET.id { if item.id == Item::LAVA_BUCKET.id {
Block::LAVA.default_state_id Block::LAVA.default_state.id
} else { } else {
Block::WATER.default_state_id Block::WATER.default_state.id
}, },
BlockFlags::NOTIFY_NEIGHBORS, BlockFlags::NOTIFY_NEIGHBORS,
) )

View File

@ -58,7 +58,7 @@ impl PumpkinItem for EnderEyeItem {
let (start_pos, end_pos) = self.get_start_and_end_pos(player); let (start_pos, end_pos) = self.get_start_and_end_pos(player);
let checker = async |pos: &BlockPos, world_inner: &Arc<World>| { let checker = async |pos: &BlockPos, world_inner: &Arc<World>| {
let state_id = world_inner.get_block_state_id(pos).await; let state_id = world_inner.get_block_state_id(pos).await;
state_id != Block::AIR.default_state_id state_id != Block::AIR.default_state.id
}; };
let Some((block_pos, _direction)) = world.raycast(start_pos, end_pos, checker).await else { let Some((block_pos, _direction)) = world.raycast(start_pos, end_pos, checker).await else {

View File

@ -74,7 +74,7 @@ impl PumpkinItem for HoeItem {
world world
.set_block_state( .set_block_state(
&location, &location,
future_block.default_state_id, future_block.default_state.id,
BlockFlags::NOTIFY_ALL, BlockFlags::NOTIFY_ALL,
) )
.await; .await;

View File

@ -58,7 +58,7 @@ impl PumpkinItem for HoneyCombItem {
new_door_properties.powered = door_props.powered; new_door_properties.powered = door_props.powered;
new_door_properties.to_state_id(new_block) new_door_properties.to_state_id(new_block)
} else { } else {
new_block.default_state_id new_block.default_state.id
}; };
// TODO Implements trapdoors // TODO Implements trapdoors

View File

@ -29,7 +29,7 @@ impl Ignition {
let result_block_id = get_ignite_result(block, &world, &location) let result_block_id = get_ignite_result(block, &world, &location)
.await .await
.unwrap_or(fire_block.default_state_id); .unwrap_or(fire_block.default_state.id);
let Some(result_block) = Block::from_state_id(result_block_id) else { let Some(result_block) = Block::from_state_id(result_block_id) else {
return; return;

View File

@ -51,7 +51,7 @@ impl PumpkinItem for ShovelItem {
world world
.set_block_state( .set_block_state(
&location, &location,
Block::DIRT_PATH.default_state_id, Block::DIRT_PATH.default_state.id,
BlockFlags::NOTIFY_ALL, BlockFlags::NOTIFY_ALL,
) )
.await; .await;

View File

@ -10,7 +10,7 @@ use thiserror::Error;
use pumpkin_config::{BASIC_CONFIG, advanced_config}; use pumpkin_config::{BASIC_CONFIG, advanced_config};
use pumpkin_data::block_properties::{ use pumpkin_data::block_properties::{
BlockProperties, WaterLikeProperties, get_block_by_item, get_block_collision_shapes, BlockProperties, WaterLikeProperties, get_block_by_item, get_state_by_state_id,
}; };
use pumpkin_data::entity::{EntityType, entity_from_egg}; use pumpkin_data::entity::{EntityType, entity_from_egg};
use pumpkin_data::item::Item; use pumpkin_data::item::Item;
@ -1119,7 +1119,6 @@ impl Player {
[], [],
)) ))
.await; .await;
return;
} }
} }
ActionType::Interact | ActionType::InteractAt => { ActionType::Interact | ActionType::InteractAt => {
@ -1782,7 +1781,9 @@ impl Player {
.await; .await;
// Check if there is a player in the way of the block being placed // Check if there is a player in the way of the block being placed
let shapes = get_block_collision_shapes(new_state).unwrap_or_default(); let shapes = get_state_by_state_id(new_state)
.unwrap()
.get_block_collision_shapes();
for player in world.get_nearby_players(location.0.to_f64(), 3.0).await { for player in world.get_nearby_players(location.0.to_f64(), 3.0).await {
let player_box = player.1.living_entity.entity.bounding_box.load(); let player_box = player.1.living_entity.entity.bounding_box.load();
for shape in &shapes { for shape in &shapes {

View File

@ -9,7 +9,7 @@ use pumpkin_util::text::TextComponent;
pub struct ServerBroadcastEvent { pub struct ServerBroadcastEvent {
/// The message being broadcast. /// The message being broadcast.
pub message: TextComponent, pub message: TextComponent,
/// The name of the sender as a TextComponent. /// The name of the sender as a `TextComponent`.
pub sender: TextComponent, pub sender: TextComponent,
} }

View File

@ -30,6 +30,7 @@ use border::Worldborder;
use bytes::{BufMut, Bytes}; use bytes::{BufMut, Bytes};
use explosion::Explosion; use explosion::Explosion;
use pumpkin_config::BasicConfiguration; use pumpkin_config::BasicConfiguration;
use pumpkin_data::BlockDirection;
use pumpkin_data::entity::EffectType; use pumpkin_data::entity::EffectType;
use pumpkin_data::fluid::{Falling, FluidProperties}; use pumpkin_data::fluid::{Falling, FluidProperties};
use pumpkin_data::{ use pumpkin_data::{
@ -43,7 +44,6 @@ use pumpkin_data::{
sound::{Sound, SoundCategory}, sound::{Sound, SoundCategory},
world::{RAW, WorldEvent}, world::{RAW, WorldEvent},
}; };
use pumpkin_data::{BlockDirection, block_properties::get_block_outline_shapes};
use pumpkin_inventory::equipment_slot::EquipmentSlot; use pumpkin_inventory::equipment_slot::EquipmentSlot;
use pumpkin_macros::send_cancellable; use pumpkin_macros::send_cancellable;
use pumpkin_nbt::{compound::NbtCompound, to_bytes_unnamed}; use pumpkin_nbt::{compound::NbtCompound, to_bytes_unnamed};
@ -1468,7 +1468,6 @@ impl World {
} }
let block_state = self.get_block_state(position).await; let block_state = self.get_block_state(position).await;
let new_block = Block::from_state_id(block_state_id).unwrap();
let new_fluid = self.get_fluid(position).await; let new_fluid = self.get_fluid(position).await;
// WorldChunk.java line 318 // WorldChunk.java line 318
@ -1678,14 +1677,13 @@ impl World {
} }
pub async fn get_block_state_id(&self, position: &BlockPos) -> BlockStateId { pub async fn get_block_state_id(&self, position: &BlockPos) -> BlockStateId {
self.level.get_block_state(position).await.state_id self.level.get_block_state(position).await.0
} }
/// Gets the `BlockState` from the block registry. Returns Air if the block state was not found. /// Gets the `BlockState` from the block registry. Returns Air if the block state was not found.
pub async fn get_block_state(&self, position: &BlockPos) -> pumpkin_data::BlockState { pub async fn get_block_state(&self, position: &BlockPos) -> pumpkin_data::BlockState {
let id = self.get_block_state_id(position).await; let id = self.get_block_state_id(position).await;
get_state_by_state_id(id) get_state_by_state_id(id).unwrap_or(Block::AIR.default_state)
.unwrap_or(get_state_by_state_id(Block::AIR.default_state_id).unwrap())
} }
/// Gets the Block + Block state from the Block Registry, Returns None if the Block state has not been found /// Gets the Block + Block state from the Block Registry, Returns None if the Block state has not been found
@ -1694,10 +1692,7 @@ impl World {
position: &BlockPos, position: &BlockPos,
) -> (pumpkin_data::Block, pumpkin_data::BlockState) { ) -> (pumpkin_data::Block, pumpkin_data::BlockState) {
let id = self.get_block_state_id(position).await; let id = self.get_block_state_id(position).await;
get_block_and_state_by_state_id(id).unwrap_or(( get_block_and_state_by_state_id(id).unwrap_or((Block::AIR, Block::AIR.default_state))
Block::AIR,
get_state_by_state_id(Block::AIR.default_state_id).unwrap(),
))
} }
/// Updates neighboring blocks of a block /// Updates neighboring blocks of a block
@ -1910,9 +1905,9 @@ impl World {
from: Vector3<f64>, from: Vector3<f64>,
to: Vector3<f64>, to: Vector3<f64>,
) -> (bool, Option<BlockDirection>) { ) -> (bool, Option<BlockDirection>) {
let state_id = self.get_block_state_id(block_pos).await; let state = self.get_block_state(block_pos).await;
let Some(bounding_boxes) = get_block_outline_shapes(state_id) else { let Some(bounding_boxes) = state.get_block_outline_shapes() else {
return (false, None); return (false, None);
}; };
@ -2087,9 +2082,6 @@ impl BlockAccessor for World {
position: &BlockPos, position: &BlockPos,
) -> (pumpkin_data::Block, pumpkin_data::BlockState) { ) -> (pumpkin_data::Block, pumpkin_data::BlockState) {
let id = self.get_block_state(position).await.id; let id = self.get_block_state(position).await.id;
get_block_and_state_by_state_id(id).unwrap_or(( get_block_and_state_by_state_id(id).unwrap_or((Block::AIR, Block::AIR.default_state))
Block::AIR,
get_state_by_state_id(Block::AIR.default_state_id).unwrap(),
))
} }
} }

View File

@ -94,7 +94,7 @@ impl EndPortal {
world world
.set_block_state( .set_block_state(
&pos.offset(Vector3::new(x, 0, z)), &pos.offset(Vector3::new(x, 0, z)),
Block::END_PORTAL.default_state_id, Block::END_PORTAL.default_state.id,
BlockFlags::empty(), BlockFlags::empty(),
) )
.await; .await;