diff options
| -rwxr-xr-x | azalea-core/src/position.rs | 19 | ||||
| -rwxr-xr-x | azalea-world/src/chunk_storage.rs | 6 | ||||
| -rw-r--r-- | azalea/src/pathfinder/mod.rs | 4 | ||||
| -rw-r--r-- | azalea/src/pathfinder/moves/mod.rs | 18 |
4 files changed, 34 insertions, 13 deletions
diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs index 16578517..6d0b28da 100755 --- a/azalea-core/src/position.rs +++ b/azalea-core/src/position.rs @@ -228,11 +228,17 @@ impl Add<ChunkPos> for ChunkPos { } } } +impl From<ChunkPos> for u64 { + #[inline] + fn from(pos: ChunkPos) -> Self { + ((pos.x as u64) << 32) | (pos.z as u64) + } +} impl Hash for ChunkPos { + #[inline] fn hash<H: std::hash::Hasher>(&self, state: &mut H) { // optimized hash that only calls hash once - let combined = (self.x as u64) << 32 | (self.z as u64); - combined.hash(state); + u64::from(*self).hash(state); } } /// nohash_hasher lets us have IntMap<ChunkPos, _> which is significantly faster @@ -316,6 +322,15 @@ impl From<BlockPos> for ChunkSectionPos { } } } +impl From<&BlockPos> for ChunkSectionPos { + fn from(pos: &BlockPos) -> Self { + ChunkSectionPos { + x: pos.x.div_floor(16), + y: pos.y.div_floor(16), + z: pos.z.div_floor(16), + } + } +} impl From<ChunkSectionPos> for ChunkPos { fn from(pos: ChunkSectionPos) -> Self { diff --git a/azalea-world/src/chunk_storage.rs b/azalea-world/src/chunk_storage.rs index ce611a61..acf0cf22 100755 --- a/azalea-world/src/chunk_storage.rs +++ b/azalea-world/src/chunk_storage.rs @@ -397,7 +397,7 @@ impl McBufWritable for Section { } impl Section { - fn get(&self, pos: ChunkSectionBlockPos) -> BlockState { + pub fn get(&self, pos: ChunkSectionBlockPos) -> BlockState { // TODO: use the unsafe method and do the check earlier let state = self .states @@ -406,7 +406,7 @@ impl Section { BlockState::try_from(state).unwrap_or(BlockState::AIR) } - fn get_and_set(&mut self, pos: ChunkSectionBlockPos, state: BlockState) -> BlockState { + 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); @@ -414,7 +414,7 @@ impl Section { BlockState::try_from(previous_state).unwrap_or(BlockState::AIR) } - fn set(&mut self, pos: ChunkSectionBlockPos, state: BlockState) { + 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); } diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs index 831a5524..74b4342f 100644 --- a/azalea/src/pathfinder/mod.rs +++ b/azalea/src/pathfinder/mod.rs @@ -283,7 +283,7 @@ fn path_found_listener( "Entity tried to pathfind but the entity isn't in a valid world", ); let world = &world_lock.read().chunks; - let ctx = PathfinderCtx::new(&world); + let ctx = PathfinderCtx::new(world); let successors_fn: moves::SuccessorsFn = event.successors_fn; let successors = |pos: BlockPos| successors_fn(&ctx, pos); @@ -446,7 +446,7 @@ fn tick_execute_path( { // obstruction check (the path we're executing isn't possible anymore) let world = &world_lock.read().chunks; - let ctx = PathfinderCtx::new(&world); + let ctx = PathfinderCtx::new(world); let successors = |pos: BlockPos| successors_fn(&ctx, pos); if let Some(last_reached_node) = pathfinder.last_reached_node { diff --git a/azalea/src/pathfinder/moves/mod.rs b/azalea/src/pathfinder/moves/mod.rs index 9eb6462b..907db4fc 100644 --- a/azalea/src/pathfinder/moves/mod.rs +++ b/azalea/src/pathfinder/moves/mod.rs @@ -9,10 +9,9 @@ use super::astar; use azalea_block::BlockState; use azalea_client::{StartSprintEvent, StartWalkEvent}; use azalea_core::position::{BlockPos, ChunkBlockPos, ChunkPos, Vec3}; -use azalea_physics::collision::{self, BlockWithShape}; +use azalea_physics::collision::BlockWithShape; use azalea_world::ChunkStorage; use bevy_ecs::{entity::Entity, event::EventWriter}; -use nohash_hasher::IntMap; type Edge = astar::Edge<BlockPos, MoveData>; @@ -36,7 +35,7 @@ impl Debug for MoveData { pub struct PathfinderCtx<'a> { world: &'a ChunkStorage, - cached_chunks: RefCell<IntMap<ChunkPos, Vec<azalea_world::Section>>>, + cached_chunks: RefCell<Vec<(ChunkPos, Vec<azalea_world::Section>)>>, } impl<'a> PathfinderCtx<'a> { @@ -51,7 +50,13 @@ impl<'a> PathfinderCtx<'a> { let chunk_pos = ChunkPos::from(pos); let mut cached_chunks = self.cached_chunks.borrow_mut(); - if let Some(sections) = cached_chunks.get(&chunk_pos) { + if let Some(sections) = cached_chunks.iter().find_map(|(pos, sections)| { + if *pos == chunk_pos { + Some(sections) + } else { + None + } + }) { return azalea_world::chunk_storage::get_block_state_from_sections( sections, &ChunkBlockPos::from(pos), @@ -62,11 +67,12 @@ impl<'a> PathfinderCtx<'a> { let chunk = self.world.get(&chunk_pos)?; let chunk = chunk.read(); - cached_chunks.insert(chunk_pos, chunk.sections.clone()); + cached_chunks.push((chunk_pos, chunk.sections.clone())); + let chunk_block_pos = ChunkBlockPos::from(pos); azalea_world::chunk_storage::get_block_state_from_sections( &chunk.sections, - &ChunkBlockPos::from(pos), + &chunk_block_pos, self.world.min_y, ) } |
