aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--azalea-block/azalea-block-macros/src/lib.rs10
-rw-r--r--azalea-block/src/block_state.rs21
-rw-r--r--azalea-block/src/range.rs2
-rw-r--r--azalea-physics/src/collision/blocks.rs10
-rw-r--r--azalea-protocol/src/packets/game/c_section_blocks_update.rs2
-rw-r--r--azalea-world/src/chunk_storage.rs17
-rw-r--r--azalea-world/src/find_blocks.rs14
-rw-r--r--azalea-world/src/palette.rs124
-rw-r--r--azalea/src/pathfinder/mining.rs20
-rw-r--r--azalea/src/pathfinder/world.rs41
-rw-r--r--codegen/lib/code/shapes.py8
-rw-r--r--codegen/lib/utils.py2
12 files changed, 132 insertions, 139 deletions
diff --git a/azalea-block/azalea-block-macros/src/lib.rs b/azalea-block/azalea-block-macros/src/lib.rs
index 7952a8d1..f1b5c10f 100644
--- a/azalea-block/azalea-block-macros/src/lib.rs
+++ b/azalea-block/azalea-block-macros/src/lib.rs
@@ -552,7 +552,7 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
from_block_to_state_match_inner.extend(quote! {
#block_struct_name {
#from_block_to_state_combination_match_inner
- } => BlockState { id: #state_id },
+ } => BlockState::new_const(#state_id),
});
if is_default {
@@ -626,7 +626,7 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
azalea_registry::Block::#block_name_pascal_case => Box::new(#block_struct_name::default()),
});
from_registry_block_to_blockstate_match.extend(quote! {
- azalea_registry::Block::#block_name_pascal_case => BlockState { id: #default_state_id },
+ azalea_registry::Block::#block_name_pascal_case => BlockState::new_const(#default_state_id),
});
from_registry_block_to_blockstates_match.extend(quote! {
azalea_registry::Block::#block_name_pascal_case => BlockStates::from(#first_state_id..=#last_state_id),
@@ -646,7 +646,7 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
let block_id = block.name.to_string();
let from_block_to_state_match = if block.properties_and_defaults.is_empty() {
- quote! { BlockState { id: #first_state_id } }
+ quote! { BlockState::new_const(#first_state_id) }
} else {
quote! {
match self {
@@ -762,7 +762,7 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
type Value = #value;
fn try_from_block_state(block_state: BlockState) -> Option<Self::Value> {
- match block_state.id {
+ match block_state.id() {
#enum_inner_generated
_ => None
}
@@ -788,7 +788,7 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
impl From<BlockState> for Box<dyn Block> {
fn from(block_state: BlockState) -> Self {
- let b = block_state.id;
+ let b = block_state.id();
match b {
#from_state_to_block_match
_ => panic!("Invalid block state: {}", b),
diff --git a/azalea-block/src/block_state.rs b/azalea-block/src/block_state.rs
index 6a185ee4..36a01863 100644
--- a/azalea-block/src/block_state.rs
+++ b/azalea-block/src/block_state.rs
@@ -1,5 +1,6 @@
use std::{
fmt::{self, Debug},
+ hint::assert_unchecked,
io::{self, Cursor, Write},
};
@@ -27,7 +28,7 @@ pub type BlockStateIntegerRepr = u16;
pub struct BlockState {
/// The protocol ID for the block state. IDs may change every
/// version, so you shouldn't hard-code them or store them in databases.
- pub id: BlockStateIntegerRepr,
+ id: BlockStateIntegerRepr,
}
impl BlockState {
@@ -35,12 +36,21 @@ impl BlockState {
/// 0.
pub const AIR: BlockState = BlockState { id: 0 };
+ /// Create a new BlockState and panic if the block is not a valid state.
+ ///
+ /// You should probably use [`BlockState::try_from`] instead.
+ #[inline]
+ pub(crate) const fn new_const(id: BlockStateIntegerRepr) -> Self {
+ assert!(Self::is_valid_state(id));
+ Self { id }
+ }
+
/// Whether the block state is possible to exist in vanilla Minecraft.
///
/// It's equivalent to checking that the state ID is not greater than
/// [`Self::MAX_STATE`].
#[inline]
- pub fn is_valid_state(state_id: BlockStateIntegerRepr) -> bool {
+ pub const fn is_valid_state(state_id: BlockStateIntegerRepr) -> bool {
state_id <= Self::MAX_STATE
}
@@ -50,6 +60,13 @@ impl BlockState {
pub fn is_air(&self) -> bool {
self == &Self::AIR
}
+
+ /// Returns the protocol ID for the block state. IDs may change every
+ /// version, so you shouldn't hard-code them or store them in databases.
+ #[inline]
+ pub const fn id(&self) -> BlockStateIntegerRepr {
+ self.id
+ }
}
impl TryFrom<u32> for BlockState {
diff --git a/azalea-block/src/range.rs b/azalea-block/src/range.rs
index 18e74c88..cbe77284 100644
--- a/azalea-block/src/range.rs
+++ b/azalea-block/src/range.rs
@@ -14,7 +14,7 @@ impl From<RangeInclusive<BlockStateIntegerRepr>> for BlockStates {
fn from(range: RangeInclusive<BlockStateIntegerRepr>) -> Self {
let mut set = HashSet::with_capacity((range.end() - range.start() + 1) as usize);
for id in range {
- set.insert(BlockState { id });
+ set.insert(BlockState::try_from(id).unwrap_or_default());
}
Self { set }
}
diff --git a/azalea-physics/src/collision/blocks.rs b/azalea-physics/src/collision/blocks.rs
index 048ee067..ec1efc4d 100644
--- a/azalea-physics/src/collision/blocks.rs
+++ b/azalea-physics/src/collision/blocks.rs
@@ -4910,19 +4910,21 @@ static SHAPE760: LazyLock<VoxelShape> =
impl BlockWithShape for BlockState {
fn collision_shape(&self) -> &'static VoxelShape {
COLLISION_SHAPES_MAP
- .get(self.id as usize)
+ .get(self.id() as usize)
.unwrap_or(&&SHAPE1)
}
fn outline_shape(&self) -> &'static VoxelShape {
- OUTLINE_SHAPES_MAP.get(self.id as usize).unwrap_or(&&SHAPE1)
+ OUTLINE_SHAPES_MAP
+ .get(self.id() as usize)
+ .unwrap_or(&&SHAPE1)
}
fn is_collision_shape_empty(&self) -> bool {
- matches!(self.id, 0|29..=42|45..=84|86..=117|1987..=2034|2047..=2050|2054..=2056|2109..=2136|2401..=2918|3042..=4337|4342..=4349|4366..=4589|4622..=4685|4758..=4777|4858..=4913|4922..=5385|5450..=5705|5802..=5827|5892..=5905|5908..=5911|5916..=5950|5978..=5993|6037..=6041|6043..=6044|7056..=7239|7368..=7369|7372..=7373|7376..=7377|7380..=7381|7384..=7385|7388..=7389|7392..=7393|7396..=7397|8169..=8172|8190|8305..=8448|8709|8712|9033|9036|9380..=9563|9588..=9635|9952..=9983|10129..=10152|11256..=11287|11636..=11967|12205..=12206|12209..=12210|12213..=12214|12217..=12218|12221..=12222|12225..=12226|12229..=12230|12233..=12234|12237..=12238|12241..=12242|12245..=12246|12249..=12250|12253..=12254|12257..=12258|12261..=12262|12265..=12266|12269..=12270|12273..=12274|12277..=12278|12281..=12282|12285..=12286|12289..=12290|12293..=12294|12297..=12298|12301..=12302|12305..=12306|12309..=12310|12313..=12314|12317..=12318|12321..=12322|12325..=12326|12329..=12330|12333..=12334|12337..=12338|12341..=12342|12345..=12346|12349..=12350|12353..=12354|12357..=12358|12361..=12362|12365..=12366|12369..=12370|12373..=12374|12377..=12378|12381..=12382|12385..=12386|12389..=12390|12393..=12394|12429..=12430|12433..=12434|12437..=12438|12441..=12442|12445..=12446|12449..=12450|12453..=12454|12457..=12458|12461..=12462|12465..=12466|12469..=12470|12473..=12474|12477..=12478|12481..=12482|12485..=12486|12489..=12490|13518..=13519|13522|13524|13526|13528|13530..=13535|13537|13572|13783..=13809|13836..=13955|13967|13981..=13984|15189|15192|15513|15516|15837|15840|16161|16164|16485|16488|16809|16812|17133|17136|17457|17460|17781|17784|18105|18108|18429|18432|18753|18756|19077|19080|19598..=19601|19615|19617..=19618|19632|19634..=19688|19703..=19706|19899..=19900|19903..=19904|19907..=19908|19911..=19912|19915..=19916|19919..=19920|19923..=19924|19927..=19928|19931..=19932|19935..=19936|19939..=19940|19943..=19944|19947..=19948|19951..=19952|19955..=19956|19959..=19960|20123..=20170|20299..=20378|20575|20578|20995|20998|21400..=21425|21432|21435|22202|22205|22613|22616|23025|23028|23346|23828..=23955|25797..=25851|25855..=25870|25910..=25911|25918..=25919|25926..=25927|25934..=25961|26060|26063|26471|26474|26882|26885|27293|27296|27632)
+ matches!(self.id(), 0|29..=42|45..=84|86..=117|1987..=2034|2047..=2050|2054..=2056|2109..=2136|2401..=2918|3042..=4337|4342..=4349|4366..=4589|4622..=4685|4758..=4777|4858..=4913|4922..=5385|5450..=5705|5802..=5827|5892..=5905|5908..=5911|5916..=5950|5978..=5993|6037..=6041|6043..=6044|7056..=7239|7368..=7369|7372..=7373|7376..=7377|7380..=7381|7384..=7385|7388..=7389|7392..=7393|7396..=7397|8169..=8172|8190|8305..=8448|8709|8712|9033|9036|9380..=9563|9588..=9635|9952..=9983|10129..=10152|11256..=11287|11636..=11967|12205..=12206|12209..=12210|12213..=12214|12217..=12218|12221..=12222|12225..=12226|12229..=12230|12233..=12234|12237..=12238|12241..=12242|12245..=12246|12249..=12250|12253..=12254|12257..=12258|12261..=12262|12265..=12266|12269..=12270|12273..=12274|12277..=12278|12281..=12282|12285..=12286|12289..=12290|12293..=12294|12297..=12298|12301..=12302|12305..=12306|12309..=12310|12313..=12314|12317..=12318|12321..=12322|12325..=12326|12329..=12330|12333..=12334|12337..=12338|12341..=12342|12345..=12346|12349..=12350|12353..=12354|12357..=12358|12361..=12362|12365..=12366|12369..=12370|12373..=12374|12377..=12378|12381..=12382|12385..=12386|12389..=12390|12393..=12394|12429..=12430|12433..=12434|12437..=12438|12441..=12442|12445..=12446|12449..=12450|12453..=12454|12457..=12458|12461..=12462|12465..=12466|12469..=12470|12473..=12474|12477..=12478|12481..=12482|12485..=12486|12489..=12490|13518..=13519|13522|13524|13526|13528|13530..=13535|13537|13572|13783..=13809|13836..=13955|13967|13981..=13984|15189|15192|15513|15516|15837|15840|16161|16164|16485|16488|16809|16812|17133|17136|17457|17460|17781|17784|18105|18108|18429|18432|18753|18756|19077|19080|19598..=19601|19615|19617..=19618|19632|19634..=19688|19703..=19706|19899..=19900|19903..=19904|19907..=19908|19911..=19912|19915..=19916|19919..=19920|19923..=19924|19927..=19928|19931..=19932|19935..=19936|19939..=19940|19943..=19944|19947..=19948|19951..=19952|19955..=19956|19959..=19960|20123..=20170|20299..=20378|20575|20578|20995|20998|21400..=21425|21432|21435|22202|22205|22613|22616|23025|23028|23346|23828..=23955|25797..=25851|25855..=25870|25910..=25911|25918..=25919|25926..=25927|25934..=25961|26060|26063|26471|26474|26882|26885|27293|27296|27632)
}
fn is_collision_shape_full(&self) -> bool {
- matches!(self.id, 1..=21|26..=28|85|118..=156|160..=188|192..=245|249..=447|476..=1730|2041..=2046|2063..=2068|2093..=2108|2137..=2400|2919|4338..=4341|4358..=4365|5912..=5915|5958..=5959|5977|5994..=5995|6028|6030..=6036|6042|6045..=6052|6124..=6139|6780..=6983|7054..=7055|7640..=7641|8056|8199|8201..=8202|8295..=8296|8449|8690..=8702|10032..=10033|10044..=10048|10153..=10180|11253..=11255|11352..=11354|11599..=11600|11605..=11606|11611..=11616|11633..=11635|11968..=11970|12055..=12056|12061..=12062|12067..=12068|12073..=12074|12079..=12080|12085..=12086|12091..=12092|12103..=12104|12109..=12110|12115..=12116|12121..=12122|12127..=12128|12133..=12134|12139..=12140|12145..=12146|12151..=12152|12157..=12158|12163..=12164|12169..=12170|12175..=12176|12181..=12182|12187..=12188|12193..=12194|12199..=12204|13427..=13436|13517|13538..=13571|13573..=13782|13810|13826..=13835|13964|15109..=15110|15115..=15116|15121..=15122|15127..=15128|15133..=15134|15139..=15140|15145..=15146|15151..=15152|15157..=15158|15163..=15164|15169..=15170|15175..=15176|15181..=15182|19427..=19460|19489|19602..=19614|19616|19619..=19631|19633|19689..=19690|19695..=19696|19701..=19702|20379..=20394|20409..=20472|20474..=20482|20487..=20488|20897..=20902|20907..=20908|21313|21398..=21399|21750..=21752|22059..=22060|22109|22114..=22115|22520|22525..=22526|22931..=22932|22937..=22938|23343..=23345|23827|23956..=23957|23966..=23983|24308..=24309|24314..=24315|24320..=24321|24326..=24335|24660..=24661|24666..=24667|24672..=24673|24678..=24679|25704..=25751|25796|25903|25962|25964..=25967|26052..=26053|26378|26463..=26464|26789|26874..=26875|27200|27285..=27286|27611..=27620|27623..=27631|27633|27650..=27703)
+ matches!(self.id(), 1..=21|26..=28|85|118..=156|160..=188|192..=245|249..=447|476..=1730|2041..=2046|2063..=2068|2093..=2108|2137..=2400|2919|4338..=4341|4358..=4365|5912..=5915|5958..=5959|5977|5994..=5995|6028|6030..=6036|6042|6045..=6052|6124..=6139|6780..=6983|7054..=7055|7640..=7641|8056|8199|8201..=8202|8295..=8296|8449|8690..=8702|10032..=10033|10044..=10048|10153..=10180|11253..=11255|11352..=11354|11599..=11600|11605..=11606|11611..=11616|11633..=11635|11968..=11970|12055..=12056|12061..=12062|12067..=12068|12073..=12074|12079..=12080|12085..=12086|12091..=12092|12103..=12104|12109..=12110|12115..=12116|12121..=12122|12127..=12128|12133..=12134|12139..=12140|12145..=12146|12151..=12152|12157..=12158|12163..=12164|12169..=12170|12175..=12176|12181..=12182|12187..=12188|12193..=12194|12199..=12204|13427..=13436|13517|13538..=13571|13573..=13782|13810|13826..=13835|13964|15109..=15110|15115..=15116|15121..=15122|15127..=15128|15133..=15134|15139..=15140|15145..=15146|15151..=15152|15157..=15158|15163..=15164|15169..=15170|15175..=15176|15181..=15182|19427..=19460|19489|19602..=19614|19616|19619..=19631|19633|19689..=19690|19695..=19696|19701..=19702|20379..=20394|20409..=20472|20474..=20482|20487..=20488|20897..=20902|20907..=20908|21313|21398..=21399|21750..=21752|22059..=22060|22109|22114..=22115|22520|22525..=22526|22931..=22932|22937..=22938|23343..=23345|23827|23956..=23957|23966..=23983|24308..=24309|24314..=24315|24320..=24321|24326..=24335|24660..=24661|24666..=24667|24672..=24673|24678..=24679|25704..=25751|25796|25903|25962|25964..=25967|26052..=26053|26378|26463..=26464|26789|26874..=26875|27200|27285..=27286|27611..=27620|27623..=27631|27633|27650..=27703)
}
}
diff --git a/azalea-protocol/src/packets/game/c_section_blocks_update.rs b/azalea-protocol/src/packets/game/c_section_blocks_update.rs
index 05ceb30c..2a7a867e 100644
--- a/azalea-protocol/src/packets/game/c_section_blocks_update.rs
+++ b/azalea-protocol/src/packets/game/c_section_blocks_update.rs
@@ -35,7 +35,7 @@ impl AzaleaRead for BlockStateWithPosition {
impl AzaleaWrite for BlockStateWithPosition {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
- let data = ((self.state.id as u64) << 12)
+ let data = ((self.state.id() as u64) << 12)
| ((u64::from(self.pos.x) << 8) | (u64::from(self.pos.z) << 4) | u64::from(self.pos.y));
u64::azalea_write_var(&data, buf)?;
Ok(())
diff --git a/azalea-world/src/chunk_storage.rs b/azalea-world/src/chunk_storage.rs
index 39cbc84f..d8357a95 100644
--- a/azalea-world/src/chunk_storage.rs
+++ b/azalea-world/src/chunk_storage.rs
@@ -476,25 +476,18 @@ impl AzaleaWrite for Section {
impl Section {
pub fn get(&self, pos: ChunkSectionBlockPos) -> BlockState {
- // TODO: use the unsafe method and do the check earlier
- let state = self
- .states
- .get(pos.x as usize, pos.y as usize, pos.z as usize);
- // if there's an unknown block assume it's air
- BlockState::try_from(state).unwrap_or(BlockState::AIR)
+ self.states
+ .get(pos.x as usize, pos.y as usize, pos.z as usize)
}
pub fn get_and_set(&mut self, pos: ChunkSectionBlockPos, state: BlockState) -> BlockState {
- let previous_state =
- self.states
- .get_and_set(pos.x as usize, pos.y as usize, pos.z as usize, state.id);
- // if there's an unknown block assume it's air
- BlockState::try_from(previous_state).unwrap_or(BlockState::AIR)
+ self.states
+ .get_and_set(pos.x as usize, pos.y as usize, pos.z as usize, state)
}
pub fn set(&mut self, pos: ChunkSectionBlockPos, state: BlockState) {
self.states
- .set(pos.x as usize, pos.y as usize, pos.z as usize, state.id);
+ .set(pos.x as usize, pos.y as usize, pos.z as usize, state);
}
}
diff --git a/azalea-world/src/find_blocks.rs b/azalea-world/src/find_blocks.rs
index 46c1f8bb..967f20ec 100644
--- a/azalea-world/src/find_blocks.rs
+++ b/azalea-world/src/find_blocks.rs
@@ -1,17 +1,13 @@
-use azalea_block::{BlockStates, block_state::BlockState};
+use azalea_block::BlockStates;
use azalea_core::position::{BlockPos, ChunkPos};
use crate::{ChunkStorage, Instance, iterators::ChunkIterator, palette::Palette};
fn palette_maybe_has_block(palette: &Palette, block_states: &BlockStates) -> bool {
match &palette {
- Palette::SingleValue(id) => block_states.contains(&BlockState { id: *id }),
- Palette::Linear(ids) => ids
- .iter()
- .any(|&id| block_states.contains(&BlockState { id })),
- Palette::Hashmap(ids) => ids
- .iter()
- .any(|&id| block_states.contains(&BlockState { id })),
+ Palette::SingleValue(id) => block_states.contains(id),
+ Palette::Linear(ids) => ids.iter().any(|id| block_states.contains(id)),
+ Palette::Hashmap(ids) => ids.iter().any(|id| block_states.contains(id)),
Palette::Global => true,
}
}
@@ -62,7 +58,6 @@ impl Instance {
for i in 0..4096 {
let block_state = section.states.get_at_index(i);
- let block_state = BlockState { id: block_state };
if block_states.contains(&block_state) {
let (section_x, section_y, section_z) = section.states.coords_from_index(i);
@@ -190,7 +185,6 @@ impl Iterator for FindBlocks<'_> {
for i in 0..4096 {
let block_state = section.states.get_at_index(i);
- let block_state = BlockState { id: block_state };
if self.block_states.contains(&block_state) {
let (section_x, section_y, section_z) = section.states.coords_from_index(i);
diff --git a/azalea-world/src/palette.rs b/azalea-world/src/palette.rs
index 699ee2d5..37d43fac 100644
--- a/azalea-world/src/palette.rs
+++ b/azalea-world/src/palette.rs
@@ -1,7 +1,7 @@
use std::io::{Cursor, Write};
-use azalea_block::block_state::BlockStateIntegerRepr;
-use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
+use azalea_block::BlockState;
+use azalea_buf::{AzaleaRead, AzaleaWrite, BufReadError};
use tracing::warn;
use crate::BitStorage;
@@ -28,7 +28,7 @@ pub struct PalettedContainer {
impl PalettedContainer {
pub fn new(container_type: PalettedContainerKind) -> Self {
- let palette = Palette::SingleValue(0);
+ let palette = Palette::SingleValue(BlockState::AIR);
let size = container_type.size();
let storage = BitStorage::new(0, size, Some(Box::new([]))).unwrap();
@@ -105,7 +105,7 @@ impl PalettedContainer {
/// This function panics if the index is greater than or equal to the number
/// of things in the storage. (So for block states, it must be less than
/// 4096).
- pub fn get_at_index(&self, index: usize) -> BlockStateIntegerRepr {
+ pub fn get_at_index(&self, index: usize) -> BlockState {
// first get the palette id
let paletted_value = self.storage.get(index);
// and then get the value from that id
@@ -113,35 +113,39 @@ impl PalettedContainer {
}
/// Returns the value at the given coordinates.
- pub fn get(&self, x: usize, y: usize, z: usize) -> BlockStateIntegerRepr {
+ pub fn get(&self, x: usize, y: usize, z: usize) -> BlockState {
// let paletted_value = self.storage.get(self.get_index(x, y, z));
// self.palette.value_for(paletted_value as usize)
self.get_at_index(self.index_from_coords(x, y, z))
}
/// Sets the id at the given coordinates and return the previous id
- pub fn get_and_set(
- &mut self,
- x: usize,
- y: usize,
- z: usize,
- value: BlockStateIntegerRepr,
- ) -> BlockStateIntegerRepr {
+ pub fn get_and_set(&mut self, x: usize, y: usize, z: usize, value: BlockState) -> BlockState {
let paletted_value = self.id_for(value);
- self.storage
- .get_and_set(self.index_from_coords(x, y, z), paletted_value as u64)
- as BlockStateIntegerRepr
+ let block_state_id = self
+ .storage
+ .get_and_set(self.index_from_coords(x, y, z), paletted_value as u64);
+ // error in debug mode
+ #[cfg(debug_assertions)]
+ if block_state_id > BlockState::MAX_STATE.into() {
+ warn!(
+ "Old block state from get_and_set {block_state_id} was greater than max state {}",
+ BlockState::MAX_STATE
+ );
+ }
+
+ BlockState::try_from(block_state_id as u32).unwrap_or_default()
}
/// Sets the id at the given index and return the previous id. You probably
/// want `.set` instead.
- pub fn set_at_index(&mut self, index: usize, value: BlockStateIntegerRepr) {
+ pub fn set_at_index(&mut self, index: usize, value: BlockState) {
let paletted_value = self.id_for(value);
self.storage.set(index, paletted_value as u64);
}
/// Sets the id at the given coordinates and return the previous id
- pub fn set(&mut self, x: usize, y: usize, z: usize, value: BlockStateIntegerRepr) {
+ pub fn set(&mut self, x: usize, y: usize, z: usize, value: BlockState) {
self.set_at_index(self.index_from_coords(x, y, z), value);
}
@@ -170,7 +174,7 @@ impl PalettedContainer {
}
}
- fn on_resize(&mut self, bits_per_entry: u8, value: BlockStateIntegerRepr) -> usize {
+ fn on_resize(&mut self, bits_per_entry: u8, value: BlockState) -> usize {
// in vanilla this is always true, but it's sometimes false in purpur servers
// assert!(bits_per_entry <= 5, "bits_per_entry must be <= 5");
let mut new_data = self.create_or_reuse_data(bits_per_entry);
@@ -187,7 +191,7 @@ impl PalettedContainer {
}
}
- pub fn id_for(&mut self, value: BlockStateIntegerRepr) -> usize {
+ pub fn id_for(&mut self, value: BlockState) -> usize {
match &mut self.palette {
Palette::SingleValue(v) => {
if *v != value {
@@ -209,7 +213,8 @@ impl PalettedContainer {
}
}
Palette::Hashmap(palette) => {
- // TODO? vanilla keeps this in memory as a hashmap, but also i don't care
+ // TODO? vanilla keeps this in memory as a hashmap, but it should be benchmarked
+ // before changing it
if let Some(index) = palette.iter().position(|v| *v == value) {
return index;
}
@@ -221,7 +226,7 @@ impl PalettedContainer {
self.on_resize(self.bits_per_entry + 1, value)
}
}
- Palette::Global => value as usize,
+ Palette::Global => value.id() as usize,
}
}
}
@@ -247,21 +252,21 @@ pub enum PaletteKind {
#[derive(Clone, Debug)]
pub enum Palette {
/// ID of the corresponding entry in its global palette
- SingleValue(BlockStateIntegerRepr),
+ SingleValue(BlockState),
// in vanilla this keeps a `size` field that might be less than the length, but i'm not sure
// it's actually needed?
- Linear(Vec<BlockStateIntegerRepr>),
- Hashmap(Vec<BlockStateIntegerRepr>),
+ Linear(Vec<BlockState>),
+ Hashmap(Vec<BlockState>),
Global,
}
impl Palette {
- pub fn value_for(&self, id: usize) -> BlockStateIntegerRepr {
+ pub fn value_for(&self, id: usize) -> BlockState {
match self {
Palette::SingleValue(v) => *v,
- Palette::Linear(v) => v[id],
+ Palette::Linear(v) => v.get(id).copied().unwrap_or_default(),
Palette::Hashmap(v) => v.get(id).copied().unwrap_or_default(),
- Palette::Global => id as BlockStateIntegerRepr,
+ Palette::Global => BlockState::try_from(id as u32).unwrap_or_default(),
}
}
}
@@ -270,13 +275,13 @@ impl AzaleaWrite for Palette {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
match self {
Palette::SingleValue(value) => {
- value.azalea_write_var(buf)?;
+ value.azalea_write(buf)?;
}
Palette::Linear(values) => {
- values.azalea_write_var(buf)?;
+ values.azalea_write(buf)?;
}
Palette::Hashmap(values) => {
- values.azalea_write_var(buf)?;
+ values.azalea_write(buf)?;
}
Palette::Global => {}
}
@@ -305,22 +310,16 @@ impl PaletteKind {
Ok(match self {
// since they're read as varints it's actually fine to just use BlockStateIntegerRepr
// instead of the correct type (u32)
- PaletteKind::SingleValue => {
- Palette::SingleValue(BlockStateIntegerRepr::azalea_read_var(buf)?)
- }
- PaletteKind::Linear => {
- Palette::Linear(Vec::<BlockStateIntegerRepr>::azalea_read_var(buf)?)
- }
- PaletteKind::Hashmap => {
- Palette::Hashmap(Vec::<BlockStateIntegerRepr>::azalea_read_var(buf)?)
- }
+ PaletteKind::SingleValue => Palette::SingleValue(BlockState::azalea_read(buf)?),
+ PaletteKind::Linear => Palette::Linear(Vec::<BlockState>::azalea_read(buf)?),
+ PaletteKind::Hashmap => Palette::Hashmap(Vec::<BlockState>::azalea_read(buf)?),
PaletteKind::Global => Palette::Global,
})
}
pub fn as_empty_palette(&self) -> Palette {
match self {
- PaletteKind::SingleValue => Palette::SingleValue(0),
+ PaletteKind::SingleValue => Palette::SingleValue(BlockState::AIR),
PaletteKind::Linear => Palette::Linear(Vec::new()),
PaletteKind::Hashmap => Palette::Hashmap(Vec::new()),
PaletteKind::Global => Palette::Global,
@@ -361,13 +360,14 @@ mod tests {
let mut palette_container = PalettedContainer::new(PalettedContainerKind::BlockStates);
assert_eq!(palette_container.bits_per_entry, 0);
- assert_eq!(palette_container.get_at_index(0), 0);
+ assert_eq!(palette_container.get_at_index(0), BlockState::AIR);
assert_eq!(
PaletteKind::from(&palette_container.palette),
PaletteKind::SingleValue
);
- palette_container.set_at_index(0, 1);
- assert_eq!(palette_container.get_at_index(0), 1);
+ let block_state_1 = BlockState::try_from(1_u32).unwrap();
+ palette_container.set_at_index(0, block_state_1);
+ assert_eq!(palette_container.get_at_index(0), block_state_1);
assert_eq!(
PaletteKind::from(&palette_container.palette),
PaletteKind::Linear
@@ -378,34 +378,38 @@ mod tests {
fn test_resize_0_bits_to_5() {
let mut palette_container = PalettedContainer::new(PalettedContainerKind::BlockStates);
- palette_container.set_at_index(0, 0); // 0 bits
+ let set = |pc: &mut PalettedContainer, i, v: u32| {
+ pc.set_at_index(i, BlockState::try_from(v).unwrap());
+ };
+
+ set(&mut palette_container, 0, 0); // 0 bits
assert_eq!(palette_container.bits_per_entry, 0);
- palette_container.set_at_index(1, 1); // 1 bit
+ set(&mut palette_container, 1, 1); // 1 bit
assert_eq!(palette_container.bits_per_entry, 1);
- palette_container.set_at_index(2, 2); // 2 bits
+ set(&mut palette_container, 2, 2); // 2 bits
assert_eq!(palette_container.bits_per_entry, 2);
- palette_container.set_at_index(3, 3);
+ set(&mut palette_container, 3, 3);
- palette_container.set_at_index(4, 4); // 3 bits
+ set(&mut palette_container, 4, 4); // 3 bits
assert_eq!(palette_container.bits_per_entry, 3);
- palette_container.set_at_index(5, 5);
- palette_container.set_at_index(6, 6);
- palette_container.set_at_index(7, 7);
+ set(&mut palette_container, 5, 5);
+ set(&mut palette_container, 6, 6);
+ set(&mut palette_container, 7, 7);
- palette_container.set_at_index(8, 8); // 4 bits
+ set(&mut palette_container, 8, 8); // 4 bits
assert_eq!(palette_container.bits_per_entry, 4);
- palette_container.set_at_index(9, 9);
- palette_container.set_at_index(10, 10);
- palette_container.set_at_index(11, 11);
- palette_container.set_at_index(12, 12);
- palette_container.set_at_index(13, 13);
- palette_container.set_at_index(14, 14);
- palette_container.set_at_index(15, 15);
+ set(&mut palette_container, 9, 9);
+ set(&mut palette_container, 10, 10);
+ set(&mut palette_container, 11, 11);
+ set(&mut palette_container, 12, 12);
+ set(&mut palette_container, 13, 13);
+ set(&mut palette_container, 14, 14);
+ set(&mut palette_container, 15, 15);
assert_eq!(palette_container.bits_per_entry, 4);
- palette_container.set_at_index(16, 16); // 5 bits
+ set(&mut palette_container, 16, 16); // 5 bits
assert_eq!(palette_container.bits_per_entry, 5);
}
diff --git a/azalea/src/pathfinder/mining.rs b/azalea/src/pathfinder/mining.rs
index 40cdf8a2..a985ca71 100644
--- a/azalea/src/pathfinder/mining.rs
+++ b/azalea/src/pathfinder/mining.rs
@@ -27,16 +27,16 @@ impl MiningCache {
let mut water_block_state_range_min = BlockStateIntegerRepr::MAX;
let mut water_block_state_range_max = BlockStateIntegerRepr::MIN;
for state in water_block_states {
- water_block_state_range_min = water_block_state_range_min.min(state.id);
- water_block_state_range_max = water_block_state_range_max.max(state.id);
+ water_block_state_range_min = water_block_state_range_min.min(state.id());
+ water_block_state_range_max = water_block_state_range_max.max(state.id());
}
let water_block_state_range = water_block_state_range_min..=water_block_state_range_max;
let mut lava_block_state_range_min = BlockStateIntegerRepr::MAX;
let mut lava_block_state_range_max = BlockStateIntegerRepr::MIN;
for state in lava_block_states {
- lava_block_state_range_min = lava_block_state_range_min.min(state.id);
- lava_block_state_range_max = lava_block_state_range_max.max(state.id);
+ lava_block_state_range_min = lava_block_state_range_min.min(state.id());
+ lava_block_state_range_max = lava_block_state_range_max.max(state.id());
}
let lava_block_state_range = lava_block_state_range_min..=lava_block_state_range_max;
@@ -65,7 +65,7 @@ impl MiningCache {
azalea_registry::Block::RedConcretePowder.into(),
azalea_registry::Block::BlackConcretePowder.into(),
];
- falling_blocks.sort_unstable_by_key(|block| block.id);
+ falling_blocks.sort_unstable_by_key(|block| block.id());
Self {
block_state_id_costs: UnsafeCell::new(IntMap::default()),
@@ -84,7 +84,7 @@ impl MiningCache {
// SAFETY: mining is single-threaded, so this is safe
let block_state_id_costs = unsafe { &mut *self.block_state_id_costs.get() };
- if let Some(cost) = block_state_id_costs.get(&block.id) {
+ if let Some(cost) = block_state_id_costs.get(&block.id()) {
*cost
} else {
let best_tool_result = best_tool_in_hotbar_for_block(block, inventory_menu);
@@ -92,7 +92,7 @@ impl MiningCache {
cost += BLOCK_BREAK_ADDITIONAL_PENALTY;
- block_state_id_costs.insert(block.id, cost);
+ block_state_id_costs.insert(block.id(), cost);
cost
}
}
@@ -101,14 +101,14 @@ impl MiningCache {
// this already runs in about 1 nanosecond, so if you wanna try optimizing it at
// least run the benchmarks (in benches/checks.rs)
- self.water_block_state_range.contains(&block.id)
- || self.lava_block_state_range.contains(&block.id)
+ self.water_block_state_range.contains(&block.id())
+ || self.lava_block_state_range.contains(&block.id())
|| is_waterlogged(block)
}
pub fn is_falling_block(&self, block: BlockState) -> bool {
self.falling_blocks
- .binary_search_by_key(&block.id, |block| block.id)
+ .binary_search_by_key(&block.id(), |block| block.id())
.is_ok()
}
}
diff --git a/azalea/src/pathfinder/world.rs b/azalea/src/pathfinder/world.rs
index c50791b8..b89f0761 100644
--- a/azalea/src/pathfinder/world.rs
+++ b/azalea/src/pathfinder/world.rs
@@ -194,8 +194,7 @@ impl CachedWorld {
let mut passable_bitset = FixedBitSet::<{ 4096_usize.div_ceil(8) }>::new();
let mut solid_bitset = FixedBitSet::<{ 4096_usize.div_ceil(8) }>::new();
for i in 0..4096 {
- let block_state_id = section.get_at_index(i);
- let block_state = BlockState::try_from(block_state_id).unwrap_or(BlockState::AIR);
+ let block_state = section.get_at_index(i);
if is_block_state_passable(block_state) {
passable_bitset.set(i);
}
@@ -304,9 +303,7 @@ impl CachedWorld {
let west_is_in_same_section = section_block_pos.x != 0;
let Some(mining_cost) = self.with_section(section_pos, |section| {
- let block_state =
- BlockState::try_from(section.get_at_index(u16::from(section_block_pos) as usize))
- .unwrap_or_default();
+ let block_state = section.get_at_index(u16::from(section_block_pos) as usize);
let mining_cost = mining_cache.cost_for(block_state);
if mining_cost == f32::INFINITY {
@@ -316,10 +313,7 @@ impl CachedWorld {
// if there's a falling block or liquid above this block, abort
if up_is_in_same_section {
- let up_block = BlockState::try_from(
- section.get_at_index(u16::from(section_block_pos.up(1)) as usize),
- )
- .unwrap_or_default();
+ let up_block = section.get_at_index(u16::from(section_block_pos.up(1)) as usize);
if mining_cache.is_liquid(up_block) || mining_cache.is_falling_block(up_block) {
return f32::INFINITY;
}
@@ -327,10 +321,8 @@ impl CachedWorld {
// if there's a liquid to the north of this block, abort
if north_is_in_same_section {
- let north_block = BlockState::try_from(
- section.get_at_index(u16::from(section_block_pos.north(1)) as usize),
- )
- .unwrap_or_default();
+ let north_block =
+ section.get_at_index(u16::from(section_block_pos.north(1)) as usize);
if mining_cache.is_liquid(north_block) {
return f32::INFINITY;
}
@@ -338,10 +330,8 @@ impl CachedWorld {
// liquid to the east
if east_is_in_same_section {
- let east_block = BlockState::try_from(
- section.get_at_index(u16::from(section_block_pos.east(1)) as usize),
- )
- .unwrap_or_default();
+ let east_block =
+ section.get_at_index(u16::from(section_block_pos.east(1)) as usize);
if mining_cache.is_liquid(east_block) {
return f32::INFINITY;
}
@@ -349,10 +339,8 @@ impl CachedWorld {
// liquid to the south
if south_is_in_same_section {
- let south_block = BlockState::try_from(
- section.get_at_index(u16::from(section_block_pos.south(1)) as usize),
- )
- .unwrap_or_default();
+ let south_block =
+ section.get_at_index(u16::from(section_block_pos.south(1)) as usize);
if mining_cache.is_liquid(south_block) {
return f32::INFINITY;
}
@@ -360,10 +348,8 @@ impl CachedWorld {
// liquid to the west
if west_is_in_same_section {
- let west_block = BlockState::try_from(
- section.get_at_index(u16::from(section_block_pos.west(1)) as usize),
- )
- .unwrap_or_default();
+ let west_block =
+ section.get_at_index(u16::from(section_block_pos.west(1)) as usize);
if mining_cache.is_liquid(west_block) {
return f32::INFINITY;
}
@@ -391,10 +377,7 @@ impl CachedWorld {
let check_should_avoid_this_block = |pos: BlockPos, check: &dyn Fn(BlockState) -> bool| {
let block_state = self
.with_section(ChunkSectionPos::from(pos), |section| {
- BlockState::try_from(
- section.get_at_index(u16::from(ChunkSectionBlockPos::from(pos)) as usize),
- )
- .unwrap_or_default()
+ section.get_at_index(u16::from(ChunkSectionBlockPos::from(pos)) as usize)
})
.unwrap_or_default();
check(block_state)
diff --git a/codegen/lib/code/shapes.py b/codegen/lib/code/shapes.py
index 5d5f826d..0896bd82 100644
--- a/codegen/lib/code/shapes.py
+++ b/codegen/lib/code/shapes.py
@@ -151,18 +151,18 @@ pub trait BlockWithShape {{
impl BlockWithShape for BlockState {{
fn collision_shape(&self) -> &'static VoxelShape {{
- COLLISION_SHAPES_MAP.get(self.id as usize).unwrap_or(&&SHAPE1)
+ COLLISION_SHAPES_MAP.get(self.id() as usize).unwrap_or(&&SHAPE1)
}}
fn outline_shape(&self) -> &'static VoxelShape {{
- OUTLINE_SHAPES_MAP.get(self.id as usize).unwrap_or(&&SHAPE1)
+ OUTLINE_SHAPES_MAP.get(self.id() as usize).unwrap_or(&&SHAPE1)
}}
fn is_collision_shape_empty(&self) -> bool {{
- matches!(self.id, {empty_shape_match_code})
+ matches!(self.id(), {empty_shape_match_code})
}}
fn is_collision_shape_full(&self) -> bool {{
- matches!(self.id, {block_shape_match_code})
+ matches!(self.id(), {block_shape_match_code})
}}
}}
diff --git a/codegen/lib/utils.py b/codegen/lib/utils.py
index 162dd0fa..fd1e553b 100644
--- a/codegen/lib/utils.py
+++ b/codegen/lib/utils.py
@@ -10,7 +10,7 @@ def to_snake_case(name: str):
def to_camel_case(name: str):
- s = re.sub('[_ ](\w)', lambda m: m.group(1).upper(),
+ s = re.sub(r'[_ ](\w)', lambda m: m.group(1).upper(),
name.replace('.', '_').replace('/', '_'))
s = upper_first_letter(s)
# if the first character is a number, we need to add an underscore