diff --git a/src/scripting/client/mod.rs b/src/scripting/client/mod.rs
index 9f06dd8..8ba98ee 100644
--- a/src/scripting/client/mod.rs
+++ b/src/scripting/client/mod.rs
@@ -122,7 +122,6 @@ impl UserData for Client {
m.add_method_mut("attack", interaction::attack);
m.add_method_mut("block_interact", interaction::block_interact);
m.add_method_mut("goto", movement::goto);
- m.add_method_mut("goto_without_mining", movement::goto_without_mining);
m.add_method_mut("jump", movement::jump);
m.add_method_mut("look_at", movement::look_at);
m.add_method_mut("set_direction", movement::set_direction);
diff --git a/src/scripting/client/movement.rs b/src/scripting/client/movement.rs
index 52616a8..f1b40f1 100644
--- a/src/scripting/client/movement.rs
+++ b/src/scripting/client/movement.rs
@@ -1,39 +1,99 @@
use super::{Client, Vec3};
use azalea::{
- BlockPos, SprintDirection, WalkDirection, pathfinder::goals::BlockPosGoal, prelude::*,
+ BlockPos, BotClientExt, Client as AzaleaClient, SprintDirection, WalkDirection,
+ pathfinder::{
+ PathfinderClientExt,
+ goals::{BlockPosGoal, Goal, RadiusGoal, ReachBlockPosGoal, XZGoal, YGoal},
+ },
};
-use mlua::{Lua, Result};
+use mlua::{FromLua, Lua, Result, Table, Value};
pub fn stop_pathfinding(_lua: &Lua, client: &Client, _: ()) -> Result<()> {
client.inner.as_ref().unwrap().stop_pathfinding();
Ok(())
}
-pub fn goto(_lua: &Lua, client: &mut Client, position: Vec3) -> Result<()> {
- #[allow(clippy::cast_possible_truncation)]
- client
- .inner
- .as_ref()
- .unwrap()
- .goto(BlockPosGoal(BlockPos::new(
- position.x as i32,
- position.y as i32,
- position.z as i32,
- )));
- Ok(())
-}
+pub fn goto(
+ lua: &Lua,
+ client: &mut Client,
+ (data, metadata): (Value, Option
),
+) -> Result<()> {
+ fn g(client: &AzaleaClient, without_mining: bool, goal: impl Goal + Send + Sync + 'static) {
+ if without_mining {
+ client.goto_without_mining(goal);
+ } else {
+ client.goto(goal);
+ }
+ }
+
+ let error = mlua::Error::FromLuaConversionError {
+ from: data.type_name(),
+ to: "Table".to_string(),
+ message: None,
+ };
+ let client = client.inner.as_ref().unwrap();
+ let (goal_type, without_mining) = metadata
+ .map(|t| {
+ (
+ t.get("type").unwrap_or_default(),
+ t.get("without_mining").unwrap_or_default(),
+ )
+ })
+ .unwrap_or_default();
-pub fn goto_without_mining(_lua: &Lua, client: &mut Client, position: Vec3) -> Result<()> {
#[allow(clippy::cast_possible_truncation)]
- client
- .inner
- .as_ref()
- .unwrap()
- .goto_without_mining(BlockPosGoal(BlockPos::new(
- position.x as i32,
- position.y as i32,
- position.z as i32,
- )));
+ match goal_type {
+ 1 => {
+ let t = data.as_table().ok_or(error)?;
+ let p = Vec3::from_lua(t.get("position")?, lua)?;
+ g(
+ client,
+ without_mining,
+ RadiusGoal {
+ pos: azalea::Vec3::new(p.x, p.y, p.z),
+ radius: t.get("radius")?,
+ },
+ );
+ }
+ 2 => {
+ let p = Vec3::from_lua(data, lua)?;
+ g(
+ client,
+ without_mining,
+ ReachBlockPosGoal {
+ pos: BlockPos::new(p.x as i32, p.y as i32, p.z as i32),
+ chunk_storage: client.world().read().chunks.clone(),
+ },
+ );
+ }
+ 3 => {
+ let t = data.as_table().ok_or(error)?;
+ g(
+ client,
+ without_mining,
+ XZGoal {
+ x: t.get("x")?,
+ z: t.get("z")?,
+ },
+ );
+ }
+ 4 => g(
+ client,
+ without_mining,
+ YGoal {
+ y: data.as_integer().ok_or(error)?,
+ },
+ ),
+ _ => {
+ let p = Vec3::from_lua(data, lua)?;
+ g(
+ client,
+ without_mining,
+ BlockPosGoal(BlockPos::new(p.x as i32, p.y as i32, p.z as i32)),
+ );
+ }
+ }
+
Ok(())
}