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) {
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)]
@@ -506,15 +506,14 @@ pub struct OptimizedBlock {
pub experience: Option<Experience>,
}
impl ToTokens for OptimizedBlock {
fn to_tokens(&self, tokens: &mut TokenStream) {
impl OptimizedBlock {
fn to_tokens(&self, tokens: &mut TokenStream, all_states: &[BlockState]) {
let id = LitInt::new(&self.id.to_string(), Span::call_site());
let name = LitStr::new(&self.name, Span::call_site());
let translation_key = LitStr::new(&self.translation_key, Span::call_site());
let hardness = &self.hardness;
let blast_resistance = &self.blast_resistance;
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 velocity_multiplier = &self.velocity_multiplier;
let jump_velocity_multiplier = &self.jump_velocity_multiplier;
@@ -535,6 +534,14 @@ impl ToTokens for OptimizedBlock {
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! {
Block {
id: #id,
@@ -546,7 +553,7 @@ impl ToTokens for OptimizedBlock {
velocity_multiplier: #velocity_multiplier,
jump_velocity_multiplier: #jump_velocity_multiplier,
item_id: #item_id,
default_state_id: #default_state_id,
default_state: #default_state,
states: &[#(#states),*],
loot_table: #loot_table,
experience: #experience,
@@ -787,7 +794,7 @@ pub(crate) fn build() -> TokenStream {
.iter()
.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 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.
for (name, block) in optimized_blocks {
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 state_start = block.states.iter().map(|state| state.id).min().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] = &[
#(#unique_states),*
#(#unique_states_tokens),*
];
pub static BLOCK_ENTITY_TYPES: &[&str] = &[
@@ -924,39 +932,6 @@ pub(crate) fn build() -> TokenStream {
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 {
if block_state.is_solid() {
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();
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.

View File

@@ -1,5 +1,7 @@
use crate::BlockDirection;
use crate::block_properties::Instrument;
use pumpkin_util::math::vector3::Vector3;
use crate::block_properties::{COLLISION_SHAPES, Instrument, get_block_by_state_id};
use crate::{Block, BlockDirection, CollisionShape};
#[derive(Clone, Debug)]
pub struct BlockState {
@@ -18,6 +20,12 @@ pub struct BlockState {
pub block_entity_type: u16,
}
impl PartialEq for BlockState {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[repr(u8)]
pub enum PistonBehavior {
@@ -83,6 +91,41 @@ impl BlockState {
_ => 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)]

View File

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

View File

@@ -150,7 +150,7 @@ impl PlayerInventory {
&*self.get_stack(Self::OFF_HAND_SLOT).await.lock().await,
stack,
) {
return Self::OFF_HAND_SLOT as i16;
Self::OFF_HAND_SLOT as i16
} else {
for i in 0..Self::MAIN_SIZE {
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()
}
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_u32: u32 = variant_index_i32.try_into().map_err(|_| {
ReadingError::Message(format!(
"Invalid variant index {} for enum, cannot convert to u32",
variant_index_i32
"Invalid variant index {variant_index_i32} for enum, cannot convert to u32"
))
})?;
let val = seed.deserialize(variant_index_u32.into_deserializer())?;

View File

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

View File

@@ -172,7 +172,7 @@ impl PermissionManager {
// Check wildcard permissions at each level
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;
}
@@ -186,7 +186,7 @@ impl PermissionManager {
if i < key_parts.len() - 1 {
if let Some(value) =
attachment.has_permission_set(&format!("{}.*", current_node))
attachment.has_permission_set(&format!("{current_node}.*"))
{
return value;
}
@@ -240,7 +240,7 @@ pub enum PermissionLvl {
impl PartialOrd for PermissionLvl {
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)
.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 {
Ok(Color::Named(NamedColor::try_from(s.as_str()).map_err(
|_| 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 crossbeam::atomic::AtomicCell;
use pumpkin_data::{
Block, BlockDirection, BlockState,
block_properties::{get_block_by_state_id, get_state_by_state_id},
};
use pumpkin_data::{Block, BlockDirection, BlockState, block_properties::get_block_by_state_id};
use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos;
@@ -32,7 +29,7 @@ impl PistonBlockEntity {
world.remove_block_entity(&pos).await;
if world.get_block(&pos).await == Block::MOVING_PISTON {
let state = if self.source {
Block::AIR.default_state_id
Block::AIR.default_state.id
} else {
self.pushed_block_state.id
};
@@ -109,7 +106,7 @@ impl BlockEntity for PistonBlockEntity {
Self: Sized,
{
// 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 last_progress = nbt.get_float(LAST_PROGRESS).unwrap_or(0.0);
let extending = nbt.get_bool(EXTENDING).unwrap_or(false);

View File

@@ -22,24 +22,20 @@ pub struct BlockStateCodec {
impl BlockStateCodec {
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 {
let mut properties_vec: Vec<(&str, &str)> = Vec::with_capacity(properties.len());
for (key, value) in properties {
properties_vec.push((key, value));
}
let block_properties = block.from_properties(properties_vec).unwrap();
state_id = block_properties.to_state_id(&block);
}
return get_state_by_state_id(state_id);
if let Some(properties) = &self.properties {
let properties_vec: Vec<(&str, &str)> = properties
.iter()
.map(|(key, value)| (key.as_str(), value.as_str()))
.collect();
let block_properties = block.from_properties(properties_vec).unwrap();
state_id = block_properties.to_state_id(&block);
}
None
get_state_by_state_id(state_id)
}
}

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
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct RawBlockState {
pub state_id: BlockStateId,
}
pub struct RawBlockState(pub BlockStateId);
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
pub fn new(registry_id: &str) -> Option<Self> {
let block = get_block(registry_id);
block.map(|block| Self {
state_id: block.default_state_id,
})
block.map(|block| Self(block.default_state.id))
}
#[inline]
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 {
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 pumpkin_data::{Block, BlockState};
use pumpkin_util::{
math::{clamped_map, floor_div, vector2::Vector2, vector3::Vector3},
random::{RandomDeriver, RandomDeriverImpl, RandomImpl},
};
use crate::block::RawBlockState;
use super::{
chunk_noise::{LAVA_BLOCK, WATER_BLOCK},
noise_router::{
@@ -22,23 +21,23 @@ use super::{
#[derive(Clone)]
pub struct FluidLevel {
max_y: i32,
state: RawBlockState,
block: Block,
}
impl FluidLevel {
pub fn new(max_y: i32, state: RawBlockState) -> Self {
Self { max_y, state }
pub fn new(max_y: i32, block: Block) -> Self {
Self { max_y, block }
}
pub fn max_y_exclusive(&self) -> i32 {
self.max_y
}
fn get_block_state(&self, y: i32) -> RawBlockState {
fn get_block(&self, y: i32) -> Block {
if y < self.max_y {
self.state
self.block.clone()
} else {
RawBlockState::AIR
Block::AIR
}
}
}
@@ -51,18 +50,18 @@ pub enum FluidLevelSampler {
pub struct StaticFluidLevelSampler {
y: i32,
state: RawBlockState,
block: Block,
}
impl StaticFluidLevelSampler {
pub fn new(y: i32, state: RawBlockState) -> Self {
Self { y, state }
pub fn new(y: i32, block: Block) -> Self {
Self { y, block }
}
}
impl FluidLevelSamplerImpl for StaticFluidLevelSampler {
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,
) -> f64 {
let y = pos.y();
let block_state1 = level_1.get_block_state(y).to_block();
let block_state2 = level_2.get_block_state(y).to_block();
let block_state1 = level_1.get_block(y);
let block_state2 = level_2.get_block(y);
if (block_state1 != LAVA_BLOCK.to_block() || block_state2 != WATER_BLOCK.to_block())
&& (block_state1 != WATER_BLOCK.to_block() || block_state2 != LAVA_BLOCK.to_block())
if (block_state1 != LAVA_BLOCK || block_state2 != WATER_BLOCK)
&& (block_state1 != WATER_BLOCK || block_state2 != LAVA_BLOCK)
{
let level_diff = (level_1.max_y - level_2.max_y).abs();
if level_diff == 0 {
@@ -287,7 +286,7 @@ impl WorldAquiferSampler {
let bl3 = j > o;
if bl3 || bl2 {
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 {
bl = true;
}
@@ -411,11 +410,8 @@ impl WorldAquiferSampler {
level: i32,
router: &mut ChunkNoiseRouter,
sample_options: &ChunkNoiseFunctionSampleOptions,
) -> RawBlockState {
if level <= -10
&& level != MIN_HEIGHT_CELL
&& default_level.state.to_block() != LAVA_BLOCK.to_block()
{
) -> Block {
if level <= -10 && level != MIN_HEIGHT_CELL && default_level.block != LAVA_BLOCK {
let x = floor_div(block_x, 64);
let y = floor_div(block_y, 40);
let z = floor_div(block_z, 64);
@@ -427,7 +423,7 @@ impl WorldAquiferSampler {
}
}
default_level.state
default_level.block
}
fn apply_internal(
@@ -437,7 +433,7 @@ impl WorldAquiferSampler {
sample_options: &ChunkNoiseFunctionSampleOptions,
height_estimator: &mut SurfaceHeightEstimateSampler,
density: f64,
) -> Option<RawBlockState> {
) -> Option<BlockState> {
if density > 0f64 {
None
} else {
@@ -446,8 +442,8 @@ impl WorldAquiferSampler {
let k = pos.z();
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() {
Some(LAVA_BLOCK)
if fluid_level.get_block(j) == LAVA_BLOCK {
Some(LAVA_BLOCK.default_state)
} else {
let scaled_x = floor_div(i - 5, 16);
let scaled_y = floor_div(j + 1, 12);
@@ -501,21 +497,20 @@ impl WorldAquiferSampler {
);
let d =
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 {
// TODO: Handle fluid tick
Some(block_state)
} else if block_state.to_block() == WATER_BLOCK.to_block()
Some(block_state.default_state)
} else if block_state == WATER_BLOCK
&& self
.fluid_level
.get_fluid_level(i, j - 1, k)
.get_block_state(j - 1)
.to_block()
== LAVA_BLOCK.to_block()
.get_block(j - 1)
== LAVA_BLOCK
{
Some(block_state)
Some(block_state.default_state)
} else {
let barrier_sample = router.barrier_noise(pos, sample_options);
let fluid_level3 = self.get_water_level(
@@ -578,7 +573,7 @@ impl WorldAquiferSampler {
//TODO Handle fluid tick
Some(block_state)
Some(block_state.default_state)
}
}
}
@@ -594,7 +589,7 @@ impl AquiferSamplerImpl for WorldAquiferSampler {
pos: &impl NoisePos,
sample_options: &ChunkNoiseFunctionSampleOptions,
height_estimator: &mut SurfaceHeightEstimateSampler,
) -> Option<RawBlockState> {
) -> Option<BlockState> {
let density = router.final_density(pos, sample_options);
self.apply_internal(router, pos, sample_options, height_estimator, density)
}
@@ -617,7 +612,7 @@ impl AquiferSamplerImpl for SeaLevelAquiferSampler {
pos: &impl NoisePos,
sample_options: &ChunkNoiseFunctionSampleOptions,
_height_estimator: &mut SurfaceHeightEstimateSampler,
) -> Option<RawBlockState> {
) -> Option<BlockState> {
let sample = router.final_density(pos, sample_options);
//log::debug!("Aquifer sample {:?}: {}", &pos, sample);
if sample > 0f64 {
@@ -626,7 +621,8 @@ impl AquiferSamplerImpl for SeaLevelAquiferSampler {
Some(
self.level_sampler
.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,
sample_options: &ChunkNoiseFunctionSampleOptions,
height_estimator: &mut SurfaceHeightEstimateSampler,
) -> Option<RawBlockState>;
) -> Option<BlockState>;
}
#[cfg(test)]
@@ -728,7 +724,7 @@ mod test {
BlockStateSampler::Aquifer(aquifer) => aquifer,
_ => unreachable!(),
};
let aquifer = match sampler {
let aquifer = match *sampler {
AquiferSampler::Aquifer(aquifer) => aquifer,
_ => unreachable!(),
};
@@ -1445,7 +1441,7 @@ mod test {
for ((x, y, z), (y1, state)) in values {
let level = aquifer.get_fluid_level(x, y, z, &mut router, &mut height_estimator, &env);
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, 72, 0.11433776346079558), 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, 70, 0.002068623223791626), None),
((114, 0, 72, 0.0038193250297024243), None),
@@ -1807,9 +1809,18 @@ mod test {
((116, -20, 70, 0.11589560860382501), None),
((116, -20, 72, 0.11889599517563405), 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, 68, -7.530784033722614E-4), Some(WATER_BLOCK)),
(
(116, 0, 64, -0.003764380972543319),
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, 72, 0.0027605740566328273), None),
((116, 0, 74, 0.0046712919320928475), None),
@@ -1906,10 +1917,22 @@ mod test {
((118, -20, 70, 0.12038440430256446), None),
((118, -20, 72, 0.12325317705242089), 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, 68, -0.0020166185756455924), Some(WATER_BLOCK)),
((118, 0, 70, -2.901294172670075E-4), Some(WATER_BLOCK)),
(
(118, 0, 64, -0.00501589634392619),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(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, 74, 0.0035605198020311826), None),
((118, 20, 64, 0.040232966220497414), None),
@@ -2017,10 +2040,22 @@ mod test {
((120, -20, 70, 0.12469970986670785), None),
((120, -20, 72, 0.1274266324562779), 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, 68, -0.003355964670343278), Some(WATER_BLOCK)),
((120, 0, 70, -0.0016206542469077872), Some(WATER_BLOCK)),
(
(120, 0, 64, -0.006329576321547214),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(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, 74, 0.002332419553726638), None),
((120, 20, 64, 0.04783863627983937), None),
@@ -2050,12 +2085,30 @@ mod test {
(120, 40, 74, -0.013001583733654043),
Some(RawBlockState::AIR),
),
((120, 60, 64, -0.010805185122555435), Some(WATER_BLOCK)),
((120, 60, 66, -0.011684313707812422), Some(WATER_BLOCK)),
((120, 60, 68, -0.007705484690135335), Some(WATER_BLOCK)),
((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, 64, -0.010805185122555435),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(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, 66, -0.3586517592327399), 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, 72, 0.13141636494496137), 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, 68, -0.004737470102527975), Some(WATER_BLOCK)),
((122, 0, 70, -0.0030099389619020873), Some(WATER_BLOCK)),
((122, 0, 72, -0.0010942861750551764), Some(WATER_BLOCK)),
(
(122, 0, 64, -0.007667256303541582),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(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, 20, 64, 0.05535892661135848), None),
((122, 20, 66, 0.05444413322973901), None),
@@ -2152,12 +2220,30 @@ mod test {
Some(RawBlockState::AIR),
),
((122, 40, 74, -0.02133677750482264), None),
((122, 60, 64, -0.02580014098083049), Some(WATER_BLOCK)),
((122, 60, 66, -0.027410062228040422), Some(WATER_BLOCK)),
((122, 60, 68, -0.02425659570836858), Some(WATER_BLOCK)),
((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, 64, -0.02580014098083049),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(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),
Some(RawBlockState::AIR),
@@ -2224,11 +2310,26 @@ mod test {
((124, -20, 70, 0.1327707947453995), None),
((124, -20, 72, 0.13519345838131658), 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, 68, -0.0061446463166489424), Some(WATER_BLOCK)),
((124, 0, 70, -0.004442459854201204), Some(WATER_BLOCK)),
((124, 0, 72, -0.0025318494505197223), Some(WATER_BLOCK)),
(
(124, 0, 64, -0.009009809178163559),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(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, 20, 64, 0.06277697412858188), None),
((124, 20, 66, 0.06182400117210263), None),
@@ -2239,15 +2340,42 @@ mod test {
((124, 40, 64, -0.004596793013348681), None),
((124, 40, 66, -0.007881293688553023), 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, 74, -0.017978317799117856), Some(WATER_BLOCK)),
((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, 60, 70, -0.04106936165998065), Some(WATER_BLOCK)),
((124, 60, 72, -0.048715160337165046), Some(WATER_BLOCK)),
((124, 60, 74, -0.053817378732386144), Some(WATER_BLOCK)),
(
(124, 40, 70, -0.013513605008223933),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(124, 40, 72, -0.015880866729427373),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(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, 66, -0.37887533037235366),
@@ -2317,12 +2445,30 @@ mod test {
((126, -20, 70, 0.13641807828631622), None),
((126, -20, 72, 0.13869641277763253), 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, 68, -0.007576245457331987), Some(WATER_BLOCK)),
((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, 64, -0.010355206926252296),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(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, 66, 0.06908003164862005), None),
((126, 20, 68, 0.0681425614589177), None),
@@ -2331,16 +2477,46 @@ mod test {
((126, 20, 74, 0.06551116407146489), None),
((126, 40, 64, 0.004497597038868666), 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, 72, -0.006463772144671846), Some(WATER_BLOCK)),
((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, 60, 68, -0.04568337003176991), Some(WATER_BLOCK)),
((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, 68, -0.0015191728313191184),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(126, 40, 70, -0.0041188588354404134),
Some(RawBlockState(WATER_BLOCK.default_state.id)),
),
(
(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),
Some(RawBlockState::AIR),
@@ -2386,7 +2562,7 @@ mod test {
let pos = UnblendedNoisePos::new(x, y, z);
assert_eq!(
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 {
pub fn get(&self, random: &mut RandomGenerator) -> BlockState {
Pool.get(&self.entries, random)
Pool::get(&self.entries, random)
.unwrap()
.get_state()
.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 crate::{block::RawBlockState, generation::section_coords};
use crate::generation::section_coords;
use super::{
GlobalRandomConfig,
@@ -24,13 +24,13 @@ use super::{
settings::GenerationShapeConfig,
};
pub const LAVA_BLOCK: RawBlockState = default_block_state!("lava");
pub const WATER_BLOCK: RawBlockState = default_block_state!("water");
pub const LAVA_BLOCK: Block = Block::LAVA;
pub const WATER_BLOCK: Block = Block::WATER;
pub const CHUNK_DIM: u8 = 16;
pub enum BlockStateSampler {
Aquifer(AquiferSampler),
Aquifer(Box<AquiferSampler>),
Ore(OreVeinSampler),
Chained(ChainedBlockStateSampler),
}
@@ -42,7 +42,7 @@ impl BlockStateSampler {
pos: &impl NoisePos,
sample_options: &ChunkNoiseFunctionSampleOptions,
height_estimator: &mut SurfaceHeightEstimateSampler,
) -> Option<RawBlockState> {
) -> Option<BlockState> {
match self {
Self::Aquifer(aquifer) => aquifer.apply(router, pos, sample_options, height_estimator),
Self::Ore(ore) => ore.sample(router, pos, sample_options),
@@ -66,7 +66,7 @@ impl ChainedBlockStateSampler {
pos: &impl NoisePos,
sample_options: &ChunkNoiseFunctionSampleOptions,
height_estimator: &mut SurfaceHeightEstimateSampler,
) -> Option<RawBlockState> {
) -> Option<BlockState> {
self.samplers
.iter_mut()
.map(|sampler| sampler.sample(router, pos, sample_options, height_estimator))
@@ -221,7 +221,7 @@ impl<'a> ChunkNoiseGenerator<'a> {
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 {
let ore_sampler = OreVeinSampler::new(random_config.ore_random_deriver.clone());
@@ -370,7 +370,7 @@ impl<'a> ChunkNoiseGenerator<'a> {
start_pos: Vector3<i32>,
cell_pos: Vector3<i32>,
height_estimator: &mut SurfaceHeightEstimateSampler,
) -> Option<RawBlockState> {
) -> Option<BlockState> {
//TODO: Fix this when Blender is added
let pos = UnblendedNoisePos::new(
start_pos.x + cell_pos.x,

View File

@@ -50,15 +50,12 @@ impl BambooFeature {
if !block.to_block().is_tagged_with("minecraft:dirt").unwrap() {
continue;
}
chunk.set_block_state(
&block_below.0,
&get_state_by_state_id(Block::PODZOL.id).unwrap(),
);
chunk.set_block_state(&block_below.0, &Block::PODZOL.default_state);
}
}
}
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 {
if chunk.is_air(&bpos.0) {
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 original_props = &wall_coral
.properties(wall_coral.default_state_id)
.properties(wall_coral.default_state.id)
.unwrap()
.to_props();
let facing = dir.to_facing();
@@ -89,7 +89,7 @@ impl CoralFeature {
pub fn get_random_tag_entry(tag: &str, random: &mut RandomGenerator) -> BlockState {
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 {

View File

@@ -1,5 +1,4 @@
use pumpkin_data::BlockDirection;
use pumpkin_macros::default_block_state;
use pumpkin_data::{Block, BlockDirection};
use pumpkin_util::{
math::{position::BlockPos, vector3::Vector3},
random::RandomGenerator,
@@ -8,7 +7,6 @@ use serde::Deserialize;
use crate::{
ProtoChunk,
block::RawBlockState,
generation::{chunk_noise::WATER_BLOCK, height_limit::HeightLimitView},
};
@@ -18,10 +16,10 @@ use crate::{
pub struct DesertWellFeature;
impl DesertWellFeature {
const CAN_GENERATE: RawBlockState = default_block_state!("sand");
const SAND: RawBlockState = default_block_state!("sand");
const SLAB: RawBlockState = default_block_state!("sandstone_slab");
const WALL: RawBlockState = default_block_state!("sandstone");
const CAN_GENERATE: Block = Block::SAND;
const SAND: Block = Block::SAND;
const SLAB: Block = Block::SANDSTONE_SLAB;
const WALL: Block = Block::SANDSTONE;
pub fn generate(
&self,
@@ -37,8 +35,8 @@ impl DesertWellFeature {
block_pos = block_pos.down();
}
let block = chunk.get_block_state(&pos.0).to_block();
const CAN_GENERATE: RawBlockState = default_block_state!("sand");
if CAN_GENERATE.to_block().id != block.id {
const CAN_GENERATE: Block = Block::SAND;
if CAN_GENERATE.id != block.id {
return false;
}
@@ -58,28 +56,28 @@ impl DesertWellFeature {
for k in -2..=2 {
chunk.set_block_state(
&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() {
chunk.set_block_state(
&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));
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() {
chunk.set_block_state(
&block_pos2.add(&direction2.to_offset()),
&Self::SAND.to_state(),
&Self::SAND.default_state,
);
}
@@ -90,26 +88,26 @@ impl DesertWellFeature {
}
chunk.set_block_state(
&block_pos.0.add(&Vector3::new(j, 1, k)),
&Self::WALL.to_state(),
&Self::WALL.default_state,
);
}
}
chunk.set_block_state(
&block_pos.0.add(&Vector3::new(2, 1, 0)),
&Self::SLAB.to_state(),
&Self::SLAB.default_state,
);
chunk.set_block_state(
&block_pos.0.add(&Vector3::new(-2, 1, 0)),
&Self::SLAB.to_state(),
&Self::SLAB.default_state,
);
chunk.set_block_state(
&block_pos.0.add(&Vector3::new(0, 1, 2)),
&Self::SLAB.to_state(),
&Self::SLAB.default_state,
);
chunk.set_block_state(
&block_pos.0.add(&Vector3::new(0, 1, -2)),
&Self::SLAB.to_state(),
&Self::SLAB.default_state,
);
for j in -1..=1 {
@@ -117,13 +115,13 @@ impl DesertWellFeature {
if j == 0 && k == 0 {
chunk.set_block_state(
&block_pos.0.add(&Vector3::new(j, 4, k)),
&Self::WALL.to_state(),
&Self::WALL.default_state,
);
continue;
}
chunk.set_block_state(
&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 {
chunk.set_block_state(
&block_pos.0.add(&Vector3::new(-1, j, -1)),
&Self::WALL.to_state(),
&Self::WALL.default_state,
);
chunk.set_block_state(
&block_pos.0.add(&Vector3::new(-1, j, 1)),
&Self::WALL.to_state(),
&Self::WALL.default_state,
);
chunk.set_block_state(
&block_pos.0.add(&Vector3::new(1, j, -1)),
&Self::WALL.to_state(),
&Self::WALL.default_state,
);
chunk.set_block_state(
&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 crate::ProtoChunk;
@@ -20,10 +20,7 @@ pub(super) fn gen_dripstone(chunk: &mut ProtoChunk, pos: BlockPos) -> bool {
.is_tagged_with("minecraft:dripstone_replaceable_blocks")
.unwrap()
{
chunk.set_block_state(
&pos.0,
&get_state_by_state_id(Block::DRIPSTONE_BLOCK.default_state_id).unwrap(),
);
chunk.set_block_state(&pos.0, &Block::DRIPSTONE_BLOCK.default_state);
return true;
}
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 serde::Deserialize;
@@ -22,13 +22,12 @@ impl EndPlatformFeature {
for _ in -2..2 {
for _ in -2..2 {
for t in -1..3 {
let block = if t == -1 {
Block::OBSIDIAN.default_state_id
let state = if t == -1 {
Block::OBSIDIAN.default_state
} 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).state_id == state.id {
if chunk.get_block_state(&pos.0).0 == state.id {
continue;
}
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::{
math::position::BlockPos,
random::{RandomGenerator, RandomImpl},
@@ -98,19 +98,13 @@ impl EndSpikeFeature {
<= (radius * radius + 1)
&& pos.0.y < spike.height
{
chunk.set_block_state(
&pos.0,
&get_state_by_state_id(Block::OBSIDIAN.default_state_id).unwrap(),
);
chunk.set_block_state(&pos.0, &Block::OBSIDIAN.default_state);
continue;
}
if pos.0.y <= 65 {
continue;
}
chunk.set_block_state(
&pos.0,
&get_state_by_state_id(Block::AIR.default_state_id).unwrap(),
);
chunk.set_block_state(&pos.0, &Block::AIR.default_state);
}
// TODO
}

View File

@@ -38,20 +38,14 @@ impl SeagrassFeature {
if chunk.get_block_state(&tall_pos.0).to_block() == Block::WATER {
let mut props = TallSeagrassLikeProperties::default(&Block::TALL_SEAGRASS);
props.half = DoubleBlockHalf::Upper;
chunk.set_block_state(
&top_pos.0,
&get_state_by_state_id(Block::TALL_SEAGRASS.default_state_id).unwrap(),
);
chunk.set_block_state(&top_pos.0, &Block::TALL_SEAGRASS.default_state);
chunk.set_block_state(
&tall_pos.0,
&get_state_by_state_id(props.to_state_id(&Block::TALL_SEAGRASS)).unwrap(),
);
}
} else {
chunk.set_block_state(
&top_pos.0,
&get_state_by_state_id(Block::SEAGRASS.default_state_id).unwrap(),
);
chunk.set_block_state(&top_pos.0, &Block::SEAGRASS.default_state);
}
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 block =
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::{
math::clamped_map,
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::{
chunk_density_function::ChunkNoiseFunctionSampleOptions, density_function::NoisePos,
@@ -23,7 +24,7 @@ impl OreVeinSampler {
router: &mut ChunkNoiseRouter,
pos: &impl NoisePos,
sample_options: &ChunkNoiseFunctionSampleOptions,
) -> Option<RawBlockState> {
) -> Option<BlockState> {
let vein_toggle = router.vein_toggle(pos, sample_options);
let vein_type: &VeinType = if vein_toggle > 0f64 {
&vein_type::COPPER
@@ -56,12 +57,12 @@ impl OreVeinSampler {
&& vein_gap > (-0.3f32 as f64)
{
Some(if random.next_f32() < 0.02f32 {
vein_type.raw_ore
vein_type.raw_ore.default_state.clone()
} else {
vein_type.ore
vein_type.ore.default_state.clone()
})
} else {
Some(vein_type.stone)
Some(vein_type.stone.default_state.clone())
};
}
}
@@ -71,29 +72,29 @@ impl OreVeinSampler {
}
pub struct VeinType {
ore: RawBlockState,
raw_ore: RawBlockState,
stone: RawBlockState,
ore: Block,
raw_ore: Block,
stone: Block,
min_y: i32,
max_y: i32,
}
// One of the victims of removing compile time blocks
pub mod vein_type {
use pumpkin_macros::default_block_state;
use pumpkin_data::Block;
use super::*;
pub const COPPER: VeinType = VeinType {
ore: default_block_state!("copper_ore"),
raw_ore: default_block_state!("raw_copper_block"),
stone: default_block_state!("granite"),
ore: Block::COPPER_ORE,
raw_ore: Block::RAW_COPPER_BLOCK,
stone: Block::GRANITE,
min_y: 0,
max_y: 50,
};
pub const IRON: VeinType = VeinType {
ore: default_block_state!("deepslate_iron_ore"),
raw_ore: default_block_state!("raw_iron_block"),
stone: default_block_state!("tuff"),
ore: Block::DEEPSLATE_IRON_ORE,
raw_ore: Block::RAW_IRON_BLOCK,
stone: Block::TUFF,
min_y: -60,
max_y: -8,
};

View File

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

View File

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

View File

@@ -53,6 +53,6 @@ pub trait WallMountedBlock {
) -> Option<BlockStateId> {
(self.get_direction(state_id, block).opposite() == direction
&& !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) {
// TODO: push up entities
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;
}
@@ -40,10 +40,10 @@ impl PumpkinBlock for DirtPathBlock {
_use_item_on: &SUseItemOn,
) -> BlockStateId {
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(

View File

@@ -24,7 +24,7 @@ impl PumpkinBlock for FarmLandBlock {
async fn on_scheduled_tick(&self, world: &Arc<World>, _block: &Block, pos: &BlockPos) {
// TODO: push up entities
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;
}
@@ -40,9 +40,9 @@ impl PumpkinBlock for FarmLandBlock {
_use_item_on: &SUseItemOn,
) -> BlockStateId {
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(

View File

@@ -108,7 +108,7 @@ impl PumpkinBlock for FireBlock {
_neighbor_state: BlockStateId,
) -> BlockStateId {
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

View File

@@ -41,7 +41,7 @@ impl PumpkinBlock for SoulFireBlock {
_neighbor_state: BlockStateId,
) -> BlockStateId {
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

View File

@@ -33,7 +33,7 @@ impl PumpkinBlock for GrindstoneBlock {
_replacing: BlockIsReplacing,
_use_item_on: &SUseItemOn,
) -> 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.to_state_id(block)

View File

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

View File

@@ -162,7 +162,7 @@ impl PumpkinBlock for NoteBlock {
_replacing: BlockIsReplacing,
_use_item_on: &SUseItemOn,
) -> 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(

View File

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

View File

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

View File

@@ -85,7 +85,7 @@ pub trait RedstoneGateBlock<T: Send + BlockProperties + RedstoneGateBlockPropert
return;
}
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;
for dir in BlockDirection::all() {
world

View File

@@ -161,7 +161,7 @@ impl PumpkinBlock for ButtonBlock {
_replacing: BlockIsReplacing,
_use_item_on: &SUseItemOn,
) -> 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.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)
.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,
_use_item_on: &SUseItemOn,
) -> 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.to_state_id(block)

View File

@@ -55,7 +55,7 @@ impl PumpkinBlock for RedstoneTorchBlock {
if face == BlockDirection::Down {
let support_block = world.get_block_state(&block_pos.down()).await;
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();
@@ -74,7 +74,7 @@ impl PumpkinBlock for RedstoneTorchBlock {
} else if directions[0] == Facing::Down {
let support_block = world.get_block_state(&block_pos.down()).await;
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;
if support_block.is_center_solid(BlockDirection::Up) {
block.default_state_id
block.default_state.id
} else {
0
}

View File

@@ -229,7 +229,7 @@ impl PumpkinBlock for RepeaterBlock {
if !RedstoneGateBlock::can_place_above(self, world, *neighbor_pos, &neighbor_state)
.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)
});
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.south = connect_south.await;

View File

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

View File

@@ -50,7 +50,7 @@ impl PumpkinBlock for TorchBlock {
if face == BlockDirection::Down {
let support_block = world.get_block_state(&block_pos.down()).await;
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();
@@ -69,7 +69,7 @@ impl PumpkinBlock for TorchBlock {
} else if directions[0] == Facing::Down {
let support_block = world.get_block_state(&block_pos.down()).await;
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;
if support_block.is_center_solid(BlockDirection::Up) {
block.default_state_id
block.default_state.id
} else {
0
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -58,7 +58,7 @@ pub trait ArgumentConsumer: Sync + GetClientSideArgParser {
args: &mut RawArgs<'a>,
) -> 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.
async fn suggest<'a>(

View File

@@ -46,7 +46,7 @@ impl CommandExecutor for Executor {
args: &ConsumedArgs<'a>,
) -> Result<(), CommandError> {
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 to = BlockPosArgumentConsumer::find_arg(args, ARG_TO)?;
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) {
players
} else if let Some(player) = sender.as_player() {
&[player.clone()]
&[player]
} else {
return Ok(());
};

View File

@@ -39,7 +39,7 @@ impl CommandExecutor for Executor {
args: &ConsumedArgs<'a>,
) -> Result<(), CommandError> {
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 mode = self.0;
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_util::math::{position::BlockPos, vector3::Vector3};
@@ -48,13 +47,10 @@ impl Navigator {
goal.current_progress.y,
goal.current_progress.z + z,
);
let shapes = get_block_collision_shapes(
world
.get_block_state(&BlockPos(potential_pos.to_i32()))
.await
.id,
)
.unwrap();
let state = world
.get_block_state(&BlockPos(potential_pos.to_i32()))
.await;
let shapes = state.get_block_collision_shapes();
if !shapes.is_empty() {
continue;
}

View File

@@ -6,7 +6,7 @@ use crossbeam::atomic::AtomicCell;
use living::LivingEntity;
use player::Player;
use pumpkin_data::{
block_properties::{Facing, HorizontalFacing, get_block_outline_shapes},
block_properties::{Facing, HorizontalFacing},
damage::DamageType,
entity::{EntityPose, EntityType},
sound::{Sound, SoundCategory},
@@ -673,7 +673,7 @@ impl Entity {
for z in blockpos.0.z..=blockpos1.0.z {
let pos = BlockPos::new(x, y, z);
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 outlines.is_empty() {

View File

@@ -65,7 +65,7 @@ impl EntityBase for TNTEntity {
Metadata::new(
9,
MetaDataType::BlockState,
VarInt(i32::from(Block::TNT.default_state_id)),
VarInt(i32::from(Block::TNT.default_state.id)),
),
])
.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.
// If there is a strip equivalent.
if replacement_block.is_some() {
let new_block = Block::from_id(replacement_block.unwrap());
if let Some(replacement_block) = replacement_block {
let new_block = Block::from_id(replacement_block);
let new_block = &new_block.unwrap();
let new_state_id = if block.is_tagged_with("#minecraft:logs") == Some(true) {
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.to_state_id(new_block)
} else {
new_block.default_state_id
new_block.default_state.id
};
// TODO Implements trapdoors when It's implemented
world

View File

@@ -102,13 +102,13 @@ impl PumpkinItem for EmptyBucketItem {
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;
}
(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::LAVA.id && state_id == Block::LAVA.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))
};
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)
.await;
world.schedule_fluid_tick(block.id, block_pos, 5).await;
} else if state.id == Block::LAVA.default_state_id
|| state.id == Block::WATER.default_state_id
} else if state.id == Block::LAVA.default_state.id
|| state.id == Block::WATER.default_state.id
{
world
.break_block(&block_pos, None, BlockFlags::NOTIFY_NEIGHBORS)
@@ -142,7 +142,7 @@ impl PumpkinItem for EmptyBucketItem {
world
.set_block_state(
&block_pos,
Block::AIR.default_state_id,
Block::AIR.default_state.id,
BlockFlags::NOTIFY_NEIGHBORS,
)
.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
} else {
&Item::WATER_BUCKET
@@ -255,14 +255,14 @@ impl PumpkinItem for FilledBucketItem {
world
.schedule_fluid_tick(block.id, pos.offset(direction.to_offset()), 5)
.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
.set_block_state(
&pos.offset(direction.to_offset()),
if item.id == Item::LAVA_BUCKET.id {
Block::LAVA.default_state_id
Block::LAVA.default_state.id
} else {
Block::WATER.default_state_id
Block::WATER.default_state.id
},
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 checker = async |pos: &BlockPos, world_inner: &Arc<World>| {
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 {

View File

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

View File

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

View File

@@ -29,7 +29,7 @@ impl Ignition {
let result_block_id = get_ignite_result(block, &world, &location)
.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 {
return;

View File

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

View File

@@ -10,7 +10,7 @@ use thiserror::Error;
use pumpkin_config::{BASIC_CONFIG, advanced_config};
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::item::Item;
@@ -1119,7 +1119,6 @@ impl Player {
[],
))
.await;
return;
}
}
ActionType::Interact | ActionType::InteractAt => {
@@ -1782,7 +1781,9 @@ impl Player {
.await;
// 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 {
let player_box = player.1.living_entity.entity.bounding_box.load();
for shape in &shapes {

View File

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

View File

@@ -30,6 +30,7 @@ use border::Worldborder;
use bytes::{BufMut, Bytes};
use explosion::Explosion;
use pumpkin_config::BasicConfiguration;
use pumpkin_data::BlockDirection;
use pumpkin_data::entity::EffectType;
use pumpkin_data::fluid::{Falling, FluidProperties};
use pumpkin_data::{
@@ -43,7 +44,6 @@ use pumpkin_data::{
sound::{Sound, SoundCategory},
world::{RAW, WorldEvent},
};
use pumpkin_data::{BlockDirection, block_properties::get_block_outline_shapes};
use pumpkin_inventory::equipment_slot::EquipmentSlot;
use pumpkin_macros::send_cancellable;
use pumpkin_nbt::{compound::NbtCompound, to_bytes_unnamed};
@@ -1468,7 +1468,6 @@ impl World {
}
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;
// WorldChunk.java line 318
@@ -1678,14 +1677,13 @@ impl World {
}
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.
pub async fn get_block_state(&self, position: &BlockPos) -> pumpkin_data::BlockState {
let id = self.get_block_state_id(position).await;
get_state_by_state_id(id)
.unwrap_or(get_state_by_state_id(Block::AIR.default_state_id).unwrap())
get_state_by_state_id(id).unwrap_or(Block::AIR.default_state)
}
/// 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,
) -> (pumpkin_data::Block, pumpkin_data::BlockState) {
let id = self.get_block_state_id(position).await;
get_block_and_state_by_state_id(id).unwrap_or((
Block::AIR,
get_state_by_state_id(Block::AIR.default_state_id).unwrap(),
))
get_block_and_state_by_state_id(id).unwrap_or((Block::AIR, Block::AIR.default_state))
}
/// Updates neighboring blocks of a block
@@ -1910,9 +1905,9 @@ impl World {
from: Vector3<f64>,
to: Vector3<f64>,
) -> (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);
};
@@ -2087,9 +2082,6 @@ impl BlockAccessor for World {
position: &BlockPos,
) -> (pumpkin_data::Block, pumpkin_data::BlockState) {
let id = self.get_block_state(position).await.id;
get_block_and_state_by_state_id(id).unwrap_or((
Block::AIR,
get_state_by_state_id(Block::AIR.default_state_id).unwrap(),
))
get_block_and_state_by_state_id(id).unwrap_or((Block::AIR, Block::AIR.default_state))
}
}

View File

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