aboutsummaryrefslogtreecommitdiff
path: root/azalea-block/src
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2023-03-07 22:09:56 -0600
committerGitHub <noreply@github.com>2023-03-07 22:09:56 -0600
commit5dd35c7ed82c38ef36ca28f630e8d05c5db2cbea (patch)
tree72719e46479e7884ea535c768ab7c244ce048063 /azalea-block/src
parent719379a8a76ab0685f2bd14bebe2f0cd1e97f06b (diff)
downloadazalea-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-xazalea-block/src/generated.rs (renamed from azalea-block/src/blocks.rs)15
-rwxr-xr-xazalea-block/src/lib.rs60
-rw-r--r--azalea-block/src/range.rs33
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)
+ }
+}