mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 14:26:04 +00:00
try to add a .entity_by function
still doesn't work because i want to make the predicate magic
This commit is contained in:
parent
3dc910f079
commit
9e4e417e50
6 changed files with 85 additions and 29 deletions
|
@ -37,13 +37,14 @@ use azalea_world::{
|
|||
};
|
||||
use bevy_app::App;
|
||||
use bevy_ecs::{
|
||||
query::WorldQuery,
|
||||
query::{ReadOnlyWorldQuery, WorldQuery},
|
||||
schedule::{IntoSystemDescriptor, Schedule, Stage, SystemSet},
|
||||
world::EntityRef,
|
||||
};
|
||||
use bevy_time::TimePlugin;
|
||||
use iyes_loopless::prelude::*;
|
||||
use log::{debug, error};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use parking_lot::{Mutex, MutexGuard, RwLock};
|
||||
use std::{fmt::Debug, io, net::SocketAddr, ops::DerefMut, sync::Arc, time::Duration};
|
||||
use thiserror::Error;
|
||||
use tokio::{sync::mpsc, time};
|
||||
|
@ -476,16 +477,6 @@ impl Client {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// A convenience function for getting components of our player's entity.
|
||||
pub fn query<'w, Q: WorldQuery>(
|
||||
&self,
|
||||
ecs: &'w mut bevy_ecs::world::World,
|
||||
) -> <Q as WorldQuery>::Item<'w> {
|
||||
ecs.query::<Q>()
|
||||
.get_mut(ecs, self.entity)
|
||||
.expect("Our client is missing a required component.")
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
|
57
azalea-client/src/entity_query.rs
Normal file
57
azalea-client/src/entity_query.rs
Normal file
|
@ -0,0 +1,57 @@
|
|||
use azalea_world::entity::Entity;
|
||||
use bevy_ecs::query::{ReadOnlyWorldQuery, WorldQuery};
|
||||
|
||||
use crate::Client;
|
||||
|
||||
impl Client {
|
||||
/// A convenience function for getting components of our player's entity.
|
||||
pub fn query<'w, Q: WorldQuery>(
|
||||
&self,
|
||||
ecs: &'w mut bevy_ecs::world::World,
|
||||
) -> <Q as WorldQuery>::Item<'w> {
|
||||
ecs.query::<Q>()
|
||||
.get_mut(ecs, self.entity)
|
||||
.expect("Our client is missing a required component.")
|
||||
}
|
||||
|
||||
/// Return a lightweight [`Entity`] for the entity that matches the given
|
||||
/// predicate function.
|
||||
///
|
||||
/// You can then use [`Self::map_entity`] to get components from this
|
||||
/// entity.
|
||||
pub fn entity_by<'a, F: ReadOnlyWorldQuery, Q: ReadOnlyWorldQuery>(
|
||||
&mut self,
|
||||
mut predicate: impl EntityPredicate<'a, Q>,
|
||||
) -> Option<Entity> {
|
||||
let mut ecs = self.ecs.lock();
|
||||
let mut query = ecs.query_filtered::<(Entity, Q), F>();
|
||||
let entity = query
|
||||
.iter_mut(&mut ecs)
|
||||
.find(|(_, q)| predicate.matches(q))
|
||||
.map(|(entity, _)| entity);
|
||||
entity
|
||||
}
|
||||
}
|
||||
|
||||
pub trait EntityPredicate<'a, Q: ReadOnlyWorldQuery> {
|
||||
fn matches(&self, components: &<Q as WorldQuery>::Item<'a>) -> bool;
|
||||
}
|
||||
impl<'a, F, Q> EntityPredicate<'a, Q> for F
|
||||
where
|
||||
F: Fn(Q) -> bool,
|
||||
Q: ReadOnlyWorldQuery,
|
||||
{
|
||||
fn matches(&self, query: &<Q as WorldQuery>::Item<'a>) -> bool {
|
||||
(self)(query)
|
||||
}
|
||||
}
|
||||
// impl<'a, F, Q1, Q2> EntityPredicate<'a, (Q1, Q2)> for F
|
||||
// where
|
||||
// F: Fn(Q1, Q2) -> bool,
|
||||
// Q1: WorldQuery<Item<'a> = Q1>,
|
||||
// Q2: WorldQuery<Item<'a> = Q2>,
|
||||
// {
|
||||
// fn matches(&self, query: <(Q1, Q2) as WorldQuery>::Item<'_>) -> bool {
|
||||
// (self)(query.0, query.1)
|
||||
// }
|
||||
// }
|
|
@ -13,6 +13,7 @@
|
|||
mod account;
|
||||
mod chat;
|
||||
mod client;
|
||||
mod entity_query;
|
||||
mod get_mc_dir;
|
||||
mod local_player;
|
||||
mod movement;
|
||||
|
@ -22,6 +23,7 @@ mod player;
|
|||
mod plugins;
|
||||
|
||||
pub use account::Account;
|
||||
pub use bevy_ecs as ecs;
|
||||
pub use client::{start_ecs, ChatPacket, Client, ClientInformation, Event, JoinError};
|
||||
pub use local_player::LocalPlayer;
|
||||
pub use movement::{SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection};
|
||||
|
|
|
@ -46,12 +46,16 @@ async fn swarm_handle(
|
|||
) -> anyhow::Result<()> {
|
||||
match event {
|
||||
SwarmEvent::Tick => {
|
||||
// choose an arbitrary player within render distance to target
|
||||
if let Some(target) = swarm.worlds.read().entity_by(|_: &Player| true) {
|
||||
if let Some(target_entity) =
|
||||
swarm.entity_by::<Player>(|name: &Name| name == "Herobrine")
|
||||
{
|
||||
let target_bounding_box =
|
||||
swarm.map_entity(target_entity, |bb: &BoundingBox| bb.clone());
|
||||
|
||||
for (bot, bot_state) in swarm {
|
||||
bot.tick_goto_goal(pathfinder::Goals::Reach(target.bounding_box));
|
||||
bot.tick_goto_goal(pathfinder::Goals::Reach(target_bounding_box));
|
||||
// if target.bounding_box.distance(bot.eyes) < bot.reach_distance() {
|
||||
if azalea::entities::can_reach(bot.entity(), target.bounding_box) {
|
||||
if azalea::entities::can_reach(bot.entity(), target_bounding_box) {
|
||||
bot.swing();
|
||||
}
|
||||
if !bot.using_held_item() && bot.hunger() <= 17 {
|
||||
|
|
|
@ -16,7 +16,7 @@ use log::error;
|
|||
use parking_lot::{Mutex, RwLock};
|
||||
use std::{future::Future, net::SocketAddr, sync::Arc, time::Duration};
|
||||
use thiserror::Error;
|
||||
use tokio::sync::mpsc::{self, UnboundedSender};
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
/// A helper macro that generates a [`SwarmPlugins`] struct from a list of
|
||||
/// objects that implement [`SwarmPlugin`].
|
||||
|
@ -57,10 +57,10 @@ pub struct Swarm<S> {
|
|||
/// Plugins that are set for new bots
|
||||
plugins: Plugins,
|
||||
|
||||
bots_tx: UnboundedSender<(Option<Event>, (Client, S))>,
|
||||
swarm_tx: UnboundedSender<SwarmEvent>,
|
||||
bots_tx: mpsc::UnboundedSender<(Option<Event>, (Client, S))>,
|
||||
swarm_tx: mpsc::UnboundedSender<SwarmEvent>,
|
||||
|
||||
run_schedule_sender: UnboundedSender<()>,
|
||||
run_schedule_sender: mpsc::Sender<()>,
|
||||
}
|
||||
|
||||
/// An event about something that doesn't have to do with a single bot.
|
||||
|
@ -239,7 +239,7 @@ pub async fn start_swarm<
|
|||
let (bots_tx, mut bots_rx) = mpsc::unbounded_channel();
|
||||
let (swarm_tx, mut swarm_rx) = mpsc::unbounded_channel();
|
||||
|
||||
let (run_schedule_sender, run_schedule_receiver) = mpsc::unbounded_channel();
|
||||
let (run_schedule_sender, run_schedule_receiver) = mpsc::channel(1);
|
||||
let ecs_lock = start_ecs(run_schedule_receiver, run_schedule_sender.clone());
|
||||
|
||||
let mut swarm = Swarm {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use azalea::ecs::query::With;
|
||||
use azalea::entity::metadata::Player;
|
||||
use azalea::pathfinder::BlockPosGoal;
|
||||
// use azalea::ClientInformation;
|
||||
|
@ -92,13 +93,14 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result<
|
|||
return Ok(())
|
||||
};
|
||||
let mut ecs = bot.ecs.lock();
|
||||
let entity = bot
|
||||
.ecs
|
||||
.lock()
|
||||
.query::<&Player>()
|
||||
.iter(&mut ecs)
|
||||
.find(|e| e.name() == Some(sender));
|
||||
// let entity = None;
|
||||
// let entity = bot
|
||||
// .ecs
|
||||
// .lock()
|
||||
// .query::<&Player>()
|
||||
// .iter(&mut ecs)
|
||||
// .find(|e| e.name() == Some(sender));
|
||||
// let entity = bot.entity_by::<With<Player>>(|name: &Name| name == sender);
|
||||
let entity = bot.entity_by(|name: &Name| name == sender);
|
||||
if let Some(entity) = entity {
|
||||
if m.content() == "goto" {
|
||||
let target_pos_vec3 = entity.pos();
|
||||
|
@ -108,7 +110,7 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result<
|
|||
let target_pos_vec3 = entity.pos();
|
||||
let target_pos: BlockPos = target_pos_vec3.into();
|
||||
println!("target_pos: {:?}", target_pos);
|
||||
bot.look_at(&target_pos.center());
|
||||
bot.look_at(target_pos.center());
|
||||
} else if m.content() == "jump" {
|
||||
bot.set_jumping(true);
|
||||
} else if m.content() == "walk" {
|
||||
|
|
Loading…
Add table
Reference in a new issue