mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 14:26:04 +00:00
start adding sneaking
This commit is contained in:
parent
737af37c19
commit
83dc3dd0e4
13 changed files with 230 additions and 43 deletions
|
@ -30,7 +30,7 @@ use azalea_core::{position::Vec3, tick::GameTick};
|
||||||
use azalea_entity::{
|
use azalea_entity::{
|
||||||
indexing::{EntityIdIndex, EntityUuidIndex},
|
indexing::{EntityIdIndex, EntityUuidIndex},
|
||||||
metadata::Health,
|
metadata::Health,
|
||||||
EntityPlugin, EntityUpdateSet, EyeHeight, LocalEntity, Position,
|
EntityPlugin, EntityUpdateSet, EyeHeight, LocalEntity, Position, Sneaking,
|
||||||
};
|
};
|
||||||
use azalea_physics::PhysicsPlugin;
|
use azalea_physics::PhysicsPlugin;
|
||||||
use azalea_protocol::{
|
use azalea_protocol::{
|
||||||
|
@ -640,6 +640,7 @@ pub struct JoinedClientBundle {
|
||||||
pub permission_level: PermissionLevel,
|
pub permission_level: PermissionLevel,
|
||||||
pub chunk_batch_info: ChunkBatchInfo,
|
pub chunk_batch_info: ChunkBatchInfo,
|
||||||
pub hunger: Hunger,
|
pub hunger: Hunger,
|
||||||
|
pub sneaking: Sneaking,
|
||||||
|
|
||||||
pub entity_id_index: EntityIdIndex,
|
pub entity_id_index: EntityIdIndex,
|
||||||
|
|
||||||
|
|
|
@ -47,21 +47,6 @@ pub struct LocalGameMode {
|
||||||
pub previous: Option<GameMode>,
|
pub previous: Option<GameMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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<&ClientboundPlayerAbilitiesPacket> for PlayerAbilities {
|
impl From<&ClientboundPlayerAbilitiesPacket> for PlayerAbilities {
|
||||||
fn from(packet: &ClientboundPlayerAbilitiesPacket) -> Self {
|
fn from(packet: &ClientboundPlayerAbilitiesPacket) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
use crate::client::Client;
|
use crate::client::Client;
|
||||||
|
use crate::inventory::InventoryComponent;
|
||||||
|
use crate::local_player::PlayerAbilities;
|
||||||
use crate::packet_handling::game::SendPacketEvent;
|
use crate::packet_handling::game::SendPacketEvent;
|
||||||
use azalea_core::position::Vec3;
|
use azalea_core::position::Vec3;
|
||||||
use azalea_core::tick::GameTick;
|
use azalea_core::tick::GameTick;
|
||||||
|
use azalea_entity::metadata::{ShiftKeyDown, Sleeping, SleepingPos, Swimming};
|
||||||
use azalea_entity::{metadata::Sprinting, Attributes, Jumping};
|
use azalea_entity::{metadata::Sprinting, Attributes, Jumping};
|
||||||
use azalea_entity::{InLoadedChunk, LastSentPosition, LookDirection, Physics, Position};
|
use azalea_entity::{InLoadedChunk, LastSentPosition, LookDirection, Physics, Position, Sneaking};
|
||||||
use azalea_physics::{ai_step, PhysicsSet};
|
use azalea_physics::{ai_step, PhysicsSet};
|
||||||
use azalea_protocol::packets::game::serverbound_player_command_packet::ServerboundPlayerCommandPacket;
|
use azalea_protocol::packets::game::serverbound_player_command_packet::ServerboundPlayerCommandPacket;
|
||||||
use azalea_protocol::packets::game::{
|
use azalea_protocol::packets::game::{
|
||||||
|
@ -12,10 +15,11 @@ use azalea_protocol::packets::game::{
|
||||||
serverbound_move_player_rot_packet::ServerboundMovePlayerRotPacket,
|
serverbound_move_player_rot_packet::ServerboundMovePlayerRotPacket,
|
||||||
serverbound_move_player_status_only_packet::ServerboundMovePlayerStatusOnlyPacket,
|
serverbound_move_player_status_only_packet::ServerboundMovePlayerStatusOnlyPacket,
|
||||||
};
|
};
|
||||||
use azalea_world::{MinecraftEntityId, MoveEntityError};
|
use azalea_world::{InstanceContainer, InstanceName, MinecraftEntityId, MoveEntityError};
|
||||||
use bevy_app::{App, Plugin, Update};
|
use bevy_app::{App, Plugin, Update};
|
||||||
use bevy_ecs::prelude::{Event, EventWriter};
|
use bevy_ecs::prelude::{Event, EventWriter};
|
||||||
use bevy_ecs::schedule::SystemSet;
|
use bevy_ecs::schedule::SystemSet;
|
||||||
|
use bevy_ecs::system::Res;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
component::Component, entity::Entity, event::EventReader, query::With,
|
component::Component, entity::Entity, event::EventReader, query::With,
|
||||||
schedule::IntoSystemConfigs, system::Query,
|
schedule::IntoSystemConfigs, system::Query,
|
||||||
|
@ -57,11 +61,13 @@ impl Plugin for PlayerMovePlugin {
|
||||||
.add_systems(
|
.add_systems(
|
||||||
GameTick,
|
GameTick,
|
||||||
(
|
(
|
||||||
(tick_controls, local_player_ai_step)
|
(update_sneaking, tick_controls, local_player_ai_step)
|
||||||
.chain()
|
.chain()
|
||||||
.in_set(PhysicsSet)
|
.in_set(PhysicsSet)
|
||||||
.before(ai_step),
|
.before(ai_step),
|
||||||
send_sprinting_if_needed.after(azalea_entity::update_in_loaded_chunk),
|
(send_sprinting_if_needed, send_shift_key_down_if_needed)
|
||||||
|
.chain()
|
||||||
|
.after(azalea_entity::update_in_loaded_chunk),
|
||||||
send_position.after(PhysicsSet),
|
send_position.after(PhysicsSet),
|
||||||
)
|
)
|
||||||
.chain(),
|
.chain(),
|
||||||
|
@ -117,7 +123,7 @@ pub struct LastSentLookDirection {
|
||||||
pub y_rot: f32,
|
pub y_rot: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component for entities that can move and sprint. Usually only in
|
/// Component for entities that can move, sprint, and sneak. Usually only in
|
||||||
/// [`LocalEntity`]s.
|
/// [`LocalEntity`]s.
|
||||||
///
|
///
|
||||||
/// [`LocalEntity`]: azalea_entity::LocalEntity
|
/// [`LocalEntity`]: azalea_entity::LocalEntity
|
||||||
|
@ -126,7 +132,15 @@ pub struct PhysicsState {
|
||||||
/// Minecraft only sends a movement packet either after 20 ticks or if the
|
/// Minecraft only sends a movement packet either after 20 ticks or if the
|
||||||
/// player moved enough. This is that tick counter.
|
/// player moved enough. This is that tick counter.
|
||||||
pub position_remainder: u32,
|
pub position_remainder: u32,
|
||||||
|
|
||||||
pub was_sprinting: bool,
|
pub was_sprinting: bool,
|
||||||
|
|
||||||
|
/// Whether the player was sneaking last tick. You shouldn't modify this.
|
||||||
|
///
|
||||||
|
/// If you want to check or change the player's sneak state from the ECS,
|
||||||
|
/// use the [`ShiftKeyDown`] component.
|
||||||
|
pub was_sneaking: bool,
|
||||||
|
|
||||||
// Whether we're going to try to start sprinting this tick. Equivalent to
|
// Whether we're going to try to start sprinting this tick. Equivalent to
|
||||||
// holding down ctrl for a tick.
|
// holding down ctrl for a tick.
|
||||||
pub trying_to_sprint: bool,
|
pub trying_to_sprint: bool,
|
||||||
|
@ -251,10 +265,11 @@ fn send_sprinting_if_needed(
|
||||||
mut query: Query<(Entity, &MinecraftEntityId, &Sprinting, &mut PhysicsState)>,
|
mut query: Query<(Entity, &MinecraftEntityId, &Sprinting, &mut PhysicsState)>,
|
||||||
mut send_packet_events: EventWriter<SendPacketEvent>,
|
mut send_packet_events: EventWriter<SendPacketEvent>,
|
||||||
) {
|
) {
|
||||||
for (entity, minecraft_entity_id, sprinting, mut physics_state) in query.iter_mut() {
|
for (entity, &minecraft_entity_id, &Sprinting(sprinting), mut physics_state) in query.iter_mut()
|
||||||
|
{
|
||||||
let was_sprinting = physics_state.was_sprinting;
|
let was_sprinting = physics_state.was_sprinting;
|
||||||
if **sprinting != was_sprinting {
|
if sprinting != was_sprinting {
|
||||||
let sprinting_action = if **sprinting {
|
let sprinting_action = if sprinting {
|
||||||
azalea_protocol::packets::game::serverbound_player_command_packet::Action::StartSprinting
|
azalea_protocol::packets::game::serverbound_player_command_packet::Action::StartSprinting
|
||||||
} else {
|
} else {
|
||||||
azalea_protocol::packets::game::serverbound_player_command_packet::Action::StopSprinting
|
azalea_protocol::packets::game::serverbound_player_command_packet::Action::StopSprinting
|
||||||
|
@ -262,22 +277,122 @@ fn send_sprinting_if_needed(
|
||||||
send_packet_events.send(SendPacketEvent {
|
send_packet_events.send(SendPacketEvent {
|
||||||
entity,
|
entity,
|
||||||
packet: ServerboundPlayerCommandPacket {
|
packet: ServerboundPlayerCommandPacket {
|
||||||
id: **minecraft_entity_id,
|
id: *minecraft_entity_id,
|
||||||
action: sprinting_action,
|
action: sprinting_action,
|
||||||
data: 0,
|
data: 0,
|
||||||
}
|
}
|
||||||
.get(),
|
.get(),
|
||||||
});
|
});
|
||||||
physics_state.was_sprinting = **sprinting;
|
physics_state.was_sprinting = sprinting;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_shift_key_down_if_needed(
|
||||||
|
mut query: Query<(Entity, &MinecraftEntityId, &ShiftKeyDown, &mut PhysicsState)>,
|
||||||
|
mut send_packet_events: EventWriter<SendPacketEvent>,
|
||||||
|
) {
|
||||||
|
for (entity, &minecraft_entity_id, &ShiftKeyDown(sneaking), mut physics_state) in
|
||||||
|
query.iter_mut()
|
||||||
|
{
|
||||||
|
let was_sneaking = physics_state.was_sneaking;
|
||||||
|
if sneaking != was_sneaking {
|
||||||
|
let sneaking_action = if sneaking {
|
||||||
|
azalea_protocol::packets::game::serverbound_player_command_packet::Action::PressShiftKey
|
||||||
|
} else {
|
||||||
|
azalea_protocol::packets::game::serverbound_player_command_packet::Action::ReleaseShiftKey
|
||||||
|
};
|
||||||
|
send_packet_events.send(SendPacketEvent {
|
||||||
|
entity,
|
||||||
|
packet: ServerboundPlayerCommandPacket {
|
||||||
|
id: *minecraft_entity_id,
|
||||||
|
action: sneaking_action,
|
||||||
|
data: 0,
|
||||||
|
}
|
||||||
|
.get(),
|
||||||
|
});
|
||||||
|
physics_state.was_sneaking = sneaking;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn can_player_fit_within_blocks_and_entities_when(
|
||||||
|
_pose: azalea_entity::Pose,
|
||||||
|
_position: Vec3,
|
||||||
|
_instance: &azalea_world::Instance,
|
||||||
|
) -> bool {
|
||||||
|
// TODO
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_sneaking(
|
||||||
|
mut query: Query<(
|
||||||
|
&PlayerAbilities,
|
||||||
|
&Swimming,
|
||||||
|
// TODO: isPassenger
|
||||||
|
&ShiftKeyDown,
|
||||||
|
&SleepingPos,
|
||||||
|
&Position,
|
||||||
|
&InstanceName,
|
||||||
|
&mut Sneaking,
|
||||||
|
)>,
|
||||||
|
instances: Res<InstanceContainer>,
|
||||||
|
) {
|
||||||
|
for (
|
||||||
|
player_abilities,
|
||||||
|
&Swimming(swimming),
|
||||||
|
&ShiftKeyDown(shift_key_down),
|
||||||
|
&SleepingPos(sleeping_pos),
|
||||||
|
&Position(position),
|
||||||
|
instance_name,
|
||||||
|
mut sneaking,
|
||||||
|
) in query.iter_mut()
|
||||||
|
{
|
||||||
|
let Some(instance) = instances.get(instance_name) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
// this.crouching = !this.getAbilities().flying
|
||||||
|
// && !this.isSwimming()
|
||||||
|
// && !this.isPassenger()
|
||||||
|
// && this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.CROUCHING)
|
||||||
|
// && (this.isShiftKeyDown()
|
||||||
|
// || !this.isSleeping() && !this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.STANDING));
|
||||||
|
|
||||||
|
let instance = instance.read();
|
||||||
|
|
||||||
|
**sneaking = !player_abilities.flying
|
||||||
|
&& !swimming
|
||||||
|
// && !isPassenger
|
||||||
|
// && this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.CROUCHING)
|
||||||
|
&& can_player_fit_within_blocks_and_entities_when(
|
||||||
|
azalea_entity::Pose::Crouching,
|
||||||
|
position,
|
||||||
|
&instance,
|
||||||
|
)
|
||||||
|
&& (shift_key_down
|
||||||
|
|| (
|
||||||
|
sleeping_pos.is_none()
|
||||||
|
&& !can_player_fit_within_blocks_and_entities_when(azalea_entity::Pose::Standing, position, &instance)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_moving_slowly(sneaking: bool, is_visually_crawling: bool) -> bool {
|
||||||
|
sneaking || is_visually_crawling
|
||||||
|
}
|
||||||
|
|
||||||
/// Update the impulse from self.move_direction. The multiplier is used for
|
/// Update the impulse from self.move_direction. The multiplier is used for
|
||||||
/// sneaking.
|
/// sneaking.
|
||||||
pub(crate) fn tick_controls(mut query: Query<&mut PhysicsState>) {
|
pub(crate) fn tick_controls(mut query: Query<(&mut PhysicsState, &Sneaking, &InventoryComponent)>) {
|
||||||
for mut physics_state in query.iter_mut() {
|
for (mut physics_state, &Sneaking(sneaking), inventory) in query.iter_mut() {
|
||||||
let multiplier: Option<f32> = None;
|
let multiplier: Option<f32> = if is_moving_slowly(sneaking, false) {
|
||||||
|
let sneaking_speed_bonus =
|
||||||
|
azalea_entity::enchantments::get_sneaking_speed_bonus(&inventory.inventory_menu);
|
||||||
|
Some(f32::clamp(0.3 + sneaking_speed_bonus, 0., 1.))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let mut forward_impulse: f32 = 0.;
|
let mut forward_impulse: f32 = 0.;
|
||||||
let mut left_impulse: f32 = 0.;
|
let mut left_impulse: f32 = 0.;
|
||||||
|
@ -397,6 +512,27 @@ impl Client {
|
||||||
direction,
|
direction,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Start or stop sneaking.
|
||||||
|
///
|
||||||
|
/// ```rust,no_run
|
||||||
|
/// # use azalea_client::{Client, WalkDirection, SprintDirection};
|
||||||
|
/// # use std::time::Duration;
|
||||||
|
/// # async fn example(mut bot: Client) {
|
||||||
|
/// // toggle sneak
|
||||||
|
/// bot.sneak(!bot.sneaking());
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
pub fn sneak(&mut self, sneaking: bool) {
|
||||||
|
let mut ecs = self.ecs.lock();
|
||||||
|
let mut sneaking_component = self.query::<&mut ShiftKeyDown>(&mut ecs);
|
||||||
|
**sneaking_component = sneaking;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether the player is sneaking.
|
||||||
|
pub fn sneaking(&self) -> bool {
|
||||||
|
*self.component::<ShiftKeyDown>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An event sent when the client starts walking. This does not get sent for
|
/// An event sent when the client starts walking. This does not get sent for
|
||||||
|
|
|
@ -136,8 +136,9 @@ pub fn process_packet_events(ecs: &mut World) {
|
||||||
last_sent_direction: crate::movement::LastSentLookDirection::default(),
|
last_sent_direction: crate::movement::LastSentLookDirection::default(),
|
||||||
abilities: crate::local_player::PlayerAbilities::default(),
|
abilities: crate::local_player::PlayerAbilities::default(),
|
||||||
permission_level: crate::local_player::PermissionLevel::default(),
|
permission_level: crate::local_player::PermissionLevel::default(),
|
||||||
hunger: Hunger::default(),
|
|
||||||
chunk_batch_info: crate::chunks::ChunkBatchInfo::default(),
|
chunk_batch_info: crate::chunks::ChunkBatchInfo::default(),
|
||||||
|
hunger: Hunger::default(),
|
||||||
|
sneaking: azalea_entity::Sneaking::default(),
|
||||||
|
|
||||||
entity_id_index: EntityIdIndex::default(),
|
entity_id_index: EntityIdIndex::default(),
|
||||||
|
|
||||||
|
|
|
@ -142,9 +142,19 @@ pub enum Pose {
|
||||||
Sleeping,
|
Sleeping,
|
||||||
Swimming,
|
Swimming,
|
||||||
SpinAttack,
|
SpinAttack,
|
||||||
Sneaking,
|
Crouching,
|
||||||
LongJumping,
|
LongJumping,
|
||||||
Dying,
|
Dying,
|
||||||
|
Croaking,
|
||||||
|
UsingTongue,
|
||||||
|
Sitting,
|
||||||
|
Roaring,
|
||||||
|
Sniffing,
|
||||||
|
Emerging,
|
||||||
|
Digging,
|
||||||
|
Sliding,
|
||||||
|
Shooting,
|
||||||
|
Inhaling,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, McBuf)]
|
#[derive(Debug, Clone, McBuf)]
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
|
use azalea_registry::Enchantment;
|
||||||
|
|
||||||
pub fn get_enchant_level(
|
pub fn get_enchant_level(
|
||||||
_enchantment: azalea_registry::Enchantment,
|
_enchantment: Enchantment,
|
||||||
_player_inventory: &azalea_inventory::Menu,
|
_player_inventory: &azalea_inventory::Menu,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_sneaking_speed_bonus(player_inventory: &azalea_inventory::Menu) -> f32 {
|
||||||
|
get_enchant_level(Enchantment::SwiftSneak, player_inventory) as f32 * 0.15
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ pub mod attributes;
|
||||||
mod data;
|
mod data;
|
||||||
mod dimensions;
|
mod dimensions;
|
||||||
mod effects;
|
mod effects;
|
||||||
mod enchantments;
|
pub mod enchantments;
|
||||||
pub mod metadata;
|
pub mod metadata;
|
||||||
pub mod mining;
|
pub mod mining;
|
||||||
mod plugin;
|
mod plugin;
|
||||||
|
@ -138,7 +138,7 @@ impl Debug for EntityUuid {
|
||||||
/// You are free to change this; there's systems that update the indexes
|
/// You are free to change this; there's systems that update the indexes
|
||||||
/// automatically.
|
/// automatically.
|
||||||
#[derive(Component, Clone, Copy, Debug, Default, PartialEq, Deref, DerefMut)]
|
#[derive(Component, Clone, Copy, Debug, Default, PartialEq, Deref, DerefMut)]
|
||||||
pub struct Position(Vec3);
|
pub struct Position(pub Vec3);
|
||||||
impl Position {
|
impl Position {
|
||||||
pub fn new(pos: Vec3) -> Self {
|
pub fn new(pos: Vec3) -> Self {
|
||||||
Self(pos)
|
Self(pos)
|
||||||
|
@ -425,6 +425,26 @@ impl FluidOnEyes {
|
||||||
#[derive(Component, Clone, Debug, PartialEq, Deref, DerefMut)]
|
#[derive(Component, Clone, Debug, PartialEq, Deref, DerefMut)]
|
||||||
pub struct OnClimbable(bool);
|
pub struct OnClimbable(bool);
|
||||||
|
|
||||||
|
/// A component that indicates whether the player is currently sneaking.
|
||||||
|
#[derive(Component, Clone, Deref, DerefMut, Default)]
|
||||||
|
pub struct Sneaking(pub 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,
|
||||||
|
}
|
||||||
|
|
||||||
// #[cfg(test)]
|
// #[cfg(test)]
|
||||||
// mod tests {
|
// mod tests {
|
||||||
// use super::*;
|
// use super::*;
|
||||||
|
|
|
@ -1986,7 +1986,7 @@ impl Default for DolphinMetadataBundle {
|
||||||
aggressive: Aggressive(false),
|
aggressive: Aggressive(false),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
treasure_pos: TreasurePos(Default::default()),
|
treasure_pos: TreasurePos(BlockPos::new(0, 0, 0)),
|
||||||
got_fish: GotFish(false),
|
got_fish: GotFish(false),
|
||||||
moistness_level: MoistnessLevel(2400),
|
moistness_level: MoistnessLevel(2400),
|
||||||
}
|
}
|
||||||
|
@ -3014,7 +3014,7 @@ impl Default for FallingBlockMetadataBundle {
|
||||||
pose: Pose::default(),
|
pose: Pose::default(),
|
||||||
ticks_frozen: TicksFrozen(0),
|
ticks_frozen: TicksFrozen(0),
|
||||||
},
|
},
|
||||||
start_pos: StartPos(Default::default()),
|
start_pos: StartPos(BlockPos::new(0, 0, 0)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8604,10 +8604,10 @@ impl Default for TurtleMetadataBundle {
|
||||||
abstract_ageable_baby: AbstractAgeableBaby(false),
|
abstract_ageable_baby: AbstractAgeableBaby(false),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
home_pos: HomePos(Default::default()),
|
home_pos: HomePos(BlockPos::new(0, 0, 0)),
|
||||||
has_egg: HasEgg(false),
|
has_egg: HasEgg(false),
|
||||||
laying_egg: LayingEgg(false),
|
laying_egg: LayingEgg(false),
|
||||||
travel_pos: TravelPos(Default::default()),
|
travel_pos: TravelPos(BlockPos::new(0, 0, 0)),
|
||||||
going_home: GoingHome(false),
|
going_home: GoingHome(false),
|
||||||
travelling: Travelling(false),
|
travelling: Travelling(false),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use syn::{
|
use syn::{
|
||||||
braced,
|
braced,
|
||||||
parse::{Parse, ParseStream, Result},
|
parse::{Parse, ParseStream, Result},
|
||||||
Ident, LitInt, Token,
|
Ident, LitInt, Token,
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@ mod world_collisions;
|
||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
|
|
||||||
use azalea_core::{aabb::AABB, direction::Axis, math::EPSILON, position::Vec3};
|
use azalea_core::{aabb::AABB, direction::Axis, math::EPSILON, position::Vec3};
|
||||||
|
use azalea_entity::{metadata::ShiftKeyDown, PlayerAbilities};
|
||||||
use azalea_world::{Instance, MoveEntityError};
|
use azalea_world::{Instance, MoveEntityError};
|
||||||
use bevy_ecs::world::Mut;
|
use bevy_ecs::world::Mut;
|
||||||
pub use blocks::BlockWithShape;
|
pub use blocks::BlockWithShape;
|
||||||
|
@ -138,6 +139,7 @@ pub fn move_colliding(
|
||||||
world: &Instance,
|
world: &Instance,
|
||||||
position: &mut Mut<azalea_entity::Position>,
|
position: &mut Mut<azalea_entity::Position>,
|
||||||
physics: &mut azalea_entity::Physics,
|
physics: &mut azalea_entity::Physics,
|
||||||
|
abilities: &PlayerAbilities,
|
||||||
) -> Result<(), MoveEntityError> {
|
) -> Result<(), MoveEntityError> {
|
||||||
// TODO: do all these
|
// TODO: do all these
|
||||||
|
|
||||||
|
@ -250,6 +252,24 @@ pub fn move_colliding(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn maybe_back_off_from_edge(
|
||||||
|
abilities: &PlayerAbilities,
|
||||||
|
movement: &Vec3,
|
||||||
|
mover_type: MoverType,
|
||||||
|
is_shift_key_held: &ShiftKeyDown
|
||||||
|
) -> Vec3 {
|
||||||
|
// if (!this.abilities.flying
|
||||||
|
// && movement.y <= 0.0
|
||||||
|
// && (moverType == MoverType.SELF || moverType == MoverType.PLAYER)
|
||||||
|
// && this.isStayingOnGroundSurface()
|
||||||
|
// && this.isAboveGround()) {
|
||||||
|
|
||||||
|
let is_backing_off = !abilities.flying
|
||||||
|
&& movement.y <= 0.
|
||||||
|
&& matches!(mover_type, MoverType::Own | MoverType::Player)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
fn collide_bounding_box(
|
fn collide_bounding_box(
|
||||||
movement: &Vec3,
|
movement: &Vec3,
|
||||||
entity_bounding_box: &AABB,
|
entity_bounding_box: &AABB,
|
||||||
|
|
|
@ -335,7 +335,7 @@ fn handle_on_climbable(
|
||||||
|
|
||||||
// sneaking on ladders/vines
|
// sneaking on ladders/vines
|
||||||
if y < 0.0
|
if y < 0.0
|
||||||
&& pose.copied() == Some(Pose::Sneaking)
|
&& pose.copied() == Some(Pose::Crouching)
|
||||||
&& azalea_registry::Block::from(
|
&& azalea_registry::Block::from(
|
||||||
world
|
world
|
||||||
.chunks
|
.chunks
|
||||||
|
|
|
@ -136,11 +136,19 @@ pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
|
||||||
tokio::time::sleep(Duration::from_secs_f32(seconds)).await;
|
tokio::time::sleep(Duration::from_secs_f32(seconds)).await;
|
||||||
bot.walk(WalkDirection::None);
|
bot.walk(WalkDirection::None);
|
||||||
});
|
});
|
||||||
source.reply(&format!("ok, spriting for {seconds} seconds"));
|
source.reply(&format!("ok, sprinting for {seconds} seconds"));
|
||||||
1
|
1
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
commands.register(literal("sneak").executes(|ctx: &Ctx| {
|
||||||
|
let source = ctx.source.lock();
|
||||||
|
let mut bot = source.bot.clone();
|
||||||
|
bot.sneak(!bot.sneaking());
|
||||||
|
source.reply("ok");
|
||||||
|
1
|
||||||
|
}));
|
||||||
|
|
||||||
commands.register(literal("north").executes(|ctx: &Ctx| {
|
commands.register(literal("north").executes(|ctx: &Ctx| {
|
||||||
let mut source = ctx.source.lock();
|
let mut source = ctx.source.lock();
|
||||||
source.bot.set_direction(180., 0.);
|
source.bot.set_direction(180., 0.);
|
||||||
|
|
|
@ -347,7 +347,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
|
||||||
# _marker: Allay,
|
# _marker: Allay,
|
||||||
# parent: AbstractCreatureBundle {
|
# parent: AbstractCreatureBundle {
|
||||||
# on_fire: OnFire(false),
|
# on_fire: OnFire(false),
|
||||||
# shift_key_down: ShiftKeyDown(false),
|
# sneaking: ShiftKeyDown(false),
|
||||||
# },
|
# },
|
||||||
# sprinting: Sprinting(false),
|
# sprinting: Sprinting(false),
|
||||||
# swimming: Swimming(false)
|
# swimming: Swimming(false)
|
||||||
|
@ -360,7 +360,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
|
||||||
|
|
||||||
def generate_fields(this_entity_id: str):
|
def generate_fields(this_entity_id: str):
|
||||||
# on_fire: OnFire(false),
|
# on_fire: OnFire(false),
|
||||||
# shift_key_down: ShiftKeyDown(false),
|
# sneaking: ShiftKeyDown(false),
|
||||||
|
|
||||||
# _marker
|
# _marker
|
||||||
this_entity_struct_name = upper_first_letter(
|
this_entity_struct_name = upper_first_letter(
|
||||||
|
|
Loading…
Add table
Reference in a new issue