1
2
Fork 0
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:
mat 2023-01-16 22:58:20 -06:00
parent 3dc910f079
commit 9e4e417e50
6 changed files with 85 additions and 29 deletions

View file

@ -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)]

View 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)
// }
// }

View file

@ -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};

View file

@ -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 {

View file

@ -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 {

View file

@ -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" {