From 5dd35c7ed82c38ef36ca28f630e8d05c5db2cbea Mon Sep 17 00:00:00 2001 From: mat <27899617+mat-1@users.noreply.github.com> Date: Tue, 7 Mar 2023 22:09:56 -0600 Subject: Add World::find_block (#80) * start adding World::find_block * keep working on find_block * BlockStates * fix sorting * update examples that use find_one_block * azalea_block::properties * fix tests * add a gotoblock command to testbot --- azalea/examples/craft_dig_straight_down.rs | 79 ------------------------- azalea/examples/mine_a_chunk.rs | 53 ----------------- azalea/examples/pvp.rs | 65 -------------------- azalea/examples/testbot.rs | 37 +++++++++--- azalea/examples/todo/README.md | 1 + azalea/examples/todo/craft_dig_straight_down.rs | 78 ++++++++++++++++++++++++ azalea/examples/todo/mine_a_chunk.rs | 53 +++++++++++++++++ azalea/examples/todo/pvp.rs | 65 ++++++++++++++++++++ 8 files changed, 225 insertions(+), 206 deletions(-) delete mode 100755 azalea/examples/craft_dig_straight_down.rs delete mode 100644 azalea/examples/mine_a_chunk.rs delete mode 100755 azalea/examples/pvp.rs create mode 100644 azalea/examples/todo/README.md create mode 100644 azalea/examples/todo/craft_dig_straight_down.rs create mode 100644 azalea/examples/todo/mine_a_chunk.rs create mode 100644 azalea/examples/todo/pvp.rs (limited to 'azalea/examples') diff --git a/azalea/examples/craft_dig_straight_down.rs b/azalea/examples/craft_dig_straight_down.rs deleted file mode 100755 index 0632776e..00000000 --- a/azalea/examples/craft_dig_straight_down.rs +++ /dev/null @@ -1,79 +0,0 @@ -use azalea::pathfinder; -use azalea::prelude::*; -use parking_lot::Mutex; -use std::sync::Arc; - -#[derive(Default, Clone, Component)] -struct State { - pub started: Arc>, -} - -#[tokio::main] -async fn main() { - let account = Account::offline("bot"); - // or let bot = Account::microsoft("email").await; - - azalea::ClientBuilder::new() - .set_handler(handle) - .start(account, "localhost") - .await - .unwrap(); -} - -async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> { - match event { - Event::Chat(m) => { - if m.username() == Some(bot.profile.name) { - return Ok(()); - }; - if m.content() == "go" { - { - // make sure we only start once - if *state.started.lock() { - return Ok(()); - }; - *state.started.lock() = true; - } - - bot.goto(pathfinder::Goals::NearXZ(5, azalea::BlockXZ(0, 0))) - .await; - let chest = bot - .open_container(&bot.world().find_one_block(|b| b.id == "minecraft:chest")) - .await - .unwrap(); - bot.take_amount(&chest, 5, |i| i.id == "#minecraft:planks") - .await; - chest.close().await; - - let crafting_table = bot - .open_crafting_table( - &bot.world - .find_one_block(|b| b.id == "minecraft:crafting_table"), - ) - .await - .unwrap(); - bot.craft(&crafting_table, &bot.recipe_for("minecraft:sticks")) - .await?; - let pickaxe = bot - .craft(&crafting_table, &bot.recipe_for("minecraft:wooden_pickaxe")) - .await?; - crafting_table.close().await; - - bot.hold(&pickaxe); - - loop { - if let Err(e) = bot - .dig(azalea::entity::feet_pos(bot.entity()).down(1)) - .await - { - println!("{:?}", e); - break; - } - } - } - } - _ => {} - } - - Ok(()) -} diff --git a/azalea/examples/mine_a_chunk.rs b/azalea/examples/mine_a_chunk.rs deleted file mode 100644 index 74ffacac..00000000 --- a/azalea/examples/mine_a_chunk.rs +++ /dev/null @@ -1,53 +0,0 @@ -use azalea::{prelude::*, swarm::prelude::*}; - -#[tokio::main] -async fn main() { - let mut accounts = Vec::new(); - let mut states = Vec::new(); - - for i in 0..10 { - accounts.push(Account::offline(&format!("bot{i}"))); - states.push(State::default()); - } - - let e = SwarmBuilder::new() - .add_accounts(accounts.clone()) - .set_handler(handle) - .set_swarm_handler(swarm_handle) - .start("localhost") - .await; -} - -#[derive(Default, Clone, Component)] -struct State {} - -#[derive(Default, Clone, Resource)] -struct SwarmState {} - -async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> { - Ok(()) -} - -async fn swarm_handle(swarm: Swarm, event: SwarmEvent, state: SwarmState) -> anyhow::Result<()> { - match &event { - SwarmEvent::Login => { - swarm.goto(azalea::BlockPos::new(0, 70, 0)).await; - // or bots.goto_goal(pathfinder::Goals::Goto(azalea::BlockPos(0, 70, 0))).await; - - // destroy the blocks in this area and then leave - - swarm - .fill( - azalea::Selection::Range( - azalea::BlockPos::new(0, 0, 0), - azalea::BlockPos::new(16, 255, 16), - ), - azalea::block::Air, - ) - .await; - } - _ => {} - } - - Ok(()) -} diff --git a/azalea/examples/pvp.rs b/azalea/examples/pvp.rs deleted file mode 100755 index fb5a768d..00000000 --- a/azalea/examples/pvp.rs +++ /dev/null @@ -1,65 +0,0 @@ -use std::time::Duration; - -use azalea::ecs::query::With; -use azalea::entity::metadata::Player; -use azalea::{pathfinder, Account, Client, Event, GameProfileComponent}; -use azalea::{prelude::*, swarm::prelude::*}; - -#[tokio::main] -async fn main() { - let mut accounts = Vec::new(); - let mut states = Vec::new(); - - for i in 0..10 { - accounts.push(Account::offline(&format!("bot{i}"))); - states.push(State::default()); - } - - SwarmBuilder::new() - .add_accounts(accounts.clone()) - .set_handler(handle) - .set_swarm_handler(swarm_handle) - .join_delay(Duration::from_millis(1000)) - .start("localhost") - .await - .unwrap(); -} - -#[derive(Component, Default, Clone)] -struct State {} - -#[derive(Resource, Default, Clone)] -struct SwarmState {} - -async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> { - Ok(()) -} -async fn swarm_handle(swarm: Swarm, event: SwarmEvent, state: SwarmState) -> anyhow::Result<()> { - match event { - SwarmEvent::Tick => { - if let Some(target_entity) = - swarm.entity_by::>(|profile: &&GameProfileComponent| { - profile.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)); - // if target.bounding_box.distance(bot.eyes) < bot.reach_distance() { - if azalea::entities::can_reach(bot.entity(), target_bounding_box) { - bot.swing(); - } - if !bot.using_held_item() && bot.hunger() <= 17 { - bot.hold(azalea::ItemGroup::Food); - tokio::task::spawn(bot.use_held_item()); - } - } - } - } - _ => {} - } - - Ok(()) -} diff --git a/azalea/examples/testbot.rs b/azalea/examples/testbot.rs index 7b7b32b0..a25b28e3 100644 --- a/azalea/examples/testbot.rs +++ b/azalea/examples/testbot.rs @@ -52,17 +52,17 @@ async fn main() -> anyhow::Result<()> { } loop { - // let e = SwarmBuilder::new() - // .add_accounts(accounts.clone()) - // .set_handler(handle) - // .set_swarm_handler(swarm_handle) - // .join_delay(Duration::from_millis(1000)) - // .start("localhost") - // .await; - let e = azalea::ClientBuilder::new() + let e = SwarmBuilder::new() + .add_accounts(accounts.clone()) .set_handler(handle) - .start(Account::offline("bot"), "localhost") + .set_swarm_handler(swarm_handle) + .join_delay(Duration::from_millis(1000)) + .start("localhost") .await; + // let e = azalea::ClientBuilder::new() + // .set_handler(handle) + // .start(Account::offline("bot"), "localhost") + // .await; eprintln!("{e:?}"); } } @@ -140,6 +140,25 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result< "lag" => { std::thread::sleep(Duration::from_millis(1000)); } + "findblock" => { + let target_pos = bot.world().read().find_block( + bot.component::(), + &azalea_registry::Block::DiamondBlock.into(), + ); + bot.chat(&format!("target_pos: {target_pos:?}",)); + } + "gotoblock" => { + let target_pos = bot.world().read().find_block( + bot.component::(), + &azalea_registry::Block::DiamondBlock.into(), + ); + if let Some(target_pos) = target_pos { + // +1 to stand on top of the block + bot.goto(BlockPosGoal::from(target_pos.up(1))); + } else { + bot.chat("no diamond block found"); + } + } _ => {} } } diff --git a/azalea/examples/todo/README.md b/azalea/examples/todo/README.md new file mode 100644 index 00000000..ab31cf22 --- /dev/null +++ b/azalea/examples/todo/README.md @@ -0,0 +1 @@ +These examples don't work yet and were only written to help design APIs. They will work in the future (probably with minor changes). diff --git a/azalea/examples/todo/craft_dig_straight_down.rs b/azalea/examples/todo/craft_dig_straight_down.rs new file mode 100644 index 00000000..4c980ccf --- /dev/null +++ b/azalea/examples/todo/craft_dig_straight_down.rs @@ -0,0 +1,78 @@ +use azalea::pathfinder; +use azalea::prelude::*; +use parking_lot::Mutex; +use std::sync::Arc; + +#[derive(Default, Clone, Component)] +struct State { + pub started: Arc>, +} + +#[tokio::main] +async fn main() { + let account = Account::offline("bot"); + // or let bot = Account::microsoft("email").await; + + azalea::ClientBuilder::new() + .set_handler(handle) + .start(account, "localhost") + .await + .unwrap(); +} + +async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> { + match event { + Event::Chat(m) => { + if m.username() == Some(bot.profile.name) { + return Ok(()); + }; + if m.content() == "go" { + { + // make sure we only start once + if *state.started.lock() { + return Ok(()); + }; + *state.started.lock() = true; + } + + bot.goto(pathfinder::Goals::NearXZ(5, azalea::BlockXZ(0, 0))) + .await; + let chest = bot + .open_container(&bot.world().find_block(azalea_registry::Block::Chest)) + .await + .unwrap(); + bot.take_amount(&chest, 5, |i| i.id == "#minecraft:planks") + .await; + chest.close().await; + + let crafting_table = bot + .open_crafting_table( + &bot.world.find_block(azalea_registry::Block::CraftingTable), + ) + .await + .unwrap(); + bot.craft(&crafting_table, &bot.recipe_for("minecraft:sticks")) + .await?; + let pickaxe = bot + .craft(&crafting_table, &bot.recipe_for("minecraft:wooden_pickaxe")) + .await?; + crafting_table.close().await; + + bot.hold(&pickaxe); + + loop { + if let Err(e) = bot + .dig(azalea::entity::feet_pos(bot.entity()).down(1)) + .await + { + println!("{:?}", e); + break; + } + } + } + } + _ => {} + } + + Ok(()) +} diff --git a/azalea/examples/todo/mine_a_chunk.rs b/azalea/examples/todo/mine_a_chunk.rs new file mode 100644 index 00000000..74ffacac --- /dev/null +++ b/azalea/examples/todo/mine_a_chunk.rs @@ -0,0 +1,53 @@ +use azalea::{prelude::*, swarm::prelude::*}; + +#[tokio::main] +async fn main() { + let mut accounts = Vec::new(); + let mut states = Vec::new(); + + for i in 0..10 { + accounts.push(Account::offline(&format!("bot{i}"))); + states.push(State::default()); + } + + let e = SwarmBuilder::new() + .add_accounts(accounts.clone()) + .set_handler(handle) + .set_swarm_handler(swarm_handle) + .start("localhost") + .await; +} + +#[derive(Default, Clone, Component)] +struct State {} + +#[derive(Default, Clone, Resource)] +struct SwarmState {} + +async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> { + Ok(()) +} + +async fn swarm_handle(swarm: Swarm, event: SwarmEvent, state: SwarmState) -> anyhow::Result<()> { + match &event { + SwarmEvent::Login => { + swarm.goto(azalea::BlockPos::new(0, 70, 0)).await; + // or bots.goto_goal(pathfinder::Goals::Goto(azalea::BlockPos(0, 70, 0))).await; + + // destroy the blocks in this area and then leave + + swarm + .fill( + azalea::Selection::Range( + azalea::BlockPos::new(0, 0, 0), + azalea::BlockPos::new(16, 255, 16), + ), + azalea::block::Air, + ) + .await; + } + _ => {} + } + + Ok(()) +} diff --git a/azalea/examples/todo/pvp.rs b/azalea/examples/todo/pvp.rs new file mode 100644 index 00000000..fb5a768d --- /dev/null +++ b/azalea/examples/todo/pvp.rs @@ -0,0 +1,65 @@ +use std::time::Duration; + +use azalea::ecs::query::With; +use azalea::entity::metadata::Player; +use azalea::{pathfinder, Account, Client, Event, GameProfileComponent}; +use azalea::{prelude::*, swarm::prelude::*}; + +#[tokio::main] +async fn main() { + let mut accounts = Vec::new(); + let mut states = Vec::new(); + + for i in 0..10 { + accounts.push(Account::offline(&format!("bot{i}"))); + states.push(State::default()); + } + + SwarmBuilder::new() + .add_accounts(accounts.clone()) + .set_handler(handle) + .set_swarm_handler(swarm_handle) + .join_delay(Duration::from_millis(1000)) + .start("localhost") + .await + .unwrap(); +} + +#[derive(Component, Default, Clone)] +struct State {} + +#[derive(Resource, Default, Clone)] +struct SwarmState {} + +async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> { + Ok(()) +} +async fn swarm_handle(swarm: Swarm, event: SwarmEvent, state: SwarmState) -> anyhow::Result<()> { + match event { + SwarmEvent::Tick => { + if let Some(target_entity) = + swarm.entity_by::>(|profile: &&GameProfileComponent| { + profile.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)); + // if target.bounding_box.distance(bot.eyes) < bot.reach_distance() { + if azalea::entities::can_reach(bot.entity(), target_bounding_box) { + bot.swing(); + } + if !bot.using_held_item() && bot.hunger() <= 17 { + bot.hold(azalea::ItemGroup::Food); + tokio::task::spawn(bot.use_held_item()); + } + } + } + } + _ => {} + } + + Ok(()) +} -- cgit v1.2.3