aboutsummaryrefslogtreecommitdiff
path: root/azalea/src/pathfinder/world.rs
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2025-05-07 07:09:48 +0900
committermat <git@matdoes.dev>2025-05-07 07:09:48 +0900
commit7b442368daf29b43e20e122aac440e10d2fc7464 (patch)
treee20236c281c96fab305387bdbc78708d56b0db49 /azalea/src/pathfinder/world.rs
parentf7c9419045470495fe76b0167d09d17c3cf4cc56 (diff)
downloadazalea-drasl-7b442368daf29b43e20e122aac440e10d2fc7464.tar.xz
fix some edge cases when pathfinding on slabs and stairs
Diffstat (limited to 'azalea/src/pathfinder/world.rs')
-rw-r--r--azalea/src/pathfinder/world.rs35
1 files changed, 33 insertions, 2 deletions
diff --git a/azalea/src/pathfinder/world.rs b/azalea/src/pathfinder/world.rs
index 45d05810..3b1b36b9 100644
--- a/azalea/src/pathfinder/world.rs
+++ b/azalea/src/pathfinder/world.rs
@@ -3,7 +3,7 @@ use std::{
sync::Arc,
};
-use azalea_block::BlockState;
+use azalea_block::{BlockState, properties};
use azalea_core::{
bitset::FixedBitSet,
position::{BlockPos, ChunkPos, ChunkSectionBlockPos, ChunkSectionPos},
@@ -241,6 +241,21 @@ impl CachedWorld {
passable
}
+ /// Get the block state at the given position. This is relatively slow, so
+ /// you should avoid it whenever possible.
+ pub fn get_block_state(&self, pos: RelBlockPos) -> BlockState {
+ self.get_block_state_at_pos(pos.apply(self.origin))
+ }
+
+ fn get_block_state_at_pos(&self, pos: BlockPos) -> BlockState {
+ let (section_pos, section_block_pos) =
+ (ChunkSectionPos::from(pos), ChunkSectionBlockPos::from(pos));
+ let index = u16::from(section_block_pos) as usize;
+
+ self.with_section(section_pos, |section| section.get_at_index(index))
+ .unwrap_or_default()
+ }
+
pub fn is_block_solid(&self, pos: RelBlockPos) -> bool {
self.is_block_pos_solid(pos.apply(self.origin))
}
@@ -487,6 +502,10 @@ impl CachedWorld {
}
distance
}
+
+ pub fn origin(&self) -> BlockPos {
+ self.origin
+ }
}
/// whether this block is passable
@@ -537,7 +556,19 @@ pub fn is_block_state_solid(block: BlockState) -> bool {
// fast path
return false;
}
- block.is_collision_shape_full()
+ if block.is_collision_shape_full() {
+ return true;
+ }
+
+ if matches!(
+ block.property::<properties::Type>(),
+ Some(properties::Type::Top | properties::Type::Double)
+ ) {
+ // top slabs
+ return true;
+ }
+
+ false
}
pub fn is_block_state_standable(block: BlockState) -> bool {