aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xazalea-core/src/position.rs19
-rwxr-xr-xazalea-world/src/chunk_storage.rs6
-rw-r--r--azalea/src/pathfinder/mod.rs4
-rw-r--r--azalea/src/pathfinder/moves/mod.rs18
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,
)
}