diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2023-07-15 04:39:43 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-15 04:39:43 -0500 |
| commit | cde7e35046b726b07bf3e067c080b85a12b2fd74 (patch) | |
| tree | 9d517911cbaf14f007958a92392101f24ec14118 /azalea | |
| parent | 148f20381750be3e2c38a6bdaf8d339113da1b39 (diff) | |
| download | azalea-drasl-cde7e35046b726b07bf3e067c080b85a12b2fd74.tar.xz | |
Attacking (#96)
* add Client::attack
* partially implement attack cooldowns
* attack speed modifiers
* don't care clippy
---------
Co-authored-by: mat <git@matdoes.dev>
Diffstat (limited to 'azalea')
| -rw-r--r-- | azalea/examples/testbot.rs | 52 | ||||
| -rw-r--r-- | azalea/src/auto_respawn.rs | 1 | ||||
| -rw-r--r-- | azalea/src/bot.rs | 50 | ||||
| -rw-r--r-- | azalea/src/container.rs | 10 | ||||
| -rw-r--r-- | azalea/src/lib.rs | 1 | ||||
| -rw-r--r-- | azalea/src/mining.rs | 40 | ||||
| -rw-r--r-- | azalea/src/prelude.rs | 4 |
7 files changed, 105 insertions, 53 deletions
diff --git a/azalea/examples/testbot.rs b/azalea/examples/testbot.rs index 337ac6ec..75a6ca67 100644 --- a/azalea/examples/testbot.rs +++ b/azalea/examples/testbot.rs @@ -11,6 +11,8 @@ use azalea::pathfinder::BlockPosGoal; use azalea::protocol::packets::game::ClientboundGamePacket; use azalea::{prelude::*, swarm::prelude::*, BlockPos, GameProfileComponent, WalkDirection}; use azalea::{Account, Client, Event}; +use azalea_core::Vec3; +use azalea_world::{InstanceName, MinecraftEntityId}; use std::time::Duration; #[derive(Default, Clone, Component)] @@ -220,6 +222,56 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result< println!("no container found"); } } + "attack" => { + let mut nearest_entity = None; + let mut nearest_distance = f64::INFINITY; + let mut nearest_pos = Vec3::default(); + let bot_position = bot.position(); + let bot_entity = bot.entity; + let bot_instance_name = bot.component::<InstanceName>(); + { + let mut ecs = bot.ecs.lock(); + let mut query = ecs.query_filtered::<( + azalea::ecs::entity::Entity, + &MinecraftEntityId, + &Position, + &InstanceName, + &EyeHeight, + ), With<MinecraftEntityId>>( + ); + for (entity, &entity_id, position, instance_name, eye_height) in + query.iter(&ecs) + { + if entity == bot_entity { + continue; + } + if instance_name != &bot_instance_name { + continue; + } + + let distance = bot_position.distance_to(position); + if distance < 4.0 && distance < nearest_distance { + nearest_entity = Some(entity_id); + nearest_distance = distance; + nearest_pos = position.up(**eye_height as f64); + } + } + } + if let Some(nearest_entity) = nearest_entity { + bot.look_at(nearest_pos); + bot.attack(nearest_entity); + bot.chat("attacking"); + let mut ticks = bot.get_tick_broadcaster(); + while ticks.recv().await.is_ok() { + if !bot.has_attack_cooldown() { + break; + } + } + bot.chat("finished attacking"); + } else { + bot.chat("no entities found"); + } + } _ => {} } } diff --git a/azalea/src/auto_respawn.rs b/azalea/src/auto_respawn.rs index 6d9c5954..77a75b4b 100644 --- a/azalea/src/auto_respawn.rs +++ b/azalea/src/auto_respawn.rs @@ -21,6 +21,5 @@ fn auto_respawn( perform_respawn_events.send(PerformRespawnEvent { entity: event.entity, }); - println!("auto respawning"); } } diff --git a/azalea/src/bot.rs b/azalea/src/bot.rs index 7940e7b0..71d96c4d 100644 --- a/azalea/src/bot.rs +++ b/azalea/src/bot.rs @@ -8,7 +8,10 @@ use crate::ecs::{ query::{With, Without}, system::{Commands, Query}, }; -use azalea_core::Vec3; +use azalea_client::interact::SwingArmEvent; +use azalea_client::mining::Mining; +use azalea_client::TickBroadcast; +use azalea_core::{BlockPos, Vec3}; use azalea_entity::{ clamp_look_direction, metadata::Player, EyeHeight, Jumping, Local, LookDirection, Position, }; @@ -67,18 +70,25 @@ fn stop_jumping(mut query: Query<(&mut Jumping, &mut Bot)>) { } pub trait BotClientExt { + /// Queue a jump for the next tick. fn jump(&mut self); + /// Turn the bot's head to look at the coordinate in the world. fn look_at(&mut self, pos: Vec3); + /// Get a receiver that will receive a message every tick. + fn get_tick_broadcaster(&self) -> tokio::sync::broadcast::Receiver<()>; + /// Mine a block. This won't turn the bot's head towards the block, so if + /// that's necessary you'll have to do that yourself with [`look_at`]. + /// + /// [`look_at`]: crate::prelude::BotClientExt::look_at + async fn mine(&mut self, position: BlockPos); } impl BotClientExt for azalea_client::Client { - /// Queue a jump for the next tick. fn jump(&mut self) { let mut ecs = self.ecs.lock(); ecs.send_event(JumpEvent(self.entity)); } - /// Turn the bot's head to look at the coordinate in the world. fn look_at(&mut self, position: Vec3) { let mut ecs = self.ecs.lock(); ecs.send_event(LookAtEvent { @@ -86,6 +96,40 @@ impl BotClientExt for azalea_client::Client { position, }); } + + /// ``` + /// # use azalea::prelude::*; + /// # async fn example(mut bot: azalea::Client) { + /// let mut ticks = self.get_tick_broadcaster(); + /// while ticks.recv().await.is_ok() { + /// let ecs = bot.ecs.lock(); + /// if ecs.get::<WaitingForInventoryOpen>(self.entity).is_none() { + /// break; + /// } + /// } + /// # } + /// ``` + fn get_tick_broadcaster(&self) -> tokio::sync::broadcast::Receiver<()> { + let ecs = self.ecs.lock(); + let tick_broadcast = ecs.resource::<TickBroadcast>(); + tick_broadcast.subscribe() + } + + async fn mine(&mut self, position: BlockPos) { + self.start_mining(position); + // vanilla sends an extra swing arm packet when we start mining + self.ecs.lock().send_event(SwingArmEvent { + entity: self.entity, + }); + + let mut receiver = self.get_tick_broadcaster(); + while receiver.recv().await.is_ok() { + let ecs = self.ecs.lock(); + if ecs.get::<Mining>(self.entity).is_none() { + break; + } + } + } } /// Event to jump once. diff --git a/azalea/src/container.rs b/azalea/src/container.rs index dc0ba169..2261469d 100644 --- a/azalea/src/container.rs +++ b/azalea/src/container.rs @@ -3,7 +3,7 @@ use std::fmt::Formatter; use azalea_client::{ inventory::{CloseContainerEvent, ContainerClickEvent, InventoryComponent}, packet_handling::PacketEvent, - Client, TickBroadcast, + Client, }; use azalea_core::BlockPos; use azalea_inventory::{operations::ClickOperation, ItemSlot, Menu}; @@ -12,6 +12,8 @@ use bevy_app::{App, Plugin, Update}; use bevy_ecs::{component::Component, prelude::EventReader, system::Commands}; use std::fmt::Debug; +use crate::bot::BotClientExt; + pub struct ContainerPlugin; impl Plugin for ContainerPlugin { fn build(&self, app: &mut App) { @@ -49,11 +51,7 @@ impl ContainerClientExt for Client { .insert(WaitingForInventoryOpen); self.block_interact(pos); - let mut receiver = { - let ecs = self.ecs.lock(); - let tick_broadcast = ecs.resource::<TickBroadcast>(); - tick_broadcast.subscribe() - }; + let mut receiver = self.get_tick_broadcaster(); while receiver.recv().await.is_ok() { let ecs = self.ecs.lock(); if ecs.get::<WaitingForInventoryOpen>(self.entity).is_none() { diff --git a/azalea/src/lib.rs b/azalea/src/lib.rs index 297199a0..0aff2a56 100644 --- a/azalea/src/lib.rs +++ b/azalea/src/lib.rs @@ -6,7 +6,6 @@ mod auto_respawn; mod bot; mod container; -pub mod mining; pub mod pathfinder; pub mod prelude; pub mod swarm; diff --git a/azalea/src/mining.rs b/azalea/src/mining.rs deleted file mode 100644 index 8ba16436..00000000 --- a/azalea/src/mining.rs +++ /dev/null @@ -1,40 +0,0 @@ -use azalea_client::{ - interact::SwingArmEvent, - mining::{Mining, StartMiningBlockEvent}, - Client, TickBroadcast, -}; -use azalea_core::BlockPos; - -pub trait MiningExt { - /// Start mining a block. - async fn mine(&mut self, position: BlockPos); -} - -impl MiningExt for Client { - /// Start mining a block. This won't turn the bot's head towards the block, - /// so you'll have to do that yourself with [`look_at`]. - /// - /// [`look_at`]: crate::prelude::BotClientExt::look_at - async fn mine(&mut self, position: BlockPos) { - self.ecs.lock().send_event(StartMiningBlockEvent { - entity: self.entity, - position, - }); - // vanilla sends an extra swing arm packet when we start mining - self.ecs.lock().send_event(SwingArmEvent { - entity: self.entity, - }); - - let mut receiver = { - let ecs = self.ecs.lock(); - let tick_broadcast = ecs.resource::<TickBroadcast>(); - tick_broadcast.subscribe() - }; - while receiver.recv().await.is_ok() { - let ecs = self.ecs.lock(); - if ecs.get::<Mining>(self.entity).is_none() { - break; - } - } - } -} diff --git a/azalea/src/prelude.rs b/azalea/src/prelude.rs index ff3c11de..87cb0b53 100644 --- a/azalea/src/prelude.rs +++ b/azalea/src/prelude.rs @@ -2,8 +2,8 @@ //! re-exported here. pub use crate::{ - bot::BotClientExt, container::ContainerClientExt, mining::MiningExt, - pathfinder::PathfinderClientExt, ClientBuilder, + bot::BotClientExt, container::ContainerClientExt, pathfinder::PathfinderClientExt, + ClientBuilder, }; pub use azalea_client::{Account, Client, Event}; // this is necessary to make the macros that reference bevy_ecs work |
