mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 06:16:04 +00:00
start trying to fix
This commit is contained in:
parent
babb0d3a74
commit
3edd35aa42
17 changed files with 171 additions and 69 deletions
|
@ -2,7 +2,7 @@ use crate::{
|
|||
chat::ChatPlugin,
|
||||
disconnect::{DisconnectEvent, DisconnectPlugin},
|
||||
events::{Event, EventPlugin, LocalPlayerEvents},
|
||||
interact::CurrentSequenceNumber,
|
||||
interact::{CurrentSequenceNumber, InteractPlugin},
|
||||
inventory::{InventoryComponent, InventoryPlugin},
|
||||
local_player::{
|
||||
death_event, handle_send_packet_event, update_in_loaded_chunk, GameProfileComponent,
|
||||
|
@ -435,6 +435,11 @@ impl Client {
|
|||
self.query::<&T>(&mut self.ecs.lock()).clone()
|
||||
}
|
||||
|
||||
/// Get a component from this client, or `None` if it doesn't exist.
|
||||
pub fn get_component<T: Component + Clone>(&self) -> Option<T> {
|
||||
self.query::<Option<&T>>(&mut self.ecs.lock()).cloned()
|
||||
}
|
||||
|
||||
/// Get a reference to our (potentially shared) world.
|
||||
///
|
||||
/// This gets the [`Instance`] from our world container. If it's a normal
|
||||
|
@ -515,11 +520,7 @@ impl Plugin for AzaleaPlugin {
|
|||
// Minecraft ticks happen every 50ms
|
||||
app.insert_resource(FixedTime::new(Duration::from_millis(50)));
|
||||
|
||||
app.add_system(
|
||||
update_in_loaded_chunk
|
||||
.after(PhysicsSet)
|
||||
.after(handle_send_packet_event),
|
||||
);
|
||||
app.add_system(update_in_loaded_chunk.after(PhysicsSet));
|
||||
|
||||
// fire the Death event when the player dies.
|
||||
app.add_system(death_event);
|
||||
|
@ -635,5 +636,6 @@ impl PluginGroup for DefaultPlugins {
|
|||
.add(ChatPlugin)
|
||||
.add(DisconnectPlugin)
|
||||
.add(PlayerMovePlugin)
|
||||
.add(InteractPlugin)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ use azalea_protocol::packets::game::{
|
|||
serverbound_use_item_on_packet::{BlockHit, ServerboundUseItemOnPacket},
|
||||
};
|
||||
use azalea_world::{
|
||||
entity::{view_vector, EyeHeight, LookDirection, Position, WorldName},
|
||||
entity::{clamp_look_direction, view_vector, EyeHeight, LookDirection, Position, WorldName},
|
||||
InstanceContainer,
|
||||
};
|
||||
use bevy_app::{App, Plugin};
|
||||
|
@ -13,19 +13,28 @@ use bevy_ecs::{
|
|||
component::Component,
|
||||
entity::Entity,
|
||||
event::EventReader,
|
||||
system::{Query, Res},
|
||||
schedule::{IntoSystemConfig, IntoSystemConfigs},
|
||||
system::{Commands, Query, Res},
|
||||
};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use log::warn;
|
||||
|
||||
use crate::{local_player::LocalGameMode, Client, LocalPlayer};
|
||||
use crate::{
|
||||
local_player::{handle_send_packet_event, LocalGameMode},
|
||||
Client, LocalPlayer,
|
||||
};
|
||||
|
||||
/// A plugin that allows clients to interact with blocks in the world.
|
||||
pub struct InteractPlugin;
|
||||
impl Plugin for InteractPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_event::<BlockInteractEvent>()
|
||||
.add_systems((handle_block_interact_event, update_hit_result_component));
|
||||
app.add_event::<BlockInteractEvent>().add_systems(
|
||||
(
|
||||
handle_block_interact_event,
|
||||
update_hit_result_component.after(clamp_look_direction),
|
||||
)
|
||||
.before(handle_send_packet_event),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,8 +105,10 @@ fn handle_block_interact_event(
|
|||
}
|
||||
|
||||
fn update_hit_result_component(
|
||||
mut commands: Commands,
|
||||
mut query: Query<(
|
||||
&mut HitResultComponent,
|
||||
Entity,
|
||||
Option<&mut HitResultComponent>,
|
||||
&LocalGameMode,
|
||||
&Position,
|
||||
&EyeHeight,
|
||||
|
@ -106,7 +117,7 @@ fn update_hit_result_component(
|
|||
)>,
|
||||
instance_container: Res<InstanceContainer>,
|
||||
) {
|
||||
for (mut hit_result_ref, game_mode, position, eye_height, look_direction, world_name) in
|
||||
for (entity, hit_result_ref, game_mode, position, eye_height, look_direction, world_name) in
|
||||
&mut query
|
||||
{
|
||||
let pick_range = if game_mode.current == GameMode::Creative {
|
||||
|
@ -121,6 +132,10 @@ fn update_hit_result_component(
|
|||
z: position.z,
|
||||
};
|
||||
let end_position = eye_position + view_vector * pick_range;
|
||||
println!(
|
||||
"eye_position: {:?}, end_position: {:?}",
|
||||
eye_position, end_position
|
||||
);
|
||||
let instance_lock = instance_container
|
||||
.get(world_name)
|
||||
.expect("entities must always be in a valid world");
|
||||
|
@ -134,6 +149,12 @@ fn update_hit_result_component(
|
|||
fluid_pick_type: FluidPickType::None,
|
||||
},
|
||||
);
|
||||
**hit_result_ref = hit_result;
|
||||
if let Some(mut hit_result_ref) = hit_result_ref {
|
||||
**hit_result_ref = hit_result;
|
||||
} else {
|
||||
commands
|
||||
.entity(entity)
|
||||
.insert(HitResultComponent(hit_result));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,15 @@ use azalea_auth::game_profile::GameProfile;
|
|||
use azalea_core::{ChunkPos, GameMode};
|
||||
use azalea_protocol::packets::game::ServerboundGamePacket;
|
||||
use azalea_world::{
|
||||
entity::{self, Dead},
|
||||
Instance, PartialInstance,
|
||||
entity::{self, Dead, WorldName},
|
||||
Instance, InstanceContainer, PartialInstance,
|
||||
};
|
||||
use bevy_ecs::{
|
||||
component::Component, entity::Entity, event::EventReader, query::Added, system::Query,
|
||||
component::Component,
|
||||
entity::Entity,
|
||||
event::EventReader,
|
||||
query::Added,
|
||||
system::{Query, Res},
|
||||
};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use parking_lot::RwLock;
|
||||
|
@ -83,6 +87,7 @@ pub struct LocalPlayerInLoadedChunk;
|
|||
#[derive(Component, Clone, Debug, Copy)]
|
||||
pub struct LocalGameMode {
|
||||
pub current: GameMode,
|
||||
pub previous: Option<GameMode>,
|
||||
}
|
||||
|
||||
impl LocalPlayer {
|
||||
|
@ -129,16 +134,15 @@ impl Drop for LocalPlayer {
|
|||
/// Update the [`LocalPlayerInLoadedChunk`] component for all [`LocalPlayer`]s.
|
||||
pub fn update_in_loaded_chunk(
|
||||
mut commands: bevy_ecs::system::Commands,
|
||||
query: Query<(Entity, &LocalPlayer, &entity::Position)>,
|
||||
query: Query<(Entity, &WorldName, &entity::Position)>,
|
||||
instance_container: Res<InstanceContainer>,
|
||||
) {
|
||||
for (entity, local_player, position) in &query {
|
||||
let player_chunk_pos = ChunkPos::from(position);
|
||||
let in_loaded_chunk = local_player
|
||||
.world
|
||||
.read()
|
||||
.chunks
|
||||
.get(&player_chunk_pos)
|
||||
.is_some();
|
||||
let instance_lock = instance_container
|
||||
.get(&local_player)
|
||||
.expect("local player should always be in an instance");
|
||||
let in_loaded_chunk = instance_lock.read().chunks.get(&player_chunk_pos).is_some();
|
||||
if in_loaded_chunk {
|
||||
commands.entity(entity).insert(LocalPlayerInLoadedChunk);
|
||||
} else {
|
||||
|
|
|
@ -251,9 +251,14 @@ fn process_packet_events(ecs: &mut World) {
|
|||
metadata: PlayerMetadataBundle::default(),
|
||||
};
|
||||
// insert our components into the ecs :)
|
||||
commands
|
||||
.entity(player_entity)
|
||||
.insert((MinecraftEntityId(p.player_id), player_bundle));
|
||||
commands.entity(player_entity).insert((
|
||||
MinecraftEntityId(p.player_id),
|
||||
LocalGameMode {
|
||||
current: p.game_type,
|
||||
previous: p.previous_game_type.into(),
|
||||
},
|
||||
player_bundle,
|
||||
));
|
||||
}
|
||||
|
||||
// send the client information that we have set
|
||||
|
|
|
@ -164,15 +164,15 @@ impl AABB {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn move_relative(&self, x: f64, y: f64, z: f64) -> AABB {
|
||||
pub fn move_relative(&self, delta: &Vec3) -> AABB {
|
||||
AABB {
|
||||
min_x: self.min_x + x,
|
||||
min_y: self.min_y + y,
|
||||
min_z: self.min_z + z,
|
||||
min_x: self.min_x + delta.x,
|
||||
min_y: self.min_y + delta.y,
|
||||
min_z: self.min_z + delta.z,
|
||||
|
||||
max_x: self.max_x + x,
|
||||
max_y: self.max_y + y,
|
||||
max_z: self.max_z + z,
|
||||
max_x: self.max_x + delta.x,
|
||||
max_y: self.max_y + delta.y,
|
||||
max_z: self.max_z + delta.z,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,8 +242,15 @@ impl AABB {
|
|||
let delta = to - from;
|
||||
|
||||
for aabb in boxes {
|
||||
dir = Self::get_direction(aabb, from, &mut t, dir, &delta);
|
||||
dir = Self::get_direction(
|
||||
&aabb.move_relative(&pos.to_vec3()),
|
||||
from,
|
||||
&mut t,
|
||||
dir,
|
||||
&delta,
|
||||
);
|
||||
}
|
||||
println!("dir: {dir:?} delta: {delta:?}");
|
||||
let dir = dir?;
|
||||
Some(BlockHitResult {
|
||||
location: from + &(delta * t),
|
||||
|
@ -258,11 +265,11 @@ impl AABB {
|
|||
aabb: &AABB,
|
||||
from: &Vec3,
|
||||
t: &mut f64,
|
||||
dir: Option<Direction>,
|
||||
mut dir: Option<Direction>,
|
||||
delta: &Vec3,
|
||||
) -> Option<Direction> {
|
||||
if delta.x > EPSILON {
|
||||
return Self::clip_point(ClipPointOpts {
|
||||
dir = Self::clip_point(ClipPointOpts {
|
||||
t,
|
||||
approach_dir: dir,
|
||||
delta,
|
||||
|
@ -275,7 +282,7 @@ impl AABB {
|
|||
start: from,
|
||||
});
|
||||
} else if delta.x < -EPSILON {
|
||||
return Self::clip_point(ClipPointOpts {
|
||||
dir = Self::clip_point(ClipPointOpts {
|
||||
t,
|
||||
approach_dir: dir,
|
||||
delta,
|
||||
|
@ -290,7 +297,7 @@ impl AABB {
|
|||
}
|
||||
|
||||
if delta.y > EPSILON {
|
||||
return Self::clip_point(ClipPointOpts {
|
||||
dir = Self::clip_point(ClipPointOpts {
|
||||
t,
|
||||
approach_dir: dir,
|
||||
delta: &Vec3 {
|
||||
|
@ -311,7 +318,7 @@ impl AABB {
|
|||
},
|
||||
});
|
||||
} else if delta.y < -EPSILON {
|
||||
return Self::clip_point(ClipPointOpts {
|
||||
dir = Self::clip_point(ClipPointOpts {
|
||||
t,
|
||||
approach_dir: dir,
|
||||
delta: &Vec3 {
|
||||
|
@ -334,7 +341,7 @@ impl AABB {
|
|||
}
|
||||
|
||||
if delta.z > EPSILON {
|
||||
return Self::clip_point(ClipPointOpts {
|
||||
dir = Self::clip_point(ClipPointOpts {
|
||||
t,
|
||||
approach_dir: dir,
|
||||
delta: &Vec3 {
|
||||
|
@ -355,7 +362,7 @@ impl AABB {
|
|||
},
|
||||
});
|
||||
} else if delta.z < -EPSILON {
|
||||
return Self::clip_point(ClipPointOpts {
|
||||
dir = Self::clip_point(ClipPointOpts {
|
||||
t,
|
||||
approach_dir: dir,
|
||||
delta: &Vec3 {
|
||||
|
@ -381,9 +388,9 @@ impl AABB {
|
|||
}
|
||||
|
||||
fn clip_point(opts: ClipPointOpts) -> Option<Direction> {
|
||||
let t_x = (opts.begin - opts.start.x) / opts.delta.x;
|
||||
let t_y = (opts.start.y + t_x) / opts.delta.y;
|
||||
let t_z = (opts.start.z + t_x) / opts.delta.z;
|
||||
let t_x = (opts.min_x - opts.start.x) / opts.delta.x;
|
||||
let t_y = (opts.start.y + t_x) * opts.delta.y;
|
||||
let t_z = (opts.start.z + t_x) * opts.delta.z;
|
||||
if 0.0 < t_x
|
||||
&& t_x < *opts.t
|
||||
&& opts.min_x - EPSILON < t_y
|
||||
|
@ -433,3 +440,28 @@ impl AABB {
|
|||
axis.choose(self.min_x, self.min_y, self.min_z)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_aabb_clip_iterable() {
|
||||
assert_ne!(
|
||||
AABB::clip_iterable(
|
||||
&vec![AABB {
|
||||
min_x: 0.,
|
||||
min_y: 0.,
|
||||
min_z: 0.,
|
||||
max_x: 1.,
|
||||
max_y: 1.,
|
||||
max_z: 1.,
|
||||
}],
|
||||
&Vec3::new(0., 0., 0.),
|
||||
&Vec3::new(1., 1., 1.),
|
||||
&BlockPos::new(0, 0, 0),
|
||||
),
|
||||
None
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{BlockPos, Direction, Vec3};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct BlockHitResult {
|
||||
pub location: Vec3,
|
||||
pub direction: Direction,
|
||||
|
|
|
@ -2,7 +2,7 @@ use azalea_buf::McBuf;
|
|||
|
||||
use crate::Vec3;
|
||||
|
||||
#[derive(Clone, Copy, Debug, McBuf, Default)]
|
||||
#[derive(Clone, Copy, Debug, McBuf, Default, Eq, PartialEq)]
|
||||
pub enum Direction {
|
||||
#[default]
|
||||
Down = 0,
|
||||
|
|
|
@ -152,6 +152,15 @@ impl BlockPos {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert the block position into a Vec3 without centering it.
|
||||
pub fn to_vec3(&self) -> Vec3 {
|
||||
Vec3 {
|
||||
x: self.x as f64,
|
||||
y: self.y as f64,
|
||||
z: self.z as f64,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the distance of this vector from the origin by doing `x + y + z`.
|
||||
pub fn length_manhattan(&self) -> u32 {
|
||||
(self.x.abs() + self.y.abs() + self.z.abs()) as u32
|
||||
|
|
|
@ -68,6 +68,7 @@ pub fn clip(chunk_storage: &ChunkStorage, context: ClipContext) -> BlockHitResul
|
|||
block_shape,
|
||||
&block_state,
|
||||
);
|
||||
println!("block_pos: {block_pos:?} block_hit_result: {block_hit_result:?}");
|
||||
// let block_distance = if let Some(block_hit_result) = block_hit_result {
|
||||
// context.from.distance_to_sqr(&block_hit_result.location)
|
||||
// } else {
|
||||
|
@ -126,7 +127,7 @@ fn clip_with_interaction_override(
|
|||
}
|
||||
Some(block_hit_result)
|
||||
} else {
|
||||
None
|
||||
block_hit_result
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,19 +191,19 @@ pub fn traverse_blocks<C, T>(
|
|||
* if vec_sign.x > 0. {
|
||||
1. - right_before_start.x.fract()
|
||||
} else {
|
||||
right_before_start.x.fract()
|
||||
right_before_start.x.fract().abs()
|
||||
},
|
||||
y: percentage_step.y
|
||||
* if vec_sign.y > 0. {
|
||||
1. - right_before_start.y.fract()
|
||||
} else {
|
||||
right_before_start.y.fract()
|
||||
right_before_start.y.fract().abs()
|
||||
},
|
||||
z: percentage_step.z
|
||||
* if vec_sign.z > 0. {
|
||||
1. - right_before_start.z.fract()
|
||||
} else {
|
||||
right_before_start.z.fract()
|
||||
right_before_start.z.fract().abs()
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ impl DiscreteVoxelShape {
|
|||
return false;
|
||||
}
|
||||
let (x, y, z) = (x as u32, y as u32, z as u32);
|
||||
|
||||
(x < self.size(Axis::X) && y < self.size(Axis::Y) && z < self.size(Axis::Z))
|
||||
&& (self.is_full(x, y, z))
|
||||
}
|
||||
|
|
|
@ -216,7 +216,11 @@ fn collide_with_shapes(
|
|||
if y_movement != 0. {
|
||||
y_movement = Shapes::collide(&Axis::Y, &entity_box, collision_boxes, y_movement);
|
||||
if y_movement != 0. {
|
||||
entity_box = entity_box.move_relative(0., y_movement, 0.);
|
||||
entity_box = entity_box.move_relative(&Vec3 {
|
||||
x: 0.,
|
||||
y: y_movement,
|
||||
z: 0.,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,14 +231,22 @@ fn collide_with_shapes(
|
|||
if more_z_movement && z_movement != 0. {
|
||||
z_movement = Shapes::collide(&Axis::Z, &entity_box, collision_boxes, z_movement);
|
||||
if z_movement != 0. {
|
||||
entity_box = entity_box.move_relative(0., 0., z_movement);
|
||||
entity_box = entity_box.move_relative(&Vec3 {
|
||||
x: 0.,
|
||||
y: 0.,
|
||||
z: z_movement,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if x_movement != 0. {
|
||||
x_movement = Shapes::collide(&Axis::X, &entity_box, collision_boxes, x_movement);
|
||||
if x_movement != 0. {
|
||||
entity_box = entity_box.move_relative(x_movement, 0., 0.);
|
||||
entity_box = entity_box.move_relative(&Vec3 {
|
||||
x: x_movement,
|
||||
y: 0.,
|
||||
z: 0.,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -394,10 +394,12 @@ impl VoxelShape {
|
|||
|
||||
pub fn clip(&self, from: &Vec3, to: &Vec3, block_pos: &BlockPos) -> Option<BlockHitResult> {
|
||||
if self.is_empty() {
|
||||
println!("empty");
|
||||
return None;
|
||||
}
|
||||
let vector = to - from;
|
||||
if vector.length_sqr() < EPSILON {
|
||||
println!("short {}", vector.length_sqr());
|
||||
return None;
|
||||
}
|
||||
let right_after_start = from + &(vector * 0.0001);
|
||||
|
@ -415,6 +417,7 @@ impl VoxelShape {
|
|||
miss: false,
|
||||
})
|
||||
} else {
|
||||
println!("clip iterable {}", vector.length_sqr());
|
||||
AABB::clip_iterable(&self.to_aabbs(), &from, &to, &block_pos)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ use azalea_block::{Block, BlockState};
|
|||
use azalea_core::{BlockPos, Vec3};
|
||||
use azalea_world::{
|
||||
entity::{
|
||||
metadata::Sprinting, move_relative, Attributes, Jumping, Local, LookDirection, Physics,
|
||||
Position, WorldName,
|
||||
clamp_look_direction, metadata::Sprinting, move_relative, Attributes, Jumping, Local,
|
||||
LookDirection, Physics, Position, WorldName,
|
||||
},
|
||||
Instance, InstanceContainer,
|
||||
};
|
||||
|
@ -31,7 +31,11 @@ pub struct PhysicsPlugin;
|
|||
impl Plugin for PhysicsPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_event::<ForceJumpEvent>()
|
||||
.add_system(force_jump_listener.before(azalea_world::entity::update_bounding_box))
|
||||
.add_system(
|
||||
force_jump_listener
|
||||
.before(azalea_world::entity::update_bounding_box)
|
||||
.after(clamp_look_direction),
|
||||
)
|
||||
.add_systems(
|
||||
(ai_step, travel)
|
||||
.chain()
|
||||
|
|
|
@ -323,7 +323,7 @@ fn remove_despawned_entities_from_indexes(
|
|||
}
|
||||
}
|
||||
|
||||
fn clamp_look_direction(mut query: Query<&mut LookDirection>) {
|
||||
pub fn clamp_look_direction(mut query: Query<&mut LookDirection>) {
|
||||
for mut look_direction in &mut query {
|
||||
look_direction.y_rot = look_direction.y_rot % 360.0;
|
||||
look_direction.x_rot = look_direction.x_rot.clamp(-90.0, 90.0) % 360.0;
|
||||
|
|
|
@ -23,7 +23,8 @@ pub use data::*;
|
|||
use derive_more::{Deref, DerefMut};
|
||||
pub use dimensions::{update_bounding_box, EntityDimensions};
|
||||
pub use info::{
|
||||
EntityInfos, EntityPlugin, EntityUpdateSet, LoadedBy, PartialEntityInfos, RelativeEntityUpdate,
|
||||
clamp_look_direction, EntityInfos, EntityPlugin, EntityUpdateSet, LoadedBy, PartialEntityInfos,
|
||||
RelativeEntityUpdate,
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
use uuid::Uuid;
|
||||
|
@ -70,16 +71,16 @@ pub fn input_vector(direction: &LookDirection, speed: f32, acceleration: &Vec3)
|
|||
}
|
||||
|
||||
pub fn view_vector(look_direction: &LookDirection) -> Vec3 {
|
||||
let y_rot = look_direction.y_rot * 0.017453292;
|
||||
let x_rot = -look_direction.x_rot * 0.017453292;
|
||||
let x_rot_cos = f32::cos(x_rot);
|
||||
let x_rot_sin = f32::sin(x_rot);
|
||||
let x_rot = look_direction.x_rot * 0.017453292;
|
||||
let y_rot = -look_direction.y_rot * 0.017453292;
|
||||
let y_rot_cos = f32::cos(y_rot);
|
||||
let y_rot_sin = f32::sin(y_rot);
|
||||
let x_rot_cos = f32::cos(x_rot);
|
||||
let x_rot_sin = f32::sin(x_rot);
|
||||
Vec3 {
|
||||
x: (x_rot_sin * y_rot_cos) as f64,
|
||||
y: (-y_rot_sin) as f64,
|
||||
z: (x_rot_cos * y_rot_cos) as f64,
|
||||
x: (y_rot_sin * x_rot_cos) as f64,
|
||||
y: (-x_rot_sin) as f64,
|
||||
z: (y_rot_cos * x_rot_cos) as f64,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
use azalea::ecs::query::With;
|
||||
use azalea::entity::metadata::Player;
|
||||
use azalea::entity::Position;
|
||||
use azalea::interact::HitResultComponent;
|
||||
use azalea::inventory::InventoryComponent;
|
||||
use azalea::pathfinder::BlockPosGoal;
|
||||
use azalea::{prelude::*, swarm::prelude::*, BlockPos, GameProfileComponent, WalkDirection};
|
||||
|
@ -47,7 +48,7 @@ async fn main() -> anyhow::Result<()> {
|
|||
let mut accounts = Vec::new();
|
||||
let mut states = Vec::new();
|
||||
|
||||
for i in 0..5 {
|
||||
for i in 0..1 {
|
||||
accounts.push(Account::offline(&format!("bot{i}")));
|
||||
states.push(State::default());
|
||||
}
|
||||
|
@ -165,6 +166,10 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result<
|
|||
bot.chat("no diamond block found");
|
||||
}
|
||||
}
|
||||
"hitresult" => {
|
||||
let hit_result = bot.get_component::<HitResultComponent>();
|
||||
bot.chat(&format!("hit_result: {hit_result:?}",));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::ecs::{
|
|||
};
|
||||
use azalea_core::Vec3;
|
||||
use azalea_physics::{force_jump_listener, PhysicsSet};
|
||||
use azalea_world::entity::LookDirection;
|
||||
use azalea_world::entity::{clamp_look_direction, LookDirection};
|
||||
use azalea_world::entity::{metadata::Player, Jumping, Local, Position};
|
||||
use std::f64::consts::PI;
|
||||
|
||||
|
@ -23,7 +23,9 @@ impl Plugin for BotPlugin {
|
|||
.add_event::<JumpEvent>()
|
||||
.add_systems((
|
||||
insert_bot,
|
||||
look_at_listener.before(force_jump_listener),
|
||||
look_at_listener
|
||||
.before(force_jump_listener)
|
||||
.before(clamp_look_direction),
|
||||
jump_listener,
|
||||
stop_jumping
|
||||
.in_schedule(CoreSchedule::FixedUpdate)
|
||||
|
|
Loading…
Add table
Reference in a new issue