aboutsummaryrefslogtreecommitdiff
path: root/azalea/examples/testbot/commands
diff options
context:
space:
mode:
Diffstat (limited to 'azalea/examples/testbot/commands')
-rw-r--r--azalea/examples/testbot/commands/combat.rs26
-rw-r--r--azalea/examples/testbot/commands/debug.rs105
-rw-r--r--azalea/examples/testbot/commands/movement.rs191
3 files changed, 322 insertions, 0 deletions
diff --git a/azalea/examples/testbot/commands/combat.rs b/azalea/examples/testbot/commands/combat.rs
new file mode 100644
index 00000000..b440b3ac
--- /dev/null
+++ b/azalea/examples/testbot/commands/combat.rs
@@ -0,0 +1,26 @@
+use azalea::brigadier::prelude::*;
+use parking_lot::Mutex;
+
+use super::{CommandSource, Ctx};
+
+pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
+ commands.register(
+ literal("killaura").then(argument("enabled", bool()).executes(|ctx: &Ctx| {
+ let enabled = get_bool(ctx, "enabled").unwrap();
+ let source = ctx.source.lock();
+ let bot = source.bot.clone();
+ {
+ let mut ecs = bot.ecs.lock();
+ let mut entity = ecs.entity_mut(bot.entity);
+ let mut state = entity.get_mut::<crate::State>().unwrap();
+ state.killaura = enabled
+ }
+ source.reply(if enabled {
+ "Enabled killaura"
+ } else {
+ "Disabled killaura"
+ });
+ 1
+ })),
+ );
+}
diff --git a/azalea/examples/testbot/commands/debug.rs b/azalea/examples/testbot/commands/debug.rs
new file mode 100644
index 00000000..ae0808cb
--- /dev/null
+++ b/azalea/examples/testbot/commands/debug.rs
@@ -0,0 +1,105 @@
+//! Commands for debugging and getting the current state of the bot.
+
+use azalea::{
+ brigadier::prelude::*,
+ entity::{LookDirection, Position},
+ interact::HitResultComponent,
+ world::MinecraftEntityId,
+};
+use parking_lot::Mutex;
+
+use super::{CommandSource, Ctx};
+
+pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
+ commands.register(literal("ping").executes(|ctx: &Ctx| {
+ let source = ctx.source.lock();
+ source.reply("pong!");
+ 1
+ }));
+
+ commands.register(literal("whereami").executes(|ctx: &Ctx| {
+ let mut source = ctx.source.lock();
+ let Some(entity) = source.entity() else {
+ source.reply("You aren't in render distance!");
+ return 0;
+ };
+ let position = source.bot.entity_component::<Position>(entity);
+ source.reply(&format!(
+ "You are at {}, {}, {}",
+ position.x, position.y, position.z
+ ));
+ 1
+ }));
+
+ commands.register(literal("entityid").executes(|ctx: &Ctx| {
+ let mut source = ctx.source.lock();
+ let Some(entity) = source.entity() else {
+ source.reply("You aren't in render distance!");
+ return 0;
+ };
+ let entity_id = source.bot.entity_component::<MinecraftEntityId>(entity);
+ source.reply(&format!(
+ "Your Minecraft ID is {} and your ECS id is {entity:?}",
+ *entity_id
+ ));
+ 1
+ }));
+
+ let whereareyou = |ctx: &Ctx| {
+ let source = ctx.source.lock();
+ let position = source.bot.position();
+ source.reply(&format!(
+ "I'm at {}, {}, {}",
+ position.x, position.y, position.z
+ ));
+ 1
+ };
+ commands.register(literal("whereareyou").executes(whereareyou));
+ commands.register(literal("pos").executes(whereareyou));
+
+ commands.register(literal("whoareyou").executes(|ctx: &Ctx| {
+ let source = ctx.source.lock();
+ source.reply(&format!(
+ "I am {} ({})",
+ source.bot.username(),
+ source.bot.uuid()
+ ));
+ 1
+ }));
+
+ commands.register(literal("getdirection").executes(|ctx: &Ctx| {
+ let source = ctx.source.lock();
+ let direction = source.bot.component::<LookDirection>();
+ source.reply(&format!(
+ "I'm looking at {}, {}",
+ direction.y_rot, direction.x_rot
+ ));
+ 1
+ }));
+
+ commands.register(literal("health").executes(|ctx: &Ctx| {
+ let source = ctx.source.lock();
+
+ let health = source.bot.health();
+ source.reply(&format!("I have {health} health"));
+ 1
+ }));
+
+ commands.register(literal("lookingat").executes(|ctx: &Ctx| {
+ let source = ctx.source.lock();
+
+ let hit_result = *source.bot.component::<HitResultComponent>();
+
+ if hit_result.miss {
+ source.reply("I'm not looking at anything");
+ return 1;
+ }
+
+ let block_pos = hit_result.block_pos;
+ let block = source.bot.world().read().get_block_state(&block_pos);
+
+ source.reply(&format!("I'm looking at {block:?} at {block_pos:?}"));
+
+ 1
+ }));
+}
diff --git a/azalea/examples/testbot/commands/movement.rs b/azalea/examples/testbot/commands/movement.rs
new file mode 100644
index 00000000..4957533f
--- /dev/null
+++ b/azalea/examples/testbot/commands/movement.rs
@@ -0,0 +1,191 @@
+use std::time::Duration;
+
+use azalea::{
+ brigadier::prelude::*,
+ entity::{EyeHeight, Position},
+ pathfinder::goals::{BlockPosGoal, XZGoal},
+ prelude::*,
+ BlockPos, SprintDirection, WalkDirection,
+};
+use parking_lot::Mutex;
+
+use crate::BotTask;
+
+use super::{CommandSource, Ctx};
+
+pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
+ commands.register(
+ literal("goto")
+ .executes(|ctx: &Ctx| {
+ let mut source = ctx.source.lock();
+ println!("got goto");
+ // look for the sender
+ let Some(entity) = source.entity() else {
+ source.reply("I can't see you!");
+ return 0;
+ };
+ let Some(position) = source.bot.get_entity_component::<Position>(entity) else {
+ source.reply("I can't see you!");
+ return 0;
+ };
+ source.reply("ok");
+ source.bot.goto(BlockPosGoal(BlockPos::from(position)));
+ 1
+ })
+ .then(literal("xz").then(argument("x", integer()).then(
+ argument("z", integer()).executes(|ctx: &Ctx| {
+ let source = ctx.source.lock();
+ let x = get_integer(ctx, "x").unwrap();
+ let z = get_integer(ctx, "z").unwrap();
+ println!("goto xz {x} {z}");
+ source.reply("ok");
+ source.bot.goto(XZGoal { x, z });
+ 1
+ }),
+ )))
+ .then(argument("x", integer()).then(argument("y", integer()).then(
+ argument("z", integer()).executes(|ctx: &Ctx| {
+ let source = ctx.source.lock();
+ let x = get_integer(ctx, "x").unwrap();
+ let y = get_integer(ctx, "y").unwrap();
+ let z = get_integer(ctx, "z").unwrap();
+ println!("goto xyz {x} {y} {z}");
+ source.reply("ok");
+ source.bot.goto(BlockPosGoal(BlockPos::new(x, y, z)));
+ 1
+ }),
+ ))),
+ );
+
+ commands.register(literal("down").executes(|ctx: &Ctx| {
+ let source = ctx.source.clone();
+ tokio::spawn(async move {
+ let mut bot = source.lock().bot.clone();
+ let position = BlockPos::from(bot.position());
+ source.lock().reply("mining...");
+ bot.mine(position.down(1)).await;
+ source.lock().reply("done");
+ });
+ 1
+ }));
+
+ commands.register(
+ literal("look")
+ .executes(|ctx: &Ctx| {
+ // look for the sender
+ let mut source = ctx.source.lock();
+ let Some(entity) = source.entity() else {
+ source.reply("I can't see you!");
+ return 0;
+ };
+ let Some(position) = source.bot.get_entity_component::<Position>(entity) else {
+ source.reply("I can't see you!");
+ return 0;
+ };
+ let eye_height = source
+ .bot
+ .get_entity_component::<EyeHeight>(entity)
+ .map(|h| *h)
+ .unwrap_or_default();
+ source.bot.look_at(position.up(eye_height as f64));
+ 1
+ })
+ .then(argument("x", integer()).then(argument("y", integer()).then(
+ argument("z", integer()).executes(|ctx: &Ctx| {
+ let pos = BlockPos::new(
+ get_integer(ctx, "x").unwrap(),
+ get_integer(ctx, "y").unwrap(),
+ get_integer(ctx, "z").unwrap(),
+ );
+ println!("{:?}", pos);
+ let mut source = ctx.source.lock();
+ source.bot.look_at(pos.center());
+ 1
+ }),
+ ))),
+ );
+
+ commands.register(
+ literal("walk").then(argument("seconds", float()).executes(|ctx: &Ctx| {
+ let mut seconds = get_float(ctx, "seconds").unwrap();
+ let source = ctx.source.lock();
+ let mut bot = source.bot.clone();
+
+ if seconds < 0. {
+ bot.walk(WalkDirection::Backward);
+ seconds = -seconds;
+ } else {
+ bot.walk(WalkDirection::Forward);
+ }
+
+ tokio::spawn(async move {
+ tokio::time::sleep(Duration::from_secs_f32(seconds)).await;
+ bot.walk(WalkDirection::None);
+ });
+ source.reply(&format!("ok, walking for {seconds} seconds"));
+ 1
+ })),
+ );
+ commands.register(
+ literal("sprint").then(argument("seconds", float()).executes(|ctx: &Ctx| {
+ let seconds = get_float(ctx, "seconds").unwrap();
+ let source = ctx.source.lock();
+ let mut bot = source.bot.clone();
+ bot.sprint(SprintDirection::Forward);
+ tokio::spawn(async move {
+ tokio::time::sleep(Duration::from_secs_f32(seconds)).await;
+ bot.walk(WalkDirection::None);
+ });
+ source.reply(&format!("ok, spriting for {seconds} seconds"));
+ 1
+ })),
+ );
+
+ commands.register(literal("north").executes(|ctx: &Ctx| {
+ let mut source = ctx.source.lock();
+ source.bot.set_direction(180., 0.);
+ source.reply("ok");
+ 1
+ }));
+ commands.register(literal("south").executes(|ctx: &Ctx| {
+ let mut source = ctx.source.lock();
+ source.bot.set_direction(0., 0.);
+ source.reply("ok");
+ 1
+ }));
+ commands.register(literal("east").executes(|ctx: &Ctx| {
+ let mut source = ctx.source.lock();
+ source.bot.set_direction(-90., 0.);
+ source.reply("ok");
+ 1
+ }));
+ commands.register(literal("west").executes(|ctx: &Ctx| {
+ let mut source = ctx.source.lock();
+ source.bot.set_direction(90., 0.);
+ source.reply("ok");
+ 1
+ }));
+ commands.register(
+ literal("jump")
+ .executes(|ctx: &Ctx| {
+ let mut source = ctx.source.lock();
+ source.bot.jump();
+ source.reply("ok");
+ 1
+ })
+ .then(argument("enabled", bool()).executes(|ctx: &Ctx| {
+ let jumping = get_bool(ctx, "enabled").unwrap();
+ let mut source = ctx.source.lock();
+ source.bot.set_jumping(jumping);
+ 1
+ })),
+ );
+
+ commands.register(literal("stop").executes(|ctx: &Ctx| {
+ let source = ctx.source.lock();
+ source.bot.stop_pathfinding();
+ source.reply("ok");
+ *source.state.task.lock() = BotTask::None;
+ 1
+ }));
+}