diff --git a/azalea-core/src/aabb.rs b/azalea-core/src/aabb.rs index 40230fe4..9ebdbcb9 100644 --- a/azalea-core/src/aabb.rs +++ b/azalea-core/src/aabb.rs @@ -14,6 +14,19 @@ pub struct AABB { pub max_z: f64, } +pub struct ClipPointOpts<'a> { + pub t: &'a mut [f64], + pub approach_dir: Option, + pub delta: &'a Vec3, + pub begin: f64, + pub min_x: f64, + pub max_x: f64, + pub min_z: f64, + pub max_z: f64, + pub result_dir: Direction, + pub start: &'a Vec3, +} + impl AABB { pub fn contract(&self, x: f64, y: f64, z: f64) -> AABB { let mut min_x = self.min_x; @@ -216,10 +229,7 @@ impl AABB { let x = max.x - min.x; let y = max.y - min.y; let z = max.z - min.z; - let dir = self.get_direction(self, min, &mut t, None, &Vec3 { x, y, z }); - if dir.is_none() { - return None; - } + let _dir = self.get_direction(self, min, &mut t, None, &Vec3 { x, y, z })?; let t = t[0]; Some(min.add(t * x, t * y, t * z)) } @@ -240,13 +250,11 @@ impl AABB { for aabb in boxes { dir = self.get_direction(aabb, from, &mut t, dir, &Vec3 { x, y, z }); } - if dir.is_none() { - return None; - } + let dir = dir?; let t = t[0]; Some(BlockHitResult { location: from.add(t * x, t * y, t * z), - direction: dir.unwrap(), + direction: dir, block_pos: *pos, inside: false, miss: false, @@ -262,151 +270,139 @@ impl AABB { delta: &Vec3, ) -> Option { if delta.x > EPSILON { - return self.clip_point( + return self.clip_point(ClipPointOpts { t, - dir, + approach_dir: dir, delta, - aabb.min_x, - aabb.min_y, - aabb.max_y, - aabb.min_z, - aabb.max_z, - Direction::West, - from, - ); + begin: aabb.min_x, + min_x: aabb.min_y, + max_x: aabb.max_y, + min_z: aabb.min_z, + max_z: aabb.max_z, + result_dir: Direction::West, + start: from, + }); } else if delta.x < -EPSILON { - return self.clip_point( + return self.clip_point(ClipPointOpts { t, - dir, + approach_dir: dir, delta, - aabb.max_x, - aabb.min_y, - aabb.max_y, - aabb.min_z, - aabb.max_z, - Direction::East, - from, - ); + begin: aabb.max_x, + min_x: aabb.min_y, + max_x: aabb.max_y, + min_z: aabb.min_z, + max_z: aabb.max_z, + result_dir: Direction::East, + start: from, + }); } if delta.y > EPSILON { - return self.clip_point( + return self.clip_point(ClipPointOpts { t, - dir, - &Vec3 { + approach_dir: dir, + delta: &Vec3 { x: delta.y, y: delta.z, z: delta.x, }, - aabb.min_y, - aabb.min_z, - aabb.max_z, - aabb.min_x, - aabb.max_x, - Direction::Down, - &Vec3 { + begin: aabb.min_y, + min_x: aabb.min_z, + max_x: aabb.max_z, + min_z: aabb.min_x, + max_z: aabb.max_x, + result_dir: Direction::Down, + start: &Vec3 { x: from.y, y: from.z, z: from.x, }, - ); + }); } else if delta.y < -EPSILON { - return self.clip_point( + return self.clip_point(ClipPointOpts { t, - dir, - &Vec3 { + approach_dir: dir, + delta: &Vec3 { x: delta.y, y: delta.z, z: delta.x, }, - aabb.max_y, - aabb.min_z, - aabb.max_z, - aabb.min_x, - aabb.max_x, - Direction::Up, - &Vec3 { + begin: aabb.max_y, + min_x: aabb.min_z, + max_x: aabb.max_z, + min_z: aabb.min_x, + max_z: aabb.max_x, + result_dir: Direction::Up, + start: &Vec3 { x: from.y, y: from.z, z: from.x, }, - ); + }); } if delta.z > EPSILON { - return self.clip_point( + return self.clip_point(ClipPointOpts { t, - dir, - &Vec3 { + approach_dir: dir, + delta: &Vec3 { x: delta.z, y: delta.x, z: delta.y, }, - aabb.min_z, - aabb.min_x, - aabb.max_x, - aabb.min_y, - aabb.max_y, - Direction::North, - &Vec3 { + begin: aabb.min_z, + min_x: aabb.min_x, + max_x: aabb.max_x, + min_z: aabb.min_y, + max_z: aabb.max_y, + result_dir: Direction::North, + start: &Vec3 { x: from.z, y: from.x, z: from.y, }, - ); + }); } else if delta.z < -EPSILON { - return self.clip_point( + return self.clip_point(ClipPointOpts { t, - dir, - &Vec3 { + approach_dir: dir, + delta: &Vec3 { x: delta.z, y: delta.x, z: delta.y, }, - aabb.max_z, - aabb.min_x, - aabb.max_x, - aabb.min_y, - aabb.max_y, - Direction::South, - &Vec3 { + begin: aabb.max_z, + min_x: aabb.min_x, + max_x: aabb.max_x, + min_z: aabb.min_y, + max_z: aabb.max_y, + result_dir: Direction::South, + start: &Vec3 { x: from.z, y: from.x, z: from.y, }, - ); + }); } dir } - fn clip_point( - &self, - t: &mut [f64], - approach_dir: Option, - delta: &Vec3, - begin: f64, - min_x: f64, - max_x: f64, - min_z: f64, - max_z: f64, - result_dir: Direction, - start: &Vec3, - ) -> Option { - let t_x = (begin - start.x) / delta.x; - let t_y = (start.y + t_x) / delta.y; - let t_z = (start.z + t_x) / delta.z; + fn clip_point(&self, opts: ClipPointOpts) -> Option { + let t_x = (opts.begin - opts.start.x) / opts.delta.x; + let t_y = (opts.start.y + t_x) / opts.delta.y; + let t_z = (opts.start.z + t_x) / opts.delta.z; if 0.0 < t_x - && t_x < t[0] - && min_x - EPSILON < t_y - && t_y < max_x + EPSILON - && min_z - EPSILON < t_z - && t_z < max_z + EPSILON + && t_x < opts.t[0] + && opts.min_x - EPSILON < t_y + && t_y < opts.max_x + EPSILON + && opts.min_z - EPSILON < t_z + && t_z < opts.max_z + EPSILON { - t[0] = t_x; - Some(result_dir) + opts.t[0] = t_x; + Some(opts.result_dir) } else { - approach_dir + opts.approach_dir } } diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs index 6a0de350..d0931a39 100644 --- a/azalea-core/src/position.rs +++ b/azalea-core/src/position.rs @@ -304,9 +304,9 @@ impl McBufReadable for BlockPos { fn read_from(buf: &mut impl Read) -> Result { let val = u64::read_from(buf)?; println!("reading blockpos from {}", val); - let x = (val << 64 - X_OFFSET - PACKED_X_LENGTH >> 64 - PACKED_X_LENGTH) as i32; - let y = (val << 64 - PACKED_Y_LENGTH >> 64 - PACKED_Y_LENGTH) as i32; - let z = (val << 64 - Z_OFFSET - PACKED_Z_LENGTH >> 64 - PACKED_Z_LENGTH) as i32; + let x = (val << (64 - X_OFFSET - PACKED_X_LENGTH) >> (64 - PACKED_X_LENGTH)) as i32; + let y = (val << (64 - PACKED_Y_LENGTH) >> (64 - PACKED_Y_LENGTH)) as i32; + let z = (val << (64 - Z_OFFSET - PACKED_Z_LENGTH) >> (64 - PACKED_Z_LENGTH)) as i32; Ok(BlockPos { x, y, z }) } } @@ -335,7 +335,7 @@ impl McBufWritable for BlockPos { fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { let mut val: u64 = 0; val |= ((self.x as u64) & PACKED_X_MASK) << X_OFFSET; - val |= ((self.y as u64) & PACKED_Y_MASK) << 0; + val |= (self.y as u64) & PACKED_Y_MASK; val |= ((self.z as u64) & PACKED_Z_MASK) << Z_OFFSET; val.write_into(buf) } diff --git a/azalea-world/src/entity/mod.rs b/azalea-world/src/entity/mod.rs index 37321e0a..7c3e3873 100644 --- a/azalea-world/src/entity/mod.rs +++ b/azalea-world/src/entity/mod.rs @@ -2,6 +2,7 @@ mod data; mod dimensions; use crate::Dimension; +use azalea_block::BlockState; use azalea_core::{BlockPos, Vec3, AABB}; pub use data::*; pub use dimensions::*; @@ -36,7 +37,7 @@ impl<'d> EntityRef<'d> { } pub fn make_bounding_box(&self) -> AABB { - self.dimensions.make_bounding_box(&self.pos()) + self.dimensions.make_bounding_box(self.pos()) } /// Get the position of the block below the entity, but a little lower. @@ -63,20 +64,20 @@ impl<'d> EntityRef<'d> { let pos = BlockPos { x, y, z }; // TODO: check if block below is a fence, wall, or fence gate - // let block_pos = pos.below(); - // let block_state = dimension.get_block_state(&block_pos); - // if block_state == Some(BlockState::Air) { - // let block_pos_below = block_pos.below(); - // let block_state_below = dimension.get_block_state(&block_pos_below); - // if let Some(block_state_below) = block_state_below { - // if block_state_below.is_fence() - // || block_state_below.is_wall() - // || block_state_below.is_fence_gate() - // { - // return block_pos_below; - // } - // } - // } + let block_pos = pos.below(); + let block_state = self.dimension.get_block_state(&block_pos); + if block_state == Some(BlockState::Air) { + let block_pos_below = block_pos.below(); + let block_state_below = self.dimension.get_block_state(&block_pos_below); + if let Some(_block_state_below) = block_state_below { + // if block_state_below.is_fence() + // || block_state_below.is_wall() + // || block_state_below.is_fence_gate() + // { + // return block_pos_below; + // } + } + } pos } @@ -102,6 +103,9 @@ impl<'d> EntityMut<'d> { /// Sets the position of the entity. This doesn't update the cache in /// azalea-world, and should only be used within azalea-world! + /// + /// # Safety + /// Cached position in the dimension must be updated. pub unsafe fn move_unchecked(&mut self, new_pos: Vec3) { self.pos = new_pos; let bounding_box = self.make_bounding_box(); @@ -147,7 +151,7 @@ impl<'d> EntityMut<'d> { } pub fn make_bounding_box(&self) -> AABB { - self.dimensions.make_bounding_box(&self.pos()) + self.dimensions.make_bounding_box(self.pos()) } /// Get the position of the block below the entity, but a little lower. @@ -174,20 +178,20 @@ impl<'d> EntityMut<'d> { let pos = BlockPos { x, y, z }; // TODO: check if block below is a fence, wall, or fence gate - // let block_pos = pos.below(); - // let block_state = dimension.get_block_state(&block_pos); - // if block_state == Some(BlockState::Air) { - // let block_pos_below = block_pos.below(); - // let block_state_below = dimension.get_block_state(&block_pos_below); - // if let Some(block_state_below) = block_state_below { - // if block_state_below.is_fence() - // || block_state_below.is_wall() - // || block_state_below.is_fence_gate() - // { - // return block_pos_below; - // } - // } - // } + let block_pos = pos.below(); + let block_state = self.dimension.get_block_state(&block_pos); + if block_state == Some(BlockState::Air) { + let block_pos_below = block_pos.below(); + let block_state_below = self.dimension.get_block_state(&block_pos_below); + if let Some(_block_state_below) = block_state_below { + // if block_state_below.is_fence() + // || block_state_below.is_wall() + // || block_state_below.is_fence_gate() + // { + // return block_pos_below; + // } + } + } pos } diff --git a/azalea-world/src/entity_storage.rs b/azalea-world/src/entity_storage.rs index c7fd9c0b..4dd3ec12 100644 --- a/azalea-world/src/entity_storage.rs +++ b/azalea-world/src/entity_storage.rs @@ -63,7 +63,7 @@ impl EntityStorage { /// Get a mutable reference to an entity by its id. #[inline] - pub fn get_mut_by_id<'d>(&'d mut self, id: u32) -> Option<&'d mut EntityData> { + pub fn get_mut_by_id(&mut self, id: u32) -> Option<&mut EntityData> { self.data_by_id.get_mut(&id) } diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index 77bb0f0f..93d2dcb2 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -123,23 +123,16 @@ impl Dimension { self.entity_storage.get_mut_by_id(id) } - pub fn entity<'d>(&'d self, id: u32) -> Option> { - let entity_data = self.entity_storage.get_by_id(id); - if let Some(entity_data) = entity_data { - Some(EntityRef::new(self, id, entity_data)) - } else { - None - } + pub fn entity(&self, id: u32) -> Option { + let entity_data = self.entity_storage.get_by_id(id)?; + Some(EntityRef::new(self, id, entity_data)) } - pub fn entity_mut<'d>(&'d mut self, id: u32) -> Option> { - let entity_data = self.entity_storage.get_mut_by_id(id); - if let Some(entity_data) = entity_data { - let entity_ptr = unsafe { entity_data.as_ptr() }; - Some(EntityMut::new(self, id, entity_ptr)) - } else { - None - } + pub fn entity_mut(&mut self, id: u32) -> Option { + let entity_data = self.entity_storage.get_mut_by_id(id)?; + + let entity_ptr = unsafe { entity_data.as_ptr() }; + Some(EntityMut::new(self, id, entity_ptr)) } pub fn entity_by_uuid(&self, uuid: &Uuid) -> Option<&EntityData> { diff --git a/azalea-world/src/palette.rs b/azalea-world/src/palette.rs index 4e0f9a96..1b057e4f 100644 --- a/azalea-world/src/palette.rs +++ b/azalea-world/src/palette.rs @@ -112,8 +112,8 @@ impl PalettedContainer { // sanity check debug_assert_eq!(storage.size(), self.container_type.size()); - // let palette = new_palette_type.into_empty_palette(1usize << (bits_per_entry as usize)); - let palette = new_palette_type.into_empty_palette(); + // let palette = new_palette_type.as_empty_palette(1usize << (bits_per_entry as usize)); + let palette = new_palette_type.as_empty_palette(); PalettedContainer { bits_per_entry, palette, @@ -129,8 +129,7 @@ impl PalettedContainer { let mut new_data = self.create_or_reuse_data(bits_per_entry); new_data.copy_from(&self.palette, &self.storage); *self = new_data; - let id = self.id_for(value); - id + self.id_for(value) } fn copy_from(&mut self, palette: &Palette, storage: &BitStorage) { @@ -268,7 +267,7 @@ impl PaletteType { }) } - pub fn into_empty_palette(&self) -> Palette { + pub fn as_empty_palette(&self) -> Palette { match self { PaletteType::SingleValue => Palette::SingleValue(0), PaletteType::Linear => Palette::Linear(Vec::new()), @@ -298,7 +297,7 @@ impl PalettedContainerType { } fn size(&self) -> usize { - 1 << self.size_bits() * 3 + 1 << (self.size_bits() * 3) } } diff --git a/bot/src/main.rs b/bot/src/main.rs index bad00b57..0b49f30b 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -15,7 +15,7 @@ async fn main() -> Result<(), Box> { // println!("{}", response.description.to_ansi(None)); let account = Account::offline("bot"); - let (mut client, mut rx) = account.join(&address.try_into().unwrap()).await.unwrap(); + let (client, mut rx) = account.join(&address.try_into().unwrap()).await.unwrap(); println!("connected"); while let Some(e) = &rx.recv().await {