aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2025-08-14 20:40:13 -0500
committerGitHub <noreply@github.com>2025-08-14 20:40:13 -0500
commite74ed047dbaf3877db4a89a2d589e992abd0bb11 (patch)
tree0a728c8be167a1d59a5492ed9df666f41cf12e57
parent6695132ddb31780786c67b8b9ff5df8ab3891438 (diff)
downloadazalea-drasl-e74ed047dbaf3877db4a89a2d589e992abd0bb11.tar.xz
Sneaking (#237)
* start implementing sneaking * fix horizontal_collision being inverted and cleanup * clippy * change dimensions and eye height based on pose * proper support for automatically crouching in certain cases * fix anticheat issues * add line to changelog and update a comment
-rw-r--r--CHANGELOG.md5
-rw-r--r--azalea-brigadier/src/builder/argument_builder.rs13
-rw-r--r--azalea-client/src/client.rs21
-rw-r--r--azalea-client/src/lib.rs5
-rw-r--r--azalea-client/src/local_player.rs38
-rw-r--r--azalea-client/src/plugins/attack.rs10
-rw-r--r--azalea-client/src/plugins/interact/mod.rs19
-rw-r--r--azalea-client/src/plugins/interact/pick.rs9
-rw-r--r--azalea-client/src/plugins/inventory.rs5
-rw-r--r--azalea-client/src/plugins/mining.rs5
-rw-r--r--azalea-client/src/plugins/movement.rs322
-rw-r--r--azalea-client/src/plugins/packet/game/mod.rs4
-rw-r--r--azalea-client/tests/correct_sneak_movement.rs135
-rw-r--r--azalea-client/tests/correct_sprint_sneak_movement.rs153
-rw-r--r--azalea-core/src/cursor3d.rs6
-rw-r--r--azalea-core/src/math.rs4
-rw-r--r--azalea-entity/src/attributes.rs34
-rw-r--r--azalea-entity/src/data.rs12
-rw-r--r--azalea-entity/src/dimensions.rs242
-rw-r--r--azalea-entity/src/lib.rs95
-rw-r--r--azalea-entity/src/metadata.rs458
-rw-r--r--azalea-entity/src/plugin/mod.rs53
-rw-r--r--azalea-physics/src/collision/mod.rs226
-rw-r--r--azalea-physics/src/lib.rs117
-rw-r--r--azalea-physics/src/local_player.rs67
-rw-r--r--azalea-physics/src/travel.rs246
-rw-r--r--azalea-protocol/src/packets/game/c_player_abilities.rs17
-rw-r--r--azalea/examples/nearest_entity.rs11
-rw-r--r--azalea/examples/testbot/commands/debug.rs7
-rw-r--r--azalea/examples/testbot/commands/movement.rs24
-rw-r--r--azalea/src/bot.rs14
-rw-r--r--azalea/src/pathfinder/simulation.rs6
-rw-r--r--codegen/lib/code/entity.py15
33 files changed, 1599 insertions, 799 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5850f181..c52119c1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,7 +15,8 @@ is breaking anyways, semantic versioning is not followed.
- Local clients now have a `TicksConnected` component. (@Kumpelinus)
- There is now a `azalea_inventory::default_components::get_default_component` function to get the default value of a component for a registry item.
- `ItemStack` now has a `get_component` function that supports default components.
-- Add `Client::nearest_entity_by`.
+- `Client::nearest_entity_by`.
+- Sneaking/crouching.
### Changed
@@ -26,6 +27,7 @@ is breaking anyways, semantic versioning is not followed.
- `ItemStackData::components` was renamed to `component_patch`.
- The fields in `LookDirection` have been replaced with getters.
- Renamed `Client::entity_by` to `any_entity_by`, and `Client::entities_by` to `nearest_entities_by`.
+- `EyeHeight` was moved into `EntityDimensions`, and `EntityDimensions` is now its own component.
### Fixed
@@ -33,6 +35,7 @@ is breaking anyways, semantic versioning is not followed.
- Clients no longer send invalid look directions if the server teleports us with one.
- Look directions are now rounded based on the default Minecraft sensitivity, which may help avoid flagging anticheats.
- Movement code was updated with the changes from 1.21.5, so it no longer flags Grim.
+- Clients can no longer sprint if their food level is too low.
- `azalea-chat` now handles arrays of integers in the `with` field. (@qwqawawow)
- `azalea-chat` no longer incorrectly persists styles of components in the "extra" field.
- Inventories now use the correct max stack sizes.
diff --git a/azalea-brigadier/src/builder/argument_builder.rs b/azalea-brigadier/src/builder/argument_builder.rs
index 5fbdaca5..945f7fcb 100644
--- a/azalea-brigadier/src/builder/argument_builder.rs
+++ b/azalea-brigadier/src/builder/argument_builder.rs
@@ -30,7 +30,6 @@ impl<S> Clone for ArgumentBuilderType<S> {
}
/// A node that hasn't yet been built.
-#[derive(Clone)]
pub struct ArgumentBuilder<S> {
arguments: CommandNode<S>,
@@ -196,3 +195,15 @@ impl<S> Debug for ArgumentBuilder<S> {
.finish()
}
}
+impl<S> Clone for ArgumentBuilder<S> {
+ fn clone(&self) -> Self {
+ Self {
+ arguments: self.arguments.clone(),
+ command: self.command.clone(),
+ requirement: self.requirement.clone(),
+ target: self.target.clone(),
+ forks: self.forks,
+ modifier: self.modifier.clone(),
+ }
+ }
+}
diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs
index 9481ba2d..be9c8e99 100644
--- a/azalea-client/src/client.rs
+++ b/azalea-client/src/client.rs
@@ -14,10 +14,12 @@ use azalea_core::{
tick::GameTick,
};
use azalea_entity::{
- EntityUpdateSet, EyeHeight, Position,
+ EntityUpdateSet, PlayerAbilities, Position,
+ dimensions::EntityDimensions,
indexing::{EntityIdIndex, EntityUuidIndex},
metadata::Health,
};
+use azalea_physics::local_player::PhysicsState;
use azalea_protocol::{
ServerAddress,
common::client_information::ClientInformation,
@@ -55,9 +57,9 @@ use crate::{
interact::BlockStatePredictionHandler,
inventory::Inventory,
join::{ConnectOpts, StartJoinServerEvent},
- local_player::{Hunger, InstanceHolder, PermissionLevel, PlayerAbilities, TabList},
+ local_player::{Hunger, InstanceHolder, PermissionLevel, TabList},
mining::{self},
- movement::{LastSentLookDirection, PhysicsState},
+ movement::LastSentLookDirection,
packet::game::SendPacketEvent,
player::{GameProfileComponent, PlayerInfo, retroactively_add_game_profile_component},
};
@@ -427,12 +429,21 @@ impl Client {
)
}
+ /// Get the bounding box dimensions for our client, which contains our
+ /// width, height, and eye height.
+ ///
+ /// This is a shortcut for
+ /// `self.component::<EntityDimensions>()`.
+ pub fn dimensions(&self) -> EntityDimensions {
+ self.component::<EntityDimensions>()
+ }
+
/// Get the position of this client's eyes.
///
/// This is a shortcut for
- /// `bot.position().up(bot.component::<EyeHeight>())`.
+ /// `bot.position().up(bot.dimensions().eye_height)`.
pub fn eye_position(&self) -> Vec3 {
- self.position().up((*self.component::<EyeHeight>()) as f64)
+ self.position().up(self.dimensions().eye_height as f64)
}
/// Get the health of this client.
diff --git a/azalea-client/src/lib.rs b/azalea-client/src/lib.rs
index 19e13253..c818d96a 100644
--- a/azalea-client/src/lib.rs
+++ b/azalea-client/src/lib.rs
@@ -21,6 +21,7 @@ mod plugins;
pub mod test_utils;
pub use account::{Account, AccountOpts};
+pub use azalea_physics::local_player::{PhysicsState, SprintDirection, WalkDirection};
pub use azalea_protocol::common::client_information::ClientInformation;
// Re-export bevy-tasks so plugins can make sure that they're using the same
// version.
@@ -30,7 +31,5 @@ pub use client::{
StartClientOpts, start_ecs_runner,
};
pub use events::Event;
-pub use movement::{
- PhysicsState, SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection,
-};
+pub use movement::{StartSprintEvent, StartWalkEvent};
pub use plugins::*;
diff --git a/azalea-client/src/local_player.rs b/azalea-client/src/local_player.rs
index 4a937ec7..09232d12 100644
--- a/azalea-client/src/local_player.rs
+++ b/azalea-client/src/local_player.rs
@@ -5,7 +5,6 @@ use std::{
};
use azalea_core::game_type::GameMode;
-use azalea_protocol::packets::game::c_player_abilities::ClientboundPlayerAbilities;
use azalea_world::{Instance, PartialInstance};
use bevy_ecs::{component::Component, prelude::*};
use derive_more::{Deref, DerefMut};
@@ -55,34 +54,6 @@ impl From<GameMode> for LocalGameMode {
}
}
-/// A component that contains the abilities the player has, like flying
-/// or instantly breaking blocks. This is only present on local players.
-#[derive(Clone, Debug, Component, Default)]
-pub struct PlayerAbilities {
- pub invulnerable: bool,
- pub flying: bool,
- pub can_fly: bool,
- /// Whether the player can instantly break blocks and can duplicate blocks
- /// in their inventory.
- pub instant_break: bool,
-
- pub flying_speed: f32,
- /// Used for the fov
- pub walking_speed: f32,
-}
-impl From<&ClientboundPlayerAbilities> for PlayerAbilities {
- fn from(packet: &ClientboundPlayerAbilities) -> Self {
- Self {
- invulnerable: packet.flags.invulnerable,
- flying: packet.flags.flying,
- can_fly: packet.flags.can_fly,
- instant_break: packet.flags.instant_break,
- flying_speed: packet.flying_speed,
- walking_speed: packet.walking_speed,
- }
- }
-}
-
/// Level must be 0..=4
#[derive(Component, Clone, Default, Deref, DerefMut)]
pub struct PermissionLevel(pub u8);
@@ -127,6 +98,15 @@ impl Default for Hunger {
}
}
}
+impl Hunger {
+ /// Returns true if we have enough food level to sprint.
+ ///
+ /// Note that this doesn't consider our gamemode or passenger status.
+ pub fn is_enough_to_sprint(&self) -> bool {
+ // hasEnoughFoodToSprint
+ self.food >= 6
+ }
+}
impl InstanceHolder {
/// Create a new `InstanceHolder` for the given entity.
diff --git a/azalea-client/src/plugins/attack.rs b/azalea-client/src/plugins/attack.rs
index ec4337e5..7d730bb7 100644
--- a/azalea-client/src/plugins/attack.rs
+++ b/azalea-client/src/plugins/attack.rs
@@ -1,8 +1,6 @@
use azalea_core::{game_type::GameMode, tick::GameTick};
use azalea_entity::{
- Attributes, Physics,
- indexing::EntityIdIndex,
- metadata::{ShiftKeyDown, Sprinting},
+ Attributes, Crouching, Physics, indexing::EntityIdIndex, metadata::Sprinting,
update_bounding_box,
};
use azalea_physics::PhysicsSet;
@@ -100,7 +98,7 @@ pub fn handle_attack_queued(
&mut Sprinting,
&AttackQueued,
&LocalGameMode,
- &ShiftKeyDown,
+ &Crouching,
&EntityIdIndex,
)>,
) {
@@ -111,7 +109,7 @@ pub fn handle_attack_queued(
mut sprinting,
attack_queued,
game_mode,
- sneaking,
+ crouching,
entity_id_index,
) in &mut query
{
@@ -128,7 +126,7 @@ pub fn handle_attack_queued(
ServerboundInteract {
entity_id: target_entity_id,
action: s_interact::ActionType::Attack,
- using_secondary_action: **sneaking,
+ using_secondary_action: **crouching,
},
));
commands.trigger(SwingArmEvent {
diff --git a/azalea-client/src/plugins/interact/mod.rs b/azalea-client/src/plugins/interact/mod.rs
index 634d492c..0275ca97 100644
--- a/azalea-client/src/plugins/interact/mod.rs
+++ b/azalea-client/src/plugins/interact/mod.rs
@@ -11,7 +11,7 @@ use azalea_core::{
tick::GameTick,
};
use azalea_entity::{
- Attributes, LocalEntity, LookDirection,
+ Attributes, Crouching, LocalEntity, LookDirection, PlayerAbilities,
attributes::{
creative_block_interaction_range_modifier, creative_entity_interaction_range_modifier,
},
@@ -36,7 +36,7 @@ use crate::{
attack::handle_attack_event,
interact::pick::{HitResultComponent, update_hit_result_component},
inventory::{Inventory, InventorySet},
- local_player::{LocalGameMode, PermissionLevel, PlayerAbilities},
+ local_player::{LocalGameMode, PermissionLevel},
movement::MoveEventsSet,
packet::game::SendPacketEvent,
respawn::perform_respawn,
@@ -250,12 +250,20 @@ pub fn handle_start_use_item_queued(
&mut BlockStatePredictionHandler,
&HitResultComponent,
&LookDirection,
+ &Crouching,
Option<&Mining>,
)>,
entity_id_query: Query<&MinecraftEntityId>,
) {
- for (entity, start_use_item, mut prediction_handler, hit_result, look_direction, mining) in
- query
+ for (
+ entity,
+ start_use_item,
+ mut prediction_handler,
+ hit_result,
+ look_direction,
+ crouching,
+ mining,
+ ) in query
{
commands.entity(entity).remove::<StartUseItemQueued>();
@@ -332,8 +340,7 @@ pub fn handle_start_use_item_queued(
location: r.location,
hand: InteractionHand::MainHand,
},
- // TODO: sneaking
- using_secondary_action: false,
+ using_secondary_action: **crouching,
},
));
}
diff --git a/azalea-client/src/plugins/interact/pick.rs b/azalea-client/src/plugins/interact/pick.rs
index cebbf905..a0a75910 100644
--- a/azalea-client/src/plugins/interact/pick.rs
+++ b/azalea-client/src/plugins/interact/pick.rs
@@ -5,7 +5,8 @@ use azalea_core::{
position::Vec3,
};
use azalea_entity::{
- Attributes, Dead, EyeHeight, LocalEntity, LookDirection, Physics, Position,
+ Attributes, Dead, LocalEntity, LookDirection, Physics, Position,
+ dimensions::EntityDimensions,
metadata::{ArmorStandMarker, Marker},
view_vector,
};
@@ -31,7 +32,7 @@ pub fn update_hit_result_component(
Entity,
Option<&mut HitResultComponent>,
&Position,
- &EyeHeight,
+ &EntityDimensions,
&LookDirection,
&InstanceName,
&Physics,
@@ -47,7 +48,7 @@ pub fn update_hit_result_component(
entity,
hit_result_ref,
position,
- eye_height,
+ dimensions,
look_direction,
world_name,
physics,
@@ -57,7 +58,7 @@ pub fn update_hit_result_component(
let block_pick_range = attributes.block_interaction_range.calculate();
let entity_pick_range = attributes.entity_interaction_range.calculate();
- let eye_position = position.up(eye_height.into());
+ let eye_position = position.up(dimensions.eye_height.into());
let Some(world_lock) = instance_container.get(world_name) else {
continue;
diff --git a/azalea-client/src/plugins/inventory.rs b/azalea-client/src/plugins/inventory.rs
index 732e1154..ecc8e826 100644
--- a/azalea-client/src/plugins/inventory.rs
+++ b/azalea-client/src/plugins/inventory.rs
@@ -4,6 +4,7 @@ use std::{
};
use azalea_chat::FormattedText;
+use azalea_entity::PlayerAbilities;
pub use azalea_inventory::*;
use azalea_inventory::{
item::MaxStackSizeExt,
@@ -23,9 +24,7 @@ use bevy_app::{App, Plugin, Update};
use bevy_ecs::prelude::*;
use tracing::{error, warn};
-use crate::{
- Client, local_player::PlayerAbilities, packet::game::SendPacketEvent, respawn::perform_respawn,
-};
+use crate::{Client, packet::game::SendPacketEvent, respawn::perform_respawn};
pub struct InventoryPlugin;
impl Plugin for InventoryPlugin {
diff --git a/azalea-client/src/plugins/mining.rs b/azalea-client/src/plugins/mining.rs
index f584bacb..1b7adadc 100644
--- a/azalea-client/src/plugins/mining.rs
+++ b/azalea-client/src/plugins/mining.rs
@@ -1,6 +1,6 @@
use azalea_block::{BlockState, BlockTrait, fluid_state::FluidState};
use azalea_core::{direction::Direction, game_type::GameMode, position::BlockPos, tick::GameTick};
-use azalea_entity::{FluidOnEyes, Physics, Position, mining::get_mine_progress};
+use azalea_entity::{FluidOnEyes, Physics, PlayerAbilities, Position, mining::get_mine_progress};
use azalea_inventory::ItemStack;
use azalea_physics::{PhysicsSet, collision::BlockWithShape};
use azalea_protocol::packets::game::s_player_action::{self, ServerboundPlayerAction};
@@ -17,7 +17,7 @@ use crate::{
check_is_interaction_restricted, pick::HitResultComponent,
},
inventory::{Inventory, InventorySet},
- local_player::{InstanceHolder, LocalGameMode, PermissionLevel, PlayerAbilities},
+ local_player::{InstanceHolder, LocalGameMode, PermissionLevel},
movement::MoveEventsSet,
packet::game::SendPacketEvent,
};
@@ -55,7 +55,6 @@ impl Plugin for MiningPlugin {
.in_set(MiningSet)
.after(InventorySet)
.after(MoveEventsSet)
- .before(azalea_entity::update_bounding_box)
.after(azalea_entity::update_fluid_on_eyes)
.after(crate::interact::pick::update_hit_result_component)
.after(crate::attack::handle_attack_event)
diff --git a/azalea-client/src/plugins/movement.rs b/azalea-client/src/plugins/movement.rs
index c9b3b070..ad6779fa 100644
--- a/azalea-client/src/plugins/movement.rs
+++ b/azalea-client/src/plugins/movement.rs
@@ -1,14 +1,23 @@
use std::{backtrace::Backtrace, io};
use azalea_core::{
+ game_type::GameMode,
position::{Vec2, Vec3},
tick::GameTick,
};
use azalea_entity::{
- Attributes, HasClientLoaded, Jumping, LastSentPosition, LookDirection, Physics, Position,
- metadata::Sprinting,
+ Attributes, Crouching, HasClientLoaded, Jumping, LastSentPosition, LocalEntity, LookDirection,
+ Physics, PlayerAbilities, Pose, Position,
+ dimensions::calculate_dimensions,
+ metadata::{self, Sprinting},
+ update_bounding_box,
+};
+use azalea_physics::{
+ PhysicsSet, ai_step,
+ collision::entity_collisions::{CollidableEntityQuery, PhysicsQuery},
+ local_player::{PhysicsState, SprintDirection, WalkDirection},
+ travel::{no_collision, travel},
};
-use azalea_physics::{PhysicsSet, ai_step};
use azalea_protocol::{
common::movements::MoveFlags,
packets::{
@@ -22,12 +31,17 @@ use azalea_protocol::{
},
},
};
-use azalea_world::{MinecraftEntityId, MoveEntityError};
+use azalea_registry::EntityKind;
+use azalea_world::{Instance, MinecraftEntityId, MoveEntityError};
use bevy_app::{App, Plugin, Update};
use bevy_ecs::prelude::*;
use thiserror::Error;
-use crate::{client::Client, packet::game::SendPacketEvent};
+use crate::{
+ client::Client,
+ local_player::{Hunger, InstanceHolder, LocalGameMode},
+ packet::game::SendPacketEvent,
+};
#[derive(Error, Debug)]
pub enum MovePlayerError {
@@ -58,18 +72,21 @@ impl Plugin for MovementPlugin {
Update,
(handle_sprint, handle_walk, handle_knockback)
.chain()
- .in_set(MoveEventsSet),
+ .in_set(MoveEventsSet)
+ .after(update_bounding_box),
)
.add_systems(
GameTick,
(
- (tick_controls, local_player_ai_step)
+ (tick_controls, local_player_ai_step, update_pose)
.chain()
.in_set(PhysicsSet)
.before(ai_step)
.before(azalea_physics::fluids::update_in_water_state_and_do_fluid_pushing),
send_player_input_packet,
- send_sprinting_if_needed.after(azalea_entity::update_in_loaded_chunk),
+ send_sprinting_if_needed
+ .after(azalea_entity::update_in_loaded_chunk)
+ .after(travel),
send_position.after(PhysicsSet),
)
.chain(),
@@ -97,6 +114,21 @@ impl Client {
*self.component::<Jumping>()
}
+ pub fn set_crouching(&self, crouching: bool) {
+ let mut ecs = self.ecs.lock();
+ let mut physics_state = self.query::<&mut PhysicsState>(&mut ecs);
+ physics_state.trying_to_crouch = crouching;
+ }
+
+ /// Whether the client is currently trying to sneak.
+ ///
+ /// You may want to check the [`Pose`] instead.
+ pub fn crouching(&self) -> bool {
+ let mut ecs = self.ecs.lock();
+ let physics_state = self.query::<&PhysicsState>(&mut ecs);
+ physics_state.trying_to_crouch
+ }
+
/// Sets the direction the client is looking. `y_rot` is yaw (looking to the
/// side), `x_rot` is pitch (looking up and down). You can get these
/// numbers from the vanilla f3 screen.
@@ -125,24 +157,6 @@ pub struct LastSentLookDirection {
pub y_rot: f32,
}
-/// Component for entities that can move and sprint. Usually only in
-/// [`LocalEntity`]s.
-///
-/// [`LocalEntity`]: azalea_entity::LocalEntity
-#[derive(Default, Component, Clone)]
-pub struct PhysicsState {
- /// Minecraft only sends a movement packet either after 20 ticks or if the
- /// player moved enough. This is that tick counter.
- pub position_remainder: u32,
- pub was_sprinting: bool,
- // Whether we're going to try to start sprinting this tick. Equivalent to
- // holding down ctrl for a tick.
- pub trying_to_sprint: bool,
-
- pub move_direction: WalkDirection,
- pub move_vector: Vec2,
-}
-
#[allow(clippy::type_complexity)]
pub fn send_position(
mut query: Query<
@@ -266,8 +280,7 @@ pub fn send_player_input_packet(
left: matches!(dir, D::Left | D::ForwardLeft | D::BackwardLeft),
right: matches!(dir, D::Right | D::ForwardRight | D::BackwardRight),
jump: **jumping,
- // TODO: implement sneaking
- shift: false,
+ shift: physics_state.trying_to_crouch,
sprint: physics_state.trying_to_sprint,
};
@@ -345,46 +358,144 @@ pub(crate) fn tick_controls(mut query: Query<&mut PhysicsState>) {
/// Makes the bot do one physics tick. Note that this is already handled
/// automatically by the client.
+#[allow(clippy::type_complexity)]
pub fn local_player_ai_step(
mut query: Query<
- (&PhysicsState, &mut Physics, &mut Sprinting, &mut Attributes),
- With<HasClientLoaded>,
+ (
+ Entity,
+ &PhysicsState,
+ &PlayerAbilities,
+ &metadata::Swimming,
+ &metadata::SleepingPos,
+ &InstanceHolder,
+ &Position,
+ Option<&Hunger>,
+ Option<&LastSentInput>,
+ &mut Physics,
+ &mut Sprinting,
+ &mut Crouching,
+ &mut Attributes,
+ ),
+ (With<HasClientLoaded>, With<LocalEntity>),
>,
+ physics_query: PhysicsQuery,
+ collidable_entity_query: CollidableEntityQuery,
) {
- for (physics_state, mut physics, mut sprinting, mut attributes) in query.iter_mut() {
+ for (
+ entity,
+ physics_state,
+ abilities,
+ swimming,
+ sleeping_pos,
+ instance_holder,
+ position,
+ hunger,
+ last_sent_input,
+ mut physics,
+ mut sprinting,
+ mut crouching,
+ mut attributes,
+ ) in query.iter_mut()
+ {
// server ai step
- // TODO: replace those booleans when using items, passengers, and sneaking are
- // properly implemented
- let move_vector = modify_input(physics_state.move_vector, false, false, false, &attributes);
- physics.x_acceleration = move_vector.x;
- physics.z_acceleration = move_vector.y;
+ let is_swimming = **swimming;
+ // TODO: implement passengers
+ let is_passenger = false;
+ let is_sleeping = sleeping_pos.is_some();
+
+ let world = instance_holder.instance.read();
+ let ctx = CanPlayerFitCtx {
+ world: &world,
+ entity,
+ position: *position,
+ physics_query: &physics_query,
+ collidable_entity_query: &collidable_entity_query,
+ physics: &physics,
+ };
+
+ let new_crouching = !abilities.flying
+ && !is_swimming
+ && !is_passenger
+ && can_player_fit_within_blocks_and_entities_when(&ctx, Pose::Crouching)
+ && (last_sent_input.is_some_and(|i| i.0.shift)
+ || !is_sleeping
+ && !can_player_fit_within_blocks_and_entities_when(&ctx, Pose::Standing));
+ if **crouching != new_crouching {
+ **crouching = new_crouching;
+ }
// TODO: food data and abilities
// let has_enough_food_to_sprint = self.food_data().food_level ||
// self.abilities().may_fly;
- let has_enough_food_to_sprint = true;
+ let has_enough_food_to_sprint = hunger.is_none_or(Hunger::is_enough_to_sprint);
// TODO: double tapping w to sprint i think
let trying_to_sprint = physics_state.trying_to_sprint;
- if !**sprinting
- && (
- // !self.is_in_water()
- // || self.is_underwater() &&
- has_enough_impulse_to_start_sprinting(physics_state)
- && has_enough_food_to_sprint
- // && !self.using_item()
- // && !self.has_effect(MobEffects.BLINDNESS)
- && trying_to_sprint
- )
- {
+ // TODO: swimming
+ let is_underwater = false;
+ let is_in_water = physics.is_in_water();
+ // TODO: elytra
+ let is_fall_flying = false;
+ // TODO: passenger
+ let is_passenger = false;
+ // TODO: using items
+ let using_item = false;
+ // TODO: status effects
+ let has_blindness = false;
+
+ let has_enough_impulse = has_enough_impulse_to_start_sprinting(physics_state);
+
+ // LocalPlayer.canStartSprinting
+ let can_start_sprinting = !**sprinting
+ && has_enough_impulse
+ && has_enough_food_to_sprint
+ && !using_item
+ && !has_blindness
+ && (!is_passenger || is_underwater)
+ && (!is_fall_flying || is_underwater)
+ && (!is_moving_slowly(&crouching) || is_underwater)
+ && (!is_in_water || is_underwater);
+ if trying_to_sprint && can_start_sprinting {
set_sprinting(true, &mut sprinting, &mut attributes);
}
+
+ if **sprinting {
+ // TODO: swimming
+
+ let vehicle_can_sprint = false;
+ // shouldStopRunSprinting
+ let should_stop_sprinting = has_blindness
+ || (is_passenger && !vehicle_can_sprint)
+ || !has_enough_impulse
+ || !has_enough_food_to_sprint
+ || (physics.horizontal_collision && !physics.minor_horizontal_collision)
+ || (is_in_water && !is_underwater);
+ if should_stop_sprinting {
+ set_sprinting(false, &mut sprinting, &mut attributes);
+ }
+ }
+
+ // TODO: replace those booleans when using items and passengers are properly
+ // implemented
+ let move_vector = modify_input(
+ physics_state.move_vector,
+ false,
+ false,
+ **crouching,
+ &attributes,
+ );
+ physics.x_acceleration = move_vector.x;
+ physics.z_acceleration = move_vector.y;
}
}
+fn is_moving_slowly(crouching: &Crouching) -> bool {
+ **crouching
+}
+
// LocalPlayer.modifyInput
fn modify_input(
mut move_vector: Vec2,
@@ -523,8 +634,12 @@ pub fn handle_sprint(
}
/// Change whether we're sprinting by adding an attribute modifier to the
-/// player. You should use the [`walk`] and [`sprint`] methods instead.
-/// Returns if the operation was successful.
+/// player.
+///
+/// You should use the [`Client::walk`] and [`Client::sprint`] functions
+/// instead.
+///
+/// Returns true if the operation was successful.
fn set_sprinting(
sprinting: bool,
currently_sprinting: &mut Sprinting,
@@ -533,12 +648,12 @@ fn set_sprinting(
**currently_sprinting = sprinting;
if sprinting {
attributes
- .speed
+ .movement_speed
.try_insert(azalea_entity::attributes::sprinting_modifier())
.is_ok()
} else {
attributes
- .speed
+ .movement_speed
.remove(&azalea_entity::attributes::sprinting_modifier().id)
.is_none()
}
@@ -583,34 +698,85 @@ pub fn handle_knockback(mut query: Query<&mut Physics>, mut events: EventReader<
}
}
-#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
-pub enum WalkDirection {
- #[default]
- None,
- Forward,
- Backward,
- Left,
- Right,
- ForwardRight,
- ForwardLeft,
- BackwardRight,
- BackwardLeft,
-}
+pub fn update_pose(
+ mut query: Query<(
+ Entity,
+ &mut Pose,
+ &Physics,
+ &PhysicsState,
+ &LocalGameMode,
+ &InstanceHolder,
+ &Position,
+ )>,
+ physics_query: PhysicsQuery,
+ collidable_entity_query: CollidableEntityQuery,
+) {
+ for (entity, mut pose, physics, physics_state, game_mode, instance_holder, position) in
+ query.iter_mut()
+ {
+ let world = instance_holder.instance.read();
+ let world = &*world;
+ let ctx = CanPlayerFitCtx {
+ world,
+ entity,
+ position: *position,
+ physics_query: &physics_query,
+ collidable_entity_query: &collidable_entity_query,
+ physics,
+ };
-/// The directions that we can sprint in. It's a subset of [`WalkDirection`].
-#[derive(Clone, Copy, Debug)]
-pub enum SprintDirection {
- Forward,
- ForwardRight,
- ForwardLeft,
-}
+ if !can_player_fit_within_blocks_and_entities_when(&ctx, Pose::Swimming) {
+ continue;
+ }
+
+ // TODO: implement everything else from getDesiredPose: sleeping, swimming,
+ // fallFlying, spinAttack
+ let desired_pose = if physics_state.trying_to_crouch {
+ Pose::Crouching
+ } else {
+ Pose::Standing
+ };
-impl From<SprintDirection> for WalkDirection {
- fn from(d: SprintDirection) -> Self {
- match d {
- SprintDirection::Forward => WalkDirection::Forward,
- SprintDirection::ForwardRight => WalkDirection::ForwardRight,
- SprintDirection::ForwardLeft => WalkDirection::ForwardLeft,
+ // TODO: passengers
+ let is_passenger = false;
+
+ // canPlayerFitWithinBlocksAndEntitiesWhen
+ let new_pose = if game_mode.current == GameMode::Spectator
+ || is_passenger
+ || can_player_fit_within_blocks_and_entities_when(&ctx, desired_pose)
+ {
+ desired_pose
+ } else if can_player_fit_within_blocks_and_entities_when(&ctx, Pose::Crouching) {
+ Pose::Crouching
+ } else {
+ Pose::Swimming
+ };
+
+ // avoid triggering change detection
+ if new_pose != *pose {
+ *pose = new_pose;
}
}
}
+
+struct CanPlayerFitCtx<'world, 'state, 'a, 'b> {
+ world: &'a Instance,
+ entity: Entity,
+ position: Position,
+ physics_query: &'a PhysicsQuery<'world, 'state, 'b>,
+ collidable_entity_query: &'a CollidableEntityQuery<'world, 'state>,
+ physics: &'a Physics,
+}
+fn can_player_fit_within_blocks_and_entities_when(ctx: &CanPlayerFitCtx, pose: Pose) -> bool {
+ // return this.level().noCollision(this,
+ // this.getDimensions(var1).makeBoundingBox(this.position()).deflate(1.0E-7));
+ no_collision(
+ ctx.world,
+ Some(ctx.entity),
+ ctx.physics_query,
+ ctx.collidable_entity_query,
+ ctx.physics,
+ &calculate_dimensions(EntityKind::Player, pose).make_bounding_box(*ctx.position),
+ false,
+ )
+}
diff --git a/azalea-client/src/plugins/packet/game/mod.rs b/azalea-client/src/plugins/packet/game/mod.rs
index 26d83195..49523002 100644
--- a/azalea-client/src/plugins/packet/game/mod.rs
+++ b/azalea-client/src/plugins/packet/game/mod.rs
@@ -8,7 +8,7 @@ use azalea_core::{
};
use azalea_entity::{
Dead, EntityBundle, EntityKindComponent, HasClientLoaded, LoadedBy, LocalEntity, LookDirection,
- Physics, Position, RelativeEntityUpdate,
+ Physics, PlayerAbilities, Position, RelativeEntityUpdate,
indexing::{EntityIdIndex, EntityUuidIndex},
metadata::{Health, apply_metadata},
};
@@ -33,7 +33,7 @@ use crate::{
inventory::{
ClientSideCloseContainerEvent, Inventory, MenuOpenedEvent, SetContainerContentEvent,
},
- local_player::{Hunger, InstanceHolder, LocalGameMode, PlayerAbilities, TabList},
+ local_player::{Hunger, InstanceHolder, LocalGameMode, TabList},
movement::{KnockbackEvent, KnockbackType},
packet::as_system,
player::{GameProfileComponent, PlayerInfo},
diff --git a/azalea-client/tests/correct_sneak_movement.rs b/azalea-client/tests/correct_sneak_movement.rs
new file mode 100644
index 00000000..cf1d17b5
--- /dev/null
+++ b/azalea-client/tests/correct_sneak_movement.rs
@@ -0,0 +1,135 @@
+use azalea_client::{PhysicsState, StartWalkEvent, WalkDirection, test_utils::prelude::*};
+use azalea_core::{
+ position::{BlockPos, ChunkPos, Vec3},
+ resource_location::ResourceLocation,
+};
+use azalea_entity::LookDirection;
+use azalea_protocol::{
+ common::movements::{PositionMoveRotation, RelativeMovements},
+ packets::{
+ ConnectionProtocol,
+ config::{ClientboundFinishConfiguration, ClientboundRegistryData},
+ game::{
+ ClientboundBlockUpdate, ClientboundPlayerPosition, ServerboundGamePacket,
+ ServerboundPlayerInput,
+ },
+ },
+};
+use azalea_registry::{Block, DataRegistry, DimensionType};
+use simdnbt::owned::{NbtCompound, NbtTag};
+
+#[test]
+fn test_correct_sneak_movement() {
+ init_tracing();
+
+ let mut simulation = Simulation::new(ConnectionProtocol::Configuration);
+ let sent_packets = SentPackets::new(&mut simulation);
+
+ simulation.receive_packet(ClientboundRegistryData {
+ registry_id: ResourceLocation::new("minecraft:dimension_type"),
+ entries: vec![(
+ ResourceLocation::new("minecraft:overworld"),
+ Some(NbtCompound::from_values(vec![
+ ("height".into(), NbtTag::Int(384)),
+ ("min_y".into(), NbtTag::Int(-64)),
+ ])),
+ )]
+ .into_iter()
+ .collect(),
+ });
+ simulation.tick();
+ simulation.receive_packet(ClientboundFinishConfiguration);
+ simulation.tick();
+
+ simulation.receive_packet(make_basic_login_packet(
+ DimensionType::new_raw(0), // overworld
+ ResourceLocation::new("minecraft:overworld"),
+ ));
+ simulation.tick();
+
+ sent_packets.expect_tick_end();
+ sent_packets.expect_empty();
+
+ simulation.receive_packet(make_basic_empty_chunk(ChunkPos::new(0, 0), (384 + 64) / 16));
+ simulation.receive_packet(ClientboundBlockUpdate {
+ pos: BlockPos::new(0, 119, 0),
+ block_state: Block::Stone.into(),
+ });
+ simulation.receive_packet(ClientboundBlockUpdate {
+ pos: BlockPos::new(0, 119, 1),
+ block_state: Block::Stone.into(),
+ });
+ simulation.receive_packet(ClientboundPlayerPosition {
+ id: 1,
+ change: PositionMoveRotation {
+ pos: Vec3::new(0.5, 120., 0.5),
+ delta: Vec3::ZERO,
+ look_direction: LookDirection::default(),
+ },
+ relative: RelativeMovements::all_absolute(),
+ });
+ simulation.tick();
+ simulation.tick();
+ simulation.tick();
+ sent_packets.clear();
+
+ simulation.with_component_mut::<PhysicsState>(|p| p.trying_to_crouch = true);
+ simulation.tick();
+ sent_packets.expect("PlayerInput", |p| {
+ matches!(
+ p,
+ ServerboundGamePacket::PlayerInput(p)
+ if *p == ServerboundPlayerInput { shift: true, ..Default::default() }
+ )
+ });
+ sent_packets.expect_tick_end();
+ sent_packets.expect_empty();
+
+ simulation.tick();
+ simulation.send_event(StartWalkEvent {
+ entity: simulation.entity,
+ direction: WalkDirection::Forward,
+ });
+ sent_packets.expect_tick_end();
+ sent_packets.expect_empty();
+
+ simulation.tick();
+ sent_packets.expect("PlayerInput", |p| {
+ matches!(
+ p,
+ ServerboundGamePacket::PlayerInput(p)
+ if *p == ServerboundPlayerInput { forward: true, shift: true, ..Default::default() }
+ )
+ });
+ sent_packets.expect("MovePlayerPos { z: 0.5294000033944846 }", |p| {
+ matches!(
+ p,
+ ServerboundGamePacket::MovePlayerPos(p)
+ if p.pos == Vec3::new(0.5, 120., 0.5294000033944846)
+ )
+ });
+ sent_packets.expect_tick_end();
+ sent_packets.expect_empty();
+
+ simulation.tick();
+ sent_packets.expect("MovePlayerPos { z: 0.5748524105068866 }", |p| {
+ matches!(
+ p,
+ ServerboundGamePacket::MovePlayerPos(p)
+ if p.pos == Vec3::new(0.5, 120., 0.5748524105068866)
+ )
+ });
+ sent_packets.expect_tick_end();
+ sent_packets.expect_empty();
+
+ simulation.tick();
+ sent_packets.expect("MovePlayerPos: { z: 0.6290694310673044 }", |p| {
+ matches!(
+ p,
+ ServerboundGamePacket::MovePlayerPos(p)
+ if p.pos == Vec3::new(0.5, 120., 0.6290694310673044)
+ )
+ });
+ sent_packets.expect_tick_end();
+ sent_packets.expect_empty();
+}
diff --git a/azalea-client/tests/correct_sprint_sneak_movement.rs b/azalea-client/tests/correct_sprint_sneak_movement.rs
new file mode 100644
index 00000000..5b26a8a3
--- /dev/null
+++ b/azalea-client/tests/correct_sprint_sneak_movement.rs
@@ -0,0 +1,153 @@
+use azalea_client::{PhysicsState, SprintDirection, StartSprintEvent, test_utils::prelude::*};
+use azalea_core::{
+ position::{BlockPos, ChunkPos, Vec3},
+ resource_location::ResourceLocation,
+};
+use azalea_entity::LookDirection;
+use azalea_protocol::{
+ common::movements::{PositionMoveRotation, RelativeMovements},
+ packets::{
+ ConnectionProtocol,
+ config::{ClientboundFinishConfiguration, ClientboundRegistryData},
+ game::{
+ ClientboundBlockUpdate, ClientboundPlayerPosition, ServerboundGamePacket,
+ ServerboundPlayerInput,
+ },
+ },
+};
+use azalea_registry::{Block, DataRegistry, DimensionType};
+use simdnbt::owned::{NbtCompound, NbtTag};
+
+#[test]
+fn test_correct_sprint_sneak_movement() {
+ init_tracing();
+
+ let mut simulation = Simulation::new(ConnectionProtocol::Configuration);
+ let sent_packets = SentPackets::new(&mut simulation);
+
+ simulation.receive_packet(ClientboundRegistryData {
+ registry_id: ResourceLocation::new("minecraft:dimension_type"),
+ entries: vec![(
+ ResourceLocation::new("minecraft:overworld"),
+ Some(NbtCompound::from_values(vec![
+ ("height".into(), NbtTag::Int(384)),
+ ("min_y".into(), NbtTag::Int(-64)),
+ ])),
+ )]
+ .into_iter()
+ .collect(),
+ });
+ simulation.tick();
+ simulation.receive_packet(ClientboundFinishConfiguration);
+ simulation.tick();
+
+ simulation.receive_packet(make_basic_login_packet(
+ DimensionType::new_raw(0), // overworld
+ ResourceLocation::new("minecraft:overworld"),
+ ));
+ simulation.tick();
+
+ sent_packets.expect_tick_end();
+ sent_packets.expect_empty();
+
+ simulation.receive_packet(make_basic_empty_chunk(ChunkPos::new(0, 0), (384 + 64) / 16));
+ simulation.receive_packet(ClientboundBlockUpdate {
+ pos: BlockPos::new(0, 119, 0),
+ block_state: Block::Stone.into(),
+ });
+ simulation.receive_packet(ClientboundBlockUpdate {
+ pos: BlockPos::new(0, 119, 1),
+ block_state: Block::Stone.into(),
+ });
+ simulation.receive_packet(ClientboundPlayerPosition {
+ id: 1,
+ change: PositionMoveRotation {
+ pos: Vec3::new(0.5, 120., 0.5),
+ delta: Vec3::ZERO,
+ look_direction: LookDirection::default(),
+ },
+ relative: RelativeMovements::all_absolute(),
+ });
+ simulation.tick();
+ simulation.tick();
+ simulation.tick();
+ sent_packets.clear();
+
+ // start sprinting
+ simulation.send_event(StartSprintEvent {
+ entity: simulation.entity,
+ direction: SprintDirection::Forward,
+ });
+ simulation.tick();
+ sent_packets.expect("PlayerInput", |p| {
+ matches!(
+ p,
+ ServerboundGamePacket::PlayerInput(p)
+ if *p == ServerboundPlayerInput { forward: true, sprint: true, ..Default::default() }
+ )
+ });
+ sent_packets.expect("PlayerCommand", |p| {
+ matches!(p, ServerboundGamePacket::PlayerCommand(_))
+ });
+ sent_packets.expect("MovePlayerPos { z: 0.6274000124096872 }", |p| {
+ matches!(
+ p,
+ ServerboundGamePacket::MovePlayerPos(p)
+ if p.pos == Vec3::new(0.5, 120., 0.6274000124096872)
+ )
+ });
+ sent_packets.expect_tick_end();
+ sent_packets.expect_empty();
+
+ simulation.tick();
+ sent_packets.expect("MovePlayerPos { z: 0.8243604396746886 }", |p| {
+ matches!(
+ p,
+ ServerboundGamePacket::MovePlayerPos(p)
+ if p.pos == Vec3::new(0.5, 120., 0.8243604396746886)
+ )
+ });
+ sent_packets.expect_tick_end();
+ sent_packets.expect_empty();
+ simulation.with_component_mut::<PhysicsState>(|p| p.trying_to_crouch = true);
+
+ simulation.tick();
+ sent_packets.expect("PlayerInput", |p| {
+ matches!(
+ p,
+ ServerboundGamePacket::PlayerInput(p)
+ if *p == ServerboundPlayerInput { forward: true, sprint: true, shift: true, ..Default::default() }
+ )
+ });
+ sent_packets.expect("MovePlayerPos { z: 1.0593008578621674 }", |p| {
+ matches!(
+ p,
+ ServerboundGamePacket::MovePlayerPos(p)
+ if p.pos == Vec3::new(0.5, 120., 1.0593008578621674)
+ )
+ });
+ sent_packets.expect_tick_end();
+ sent_packets.expect_empty();
+
+ simulation.tick();
+ sent_packets.expect("MovePlayerPos { z: 1.2257983479146455 }", |p| {
+ matches!(
+ p,
+ ServerboundGamePacket::MovePlayerPos(p)
+ if p.pos == Vec3::new(0.5, 120., 1.2257983479146455)
+ )
+ });
+ sent_packets.expect_tick_end();
+ sent_packets.expect_empty();
+
+ simulation.tick();
+ sent_packets.expect("MovePlayerPos: { z: 1.3549259948648078 }", |p| {
+ matches!(
+ p,
+ ServerboundGamePacket::MovePlayerPos(p)
+ if p.pos == Vec3::new(0.5, 120., 1.3549259948648078)
+ )
+ });
+ sent_packets.expect_tick_end();
+ sent_packets.expect_empty();
+}
diff --git a/azalea-core/src/cursor3d.rs b/azalea-core/src/cursor3d.rs
index dc96d890..91a14000 100644
--- a/azalea-core/src/cursor3d.rs
+++ b/azalea-core/src/cursor3d.rs
@@ -71,13 +71,13 @@ impl Cursor3d {
pub fn new(origin: BlockPos, end: BlockPos) -> Self {
let width = (end.x - origin.x + 1)
.try_into()
- .expect("Impossible width.");
+ .unwrap_or_else(|_| panic!("Impossible width, origin: {origin:?}, end: {end:?}"));
let height = (end.y - origin.y + 1)
.try_into()
- .expect("Impossible height.");
+ .unwrap_or_else(|_| panic!("Impossible height, origin: {origin:?}, end: {end:?}"));
let depth = (end.z - origin.z + 1)
.try_into()
- .expect("Impossible depth.");
+ .unwrap_or_else(|_| panic!("Impossible depth, origin: {origin:?}, end: {end:?}"));
Self {
index: 0,
diff --git a/azalea-core/src/math.rs b/azalea-core/src/math.rs
index 105069ef..e62a3d23 100644
--- a/azalea-core/src/math.rs
+++ b/azalea-core/src/math.rs
@@ -92,6 +92,10 @@ pub fn sign_as_int(num: f64) -> i32 {
if num == 0. { 0 } else { num.signum() as i32 }
}
+pub fn equal(a: f64, b: f64) -> bool {
+ (b - a).abs() < 1.0e-5
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/azalea-entity/src/attributes.rs b/azalea-entity/src/attributes.rs
index c2a22e9b..021fcd56 100644
--- a/azalea-entity/src/attributes.rs
+++ b/azalea-entity/src/attributes.rs
@@ -9,23 +9,26 @@ use thiserror::Error;
#[derive(Clone, Debug, Component)]
pub struct Attributes {
- pub speed: AttributeInstance,
+ pub movement_speed: AttributeInstance,
pub sneaking_speed: AttributeInstance,
pub attack_speed: AttributeInstance,
pub water_movement_efficiency: AttributeInstance,
pub block_interaction_range: AttributeInstance,
pub entity_interaction_range: AttributeInstance,
+
+ pub step_height: AttributeInstance,
}
#[derive(Clone, Debug)]
pub struct AttributeInstance {
pub base: f64,
modifiers_by_id: HashMap<ResourceLocation, AttributeModifier>,
+ // TODO: add cache
}
#[derive(Clone, Debug, Error)]
-#[error("A modifier with this UUID is already present.")]
+#[error("A modifier with this ID is already present.")]
pub struct AlreadyPresentError;
impl AttributeInstance {
@@ -40,13 +43,12 @@ impl AttributeInstance {
let mut total = self.base;
for modifier in self.modifiers_by_id.values() {
match modifier.operation {
- AttributeModifierOperation::Addition => total += modifier.amount,
- AttributeModifierOperation::MultiplyBase => total += self.base * modifier.amount,
- _ => {}
- }
- if let AttributeModifierOperation::MultiplyTotal = modifier.operation {
- total *= 1.0 + modifier.amount;
- }
+ AttributeModifierOperation::AddValue => total += modifier.amount,
+ AttributeModifierOperation::AddMultipliedBase => {
+ total += modifier.amount * self.base
+ }
+ AttributeModifierOperation::AddMultipliedTotal => total *= 1. + modifier.amount,
+ };
}
total
}
@@ -85,30 +87,30 @@ pub struct AttributeModifier {
#[derive(Clone, Debug, Copy, AzBuf)]
pub enum AttributeModifierOperation {
- Addition,
- MultiplyBase,
- MultiplyTotal,
+ AddValue,
+ AddMultipliedBase,
+ AddMultipliedTotal,
}
pub fn sprinting_modifier() -> AttributeModifier {
AttributeModifier {
id: ResourceLocation::new("sprinting"),
amount: 0.3f32 as f64,
- operation: AttributeModifierOperation::MultiplyTotal,
+ operation: AttributeModifierOperation::AddMultipliedTotal,
}
}
pub fn base_attack_speed_modifier(amount: f64) -> AttributeModifier {
AttributeModifier {
id: ResourceLocation::new("base_attack_speed"),
amount,
- operation: AttributeModifierOperation::Addition,
+ operation: AttributeModifierOperation::AddValue,
}
}
pub fn creative_block_interaction_range_modifier() -> AttributeModifier {
AttributeModifier {
id: ResourceLocation::new("creative_mode_block_range"),
amount: 0.5,
- operation: AttributeModifierOperation::Addition,
+ operation: AttributeModifierOperation::AddValue,
}
}
@@ -116,6 +118,6 @@ pub fn creative_entity_interaction_range_modifier() -> AttributeModifier {
AttributeModifier {
id: ResourceLocation::new("creative_mode_entity_range"),
amount: 2.0,
- operation: AttributeModifierOperation::Addition,
+ operation: AttributeModifierOperation::AddValue,
}
}
diff --git a/azalea-entity/src/data.rs b/azalea-entity/src/data.rs
index 436c6571..35e8b4c5 100644
--- a/azalea-entity/src/data.rs
+++ b/azalea-entity/src/data.rs
@@ -152,9 +152,19 @@ pub enum Pose {
Sleeping,
Swimming,
SpinAttack,
- Sneaking,
+ Crouching,
LongJumping,
Dying,
+ Croaking,
+ UsingTongue,
+ Sitting,
+ Roaring,
+ Sniffing,
+ Emerging,
+ Digging,
+ Sliding,
+ Shooting,
+ Inhaling,
}
#[derive(Debug, Clone, AzBuf)]
diff --git a/azalea-entity/src/dimensions.rs b/azalea-entity/src/dimensions.rs
index 68e9903d..92c03e61 100644
--- a/azalea-entity/src/dimensions.rs
+++ b/azalea-entity/src/dimensions.rs
@@ -1,15 +1,43 @@
use azalea_core::{aabb::AABB, position::Vec3};
use azalea_registry::EntityKind;
+use bevy_ecs::component::Component;
-#[derive(Debug, Default, Clone)]
+use crate::Pose;
+
+/// A component that contains the size of an entity and their eye height.
+#[derive(Component, Debug, Default, Clone)]
pub struct EntityDimensions {
pub width: f32,
pub height: f32,
+ /// The offset of the entity's eyes from their coordinates.
+ ///
+ /// This is used to calculate the camera position for players, when
+ /// spectating an entity, and when raycasting from the entity.
+ ///
+ /// The default eye height for a player is 1.62 blocks.
+ pub eye_height: f32,
+ /// Whether the entity isn't allowed to be scaled.
+ pub fixed: bool,
}
impl EntityDimensions {
- pub fn new(width: f32, height: f32) -> Self {
- Self { width, height }
+ pub const fn new(width: f32, height: f32) -> Self {
+ Self {
+ width,
+ height,
+ eye_height: default_eye_height(height),
+ fixed: false,
+ }
+ }
+ pub const fn fixed(self) -> Self {
+ Self {
+ fixed: true,
+ ..self
+ }
+ }
+
+ pub const fn eye_height(self, eye_height: f32) -> Self {
+ Self { eye_height, ..self }
}
pub fn make_bounding_box(&self, pos: Vec3) -> AABB {
@@ -22,55 +50,59 @@ impl EntityDimensions {
}
}
+const fn default_eye_height(height: f32) -> f32 {
+ height * 0.85
+}
+
impl From<EntityKind> for EntityDimensions {
fn from(entity: EntityKind) -> Self {
// this match statement is automatically generated by codegen/genentities.py,
// don't edit it manually!
match entity {
- EntityKind::AcaciaBoat => EntityDimensions::new(1.375, 0.5625),
- EntityKind::AcaciaChestBoat => EntityDimensions::new(1.375, 0.5625),
- EntityKind::Allay => EntityDimensions::new(0.35, 0.6),
+ EntityKind::AcaciaBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::AcaciaChestBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::Allay => EntityDimensions::new(0.35, 0.6).eye_height(0.36),
EntityKind::AreaEffectCloud => EntityDimensions::new(6.0, 0.5),
- EntityKind::Armadillo => EntityDimensions::new(0.7, 0.65),
- EntityKind::ArmorStand => EntityDimensions::new(0.5, 1.975),
- EntityKind::Arrow => EntityDimensions::new(0.5, 0.5),
- EntityKind::Axolotl => EntityDimensions::new(0.75, 0.42),
- EntityKind::BambooChestRaft => EntityDimensions::new(1.375, 0.5625),
- EntityKind::BambooRaft => EntityDimensions::new(1.375, 0.5625),
- EntityKind::Bat => EntityDimensions::new(0.5, 0.9),
- EntityKind::Bee => EntityDimensions::new(0.7, 0.6),
- EntityKind::BirchBoat => EntityDimensions::new(1.375, 0.5625),
- EntityKind::BirchChestBoat => EntityDimensions::new(1.375, 0.5625),
+ EntityKind::Armadillo => EntityDimensions::new(0.7, 0.65).eye_height(0.26),
+ EntityKind::ArmorStand => EntityDimensions::new(0.5, 1.975).eye_height(1.7775),
+ EntityKind::Arrow => EntityDimensions::new(0.5, 0.5).eye_height(0.13),
+ EntityKind::Axolotl => EntityDimensions::new(0.75, 0.42).eye_height(0.2751),
+ EntityKind::BambooChestRaft => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::BambooRaft => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::Bat => EntityDimensions::new(0.5, 0.9).eye_height(0.45),
+ EntityKind::Bee => EntityDimensions::new(0.7, 0.6).eye_height(0.3),
+ EntityKind::BirchBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::BirchChestBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
EntityKind::Blaze => EntityDimensions::new(0.6, 1.8),
EntityKind::BlockDisplay => EntityDimensions::new(0.0, 0.0),
- EntityKind::Bogged => EntityDimensions::new(0.6, 1.99),
- EntityKind::Breeze => EntityDimensions::new(0.6, 1.77),
- EntityKind::BreezeWindCharge => EntityDimensions::new(0.3125, 0.3125),
- EntityKind::Camel => EntityDimensions::new(1.7, 2.375),
- EntityKind::Cat => EntityDimensions::new(0.6, 0.7),
- EntityKind::CaveSpider => EntityDimensions::new(0.7, 0.5),
- EntityKind::CherryBoat => EntityDimensions::new(1.375, 0.5625),
- EntityKind::CherryChestBoat => EntityDimensions::new(1.375, 0.5625),
+ EntityKind::Bogged => EntityDimensions::new(0.6, 1.99).eye_height(1.74),
+ EntityKind::Breeze => EntityDimensions::new(0.6, 1.77).eye_height(1.3452),
+ EntityKind::BreezeWindCharge => EntityDimensions::new(0.3125, 0.3125).eye_height(0.0),
+ EntityKind::Camel => EntityDimensions::new(1.7, 2.375).eye_height(2.275),
+ EntityKind::Cat => EntityDimensions::new(0.6, 0.7).eye_height(0.35),
+ EntityKind::CaveSpider => EntityDimensions::new(0.7, 0.5).eye_height(0.45),
+ EntityKind::CherryBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::CherryChestBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
EntityKind::ChestMinecart => EntityDimensions::new(0.98, 0.7),
- EntityKind::Chicken => EntityDimensions::new(0.4, 0.7),
- EntityKind::Cod => EntityDimensions::new(0.5, 0.3),
+ EntityKind::Chicken => EntityDimensions::new(0.4, 0.7).eye_height(0.644),
+ EntityKind::Cod => EntityDimensions::new(0.5, 0.3).eye_height(0.195),
EntityKind::CommandBlockMinecart => EntityDimensions::new(0.98, 0.7),
- EntityKind::Cow => EntityDimensions::new(0.9, 1.4),
- EntityKind::Creaking => EntityDimensions::new(0.9, 2.7),
+ EntityKind::Cow => EntityDimensions::new(0.9, 1.4).eye_height(1.3),
+ EntityKind::Creaking => EntityDimensions::new(0.9, 2.7).eye_height(2.3),
EntityKind::Creeper => EntityDimensions::new(0.6, 1.7),
- EntityKind::DarkOakBoat => EntityDimensions::new(1.375, 0.5625),
- EntityKind::DarkOakChestBoat => EntityDimensions::new(1.375, 0.5625),
- EntityKind::Dolphin => EntityDimensions::new(0.9, 0.6),
- EntityKind::Donkey => EntityDimensions::new(1.39648, 1.5),
+ EntityKind::DarkOakBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::DarkOakChestBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::Dolphin => EntityDimensions::new(0.9, 0.6).eye_height(0.3),
+ EntityKind::Donkey => EntityDimensions::new(1.39648, 1.5).eye_height(1.425),
EntityKind::DragonFireball => EntityDimensions::new(1.0, 1.0),
- EntityKind::Drowned => EntityDimensions::new(0.6, 1.95),
+ EntityKind::Drowned => EntityDimensions::new(0.6, 1.95).eye_height(1.74),
EntityKind::Egg => EntityDimensions::new(0.25, 0.25),
- EntityKind::ElderGuardian => EntityDimensions::new(1.9975, 1.9975),
+ EntityKind::ElderGuardian => EntityDimensions::new(1.9975, 1.9975).eye_height(0.99875),
EntityKind::EndCrystal => EntityDimensions::new(2.0, 2.0),
EntityKind::EnderDragon => EntityDimensions::new(16.0, 8.0),
EntityKind::EnderPearl => EntityDimensions::new(0.25, 0.25),
- EntityKind::Enderman => EntityDimensions::new(0.6, 2.9),
- EntityKind::Endermite => EntityDimensions::new(0.4, 0.3),
+ EntityKind::Enderman => EntityDimensions::new(0.6, 2.9).eye_height(2.55),
+ EntityKind::Endermite => EntityDimensions::new(0.4, 0.3).eye_height(0.13),
EntityKind::Evoker => EntityDimensions::new(0.6, 1.95),
EntityKind::EvokerFangs => EntityDimensions::new(0.5, 0.8),
EntityKind::ExperienceBottle => EntityDimensions::new(0.25, 0.25),
@@ -80,104 +112,120 @@ impl From<EntityKind> for EntityDimensions {
EntityKind::Fireball => EntityDimensions::new(1.0, 1.0),
EntityKind::FireworkRocket => EntityDimensions::new(0.25, 0.25),
EntityKind::FishingBobber => EntityDimensions::new(0.25, 0.25),
- EntityKind::Fox => EntityDimensions::new(0.6, 0.7),
+ EntityKind::Fox => EntityDimensions::new(0.6, 0.7).eye_height(0.4),
EntityKind::Frog => EntityDimensions::new(0.5, 0.5),
EntityKind::FurnaceMinecart => EntityDimensions::new(0.98, 0.7),
- EntityKind::Ghast => EntityDimensions::new(4.0, 4.0),
- EntityKind::Giant => EntityDimensions::new(3.6, 12.0),
- EntityKind::GlowItemFrame => EntityDimensions::new(0.5, 0.5),
- EntityKind::GlowSquid => EntityDimensions::new(0.8, 0.8),
+ EntityKind::Ghast => EntityDimensions::new(4.0, 4.0).eye_height(2.6),
+ EntityKind::Giant => EntityDimensions::new(3.6, 12.0).eye_height(10.44),
+ EntityKind::GlowItemFrame => EntityDimensions::new(0.5, 0.5).eye_height(0.0),
+ EntityKind::GlowSquid => EntityDimensions::new(0.8, 0.8).eye_height(0.4),
EntityKind::Goat => EntityDimensions::new(0.9, 1.3),
- EntityKind::Guardian => EntityDimensions::new(0.85, 0.85),
- EntityKind::HappyGhast => EntityDimensions::new(4.0, 4.0),
+ EntityKind::Guardian => EntityDimensions::new(0.85, 0.85).eye_height(0.425),
+ EntityKind::HappyGhast => EntityDimensions::new(4.0, 4.0).eye_height(2.6),
EntityKind::Hoglin => EntityDimensions::new(1.39648, 1.4),
EntityKind::HopperMinecart => EntityDimensions::new(0.98, 0.7),
- EntityKind::Horse => EntityDimensions::new(1.39648, 1.6),
- EntityKind::Husk => EntityDimensions::new(0.6, 1.95),
+ EntityKind::Horse => EntityDimensions::new(1.39648, 1.6).eye_height(1.52),
+ EntityKind::Husk => EntityDimensions::new(0.6, 1.95).eye_height(1.74),
EntityKind::Illusioner => EntityDimensions::new(0.6, 1.95),
EntityKind::Interaction => EntityDimensions::new(0.0, 0.0),
EntityKind::IronGolem => EntityDimensions::new(1.4, 2.7),
- EntityKind::Item => EntityDimensions::new(0.25, 0.25),
+ EntityKind::Item => EntityDimensions::new(0.25, 0.25).eye_height(0.2125),
EntityKind::ItemDisplay => EntityDimensions::new(0.0, 0.0),
- EntityKind::ItemFrame => EntityDimensions::new(0.5, 0.5),
- EntityKind::JungleBoat => EntityDimensions::new(1.375, 0.5625),
- EntityKind::JungleChestBoat => EntityDimensions::new(1.375, 0.5625),
- EntityKind::LeashKnot => EntityDimensions::new(0.375, 0.5),
+ EntityKind::ItemFrame => EntityDimensions::new(0.5, 0.5).eye_height(0.0),
+ EntityKind::JungleBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::JungleChestBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::LeashKnot => EntityDimensions::new(0.375, 0.5).eye_height(0.0625),
EntityKind::LightningBolt => EntityDimensions::new(0.0, 0.0),
EntityKind::LingeringPotion => EntityDimensions::new(0.25, 0.25),
- EntityKind::Llama => EntityDimensions::new(0.9, 1.87),
+ EntityKind::Llama => EntityDimensions::new(0.9, 1.87).eye_height(1.7765),
EntityKind::LlamaSpit => EntityDimensions::new(0.25, 0.25),
- EntityKind::MagmaCube => EntityDimensions::new(0.52, 0.52),
- EntityKind::MangroveBoat => EntityDimensions::new(1.375, 0.5625),
- EntityKind::MangroveChestBoat => EntityDimensions::new(1.375, 0.5625),
+ EntityKind::MagmaCube => EntityDimensions::new(0.52, 0.52).eye_height(0.325),
+ EntityKind::MangroveBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::MangroveChestBoat => {
+ EntityDimensions::new(1.375, 0.5625).eye_height(0.5625)
+ }
EntityKind::Marker => EntityDimensions::new(0.0, 0.0),
EntityKind::Minecart => EntityDimensions::new(0.98, 0.7),
- EntityKind::Mooshroom => EntityDimensions::new(0.9, 1.4),
- EntityKind::Mule => EntityDimensions::new(1.39648, 1.6),
- EntityKind::OakBoat => EntityDimensions::new(1.375, 0.5625),
- EntityKind::OakChestBoat => EntityDimensions::new(1.375, 0.5625),
+ EntityKind::Mooshroom => EntityDimensions::new(0.9, 1.4).eye_height(1.3),
+ EntityKind::Mule => EntityDimensions::new(1.39648, 1.6).eye_height(1.52),
+ EntityKind::OakBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::OakChestBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
EntityKind::Ocelot => EntityDimensions::new(0.6, 0.7),
EntityKind::OminousItemSpawner => EntityDimensions::new(0.25, 0.25),
EntityKind::Painting => EntityDimensions::new(0.5, 0.5),
- EntityKind::PaleOakBoat => EntityDimensions::new(1.375, 0.5625),
- EntityKind::PaleOakChestBoat => EntityDimensions::new(1.375, 0.5625),
+ EntityKind::PaleOakBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::PaleOakChestBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
EntityKind::Panda => EntityDimensions::new(1.3, 1.25),
- EntityKind::Parrot => EntityDimensions::new(0.5, 0.9),
- EntityKind::Phantom => EntityDimensions::new(0.9, 0.5),
+ EntityKind::Parrot => EntityDimensions::new(0.5, 0.9).eye_height(0.54),
+ EntityKind::Phantom => EntityDimensions::new(0.9, 0.5).eye_height(0.175),
EntityKind::Pig => EntityDimensions::new(0.9, 0.9),
- EntityKind::Piglin => EntityDimensions::new(0.6, 1.95),
- EntityKind::PiglinBrute => EntityDimensions::new(0.6, 1.95),
+ EntityKind::Piglin => EntityDimensions::new(0.6, 1.95).eye_height(1.79),
+ EntityKind::PiglinBrute => EntityDimensions::new(0.6, 1.95).eye_height(1.79),
EntityKind::Pillager => EntityDimensions::new(0.6, 1.95),
- EntityKind::Player => EntityDimensions::new(0.6, 1.8),
+ EntityKind::Player => EntityDimensions::new(0.6, 1.8).eye_height(1.62),
EntityKind::PolarBear => EntityDimensions::new(1.4, 1.4),
- EntityKind::Pufferfish => EntityDimensions::new(0.7, 0.7),
+ EntityKind::Pufferfish => EntityDimensions::new(0.7, 0.7).eye_height(0.455),
EntityKind::Rabbit => EntityDimensions::new(0.4, 0.5),
EntityKind::Ravager => EntityDimensions::new(1.95, 2.2),
- EntityKind::Salmon => EntityDimensions::new(0.7, 0.4),
- EntityKind::Sheep => EntityDimensions::new(0.9, 1.3),
- EntityKind::Shulker => EntityDimensions::new(1.0, 1.0),
+ EntityKind::Salmon => EntityDimensions::new(0.7, 0.4).eye_height(0.26),
+ EntityKind::Sheep => EntityDimensions::new(0.9, 1.3).eye_height(1.235),
+ EntityKind::Shulker => EntityDimensions::new(1.0, 1.0).eye_height(0.5),
EntityKind::ShulkerBullet => EntityDimensions::new(0.3125, 0.3125),
- EntityKind::Silverfish => EntityDimensions::new(0.4, 0.3),
- EntityKind::Skeleton => EntityDimensions::new(0.6, 1.99),
- EntityKind::SkeletonHorse => EntityDimensions::new(1.39648, 1.6),
- EntityKind::Slime => EntityDimensions::new(0.52, 0.52),
+ EntityKind::Silverfish => EntityDimensions::new(0.4, 0.3).eye_height(0.13),
+ EntityKind::Skeleton => EntityDimensions::new(0.6, 1.99).eye_height(1.74),
+ EntityKind::SkeletonHorse => EntityDimensions::new(1.39648, 1.6).eye_height(1.52),
+ EntityKind::Slime => EntityDimensions::new(0.52, 0.52).eye_height(0.325),
EntityKind::SmallFireball => EntityDimensions::new(0.3125, 0.3125),
- EntityKind::Sniffer => EntityDimensions::new(1.9, 1.75),
- EntityKind::SnowGolem => EntityDimensions::new(0.7, 1.9),
+ EntityKind::Sniffer => EntityDimensions::new(1.9, 1.75).eye_height(1.05),
+ EntityKind::SnowGolem => EntityDimensions::new(0.7, 1.9).eye_height(1.7),
EntityKind::Snowball => EntityDimensions::new(0.25, 0.25),
EntityKind::SpawnerMinecart => EntityDimensions::new(0.98, 0.7),
- EntityKind::SpectralArrow => EntityDimensions::new(0.5, 0.5),
- EntityKind::Spider => EntityDimensions::new(1.4, 0.9),
+ EntityKind::SpectralArrow => EntityDimensions::new(0.5, 0.5).eye_height(0.13),
+ EntityKind::Spider => EntityDimensions::new(1.4, 0.9).eye_height(0.65),
EntityKind::SplashPotion => EntityDimensions::new(0.25, 0.25),
- EntityKind::SpruceBoat => EntityDimensions::new(1.375, 0.5625),
- EntityKind::SpruceChestBoat => EntityDimensions::new(1.375, 0.5625),
- EntityKind::Squid => EntityDimensions::new(0.8, 0.8),
- EntityKind::Stray => EntityDimensions::new(0.6, 1.99),
+ EntityKind::SpruceBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::SpruceChestBoat => EntityDimensions::new(1.375, 0.5625).eye_height(0.5625),
+ EntityKind::Squid => EntityDimensions::new(0.8, 0.8).eye_height(0.4),
+ EntityKind::Stray => EntityDimensions::new(0.6, 1.99).eye_height(1.74),
EntityKind::Strider => EntityDimensions::new(0.9, 1.7),
- EntityKind::Tadpole => EntityDimensions::new(0.4, 0.3),
+ EntityKind::Tadpole => EntityDimensions::new(0.4, 0.3).eye_height(0.195),
EntityKind::TextDisplay => EntityDimensions::new(0.0, 0.0),
- EntityKind::Tnt => EntityDimensions::new(0.98, 0.98),
+ EntityKind::Tnt => EntityDimensions::new(0.98, 0.98).eye_height(0.15),
EntityKind::TntMinecart => EntityDimensions::new(0.98, 0.7),
- EntityKind::TraderLlama => EntityDimensions::new(0.9, 1.87),
- EntityKind::Trident => EntityDimensions::new(0.5, 0.5),
- EntityKind::TropicalFish => EntityDimensions::new(0.5, 0.4),
+ EntityKind::TraderLlama => EntityDimensions::new(0.9, 1.87).eye_height(1.7765),
+ EntityKind::Trident => EntityDimensions::new(0.5, 0.5).eye_height(0.13),
+ EntityKind::TropicalFish => EntityDimensions::new(0.5, 0.4).eye_height(0.26),
EntityKind::Turtle => EntityDimensions::new(1.2, 0.4),
- EntityKind::Vex => EntityDimensions::new(0.4, 0.8),
- EntityKind::Villager => EntityDimensions::new(0.6, 1.95),
+ EntityKind::Vex => EntityDimensions::new(0.4, 0.8).eye_height(0.51875),
+ EntityKind::Villager => EntityDimensions::new(0.6, 1.95).eye_height(1.62),
EntityKind::Vindicator => EntityDimensions::new(0.6, 1.95),
- EntityKind::WanderingTrader => EntityDimensions::new(0.6, 1.95),
+ EntityKind::WanderingTrader => EntityDimensions::new(0.6, 1.95).eye_height(1.62),
EntityKind::Warden => EntityDimensions::new(0.9, 2.9),
- EntityKind::WindCharge => EntityDimensions::new(0.3125, 0.3125),
- EntityKind::Witch => EntityDimensions::new(0.6, 1.95),
+ EntityKind::WindCharge => EntityDimensions::new(0.3125, 0.3125).eye_height(0.0),
+ EntityKind::Witch => EntityDimensions::new(0.6, 1.95).eye_height(1.62),
EntityKind::Wither => EntityDimensions::new(0.9, 3.5),
- EntityKind::WitherSkeleton => EntityDimensions::new(0.7, 2.4),
+ EntityKind::WitherSkeleton => EntityDimensions::new(0.7, 2.4).eye_height(2.1),
EntityKind::WitherSkull => EntityDimensions::new(0.3125, 0.3125),
- EntityKind::Wolf => EntityDimensions::new(0.6, 0.85),
+ EntityKind::Wolf => EntityDimensions::new(0.6, 0.85).eye_height(0.68),
EntityKind::Zoglin => EntityDimensions::new(1.39648, 1.4),
- EntityKind::Zombie => EntityDimensions::new(0.6, 1.95),
- EntityKind::ZombieHorse => EntityDimensions::new(1.39648, 1.6),
- EntityKind::ZombieVillager => EntityDimensions::new(0.6, 1.95),
- EntityKind::ZombifiedPiglin => EntityDimensions::new(0.6, 1.95),
+ EntityKind::Zombie => EntityDimensions::new(0.6, 1.95).eye_height(1.74),
+ EntityKind::ZombieHorse => EntityDimensions::new(1.39648, 1.6).eye_height(1.52),
+ EntityKind::ZombieVillager => EntityDimensions::new(0.6, 1.95).eye_height(1.74),
+ EntityKind::ZombifiedPiglin => EntityDimensions::new(0.6, 1.95).eye_height(1.79),
}
}
}
+
+/// Calculate the dimensions that an entity with the given kind and pose would
+/// have.i
+pub fn calculate_dimensions(kind: EntityKind, pose: Pose) -> EntityDimensions {
+ match (kind, pose) {
+ (_, Pose::Sleeping) => EntityDimensions::new(0.2, 0.2).fixed().eye_height(0.2),
+ (EntityKind::Player, Pose::FallFlying) => EntityDimensions::new(0.6, 0.6).eye_height(0.4),
+ (EntityKind::Player, Pose::Swimming) => EntityDimensions::new(0.6, 0.6).eye_height(0.4),
+ (EntityKind::Player, Pose::SpinAttack) => EntityDimensions::new(0.6, 0.6).eye_height(0.4),
+ (EntityKind::Player, Pose::Crouching) => EntityDimensions::new(0.6, 1.5).eye_height(1.27),
+ (EntityKind::Player, Pose::Dying) => EntityDimensions::new(0.2, 1.2).eye_height(1.62),
+ _ => EntityDimensions::from(kind),
+ }
+}
diff --git a/azalea-entity/src/lib.rs b/azalea-entity/src/lib.rs
index 645a5534..30e00ccb 100644
--- a/azalea-entity/src/lib.rs
+++ b/azalea-entity/src/lib.rs
@@ -2,7 +2,7 @@
pub mod attributes;
mod data;
-mod dimensions;
+pub mod dimensions;
mod effects;
mod enchantments;
pub mod metadata;
@@ -31,12 +31,12 @@ use azalea_world::{ChunkStorage, InstanceName};
use bevy_ecs::{bundle::Bundle, component::Component};
pub use data::*;
use derive_more::{Deref, DerefMut};
-pub use dimensions::EntityDimensions;
use plugin::indexing::EntityChunkPos;
use uuid::Uuid;
use vec_delta_codec::VecDeltaCodec;
use self::attributes::AttributeInstance;
+use crate::dimensions::EntityDimensions;
pub use crate::plugin::*;
pub fn move_relative(
@@ -353,8 +353,6 @@ pub struct Physics {
/// and sets to 0 if we're not trying to jump.
pub no_jump_delay: u32,
- /// The width and height of the entity.
- pub dimensions: EntityDimensions,
/// The bounding box of the entity. This is more than just width and height,
/// unlike dimensions.
pub bounding_box: AABB,
@@ -362,21 +360,21 @@ pub struct Physics {
pub has_impulse: bool,
pub horizontal_collision: bool,
- // pub minor_horizontal_collision: bool,
+ // TODO: implement minor_horizontal_collision
+ pub minor_horizontal_collision: bool,
pub vertical_collision: bool,
pub water_fluid_height: f64,
pub lava_fluid_height: f64,
pub was_touching_water: bool,
- // TODO: implement fall_distance
- pub fall_distance: f32,
+ pub fall_distance: f64,
// TODO: implement remaining_fire_ticks
pub remaining_fire_ticks: i32,
}
impl Physics {
- pub fn new(dimensions: EntityDimensions, pos: Vec3) -> Self {
+ pub fn new(dimensions: &EntityDimensions, pos: Vec3) -> Self {
Self {
velocity: Vec3::ZERO,
vec_delta_codec: VecDeltaCodec::new(pos),
@@ -393,11 +391,11 @@ impl Physics {
no_jump_delay: 0,
bounding_box: dimensions.make_bounding_box(pos),
- dimensions,
has_impulse: false,
horizontal_collision: false,
+ minor_horizontal_collision: false,
vertical_collision: false,
water_fluid_height: 0.,
@@ -455,41 +453,6 @@ impl Physics {
#[derive(Component, Copy, Clone, Default)]
pub struct Dead;
-/// A component that contains the offset of the entity's eyes from the entity
-/// coordinates.
-///
-/// This is used to calculate the camera position for players, when spectating
-/// an entity, and when raycasting from the entity.
-///
-/// The default eye height for a player is 1.62 blocks.
-#[derive(Component, Clone, Copy, Debug, PartialEq, Deref, DerefMut)]
-pub struct EyeHeight(f32);
-impl EyeHeight {
- pub fn new(height: f32) -> Self {
- Self(height)
- }
-}
-impl From<EyeHeight> for f32 {
- fn from(value: EyeHeight) -> Self {
- value.0
- }
-}
-impl From<EyeHeight> for f64 {
- fn from(value: EyeHeight) -> Self {
- value.0 as f64
- }
-}
-impl From<&EyeHeight> for f32 {
- fn from(value: &EyeHeight) -> Self {
- value.0
- }
-}
-impl From<&EyeHeight> for f64 {
- fn from(value: &EyeHeight) -> Self {
- value.0 as f64
- }
-}
-
/// A component NewType for [`azalea_registry::EntityKind`].
///
/// Most of the time, you should be using `azalea_registry::EntityKind`
@@ -511,9 +474,10 @@ pub struct EntityBundle {
pub physics: Physics,
pub direction: LookDirection,
- pub eye_height: EyeHeight,
+ pub dimensions: EntityDimensions,
pub attributes: Attributes,
pub jumping: Jumping,
+ pub crouching: Crouching,
pub fluid_on_eyes: FluidOnEyes,
pub on_climbable: OnClimbable,
}
@@ -526,12 +490,6 @@ impl EntityBundle {
world_name: ResourceLocation,
) -> Self {
let dimensions = EntityDimensions::from(kind);
- let eye_height = match kind {
- // TODO: codegen hardcoded eye heights, search withEyeHeight with mojmap
- // also, eye height should change depending on pose (like sneaking, swimming, etc)
- azalea_registry::EntityKind::Player => 1.62,
- _ => dimensions.height * 0.85,
- };
Self {
kind: EntityKindComponent(kind),
@@ -540,13 +498,14 @@ impl EntityBundle {
position: Position(pos),
chunk_pos: EntityChunkPos(ChunkPos::from(&pos)),
last_sent_position: LastSentPosition(pos),
- physics: Physics::new(dimensions, pos),
- eye_height: EyeHeight(eye_height),
+ physics: Physics::new(&dimensions, pos),
+ dimensions,
direction: LookDirection::default(),
attributes: default_attributes(EntityKind::Player),
jumping: Jumping(false),
+ crouching: Crouching(false),
fluid_on_eyes: FluidOnEyes(FluidKind::Empty),
on_climbable: OnClimbable(false),
}
@@ -557,12 +516,13 @@ pub fn default_attributes(_entity_kind: EntityKind) -> Attributes {
// TODO: do the correct defaults for everything, some
// entities have different defaults
Attributes {
- speed: AttributeInstance::new(0.1),
+ movement_speed: AttributeInstance::new(0.1f32 as f64),
sneaking_speed: AttributeInstance::new(0.3),
attack_speed: AttributeInstance::new(4.0),
water_movement_efficiency: AttributeInstance::new(0.0),
block_interaction_range: AttributeInstance::new(4.5),
entity_interaction_range: AttributeInstance::new(3.0),
+ step_height: AttributeInstance::new(0.6),
}
}
@@ -586,3 +546,30 @@ impl FluidOnEyes {
#[derive(Component, Clone, Copy, Debug, PartialEq, Deref, DerefMut)]
pub struct OnClimbable(bool);
+
+/// A component that indicates whether the player is currently sneaking.
+///
+/// If the entity isn't a local player, then this is just a shortcut for
+/// checking if the [`Pose`] is `Crouching`.
+///
+/// If you need to modify this value, use
+/// `azalea_client::PhysicsState::trying_to_crouch` or `Client::set_crouching`
+/// instead.
+#[derive(Component, Clone, Copy, Deref, DerefMut, Default)]
+pub struct Crouching(bool);
+
+/// A component that contains the abilities the player has, like flying
+/// or instantly breaking blocks. This is only present on local players.
+#[derive(Clone, Debug, Component, Default)]
+pub struct PlayerAbilities {
+ pub invulnerable: bool,
+ pub flying: bool,
+ pub can_fly: bool,
+ /// Whether the player can instantly break blocks and can duplicate blocks
+ /// in their inventory.
+ pub instant_break: bool,
+
+ pub flying_speed: f32,
+ /// Used for the fov
+ pub walking_speed: f32,
+}
diff --git a/azalea-entity/src/metadata.rs b/azalea-entity/src/metadata.rs
index 422eabd8..6ccbad1a 100644
--- a/azalea-entity/src/metadata.rs
+++ b/azalea-entity/src/metadata.rs
@@ -35,7 +35,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
#[derive(Component, Deref, DerefMut, Clone, Copy)]
pub struct OnFire(pub bool);
#[derive(Component, Deref, DerefMut, Clone, Copy)]
-pub struct ShiftKeyDown(pub bool);
+pub struct AbstractEntityShiftKeyDown(pub bool);
#[derive(Component, Deref, DerefMut, Clone, Copy)]
pub struct Sprinting(pub bool);
#[derive(Component, Deref, DerefMut, Clone, Copy)]
@@ -101,7 +101,7 @@ impl Default for AcaciaBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -158,7 +158,7 @@ impl Default for AcaciaChestBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -251,7 +251,7 @@ impl Default for AllayMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -328,7 +328,7 @@ impl Default for AreaEffectCloudMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -394,7 +394,9 @@ impl Default for ArmadilloMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -514,7 +516,7 @@ impl Default for ArmorStandMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -594,7 +596,7 @@ impl Default for ArrowMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -673,7 +675,9 @@ impl Default for AxolotlMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -742,7 +746,7 @@ impl Default for BambooChestRaftMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -799,7 +803,7 @@ impl Default for BambooRaftMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -863,7 +867,7 @@ impl Default for BatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -953,7 +957,9 @@ impl Default for BeeMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -1023,7 +1029,7 @@ impl Default for BirchBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -1080,7 +1086,7 @@ impl Default for BirchChestBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -1148,7 +1154,7 @@ impl Default for BlazeMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -1247,7 +1253,7 @@ impl Default for BlockDisplayMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -1342,7 +1348,7 @@ impl Default for BoggedMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -1411,7 +1417,7 @@ impl Default for BreezeMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -1471,7 +1477,7 @@ impl Default for BreezeWindChargeMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -1548,7 +1554,9 @@ impl Default for CamelMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -1659,7 +1667,9 @@ impl Default for CatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -1741,7 +1751,9 @@ impl Default for CaveSpiderMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -1807,7 +1819,7 @@ impl Default for CherryBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -1864,7 +1876,7 @@ impl Default for CherryChestBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -1925,7 +1937,7 @@ impl Default for ChestMinecartMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -1993,7 +2005,9 @@ impl Default for ChickenMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -2066,7 +2080,7 @@ impl Default for CodMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -2143,7 +2157,7 @@ impl Default for CommandBlockMinecartMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -2213,7 +2227,9 @@ impl Default for CowMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -2308,7 +2324,7 @@ impl Default for CreakingMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -2398,7 +2414,7 @@ impl Default for CreeperMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -2465,7 +2481,7 @@ impl Default for DarkOakBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -2522,7 +2538,7 @@ impl Default for DarkOakChestBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -2595,7 +2611,7 @@ impl Default for DolphinMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -2674,7 +2690,8 @@ impl Default for DonkeyMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down:
+ AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -2745,7 +2762,7 @@ impl Default for DragonFireballMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -2806,7 +2823,9 @@ impl Default for DrownedMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -2874,7 +2893,7 @@ impl Default for EggMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -2937,7 +2956,9 @@ impl Default for ElderGuardianMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3012,7 +3033,7 @@ impl Default for EndCrystalMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3069,7 +3090,7 @@ impl Default for EnderDragonMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3130,7 +3151,7 @@ impl Default for EnderPearlMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3205,7 +3226,7 @@ impl Default for EndermanMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3276,7 +3297,7 @@ impl Default for EndermiteMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3352,7 +3373,9 @@ impl Default for EvokerMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3416,7 +3439,7 @@ impl Default for EvokerFangsMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3463,7 +3486,7 @@ impl Default for ExperienceBottleMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3518,7 +3541,7 @@ impl Default for ExperienceOrbMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3570,7 +3593,7 @@ impl Default for EyeOfEnderMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3622,7 +3645,7 @@ impl Default for FallingBlockMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3674,7 +3697,7 @@ impl Default for FireballMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3738,7 +3761,7 @@ impl Default for FireworkRocketMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3798,7 +3821,7 @@ impl Default for FishingBobberMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3831,7 +3854,7 @@ pub struct Sleeping(pub bool);
#[derive(Component, Deref, DerefMut, Clone, Copy)]
pub struct Pouncing(pub bool);
#[derive(Component, Deref, DerefMut, Clone, Copy)]
-pub struct Crouching(pub bool);
+pub struct FoxCrouching(pub bool);
#[derive(Component, Deref, DerefMut, Clone, Copy)]
pub struct FoxInterested(pub bool);
#[derive(Component, Deref, DerefMut, Clone)]
@@ -3857,7 +3880,7 @@ impl Fox {
entity.insert(Defending(bitfield & 0x80 != 0));
entity.insert(Sleeping(bitfield & 0x20 != 0));
entity.insert(Pouncing(bitfield & 0x10 != 0));
- entity.insert(Crouching(bitfield & 0x4 != 0));
+ entity.insert(FoxCrouching(bitfield & 0x4 != 0));
entity.insert(FoxInterested(bitfield & 0x8 != 0));
}
19 => {
@@ -3882,7 +3905,7 @@ pub struct FoxMetadataBundle {
defending: Defending,
sleeping: Sleeping,
pouncing: Pouncing,
- crouching: Crouching,
+ fox_crouching: FoxCrouching,
fox_interested: FoxInterested,
trusted_id_0: TrustedId0,
trusted_id_1: TrustedId1,
@@ -3904,7 +3927,9 @@ impl Default for FoxMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -3941,7 +3966,7 @@ impl Default for FoxMetadataBundle {
defending: Defending(false),
sleeping: Sleeping(false),
pouncing: Pouncing(false),
- crouching: Crouching(false),
+ fox_crouching: FoxCrouching(false),
fox_interested: FoxInterested(false),
trusted_id_0: TrustedId0(None),
trusted_id_1: TrustedId1(None),
@@ -3998,7 +4023,9 @@ impl Default for FrogMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -4072,7 +4099,7 @@ impl Default for FurnaceMinecartMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -4135,7 +4162,7 @@ impl Default for GhastMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -4202,7 +4229,7 @@ impl Default for GiantMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -4270,7 +4297,7 @@ impl Default for GlowItemFrameMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -4335,7 +4362,9 @@ impl Default for GlowSquidMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -4426,7 +4455,9 @@ impl Default for GoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -4507,7 +4538,7 @@ impl Default for GuardianMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -4591,7 +4622,9 @@ impl Default for HappyGhastMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -4671,7 +4704,9 @@ impl Default for HoglinMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -4738,7 +4773,7 @@ impl Default for HopperMinecartMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -4808,7 +4843,9 @@ impl Default for HorseMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -4886,7 +4923,9 @@ impl Default for HuskMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -4962,7 +5001,9 @@ impl Default for IllusionerMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5044,7 +5085,7 @@ impl Default for InteractionMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5105,7 +5146,7 @@ impl Default for IronGolemMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5171,7 +5212,7 @@ impl Default for ItemMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5231,7 +5272,7 @@ impl Default for ItemDisplayMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5325,7 +5366,7 @@ impl Default for ItemFrameMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5377,7 +5418,7 @@ impl Default for JungleBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5434,7 +5475,7 @@ impl Default for JungleChestBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5487,7 +5528,7 @@ impl Default for LeashKnotMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5532,7 +5573,7 @@ impl Default for LightningBoltMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5579,7 +5620,7 @@ impl Default for LingeringPotionMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5654,7 +5695,8 @@ impl Default for LlamaMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down:
+ AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5727,7 +5769,7 @@ impl Default for LlamaSpitMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5780,7 +5822,7 @@ impl Default for MagmaCubeMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5844,7 +5886,7 @@ impl Default for MangroveBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5901,7 +5943,7 @@ impl Default for MangroveChestBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -5954,7 +5996,7 @@ impl Default for MarkerMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -6003,7 +6045,7 @@ impl Default for MinecartMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -6071,7 +6113,9 @@ impl Default for MooshroomMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -6148,7 +6192,8 @@ impl Default for MuleMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down:
+ AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -6223,7 +6268,7 @@ impl Default for OakBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -6280,7 +6325,7 @@ impl Default for OakChestBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -6349,7 +6394,9 @@ impl Default for OcelotMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -6418,7 +6465,7 @@ impl Default for OminousItemSpawnerMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -6476,7 +6523,7 @@ impl Default for PaintingMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -6527,7 +6574,7 @@ impl Default for PaleOakBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -6584,7 +6631,7 @@ impl Default for PaleOakChestBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -6696,7 +6743,9 @@ impl Default for PandaMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -6785,7 +6834,9 @@ impl Default for ParrotMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -6862,7 +6913,7 @@ impl Default for PhantomMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -6943,7 +6994,9 @@ impl Default for PigMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -7037,7 +7090,9 @@ impl Default for PiglinMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -7112,7 +7167,9 @@ impl Default for PiglinBruteMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -7190,7 +7247,9 @@ impl Default for PillagerMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -7291,7 +7350,7 @@ impl Default for PlayerMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -7367,7 +7426,9 @@ impl Default for PolarBearMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -7448,7 +7509,7 @@ impl Default for PufferfishMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -7525,7 +7586,9 @@ impl Default for RabbitMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -7598,7 +7661,9 @@ impl Default for RavagerMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -7674,7 +7739,7 @@ impl Default for SalmonMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -7753,7 +7818,9 @@ impl Default for SheepMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -7840,7 +7907,7 @@ impl Default for ShulkerMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -7902,7 +7969,7 @@ impl Default for ShulkerBulletMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -7955,7 +8022,7 @@ impl Default for SilverfishMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8029,7 +8096,7 @@ impl Default for SkeletonMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8102,7 +8169,9 @@ impl Default for SkeletonHorseMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8177,7 +8246,7 @@ impl Default for SlimeMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8242,7 +8311,7 @@ impl Default for SmallFireballMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8310,7 +8379,9 @@ impl Default for SnifferMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8387,7 +8458,7 @@ impl Default for SnowGolemMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8449,7 +8520,7 @@ impl Default for SnowballMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8502,7 +8573,7 @@ impl Default for SpawnerMinecartMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8556,7 +8627,7 @@ impl Default for SpectralArrowMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8619,7 +8690,7 @@ impl Default for SpiderMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8682,7 +8753,7 @@ impl Default for SplashPotionMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8735,7 +8806,7 @@ impl Default for SpruceBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8792,7 +8863,7 @@ impl Default for SpruceChestBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8853,7 +8924,7 @@ impl Default for SquidMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -8922,7 +8993,7 @@ impl Default for StrayMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -9004,7 +9075,9 @@ impl Default for StriderMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -9080,7 +9153,7 @@ impl Default for TadpoleMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -9172,7 +9245,7 @@ impl Default for TextDisplayMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -9269,7 +9342,7 @@ impl Default for TntMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -9320,7 +9393,7 @@ impl Default for TntMinecartMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -9388,7 +9461,8 @@ impl Default for TraderLlamaMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down:
+ AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -9478,7 +9552,7 @@ impl Default for TridentMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -9544,7 +9618,7 @@ impl Default for TropicalFishMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -9628,7 +9702,9 @@ impl Default for TurtleMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -9706,7 +9782,7 @@ impl Default for VexMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -9785,7 +9861,9 @@ impl Default for VillagerMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -9863,7 +9941,9 @@ impl Default for VindicatorMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -9935,7 +10015,9 @@ impl Default for WanderingTraderMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -10012,7 +10094,7 @@ impl Default for WardenMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -10073,7 +10155,7 @@ impl Default for WindChargeMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -10134,7 +10216,9 @@ impl Default for WitchMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -10229,7 +10313,7 @@ impl Default for WitherMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -10301,7 +10385,7 @@ impl Default for WitherSkeletonMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -10367,7 +10451,7 @@ impl Default for WitherSkullMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -10455,7 +10539,9 @@ impl Default for WolfMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -10540,7 +10626,7 @@ impl Default for ZoglinMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -10621,7 +10707,7 @@ impl Default for ZombieMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -10696,7 +10782,9 @@ impl Default for ZombieHorseMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -10785,7 +10873,9 @@ impl Default for ZombieVillagerMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -10865,7 +10955,9 @@ impl Default for ZombifiedPiglinMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -10939,7 +11031,7 @@ impl Default for AbstractAgeableMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -11007,7 +11099,7 @@ impl Default for AbstractAnimalMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -11083,7 +11175,7 @@ impl Default for AbstractArrowMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -11146,7 +11238,7 @@ impl Default for AbstractBoatMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -11214,7 +11306,9 @@ impl Default for AbstractChestedHorseMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -11286,7 +11380,7 @@ impl Default for AbstractCreatureMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -11406,7 +11500,7 @@ impl Default for AbstractDisplayMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -11469,7 +11563,7 @@ impl AbstractEntity {
0 => {
let bitfield = d.value.into_byte()?;
entity.insert(OnFire(bitfield & 0x1 != 0));
- entity.insert(ShiftKeyDown(bitfield & 0x2 != 0));
+ entity.insert(AbstractEntityShiftKeyDown(bitfield & 0x2 != 0));
entity.insert(Sprinting(bitfield & 0x8 != 0));
entity.insert(Swimming(bitfield & 0x10 != 0));
entity.insert(CurrentlyGlowing(bitfield & 0x40 != 0));
@@ -11507,7 +11601,7 @@ impl AbstractEntity {
pub struct AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire,
- shift_key_down: ShiftKeyDown,
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown,
sprinting: Sprinting,
swimming: Swimming,
currently_glowing: CurrentlyGlowing,
@@ -11526,7 +11620,7 @@ impl Default for AbstractEntityMetadataBundle {
Self {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -11580,7 +11674,7 @@ impl Default for AbstractFishMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -11661,7 +11755,9 @@ impl Default for AbstractHorseMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -11738,7 +11834,7 @@ impl Default for AbstractInsentientMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -11826,7 +11922,7 @@ impl Default for AbstractLivingMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -11889,7 +11985,7 @@ impl Default for AbstractMinecartMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -11946,7 +12042,7 @@ impl Default for AbstractMonsterMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -12017,7 +12113,7 @@ impl Default for AbstractPiglinMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -12090,7 +12186,7 @@ impl Default for AbstractRaiderMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -12165,7 +12261,9 @@ impl Default for AbstractSpellcasterIllagerMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -12249,7 +12347,9 @@ impl Default for AbstractTameableMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(
+ false,
+ ),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -12320,7 +12420,7 @@ impl Default for AbstractThrownItemProjectileMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -12380,7 +12480,7 @@ impl Default for AbstractVehicleMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
@@ -12440,7 +12540,7 @@ impl Default for AbstractVillagerMetadataBundle {
parent: AbstractEntityMetadataBundle {
_marker: AbstractEntity,
on_fire: OnFire(false),
- shift_key_down: ShiftKeyDown(false),
+ abstract_entity_shift_key_down: AbstractEntityShiftKeyDown(false),
sprinting: Sprinting(false),
swimming: Swimming(false),
currently_glowing: CurrentlyGlowing(false),
diff --git a/azalea-entity/src/plugin/mod.rs b/azalea-entity/src/plugin/mod.rs
index ee6bca61..95fcb93f 100644
--- a/azalea-entity/src/plugin/mod.rs
+++ b/azalea-entity/src/plugin/mod.rs
@@ -17,7 +17,9 @@ pub use relative_updates::RelativeEntityUpdate;
use tracing::debug;
use crate::{
- Dead, EyeHeight, FluidOnEyes, LocalEntity, LookDirection, OnClimbable, Physics, Position,
+ Crouching, Dead, EntityKindComponent, FluidOnEyes, LocalEntity, LookDirection, OnClimbable,
+ Physics, Pose, Position,
+ dimensions::{EntityDimensions, calculate_dimensions},
metadata::Health,
};
@@ -56,12 +58,12 @@ impl Plugin for EntityPlugin {
debug_new_entity,
add_dead,
clamp_look_direction,
- update_fluid_on_eyes,
update_on_climbable,
+ (update_dimensions, update_bounding_box, update_fluid_on_eyes).chain(),
+ update_crouching,
),
),
)
- .add_systems(Update, update_bounding_box)
.add_systems(GameTick, update_in_loaded_chunk)
.init_resource::<EntityUuidIndex>();
}
@@ -91,15 +93,20 @@ pub fn add_dead(mut commands: Commands, query: Query<(Entity, &Health), Changed<
}
pub fn update_fluid_on_eyes(
- mut query: Query<(&mut FluidOnEyes, &Position, &EyeHeight, &InstanceName)>,
+ mut query: Query<(
+ &mut FluidOnEyes,
+ &Position,
+ &EntityDimensions,
+ &InstanceName,
+ )>,
instance_container: Res<InstanceContainer>,
) {
- for (mut fluid_on_eyes, position, eye_height, instance_name) in query.iter_mut() {
+ for (mut fluid_on_eyes, position, dimensions, instance_name) in query.iter_mut() {
let Some(instance) = instance_container.get(instance_name) else {
continue;
};
- let adjusted_eye_y = position.y + (**eye_height as f64) - 0.1111111119389534;
+ let adjusted_eye_y = position.y + (dimensions.eye_height as f64) - 0.1111111119389534;
let eye_block_pos = BlockPos::from(Vec3::new(position.x, adjusted_eye_y, position.z));
let fluid_at_eye = instance
.read()
@@ -201,13 +208,41 @@ pub fn apply_clamp_look_direction(mut look_direction: LookDirection) -> LookDire
///
/// # Safety
/// Cached position in the world must be updated.
-pub fn update_bounding_box(mut query: Query<(&Position, &mut Physics), Changed<Position>>) {
- for (position, mut physics) in query.iter_mut() {
- let bounding_box = physics.dimensions.make_bounding_box(**position);
+#[allow(clippy::type_complexity)]
+pub fn update_bounding_box(
+ mut query: Query<
+ (&mut Physics, &Position, &EntityDimensions),
+ Or<(Changed<Position>, Changed<EntityDimensions>)>,
+ >,
+) {
+ for (mut physics, position, dimensions) in query.iter_mut() {
+ let bounding_box = dimensions.make_bounding_box(**position);
physics.bounding_box = bounding_box;
}
}
+#[allow(clippy::type_complexity)]
+pub fn update_dimensions(
+ mut query: Query<
+ (&mut EntityDimensions, &EntityKindComponent, &Pose),
+ Or<(Changed<EntityKindComponent>, Changed<Pose>)>,
+ >,
+) {
+ for (mut dimensions, kind, pose) in query.iter_mut() {
+ *dimensions = calculate_dimensions(**kind, *pose);
+ }
+}
+
+pub fn update_crouching(query: Query<(&mut Crouching, &Pose), Without<LocalEntity>>) {
+ for (mut crouching, pose) in query {
+ let new_crouching = *pose == Pose::Crouching;
+ // avoid triggering change detection
+ if **crouching != new_crouching {
+ **crouching = new_crouching;
+ }
+ }
+}
+
/// Marks an entity that's in a loaded chunk. This is updated at the beginning
/// of every tick.
///
diff --git a/azalea-physics/src/collision/mod.rs b/azalea-physics/src/collision/mod.rs
index dc439f7b..d8ac3a95 100644
--- a/azalea-physics/src/collision/mod.rs
+++ b/azalea-physics/src/collision/mod.rs
@@ -11,9 +11,13 @@ use azalea_block::{BlockState, fluid_state::FluidState};
use azalea_core::{
aabb::AABB,
direction::Axis,
- math::EPSILON,
+ math::{self, EPSILON},
position::{BlockPos, Vec3},
};
+use azalea_entity::{
+ Attributes, Jumping, LookDirection, OnClimbable, Physics, PlayerAbilities, Pose, Position,
+ metadata::Sprinting,
+};
use azalea_world::{ChunkStorage, Instance, MoveEntityError};
use bevy_ecs::{entity::Entity, world::Mut};
pub use blocks::BlockWithShape;
@@ -23,6 +27,7 @@ pub use shape::*;
use tracing::warn;
use self::world_collisions::get_block_collisions;
+use crate::{local_player::PhysicsState, travel::no_collision};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MoverType {
@@ -34,22 +39,16 @@ pub enum MoverType {
}
// Entity.collide
-fn collide(
- movement: Vec3,
- world: &Instance,
- physics: &azalea_entity::Physics,
- source_entity: Option<Entity>,
- physics_query: &PhysicsQuery,
- collidable_entity_query: &CollidableEntityQuery,
-) -> Vec3 {
- let entity_bounding_box = physics.bounding_box;
+fn collide(ctx: &MoveCtx, movement: Vec3) -> Vec3 {
+ let entity_bounding_box = ctx.physics.bounding_box;
let entity_collisions = get_entity_collisions(
- world,
+ ctx.world,
&entity_bounding_box.expand_towards(movement),
- source_entity,
- physics_query,
- collidable_entity_query,
+ Some(ctx.source_entity),
+ ctx.physics_query,
+ ctx.collidable_entity_query,
);
+ let world = ctx.world;
let collided_delta = if movement.length_squared() == 0.0 {
movement
} else {
@@ -60,7 +59,7 @@ fn collide(
let y_collision = movement.y != collided_delta.y;
let z_collision = movement.z != collided_delta.z;
- let on_ground = physics.on_ground() || y_collision && movement.y < 0.;
+ let on_ground = ctx.physics.on_ground() || y_collision && movement.y < 0.;
let max_up_step = 0.6;
if max_up_step > 0. && on_ground && (x_collision || z_collision) {
@@ -106,20 +105,30 @@ fn collide(
collided_delta
}
+pub struct MoveCtx<'world, 'state, 'a, 'b> {
+ pub mover_type: MoverType,
+ pub world: &'a Instance,
+ pub position: Mut<'a, Position>,
+ pub physics: &'a mut Physics,
+ pub source_entity: Entity,
+ pub physics_query: &'a PhysicsQuery<'world, 'state, 'b>,
+ pub collidable_entity_query: &'a CollidableEntityQuery<'world, 'state>,
+ pub physics_state: Option<&'a PhysicsState>,
+ pub attributes: &'a Attributes,
+ pub abilities: Option<&'a PlayerAbilities>,
+
+ pub direction: LookDirection,
+ pub sprinting: Sprinting,
+ pub on_climbable: OnClimbable,
+ pub pose: Option<Pose>,
+ pub jumping: Jumping,
+}
+
/// Move an entity by a given delta, checking for collisions.
///
/// In Mojmap, this is `Entity.move`.
#[allow(clippy::too_many_arguments)]
-pub fn move_colliding(
- _mover_type: MoverType,
- movement: Vec3,
- world: &Instance,
- position: &mut Mut<azalea_entity::Position>,
- physics: &mut azalea_entity::Physics,
- source_entity: Option<Entity>,
- physics_query: &PhysicsQuery,
- collidable_entity_query: &CollidableEntityQuery,
-) -> Result<(), MoveEntityError> {
+pub fn move_colliding(ctx: &mut MoveCtx, mut movement: Vec3) -> Result<(), MoveEntityError> {
// TODO: do all these
// if self.no_physics {
@@ -139,20 +148,16 @@ pub fn move_colliding(
// this.setDeltaMovement(Vec3.ZERO);
// }
- // movement = this.maybeBackOffFromEdge(movement, moverType);
+ movement = maybe_back_off_from_edge(ctx, movement);
+ let collide_result = collide(ctx, movement);
- let collide_result = collide(
- movement,
- world,
- physics,
- source_entity,
- physics_query,
- collidable_entity_query,
- );
+ let move_distance_sqr = collide_result.length_squared();
- let move_distance = collide_result.length_squared();
+ let position = &mut ctx.position;
+ let physics = &mut *ctx.physics;
+ let world = ctx.world;
- if move_distance > EPSILON {
+ if move_distance_sqr > EPSILON || movement.length_squared() - move_distance_sqr < EPSILON {
// TODO: fall damage
let new_pos = {
@@ -168,8 +173,8 @@ pub fn move_colliding(
}
}
- let x_collision = movement.x != collide_result.x;
- let z_collision = movement.z != collide_result.z;
+ let x_collision = !math::equal(movement.x, collide_result.x);
+ let z_collision = !math::equal(movement.z, collide_result.z);
let horizontal_collision = x_collision || z_collision;
physics.horizontal_collision = horizontal_collision;
@@ -180,14 +185,15 @@ pub fn move_colliding(
// TODO: minecraft checks for a "minor" horizontal collision here
- let _block_pos_below = azalea_entity::on_pos_legacy(&world.chunks, **position);
- // let _block_state_below = self
- // .world
- // .get_block_state(&block_pos_below)
- // .expect("Couldn't get block state below");
+ let block_pos_below = azalea_entity::on_pos_legacy(&world.chunks, **position);
+ let block_state_below = world.get_block_state(block_pos_below).unwrap_or_default();
- // self.check_fall_damage(collide_result.y, on_ground, block_state_below,
- // block_pos_below);
+ check_fall_damage(
+ physics,
+ collide_result.y,
+ block_state_below,
+ block_pos_below,
+ );
// if self.isRemoved() { return; }
@@ -238,6 +244,136 @@ pub fn move_colliding(
Ok(())
}
+fn check_fall_damage(
+ physics: &mut Physics,
+ delta_y: f64,
+ _block_state_below: BlockState,
+ _block_pos_below: BlockPos,
+) {
+ if !physics.is_in_water() && delta_y < 0. {
+ physics.fall_distance -= delta_y as f32 as f64;
+ }
+
+ if physics.on_ground() {
+ // vanilla calls block.fallOn here but it's not relevant for us
+
+ physics.fall_distance = 0.;
+ }
+}
+
+fn maybe_back_off_from_edge(move_ctx: &mut MoveCtx, mut movement: Vec3) -> Vec3 {
+ let is_staying_on_ground_surface = move_ctx.physics_state.is_some_and(|s| s.trying_to_crouch);
+ let max_up_step = get_max_up_step(move_ctx.attributes);
+
+ let fall_ctx = CanFallAtLeastCtx {
+ physics: move_ctx.physics,
+ world: move_ctx.world,
+ source_entity: move_ctx.source_entity,
+ physics_query: move_ctx.physics_query,
+ collidable_entity_query: move_ctx.collidable_entity_query,
+ };
+
+ let Some(abilities) = move_ctx.abilities else {
+ return movement;
+ };
+
+ let is_backing_off = !abilities.flying
+ && movement.y <= 0.
+ && matches!(move_ctx.mover_type, MoverType::Own | MoverType::Player)
+ && is_staying_on_ground_surface
+ && is_above_ground(&fall_ctx, max_up_step);
+ if !is_backing_off {
+ return movement;
+ }
+
+ let min_movement = 0.05;
+ let min_movement_x = movement.x.signum() * min_movement;
+ let min_movement_z = movement.z.signum() * min_movement;
+
+ while movement.x != 0. && can_fall_at_least(&fall_ctx, movement.x, 0., max_up_step as f64) {
+ if movement.x.abs() <= min_movement {
+ movement.x = 0.;
+ break;
+ }
+
+ movement.x -= min_movement_x
+ }
+ while movement.z != 0. && can_fall_at_least(&fall_ctx, 0., movement.z, max_up_step as f64) {
+ if movement.z.abs() <= min_movement {
+ movement.z = 0.;
+ break;
+ }
+
+ movement.z -= min_movement_z
+ }
+ while movement.x != 0.0
+ && movement.z != 0.0
+ && can_fall_at_least(&fall_ctx, movement.x, movement.z, max_up_step as f64)
+ {
+ if movement.x.abs() <= min_movement {
+ movement.x = 0.;
+ } else {
+ movement.x -= min_movement_x;
+ }
+ if movement.z.abs() <= min_movement {
+ movement.z = 0.;
+ } else {
+ movement.z -= min_movement_z;
+ }
+ }
+
+ movement
+}
+
+fn get_max_up_step(attributes: &Attributes) -> f32 {
+ // this would be different if we were riding an entity
+ attributes.step_height.calculate() as f32
+}
+
+fn is_above_ground(ctx: &CanFallAtLeastCtx, max_up_step: f32) -> bool {
+ ctx.physics.on_ground()
+ && ctx.physics.fall_distance < max_up_step as f64
+ && !can_fall_at_least(ctx, 0., 0., max_up_step as f64 - ctx.physics.fall_distance)
+}
+
+pub struct CanFallAtLeastCtx<'world, 'state, 'a, 'b> {
+ physics: &'a Physics,
+ world: &'a Instance,
+ source_entity: Entity,
+ physics_query: &'a PhysicsQuery<'world, 'state, 'b>,
+ collidable_entity_query: &'a CollidableEntityQuery<'world, 'state>,
+}
+
+fn can_fall_at_least(
+ ctx: &CanFallAtLeastCtx,
+ delta_x: f64,
+ delta_z: f64,
+ max_up_step: f64,
+) -> bool {
+ let aabb = ctx.physics.bounding_box;
+ let aabb = AABB {
+ min: Vec3 {
+ x: aabb.min.x + EPSILON + delta_x,
+ y: aabb.min.y - max_up_step - EPSILON,
+ z: aabb.min.z + EPSILON + delta_z,
+ },
+ max: Vec3 {
+ x: aabb.max.x - EPSILON + delta_x,
+ y: aabb.min.y,
+ z: aabb.max.z - EPSILON + delta_z,
+ },
+ };
+ no_collision(
+ ctx.world,
+ Some(ctx.source_entity),
+ ctx.physics_query,
+ ctx.collidable_entity_query,
+ ctx.physics,
+ &aabb,
+ false,
+ )
+}
+
fn collide_bounding_box(
movement: Vec3,
entity_bounding_box: &AABB,
diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs
index 27250f61..fb62b48b 100644
--- a/azalea-physics/src/lib.rs
+++ b/azalea-physics/src/lib.rs
@@ -4,6 +4,7 @@
pub mod clip;
pub mod collision;
pub mod fluids;
+pub mod local_player;
pub mod travel;
use std::collections::HashSet;
@@ -16,18 +17,17 @@ use azalea_core::{
};
use azalea_entity::{
Attributes, EntityKindComponent, HasClientLoaded, Jumping, LocalEntity, LookDirection,
- OnClimbable, Physics, Pose, Position, metadata::Sprinting, move_relative,
+ OnClimbable, Physics, Pose, Position, dimensions::EntityDimensions, metadata::Sprinting,
+ move_relative,
};
use azalea_registry::{Block, EntityKind};
use azalea_world::{Instance, InstanceContainer, InstanceName};
use bevy_app::{App, Plugin};
use bevy_ecs::prelude::*;
use clip::box_traverse_blocks;
-use collision::{
- BLOCK_SHAPE, BlockWithShape, MoverType, VoxelShape,
- entity_collisions::{CollidableEntityQuery, PhysicsQuery},
- move_colliding,
-};
+use collision::{BLOCK_SHAPE, BlockWithShape, VoxelShape, move_colliding};
+
+use crate::collision::MoveCtx;
/// A Bevy [`SystemSet`] for running physics that makes entities do things.
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
@@ -161,12 +161,12 @@ fn jump_in_liquid(physics: &mut Physics) {
#[allow(clippy::type_complexity)]
pub fn apply_effects_from_blocks(
mut query: Query<
- (&mut Physics, &Position, &InstanceName),
+ (&mut Physics, &Position, &EntityDimensions, &InstanceName),
(With<LocalEntity>, With<HasClientLoaded>),
>,
instance_container: Res<InstanceContainer>,
) {
- for (mut physics, position, world_name) in &mut query {
+ for (mut physics, position, dimensions, world_name) in &mut query {
let Some(world_lock) = instance_container.get(world_name) else {
continue;
};
@@ -189,12 +189,13 @@ pub fn apply_effects_from_blocks(
to: **position,
}];
- check_inside_blocks(&mut physics, &world, &movement_this_tick);
+ check_inside_blocks(&mut physics, dimensions, &world, &movement_this_tick);
}
}
fn check_inside_blocks(
physics: &mut Physics,
+ dimensions: &EntityDimensions,
world: &Instance,
movements: &[EntityMovement],
) -> Vec<BlockState> {
@@ -202,8 +203,7 @@ fn check_inside_blocks(
let mut visited_blocks = HashSet::<BlockState>::new();
for movement in movements {
- let bounding_box_at_target = physics
- .dimensions
+ let bounding_box_at_target = dimensions
.make_bounding_box(movement.to)
.deflate_all(1.0E-5);
@@ -242,7 +242,7 @@ fn check_inside_blocks(
movement.to,
traversed_block,
entity_inside_collision_shape,
- physics,
+ dimensions,
)
{
continue;
@@ -262,9 +262,9 @@ fn collided_with_shape_moving_from(
to: Vec3,
traversed_block: BlockPos,
entity_inside_collision_shape: &VoxelShape,
- physics: &Physics,
+ dimensions: &EntityDimensions,
) -> bool {
- let bounding_box_from = physics.dimensions.make_bounding_box(from);
+ let bounding_box_from = dimensions.make_bounding_box(from);
let delta = to - from;
bounding_box_from.collided_along_vector(
delta,
@@ -367,63 +367,27 @@ fn get_block_pos_below_that_affects_movement(position: Position) -> BlockPos {
)
}
-/// Options for [`handle_relative_friction_and_calculate_movement`]
-struct HandleRelativeFrictionAndCalculateMovementOpts<'a, 'b, 'world, 'state> {
- block_friction: f32,
- world: &'a Instance,
- physics: &'a mut Physics,
- direction: LookDirection,
- position: Mut<'a, Position>,
- attributes: &'a Attributes,
- is_sprinting: bool,
- on_climbable: OnClimbable,
- pose: Option<Pose>,
- jumping: Jumping,
- entity: Entity,
- physics_query: &'a PhysicsQuery<'world, 'state, 'b>,
- collidable_entity_query: &'a CollidableEntityQuery<'world, 'state>,
-}
-fn handle_relative_friction_and_calculate_movement(
- HandleRelativeFrictionAndCalculateMovementOpts {
- block_friction,
- world,
- physics,
- direction,
- mut position,
- attributes,
- is_sprinting,
- on_climbable,
- pose,
- jumping,
- entity,
- physics_query,
- collidable_entity_query,
- }: HandleRelativeFrictionAndCalculateMovementOpts<'_, '_, '_, '_>,
-) -> Vec3 {
+fn handle_relative_friction_and_calculate_movement(ctx: &mut MoveCtx, block_friction: f32) -> Vec3 {
move_relative(
- physics,
- direction,
- get_friction_influenced_speed(physics, attributes, block_friction, is_sprinting),
+ ctx.physics,
+ ctx.direction,
+ get_friction_influenced_speed(ctx.physics, ctx.attributes, block_friction, ctx.sprinting),
Vec3::new(
- physics.x_acceleration as f64,
- physics.y_acceleration as f64,
- physics.z_acceleration as f64,
+ ctx.physics.x_acceleration as f64,
+ ctx.physics.y_acceleration as f64,
+ ctx.physics.z_acceleration as f64,
),
);
- physics.velocity = handle_on_climbable(physics.velocity, on_climbable, *position, world, pose);
-
- move_colliding(
- MoverType::Own,
- physics.velocity,
- world,
- &mut position,
- physics,
- Some(entity),
- physics_query,
- collidable_entity_query,
- )
- .expect("Entity should exist");
+ ctx.physics.velocity = handle_on_climbable(
+ ctx.physics.velocity,
+ ctx.on_climbable,
+ *ctx.position,
+ ctx.world,
+ ctx.pose,
+ );
+
+ move_colliding(ctx, ctx.physics.velocity).expect("Entity should exist");
// let delta_movement = entity.delta;
// ladders
// if ((entity.horizontalCollision || entity.jumping) && (entity.onClimbable()
@@ -431,19 +395,20 @@ fn handle_relative_friction_and_calculate_movement(
// PowderSnowBlock.canEntityWalkOnPowderSnow(entity))) { var3 = new
// Vec3(var3.x, 0.2D, var3.z); }
- if physics.horizontal_collision || *jumping {
- let block_at_feet: Block = world
+ if ctx.physics.horizontal_collision || *ctx.jumping {
+ let block_at_feet: Block = ctx
+ .world
.chunks
- .get_block_state((*position).into())
+ .get_block_state(BlockPos::from(*ctx.position))
.unwrap_or_default()
.into();
- if *on_climbable || block_at_feet == Block::PowderSnow {
- physics.velocity.y = 0.2;
+ if *ctx.on_climbable || block_at_feet == Block::PowderSnow {
+ ctx.physics.velocity.y = 0.2;
}
}
- physics.velocity
+ ctx.physics.velocity
}
fn handle_on_climbable(
@@ -467,7 +432,7 @@ fn handle_on_climbable(
// sneaking on ladders/vines
if y < 0.0
- && pose == Some(Pose::Sneaking)
+ && pose == Some(Pose::Crouching)
&& azalea_registry::Block::from(
world
.chunks
@@ -488,15 +453,15 @@ fn get_friction_influenced_speed(
physics: &Physics,
attributes: &Attributes,
friction: f32,
- is_sprinting: bool,
+ sprinting: Sprinting,
) -> f32 {
// TODO: have speed & flying_speed fields in entity
if physics.on_ground() {
- let speed: f32 = attributes.speed.calculate() as f32;
+ let speed = attributes.movement_speed.calculate() as f32;
speed * (0.21600002f32 / (friction * friction * friction))
} else {
// entity.flying_speed
- if is_sprinting { 0.025999999f32 } else { 0.02 }
+ if *sprinting { 0.025999999f32 } else { 0.02 }
}
}
diff --git a/azalea-physics/src/local_player.rs b/azalea-physics/src/local_player.rs
new file mode 100644
index 00000000..6ce196b6
--- /dev/null
+++ b/azalea-physics/src/local_player.rs
@@ -0,0 +1,67 @@
+use azalea_core::position::Vec2;
+use bevy_ecs::component::Component;
+
+/// Component for entities that can move and sprint. Usually only in
+/// [`LocalEntity`]s.
+///
+/// [`LocalEntity`]: azalea_entity::LocalEntity
+#[derive(Default, Component, Clone)]
+pub struct PhysicsState {
+ /// Minecraft only sends a movement packet either after 20 ticks or if the
+ /// player moved enough. This is that tick counter.
+ pub position_remainder: u32,
+ pub was_sprinting: bool,
+ // Whether we're going to try to start sprinting this tick. Equivalent to
+ // holding down ctrl for a tick.
+ pub trying_to_sprint: bool,
+
+ /// Whether our player is currently trying to sneak.
+ ///
+ /// This is distinct from
+ /// [`AbstractEntityShiftKeyDown`](azalea_entity::metadata::AbstractEntityShiftKeyDown),
+ /// which is a metadata value that is controlled by the server and affects
+ /// how the nametags of other entities are displayed.
+ ///
+ /// To check whether we're actually sneaking, you can check the
+ /// [`Crouching`] or [`Pose`] components.
+ pub trying_to_crouch: bool,
+
+ pub move_direction: WalkDirection,
+ pub move_vector: Vec2,
+}
+
+/// A direction that a player can walk in, including none.
+///
+/// Superset of [`SprintDirection`].
+#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
+pub enum WalkDirection {
+ #[default]
+ None,
+ Forward,
+ Backward,
+ Left,
+ Right,
+ ForwardRight,
+ ForwardLeft,
+ BackwardRight,
+ BackwardLeft,
+}
+
+/// The directions that a player can sprint in. It's a subset of
+/// [`WalkDirection`].
+#[derive(Clone, Copy, Debug)]
+pub enum SprintDirection {
+ Forward,
+ ForwardRight,
+ ForwardLeft,
+}
+
+impl From<SprintDirection> for WalkDirection {
+ fn from(d: SprintDirection) -> Self {
+ match d {
+ SprintDirection::Forward => WalkDirection::Forward,
+ SprintDirection::ForwardRight => WalkDirection::ForwardRight,
+ SprintDirection::ForwardLeft => WalkDirection::ForwardLeft,
+ }
+ }
+}
diff --git a/azalea-physics/src/travel.rs b/azalea-physics/src/travel.rs
index 80c289d9..1c473a45 100644
--- a/azalea-physics/src/travel.rs
+++ b/azalea-physics/src/travel.rs
@@ -4,20 +4,21 @@ use azalea_core::{
position::{BlockPos, Vec3},
};
use azalea_entity::{
- Attributes, HasClientLoaded, Jumping, LocalEntity, LookDirection, OnClimbable, Physics, Pose,
- Position, metadata::Sprinting, move_relative,
+ Attributes, HasClientLoaded, Jumping, LocalEntity, LookDirection, OnClimbable, Physics,
+ PlayerAbilities, Pose, Position, metadata::Sprinting, move_relative,
};
use azalea_world::{Instance, InstanceContainer, InstanceName};
use bevy_ecs::prelude::*;
use crate::{
- HandleRelativeFrictionAndCalculateMovementOpts,
collision::{
- MoverType, Shapes,
+ MoveCtx, MoverType, Shapes,
entity_collisions::{CollidableEntityQuery, PhysicsQuery, get_entity_collisions},
move_colliding,
+ world_collisions::{get_block_and_liquid_collisions, get_block_collisions},
},
get_block_pos_below_that_affects_movement, handle_relative_friction_and_calculate_movement,
+ local_player::PhysicsState,
};
/// Move the entity with the given acceleration while handling friction,
@@ -27,15 +28,17 @@ pub fn travel(
mut query: Query<
(
Entity,
- &mut Physics,
- &mut LookDirection,
- &mut Position,
- Option<&Sprinting>,
- Option<&Pose>,
&Attributes,
&InstanceName,
&OnClimbable,
&Jumping,
+ Option<&PhysicsState>,
+ Option<&Sprinting>,
+ Option<&Pose>,
+ Option<&PlayerAbilities>,
+ &mut Physics,
+ &mut LookDirection,
+ &mut Position,
),
(With<LocalEntity>, With<HasClientLoaded>),
>,
@@ -45,15 +48,17 @@ pub fn travel(
) {
for (
entity,
- mut physics,
- direction,
- position,
- sprinting,
- pose,
attributes,
world_name,
on_climbable,
jumping,
+ physics_state,
+ sprinting,
+ pose,
+ abilities,
+ mut physics,
+ direction,
+ position,
) in &mut query
{
let Some(world_lock) = instance_container.get(world_name) else {
@@ -65,92 +70,57 @@ pub fn travel(
// TODO: elytras
- if physics.is_in_water() || physics.is_in_lava() {
+ let mut ctx = MoveCtx {
+ mover_type: MoverType::Own,
+ world: &world,
+ position,
+ physics: &mut physics,
+ source_entity: entity,
+ physics_query: &physics_query,
+ collidable_entity_query: &collidable_entity_query,
+ physics_state,
+ attributes,
+ abilities,
+ direction: *direction,
+ sprinting,
+ on_climbable: *on_climbable,
+ pose: pose.copied(),
+ jumping: *jumping,
+ };
+
+ if ctx.physics.is_in_water() || ctx.physics.is_in_lava() {
// minecraft also checks for `this.isAffectedByFluids() &&
// !this.canStandOnFluid(fluidAtBlock)` here but it doesn't matter
// for players
- travel_in_fluid(
- &world,
- entity,
- &mut physics,
- *direction,
- position,
- attributes,
- sprinting,
- on_climbable,
- &physics_query,
- &collidable_entity_query,
- );
+ travel_in_fluid(&mut ctx);
} else {
- travel_in_air(
- &world,
- entity,
- &mut physics,
- *direction,
- position,
- attributes,
- sprinting,
- *on_climbable,
- pose,
- *jumping,
- &physics_query,
- &collidable_entity_query,
- );
+ travel_in_air(&mut ctx);
}
}
}
/// The usual movement when we're not in water or using an elytra.
-#[allow(clippy::too_many_arguments)]
-fn travel_in_air(
- world: &Instance,
- entity: Entity,
- physics: &mut Physics,
- direction: LookDirection,
- position: Mut<Position>,
- attributes: &Attributes,
- sprinting: Sprinting,
- on_climbable: OnClimbable,
- pose: Option<&Pose>,
- jumping: Jumping,
- physics_query: &PhysicsQuery,
- collidable_entity_query: &CollidableEntityQuery,
-) {
+fn travel_in_air(ctx: &mut MoveCtx) {
let gravity = get_effective_gravity();
- let block_pos_below = get_block_pos_below_that_affects_movement(*position);
+ let block_pos_below = get_block_pos_below_that_affects_movement(*ctx.position);
- let block_state_below = world
+ let block_state_below = ctx
+ .world
.chunks
.get_block_state(block_pos_below)
.unwrap_or(BlockState::AIR);
let block_below: Box<dyn BlockTrait> = block_state_below.into();
let block_friction = block_below.behavior().friction;
- let inertia = if physics.on_ground() {
+ let inertia = if ctx.physics.on_ground() {
block_friction * 0.91
} else {
0.91
};
// this applies the current delta
- let mut movement = handle_relative_friction_and_calculate_movement(
- HandleRelativeFrictionAndCalculateMovementOpts {
- block_friction,
- world,
- physics,
- direction,
- position,
- attributes,
- is_sprinting: *sprinting,
- on_climbable,
- pose: pose.copied(),
- jumping,
- entity,
- physics_query,
- collidable_entity_query,
- },
- );
+ let mut movement = handle_relative_friction_and_calculate_movement(ctx, block_friction);
movement.y -= gravity;
@@ -162,9 +132,9 @@ fn travel_in_air(
// if should_discard_friction(self) {
if false {
- physics.velocity = movement;
+ ctx.physics.velocity = movement;
} else {
- physics.velocity = Vec3 {
+ ctx.physics.velocity = Vec3 {
x: movement.x * inertia as f64,
y: movement.y * 0.9800000190734863f64,
z: movement.z * inertia as f64,
@@ -172,116 +142,86 @@ fn travel_in_air(
}
}
-#[allow(clippy::too_many_arguments)]
-fn travel_in_fluid(
- world: &Instance,
- entity: Entity,
- physics: &mut Physics,
- direction: LookDirection,
- mut position: Mut<Position>,
- attributes: &Attributes,
- sprinting: Sprinting,
- on_climbable: &OnClimbable,
- physics_query: &PhysicsQuery,
- collidable_entity_query: &CollidableEntityQuery,
-) {
- let moving_down = physics.velocity.y <= 0.;
- let y = position.y;
+fn travel_in_fluid(ctx: &mut MoveCtx) {
+ let moving_down = ctx.physics.velocity.y <= 0.;
+ let y = ctx.position.y;
let gravity = get_effective_gravity();
let acceleration = Vec3::new(
- physics.x_acceleration as f64,
- physics.y_acceleration as f64,
- physics.z_acceleration as f64,
+ ctx.physics.x_acceleration as f64,
+ ctx.physics.y_acceleration as f64,
+ ctx.physics.z_acceleration as f64,
);
- if physics.was_touching_water {
- let mut water_movement_speed = if *sprinting { 0.9 } else { 0.8 };
+ if ctx.physics.was_touching_water {
+ let mut water_movement_speed = if *ctx.sprinting { 0.9 } else { 0.8 };
let mut speed = 0.02;
- let mut water_efficiency_modifier = attributes.water_movement_efficiency.calculate() as f32;
- if !physics.on_ground() {
+ let mut water_efficiency_modifier =
+ ctx.attributes.water_movement_efficiency.calculate() as f32;
+ if !ctx.physics.on_ground() {
water_efficiency_modifier *= 0.5;
}
if water_efficiency_modifier > 0. {
water_movement_speed += (0.54600006 - water_movement_speed) * water_efficiency_modifier;
- speed += (attributes.speed.calculate() as f32 - speed) * water_efficiency_modifier;
+ speed += (ctx.attributes.movement_speed.calculate() as f32 - speed)
+ * water_efficiency_modifier;
}
// if (this.hasEffect(MobEffects.DOLPHINS_GRACE)) {
// waterMovementSpeed = 0.96F;
// }
- move_relative(physics, direction, speed, acceleration);
- move_colliding(
- MoverType::Own,
- physics.velocity,
- world,
- &mut position,
- physics,
- Some(entity),
- physics_query,
- collidable_entity_query,
- )
- .expect("Entity should exist");
+ move_relative(ctx.physics, ctx.direction, speed, acceleration);
+ move_colliding(ctx, ctx.physics.velocity).expect("Entity should exist");
- let mut new_velocity = physics.velocity;
- if physics.horizontal_collision && **on_climbable {
+ let mut new_velocity = ctx.physics.velocity;
+ if ctx.physics.horizontal_collision && *ctx.on_climbable {
// underwater ladders
new_velocity.y = 0.2;
}
new_velocity.x *= water_movement_speed as f64;
new_velocity.y *= 0.8;
new_velocity.z *= water_movement_speed as f64;
- physics.velocity =
- get_fluid_falling_adjusted_movement(gravity, moving_down, new_velocity, sprinting);
+ ctx.physics.velocity =
+ get_fluid_falling_adjusted_movement(gravity, moving_down, new_velocity, ctx.sprinting);
} else {
- move_relative(physics, direction, 0.02, acceleration);
- move_colliding(
- MoverType::Own,
- physics.velocity,
- world,
- &mut position,
- physics,
- Some(entity),
- physics_query,
- collidable_entity_query,
- )
- .expect("Entity should exist");
+ move_relative(ctx.physics, ctx.direction, 0.02, acceleration);
+ move_colliding(ctx, ctx.physics.velocity).expect("Entity should exist");
- if physics.lava_fluid_height <= fluid_jump_threshold() {
- physics.velocity.x *= 0.5;
- physics.velocity.y *= 0.8;
- physics.velocity.z *= 0.5;
+ if ctx.physics.lava_fluid_height <= fluid_jump_threshold() {
+ ctx.physics.velocity.x *= 0.5;
+ ctx.physics.velocity.y *= 0.8;
+ ctx.physics.velocity.z *= 0.5;
let new_velocity = get_fluid_falling_adjusted_movement(
gravity,
moving_down,
- physics.velocity,
- sprinting,
+ ctx.physics.velocity,
+ ctx.sprinting,
);
- physics.velocity = new_velocity;
+ ctx.physics.velocity = new_velocity;
} else {
- physics.velocity *= 0.5;
+ ctx.physics.velocity *= 0.5;
}
if gravity != 0.0 {
- physics.velocity.y -= gravity / 4.0;
+ ctx.physics.velocity.y -= gravity / 4.0;
}
}
- let velocity = physics.velocity;
- if physics.horizontal_collision
+ let velocity = ctx.physics.velocity;
+ if ctx.physics.horizontal_collision
&& is_free(
- world,
- entity,
- physics_query,
- collidable_entity_query,
- physics,
- physics.bounding_box,
- velocity.up(0.6).down(position.y).up(y),
+ ctx.world,
+ ctx.source_entity,
+ ctx.physics_query,
+ ctx.collidable_entity_query,
+ ctx.physics,
+ ctx.physics.bounding_box,
+ velocity.up(0.6).down(ctx.position.y).up(y),
)
{
- physics.velocity.y = 0.3;
+ ctx.physics.velocity.y = 0.3;
}
}
@@ -316,7 +256,7 @@ fn is_free(
source_entity: Entity,
physics_query: &PhysicsQuery,
collidable_entity_query: &CollidableEntityQuery,
- entity_physics: &mut Physics,
+ entity_physics: &Physics,
bounding_box: AABB,
delta: Vec3,
) -> bool {
@@ -333,19 +273,19 @@ fn is_free(
) && !contains_any_liquid(world, bounding_box)
}
-fn no_collision(
+pub fn no_collision(
world: &Instance,
source_entity: Option<Entity>,
physics_query: &PhysicsQuery,
collidable_entity_query: &CollidableEntityQuery,
- entity_physics: &mut Physics,
+ entity_physics: &Physics,
aabb: &AABB,
include_liquid_collisions: bool,
) -> bool {
let collisions = if include_liquid_collisions {
- crate::collision::world_collisions::get_block_and_liquid_collisions(world, aabb)
+ get_block_and_liquid_collisions(world, aabb)
} else {
- crate::collision::world_collisions::get_block_collisions(world, aabb)
+ get_block_collisions(world, aabb)
};
for collision in collisions {
diff --git a/azalea-protocol/src/packets/game/c_player_abilities.rs b/azalea-protocol/src/packets/game/c_player_abilities.rs
index 3f4e1024..8f7bbf20 100644
--- a/azalea-protocol/src/packets/game/c_player_abilities.rs
+++ b/azalea-protocol/src/packets/game/c_player_abilities.rs
@@ -1,8 +1,8 @@
use std::io::{self, Cursor, Write};
-use azalea_buf::{AzBuf, BufReadError};
-use azalea_buf::{AzaleaRead, AzaleaWrite};
+use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError};
use azalea_core::bitset::FixedBitSet;
+use azalea_entity::PlayerAbilities;
use azalea_protocol_macros::ClientboundGamePacket;
#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)]
@@ -51,3 +51,16 @@ impl AzaleaWrite for PlayerAbilitiesFlags {
set.azalea_write(buf)
}
}
+
+impl From<&ClientboundPlayerAbilities> for PlayerAbilities {
+ fn from(packet: &ClientboundPlayerAbilities) -> Self {
+ Self {
+ invulnerable: packet.flags.invulnerable,
+ flying: packet.flags.flying,
+ can_fly: packet.flags.can_fly,
+ instant_break: packet.flags.instant_break,
+ flying_speed: packet.flying_speed,
+ walking_speed: packet.walking_speed,
+ }
+ }
+}
diff --git a/azalea/examples/nearest_entity.rs b/azalea/examples/nearest_entity.rs
index 8774829e..e859751e 100644
--- a/azalea/examples/nearest_entity.rs
+++ b/azalea/examples/nearest_entity.rs
@@ -2,7 +2,8 @@ use azalea::{Bot, ClientBuilder, LookAtEvent, nearest_entity::EntityFinder};
use azalea_client::Account;
use azalea_core::tick::GameTick;
use azalea_entity::{
- EyeHeight, LocalEntity, Position,
+ LocalEntity, Position,
+ dimensions::EntityDimensions,
metadata::{ItemItem, Player},
};
use bevy_app::Plugin;
@@ -33,7 +34,7 @@ impl Plugin for LookAtStuffPlugin {
fn look_at_everything(
bots: Query<Entity, (With<LocalEntity>, With<Player>)>,
entities: EntityFinder,
- entity_positions: Query<(&Position, Option<&EyeHeight>)>,
+ entity_positions: Query<(&Position, Option<&EntityDimensions>)>,
mut look_at_event: EventWriter<LookAtEvent>,
) {
for bot_id in bots.iter() {
@@ -41,11 +42,11 @@ fn look_at_everything(
continue;
};
- let (position, eye_height) = entity_positions.get(entity).unwrap();
+ let (position, dimensions) = entity_positions.get(entity).unwrap();
let mut look_target = **position;
- if let Some(eye_height) = eye_height {
- look_target.y += **eye_height as f64;
+ if let Some(dimensions) = dimensions {
+ look_target.y += dimensions.eye_height as f64;
}
look_at_event.write(LookAtEvent {
diff --git a/azalea/examples/testbot/commands/debug.rs b/azalea/examples/testbot/commands/debug.rs
index 46f1ed33..b3a8b419 100644
--- a/azalea/examples/testbot/commands/debug.rs
+++ b/azalea/examples/testbot/commands/debug.rs
@@ -205,6 +205,13 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
1
}));
+ commands.register(literal("dimensions").executes(|ctx: &Ctx| {
+ let source = ctx.source.lock();
+ let bot_dimensions = source.bot.dimensions();
+ source.reply(format!("{bot_dimensions:?}"));
+ 1
+ }));
+
commands.register(literal("debugecsleak").executes(|ctx: &Ctx| {
let source = ctx.source.lock();
diff --git a/azalea/examples/testbot/commands/movement.rs b/azalea/examples/testbot/commands/movement.rs
index 89be3d0c..a4ac787a 100644
--- a/azalea/examples/testbot/commands/movement.rs
+++ b/azalea/examples/testbot/commands/movement.rs
@@ -3,10 +3,11 @@ use std::time::Duration;
use azalea::{
BlockPos, SprintDirection, WalkDirection,
brigadier::prelude::*,
- entity::{EyeHeight, Position},
+ entity::Position,
pathfinder::goals::{BlockPosGoal, RadiusGoal, XZGoal},
prelude::*,
};
+use azalea_entity::dimensions::EntityDimensions;
use parking_lot::Mutex;
use super::{CommandSource, Ctx};
@@ -103,8 +104,8 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
};
let eye_height = source
.bot
- .get_entity_component::<EyeHeight>(entity)
- .map(|h| *h)
+ .get_entity_component::<EntityDimensions>(entity)
+ .map(|h| h.eye_height)
.unwrap_or_default();
source.bot.look_at(position.up(eye_height as f64));
1
@@ -155,7 +156,7 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
tokio::time::sleep(Duration::from_secs_f32(seconds)).await;
bot.walk(WalkDirection::None);
});
- source.reply(format!("ok, spriting for {seconds} seconds"));
+ source.reply(format!("ok, sprinting for {seconds} seconds"));
1
})),
);
@@ -200,6 +201,21 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
})),
);
+ let sneak = |ctx: &Ctx| {
+ let source = ctx.source.lock();
+ source.bot.set_crouching(!source.bot.crouching());
+ source.reply("ok");
+ 1
+ };
+ let sneak_enabled = argument("enabled", bool()).executes(|ctx: &Ctx| {
+ let sneaking = get_bool(ctx, "enabled").unwrap();
+ let source = ctx.source.lock();
+ source.bot.set_crouching(sneaking);
+ 1
+ });
+ commands.register(literal("sneak").executes(sneak).then(sneak_enabled.clone()));
+ commands.register(literal("crouch").executes(sneak).then(sneak_enabled));
+
commands.register(literal("stop").executes(|ctx: &Ctx| {
let source = ctx.source.lock();
source.bot.stop_pathfinding();
diff --git a/azalea/src/bot.rs b/azalea/src/bot.rs
index 8784cb31..b037ed14 100644
--- a/azalea/src/bot.rs
+++ b/azalea/src/bot.rs
@@ -9,8 +9,8 @@ use azalea_core::{
tick::GameTick,
};
use azalea_entity::{
- EyeHeight, Jumping, LocalEntity, LookDirection, Position, clamp_look_direction,
- metadata::Player,
+ Jumping, LocalEntity, LookDirection, Position, clamp_look_direction,
+ dimensions::EntityDimensions, metadata::Player, update_dimensions,
};
use azalea_physics::PhysicsSet;
use bevy_app::Update;
@@ -43,7 +43,9 @@ impl Plugin for BotPlugin {
Update,
(
insert_bot,
- look_at_listener.before(clamp_look_direction),
+ look_at_listener
+ .before(clamp_look_direction)
+ .after(update_dimensions),
jump_listener,
),
)
@@ -224,12 +226,12 @@ pub struct LookAtEvent {
}
fn look_at_listener(
mut events: EventReader<LookAtEvent>,
- mut query: Query<(&Position, &EyeHeight, &mut LookDirection)>,
+ mut query: Query<(&Position, &EntityDimensions, &mut LookDirection)>,
) {
for event in events.read() {
- if let Ok((position, eye_height, mut look_direction)) = query.get_mut(event.entity) {
+ if let Ok((position, dimensions, mut look_direction)) = query.get_mut(event.entity) {
let new_look_direction =
- direction_looking_at(position.up(eye_height.into()), event.position);
+ direction_looking_at(position.up(dimensions.eye_height.into()), event.position);
trace!("look at {} (currently at {})", event.position, **position);
look_direction.update(new_look_direction);
diff --git a/azalea/src/pathfinder/simulation.rs b/azalea/src/pathfinder/simulation.rs
index 8f198ce8..89a8b3c4 100644
--- a/azalea/src/pathfinder/simulation.rs
+++ b/azalea/src/pathfinder/simulation.rs
@@ -10,7 +10,7 @@ use azalea_core::{
game_type::GameMode, position::Vec3, resource_location::ResourceLocation, tick::GameTick,
};
use azalea_entity::{
- Attributes, EntityDimensions, LookDirection, Physics, Position, default_attributes,
+ Attributes, LookDirection, Physics, Position, default_attributes, dimensions::EntityDimensions,
};
use azalea_registry::EntityKind;
use azalea_world::{ChunkStorage, Instance, InstanceContainer, MinecraftEntityId, PartialInstance};
@@ -35,7 +35,7 @@ impl SimulatedPlayerBundle {
SimulatedPlayerBundle {
position: Position::new(position),
- physics: Physics::new(dimensions, position),
+ physics: Physics::new(&dimensions, position),
physics_state: PhysicsState::default(),
look_direction: LookDirection::default(),
attributes: default_attributes(EntityKind::Player),
@@ -112,7 +112,7 @@ fn create_simulation_player_complete_bundle(
MineBundle::default(),
BlockStatePredictionHandler::default(),
azalea_client::local_player::PermissionLevel::default(),
- azalea_client::local_player::PlayerAbilities::default(),
+ azalea_entity::PlayerAbilities::default(),
)
}
diff --git a/codegen/lib/code/entity.py b/codegen/lib/code/entity.py
index d4b43d58..31cf71a8 100644
--- a/codegen/lib/code/entity.py
+++ b/codegen/lib/code/entity.py
@@ -152,6 +152,10 @@ impl From<EntityDataValue> for UpdateMetadataError {
# some generic names... we don't like these
duplicate_field_names.add("state") # SnifferState instead of State
+ duplicate_field_names.add("crouching") # FoxCrouching instead of Crouching
+
+ # make this one longer to avoid accidental use -- AbstractEntityShiftKeyDown instead of ShiftKeydown
+ duplicate_field_names.add("shift_key_down")
for entity_id in burger_entity_metadata.keys():
field_name_map[entity_id] = {}
@@ -626,7 +630,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
def generate_entity_dimensions(burger_entities_data: dict):
# lines look like
- # EntityKind::Player => EntityDimensions::new(0.6, 1.8),
+ # EntityKind::Player => EntityDimensions::new(0.6, 1.8).eye_height(1.62),
new_match_lines = []
for entity_id, entity_data in burger_entities_data["entity"].items():
if entity_id.startswith("~"):
@@ -635,9 +639,10 @@ def generate_entity_dimensions(burger_entities_data: dict):
variant_name: str = upper_first_letter(to_camel_case(entity_id))
width = entity_data["width"]
height = entity_data["height"]
- new_match_lines.append(
- f" EntityKind::{variant_name} => EntityDimensions::new({width}, {height}),"
- )
+ expr = f"EntityDimensions::new({width}, {height})"
+ if "eye_height" in entity_data:
+ expr += f".eye_height({entity_data['eye_height']})"
+ new_match_lines.append(f" EntityKind::{variant_name} => {expr},")
with open(DIMENSIONS_RS_DIR, "r") as f:
lines = f.read().split("\n")
@@ -650,7 +655,7 @@ def generate_entity_dimensions(burger_entities_data: dict):
if line.strip() == "match entity {":
in_match = True
else:
- if line.strip() == "}":
+ if line == " }":
new_lines.extend(new_match_lines)
new_lines.extend(lines[i:])
break