From 8921ae4887c2fdf1858a720e9d1fd9a626b8e734 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 20 Jan 2023 17:57:09 +0000 Subject: [PATCH] try to make entity_by work well it does work but i couldn't figure out how to make it look not terrible. Will hopefully change in the future --- azalea-client/src/entity_query.rs | 81 ++++++++++++++++++------------- azalea-client/src/lib.rs | 1 + bot/src/main.rs | 46 ++++++++++-------- 3 files changed, 73 insertions(+), 55 deletions(-) diff --git a/azalea-client/src/entity_query.rs b/azalea-client/src/entity_query.rs index fad92a07..32608d1b 100644 --- a/azalea-client/src/entity_query.rs +++ b/azalea-client/src/entity_query.rs @@ -1,5 +1,11 @@ +use std::sync::Arc; + use azalea_world::entity::Entity; -use bevy_ecs::query::{ReadOnlyWorldQuery, WorldQuery}; +use bevy_ecs::{ + prelude::Component, + query::{QueryItem, ROQueryItem, ReadOnlyWorldQuery, WorldQuery}, +}; +use parking_lot::Mutex; use crate::Client; @@ -14,44 +20,51 @@ impl Client { .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 { - // 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 - // } + /// 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( + &mut self, + predicate: impl EntityPredicate, + ) -> Option { + predicate.find(self.ecs.clone()) + } } -pub trait EntityPredicate<'a, Q: ReadOnlyWorldQuery> { - fn matches(&self, components: &::Item<'a>) -> bool; +pub trait EntityPredicate { + fn find(&self, ecs_lock: Arc>) -> Option; } -// impl<'a, F, Q> EntityPredicate<'a, Q> for F -// where -// F: Fn(Q) -> bool, -// Q: ReadOnlyWorldQuery, -// { -// fn matches(&self, query: &::Item<'a>) -> bool { -// (self)(query) -// } -// } +impl<'a, F, Q, Filter> EntityPredicate<(Q,), Filter> for F +where + F: Fn(&ROQueryItem) -> bool, + Q: ReadOnlyWorldQuery, + Filter: ReadOnlyWorldQuery, +{ + fn find(&self, ecs_lock: Arc>) -> Option { + let mut ecs = ecs_lock.lock(); + let mut query = ecs.query_filtered::<(Entity, Q), Filter>(); + let entity = query.iter(&ecs).find(|(_, q)| (self)(q)).map(|(e, _)| e); + + entity.clone() + } +} + // impl<'a, F, Q1, Q2> EntityPredicate<'a, (Q1, Q2)> for F // where -// F: Fn(Q1, Q2) -> bool, -// Q1: WorldQuery = Q1>, -// Q2: WorldQuery = Q2>, +// F: Fn(&::Item<'_>, &::Item<'_>) -> +// bool, Q1: ReadOnlyWorldQuery, +// Q2: ReadOnlyWorldQuery, // { -// fn matches(&self, query: <(Q1, Q2) as WorldQuery>::Item<'_>) -> bool { -// (self)(query.0, query.1) +// fn find(&self, ecs: &mut bevy_ecs::world::World) -> Option { +// // (self)(query) +// let mut query = ecs.query_filtered::<(Entity, Q1, Q2), ()>(); +// let entity = query +// .iter(ecs) +// .find(|(_, q1, q2)| (self)(q1, q2)) +// .map(|(e, _, _)| e); + +// entity // } // } diff --git a/azalea-client/src/lib.rs b/azalea-client/src/lib.rs index ce430a10..e51be11d 100644 --- a/azalea-client/src/lib.rs +++ b/azalea-client/src/lib.rs @@ -9,6 +9,7 @@ #![allow(incomplete_features)] #![feature(trait_upcasting)] #![feature(error_generic_member_access)] +#![feature(type_alias_impl_trait)] mod account; mod chat; diff --git a/bot/src/main.rs b/bot/src/main.rs index 0a30803f..700253cf 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -1,5 +1,8 @@ +#![feature(type_alias_impl_trait)] + use azalea::ecs::query::With; use azalea::entity::metadata::Player; +use azalea::entity::Position; use azalea::pathfinder::BlockPosGoal; // use azalea::ClientInformation; use azalea::{prelude::*, BlockPos, Swarm, SwarmEvent, WalkDirection}; @@ -92,7 +95,7 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result< let Some(sender) = m.username() else { return Ok(()) }; - let mut ecs = bot.ecs.lock(); + // let mut ecs = bot.ecs.lock(); // let entity = bot // .ecs // .lock() @@ -100,27 +103,28 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result< // .iter(&mut ecs) // .find(|e| e.name() == Some(sender)); // let entity = bot.entity_by::>(|name: &Name| name == sender); - let entity = bot.entity_by(|name: &Name| name == sender); + // let entity = bot.entity_by(|name: &Name| name == sender); + let entity = bot.entity_by::, (&Position,)>(|pos: &&Position| true); if let Some(entity) = entity { - if m.content() == "goto" { - let target_pos_vec3 = entity.pos(); - let target_pos: BlockPos = target_pos_vec3.into(); - bot.goto(BlockPosGoal::from(target_pos)); - } else if m.content() == "look" { - 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()); - } else if m.content() == "jump" { - bot.set_jumping(true); - } else if m.content() == "walk" { - bot.walk(WalkDirection::Forward); - } else if m.content() == "stop" { - bot.set_jumping(false); - bot.walk(WalkDirection::None); - } else if m.content() == "lag" { - std::thread::sleep(Duration::from_millis(1000)); - } + // if m.content() == "goto" { + // let target_pos_vec3 = entity.pos(); + // let target_pos: BlockPos = target_pos_vec3.into(); + // bot.goto(BlockPosGoal::from(target_pos)); + // } else if m.content() == "look" { + // 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()); + // } else if m.content() == "jump" { + // bot.set_jumping(true); + // } else if m.content() == "walk" { + // bot.walk(WalkDirection::Forward); + // } else if m.content() == "stop" { + // bot.set_jumping(false); + // bot.walk(WalkDirection::None); + // } else if m.content() == "lag" { + // std::thread::sleep(Duration::from_millis(1000)); + // } } } Event::Death(_) => {