diff options
| author | mat <github@matdoes.dev> | 2022-12-11 00:15:37 -0600 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2022-12-11 00:15:37 -0600 |
| commit | 37b9f10b3bcc74b48df2c6843a5286a7d41e2414 (patch) | |
| tree | 6a995f7ad3f3309e57c276e10dc7e655dae9c5bb /azalea/src/pathfinder | |
| parent | 2d6737b247b74e964fd734d5ab4828a3193c296f (diff) | |
| download | azalea-drasl-37b9f10b3bcc74b48df2c6843a5286a7d41e2414.tar.xz | |
make entities have a reference to WeakWorlds instead
... and other exciting bug fixes
Diffstat (limited to 'azalea/src/pathfinder')
| -rw-r--r-- | azalea/src/pathfinder/mod.rs | 10 | ||||
| -rw-r--r-- | azalea/src/pathfinder/moves.rs | 51 |
2 files changed, 37 insertions, 24 deletions
diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs index 8a9d7540..a1619c41 100644 --- a/azalea/src/pathfinder/mod.rs +++ b/azalea/src/pathfinder/mod.rs @@ -6,7 +6,7 @@ use crate::{Client, Event}; use async_trait::async_trait; use azalea_core::{BlockPos, CardinalDirection}; use azalea_world::entity::EntityData; -use log::debug; +use log::{debug, error}; use mtdstarlite::Edge; pub use mtdstarlite::MTDStarLite; use parking_lot::Mutex; @@ -80,7 +80,7 @@ impl Trait for azalea_client::Client { let successors = |node: &Node| { let mut edges = Vec::new(); - let world = self.world.read(); + let world = &self.world.read().shared; for possible_move in possible_moves.iter() { edges.push(Edge { target: possible_move.next_node(node), @@ -111,7 +111,11 @@ impl Trait for azalea_client::Client { .expect("Pathfinder plugin not installed!") .clone(); // convert the Option<Vec<Node>> to a VecDeque<Node> - *state.path.lock() = p.expect("no path").into_iter().collect(); + if let Some(p) = p { + *state.path.lock() = p.into_iter().collect(); + } else { + error!("no path found"); + } } } diff --git a/azalea/src/pathfinder/moves.rs b/azalea/src/pathfinder/moves.rs index ac2137d3..ccf8ba1a 100644 --- a/azalea/src/pathfinder/moves.rs +++ b/azalea/src/pathfinder/moves.rs @@ -1,10 +1,10 @@ use super::{Node, VerticalVel}; use azalea_core::{BlockPos, CardinalDirection}; use azalea_physics::collision::{self, BlockWithShape}; -use azalea_world::World; +use azalea_world::WeakWorld; /// whether this block is passable -fn is_block_passable(pos: &BlockPos, world: &World) -> bool { +fn is_block_passable(pos: &BlockPos, world: &WeakWorld) -> bool { if let Some(block) = world.get_block_state(pos) { block.shape() == &collision::empty_shape() } else { @@ -13,7 +13,7 @@ fn is_block_passable(pos: &BlockPos, world: &World) -> bool { } /// whether this block has a solid hitbox (i.e. we can stand on it) -fn is_block_solid(pos: &BlockPos, world: &World) -> bool { +fn is_block_solid(pos: &BlockPos, world: &WeakWorld) -> bool { if let Some(block) = world.get_block_state(pos) { block.shape() == &collision::block_shape() } else { @@ -22,14 +22,14 @@ fn is_block_solid(pos: &BlockPos, world: &World) -> bool { } /// Whether this block and the block above are passable -fn is_passable(pos: &BlockPos, world: &World) -> bool { +fn is_passable(pos: &BlockPos, world: &WeakWorld) -> bool { is_block_passable(pos, world) && is_block_passable(&pos.up(1), world) } /// Whether we can stand in this position. Checks if the block below is solid, /// and that the two blocks above that are passable. -fn is_standable(pos: &BlockPos, world: &World) -> bool { +fn is_standable(pos: &BlockPos, world: &WeakWorld) -> bool { is_block_solid(&pos.down(1), world) && is_passable(pos, world) } @@ -37,7 +37,7 @@ const JUMP_COST: f32 = 0.5; const WALK_ONE_BLOCK_COST: f32 = 1.0; pub trait Move { - fn cost(&self, world: &World, node: &Node) -> f32; + fn cost(&self, world: &WeakWorld, node: &Node) -> f32; /// Returns by how much the entity's position should be changed when this /// move is executed. fn offset(&self) -> BlockPos; @@ -51,7 +51,7 @@ pub trait Move { pub struct ForwardMove(pub CardinalDirection); impl Move for ForwardMove { - fn cost(&self, world: &World, node: &Node) -> f32 { + fn cost(&self, world: &WeakWorld, node: &Node) -> f32 { if is_standable(&(node.pos + self.offset()), world) && node.vertical_vel == VerticalVel::None { @@ -67,7 +67,7 @@ impl Move for ForwardMove { pub struct AscendMove(pub CardinalDirection); impl Move for AscendMove { - fn cost(&self, world: &World, node: &Node) -> f32 { + fn cost(&self, world: &WeakWorld, node: &Node) -> f32 { if node.vertical_vel == VerticalVel::None && is_block_passable(&node.pos.up(2), world) && is_standable(&(node.pos + self.offset()), world) @@ -89,7 +89,7 @@ impl Move for AscendMove { } pub struct DescendMove(pub CardinalDirection); impl Move for DescendMove { - fn cost(&self, world: &World, node: &Node) -> f32 { + fn cost(&self, world: &WeakWorld, node: &Node) -> f32 { // check whether 3 blocks vertically forward are passable if node.vertical_vel == VerticalVel::None && is_standable(&(node.pos + self.offset()), world) @@ -112,7 +112,7 @@ impl Move for DescendMove { } pub struct DiagonalMove(pub CardinalDirection); impl Move for DiagonalMove { - fn cost(&self, world: &World, node: &Node) -> f32 { + fn cost(&self, world: &WeakWorld, node: &Node) -> f32 { if node.vertical_vel != VerticalVel::None { return f32::INFINITY; } @@ -151,37 +151,46 @@ mod tests { use super::*; use azalea_block::BlockState; use azalea_core::ChunkPos; - use azalea_world::Chunk; + use azalea_world::{Chunk, PartialWorld}; #[test] fn test_is_passable() { - let mut world = World::default(); + let mut world = PartialWorld::default(); world .set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) .unwrap(); world.set_block_state(&BlockPos::new(0, 0, 0), BlockState::Stone); world.set_block_state(&BlockPos::new(0, 1, 0), BlockState::Air); - assert_eq!(is_block_passable(&BlockPos::new(0, 0, 0), &world), false); - assert_eq!(is_block_passable(&BlockPos::new(0, 1, 0), &world), true); + assert_eq!( + is_block_passable(&BlockPos::new(0, 0, 0), &world.shared), + false + ); + assert_eq!( + is_block_passable(&BlockPos::new(0, 1, 0), &world.shared), + true + ); } #[test] fn test_is_solid() { - let mut world = World::default(); + let mut world = PartialWorld::default(); world .set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) .unwrap(); world.set_block_state(&BlockPos::new(0, 0, 0), BlockState::Stone); world.set_block_state(&BlockPos::new(0, 1, 0), BlockState::Air); - assert_eq!(is_block_solid(&BlockPos::new(0, 0, 0), &world), true); - assert_eq!(is_block_solid(&BlockPos::new(0, 1, 0), &world), false); + assert_eq!(is_block_solid(&BlockPos::new(0, 0, 0), &world.shared), true); + assert_eq!( + is_block_solid(&BlockPos::new(0, 1, 0), &world.shared), + false + ); } #[test] fn test_is_standable() { - let mut world = World::default(); + let mut world = PartialWorld::default(); world .set_chunk(&ChunkPos { x: 0, z: 0 }, Some(Chunk::default())) .unwrap(); @@ -190,8 +199,8 @@ mod tests { world.set_block_state(&BlockPos::new(0, 2, 0), BlockState::Air); world.set_block_state(&BlockPos::new(0, 3, 0), BlockState::Air); - assert!(is_standable(&BlockPos::new(0, 1, 0), &world)); - assert!(!is_standable(&BlockPos::new(0, 0, 0), &world)); - assert!(!is_standable(&BlockPos::new(0, 2, 0), &world)); + assert!(is_standable(&BlockPos::new(0, 1, 0), &world.shared)); + assert!(!is_standable(&BlockPos::new(0, 0, 0), &world.shared)); + assert!(!is_standable(&BlockPos::new(0, 2, 0), &world.shared)); } } |
