improve docs a bit more and delete potatobot example

This commit is contained in:
Ubuntu 2023-02-10 18:19:06 +00:00
parent f5ae1b9717
commit 758372f938
8 changed files with 12 additions and 133 deletions

View file

@ -73,7 +73,7 @@ async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> {
# Swarms
Azalea lets you create "swarms", which are a group of bots in the same world that can perform actions together. See [testbot](https://github.com/mat-1/azalea/blob/main/azalea/examples/testbot.rs) for an example.
Azalea lets you create "swarms", which are a group of bots in the same world that can perform actions together. See [testbot](https://github.com/mat-1/azalea/blob/main/azalea/examples/testbot.rs) for an example. Also, if you're using swarms, you should also have both `azalea::prelude::*` and `azalea::swarm::prelude::*`.
# Plugins

View file

@ -1,4 +1,4 @@
use azalea::prelude::*;
use azalea::{prelude::*, swarm::prelude::*};
#[tokio::main]
async fn main() {
@ -10,7 +10,7 @@ async fn main() {
states.push(State::default());
}
let e = azalea::SwarmBuilder::new()
let e = SwarmBuilder::new()
.add_accounts(accounts.clone())
.set_handler(handle)
.set_swarm_handler(swarm_handle)

View file

@ -1,24 +0,0 @@
A relatively complex bot for farming potatoes.
Note: At the moment, all of the code here is only hypothetical. I decided to write this to help me decide how I want some the APIs to look.
## Attempted
- Sync: a sync function is called with the state and bot every time we get an event, and the function can queue events to execute at the end of the tick
Pros: No .lock().unwrap() necessary, and theoretically pausable by saving the state.
Cons: Async functions like opening containers and pathfinding are annoying because you have to keep state for them, and the code generally ends up being more confusing.
- Async non-blocking: an async function is called in a new task with the state mutex and bot every time we get an event
Pros: Easier to do async stuff like interacting with containers, code is somewhat easier to understand
Cons: Lock spam everywhere is annoying, and you have to make sure stuff doesn't accidentally run in parallel.
## Considered:
(I didn't actually try this because the problems were apparent)
- Async blocking: an async function is called with the state and bot every time we get an event, and only handles the next event when this one finishes running
Pros: No lock spam
Cons: Sometimes you want to handle multiple events at once like eating if you get hungry while pathfinding, this makes it harder without increasing complexity

View file

@ -1,31 +0,0 @@
//! Automatically eat when we get hungry.
use async_trait::async_trait;
use azalea::prelude::*;
use azalea::{Client, Event};
use parking_lot::Mutex;
use std::sync::Arc;
#[derive(Default, Clone)]
pub struct Plugin {
pub state: State,
}
#[derive(Default, Clone, Component)]
pub struct State {}
#[async_trait]
impl azalea::PluginState for Plugin {
async fn handle(self: Box<Self>, event: Event, bot: Client) {
match event {
Event::UpdateHunger => {
if !bot.using_held_item() && bot.food_level() <= 17 {
if bot.hold(azalea::ItemGroup::Food).await {
bot.use_held_item().await;
}
}
}
_ => {}
}
}
}

View file

@ -1,69 +0,0 @@
mod autoeat;
use azalea::prelude::*;
use azalea::{pathfinder, BlockPos, ItemKind, Vec3};
#[derive(Default, Clone)]
struct State {}
#[tokio::main]
async fn main() {
env_logger::init();
let account = Account::offline("bot");
azalea::start(azalea::Options {
account,
address: "localhost",
state: State::default(),
plugins: plugins![autoeat::Plugin, pathfinder::Plugin],
handle,
})
.await
.unwrap();
}
async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> {
match event {
Event::Login => {
goto_farm(bot, state).await?;
// after we get to the farm, start farming
farm(bot, state).await?;
}
_ => {}
}
Ok(())
}
// go to the place where we start farming
async fn goto_farm(bot: Client, state: State) -> anyhow::Result<()> {
bot.goto(pathfinder::Goals::Near(5, BlockPos::new(0, 70, 0)))
.await?;
Ok(())
}
// go to the chest and deposit everything in our inventory.
async fn deposit(bot: &mut Client, state: State) -> anyhow::Result<()> {
// first throw away any garbage we might have
bot.toss(|item| item.kind != ItemKind::Potato && item.kind != ItemKind::DiamondHoe);
bot.goto(Vec3::new(0, 70, 0)).await?;
let chest = bot
.open_container(&bot.world.block_at(BlockPos::new(0, 70, 0)))
.await
.unwrap();
let inventory_potato_count: usize = bot
.inventory()
.count_total(|item| item.kind == ItemKind::Potato);
if inventory_potato_count > 64 {
chest
.deposit_total_count(
|item| item.kind == azalea::ItemKind::Potato,
inventory_potato_count - 64,
)
.await;
}
chest.close().await;
Ok(())
}

View file

@ -1,8 +1,8 @@
use std::time::Duration;
use azalea::entity::metadata::Player;
use azalea::{pathfinder, Account, Client, Event, GameProfileComponent, SwarmEvent};
use azalea::{prelude::*, Swarm};
use azalea::{pathfinder, Account, Client, Event, GameProfileComponent};
use azalea::{prelude::*, swarm::prelude::*};
use azalea_ecs::query::With;
#[tokio::main]
@ -25,10 +25,10 @@ async fn main() {
.unwrap();
}
#[derive(Default, Clone)]
#[derive(Component, Default, Clone)]
struct State {}
#[derive(Default, Clone)]
#[derive(Resource, Default, Clone)]
struct SwarmState {}
async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> {

View file

@ -29,7 +29,7 @@ use tokio::sync::mpsc;
/// A swarm is a way to conveniently control many bots at once, while also
/// being able to control bots at an individual level when desired.
///
/// Swarms are created from [`azalea::SwarmBuilder`].
/// Swarms are created from [`azalea::swarm::SwarmBuilder`].
///
/// The `S` type parameter is the type of the state for individual bots.
/// It's used to make the [`Swarm::add`] function work.

View file

@ -0,0 +1,3 @@
//! A prelude that re-exports common swarm types in Azalea.
pub use crate::swarm::{Swarm, SwarmBuilder, SwarmEvent};