diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2023-03-07 22:09:56 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-07 22:09:56 -0600 |
| commit | 5dd35c7ed82c38ef36ca28f630e8d05c5db2cbea (patch) | |
| tree | 72719e46479e7884ea535c768ab7c244ce048063 /azalea-block/src | |
| parent | 719379a8a76ab0685f2bd14bebe2f0cd1e97f06b (diff) | |
| download | azalea-drasl-5dd35c7ed82c38ef36ca28f630e8d05c5db2cbea.tar.xz | |
Add World::find_block (#80)
* start adding World::find_block
* keep working on find_block
* BlockStates
* fix sorting
* update examples that use find_one_block
* azalea_block::properties
* fix tests
* add a gotoblock command to testbot
Diffstat (limited to 'azalea-block/src')
| -rwxr-xr-x | azalea-block/src/generated.rs (renamed from azalea-block/src/blocks.rs) | 15 | ||||
| -rwxr-xr-x | azalea-block/src/lib.rs | 60 | ||||
| -rw-r--r-- | azalea-block/src/range.rs | 33 |
3 files changed, 85 insertions, 23 deletions
diff --git a/azalea-block/src/blocks.rs b/azalea-block/src/generated.rs index e6923d59..afe6dfda 100755 --- a/azalea-block/src/blocks.rs +++ b/azalea-block/src/generated.rs @@ -1,20 +1,7 @@ -use std::any::Any; - -use crate::BlockBehavior; +use crate::{Block, BlockBehavior, BlockState, BlockStates}; use azalea_block_macros::make_block_states; use std::fmt::Debug; -pub trait Block: Debug + Any { - fn behavior(&self) -> BlockBehavior; - fn id(&self) -> &'static str; - fn as_blockstate(&self) -> BlockState; -} -impl dyn Block { - pub fn downcast_ref<T: Block>(&self) -> Option<&T> { - (self as &dyn Any).downcast_ref::<T>() - } -} - make_block_states! { Properties => { "snowy" => bool, diff --git a/azalea-block/src/lib.rs b/azalea-block/src/lib.rs index 7a62e588..43099db5 100755 --- a/azalea-block/src/lib.rs +++ b/azalea-block/src/lib.rs @@ -2,14 +2,49 @@ #![feature(trait_upcasting)] mod behavior; -mod blocks; +mod generated; +mod range; + +pub use generated::{blocks, properties}; use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable}; pub use behavior::BlockBehavior; -pub use blocks::*; -use std::io::{Cursor, Write}; +use core::fmt::Debug; +pub use range::BlockStates; +use std::{ + any::Any, + io::{Cursor, Write}, +}; + +pub trait Block: Debug + Any { + fn behavior(&self) -> BlockBehavior; + /// Get the Minecraft ID for this block. For example `stone` or + /// `grass_block`. + fn id(&self) -> &'static str; + /// Convert the block to a block state. This is lossless, as the block + /// contains all the state data. + fn as_block_state(&self) -> BlockState; +} +impl dyn Block { + pub fn downcast_ref<T: Block>(&self) -> Option<&T> { + (self as &dyn Any).downcast_ref::<T>() + } +} + +/// A representation of a state a block can be in. +/// +/// For example, a stone block only has one state but each possible stair +/// rotation is a different state. +#[derive(Copy, Clone, PartialEq, Eq, Default, Hash)] +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: u32, +} impl BlockState { + pub const AIR: BlockState = BlockState { id: 0 }; + /// Transmutes a u32 to a block state. /// /// # Safety @@ -52,6 +87,17 @@ impl McBufWritable for BlockState { } } +impl std::fmt::Debug for BlockState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "BlockState(id: {}, {:?})", + self.id, + Box::<dyn Block>::from(*self) + ) + } +} + #[cfg(test)] mod tests { use super::*; @@ -80,18 +126,14 @@ mod tests { "{:?}", BlockState::from(azalea_registry::Block::FloweringAzalea) ); - assert!( - formatted.ends_with(", FloweringAzaleaBlock)"), - "{}", - formatted - ); + assert!(formatted.ends_with(", FloweringAzalea)"), "{}", formatted); let formatted = format!( "{:?}", BlockState::from(azalea_registry::Block::BigDripleafStem) ); assert!( - formatted.ends_with(", BigDripleafStemBlock { facing: North, waterlogged: false })"), + formatted.ends_with(", BigDripleafStem { facing: North, waterlogged: false })"), "{}", formatted ); diff --git a/azalea-block/src/range.rs b/azalea-block/src/range.rs new file mode 100644 index 00000000..6ccf4152 --- /dev/null +++ b/azalea-block/src/range.rs @@ -0,0 +1,33 @@ +use std::{collections::HashSet, ops::RangeInclusive}; + +use crate::BlockState; + +#[derive(Debug, Clone)] +pub struct BlockStates { + pub set: HashSet<BlockState>, +} + +impl From<RangeInclusive<u32>> for BlockStates { + fn from(range: RangeInclusive<u32>) -> Self { + let mut set = HashSet::with_capacity((range.end() - range.start() + 1) as usize); + for id in range { + set.insert(BlockState { id }); + } + Self { set } + } +} + +impl IntoIterator for BlockStates { + type Item = BlockState; + type IntoIter = std::collections::hash_set::IntoIter<BlockState>; + + fn into_iter(self) -> Self::IntoIter { + self.set.into_iter() + } +} + +impl BlockStates { + pub fn contains(&self, state: &BlockState) -> bool { + self.set.contains(state) + } +} |
