1 local positions, index, global_goal
3 local function roundvec(v, d)
4 return vector.divide(vector.round(vector.multiply(v, d)), d)
7 local function findpath(pos)
10 positions = minetest.find_path(
11 minetest.localplayer:get_pos(),
13 tonumber(minetest.settings:get("goto_max_distance") or 25),
14 tonumber(minetest.settings:get("goto_max_jump") or 1),
15 tonumber(minetest.settings:get("goto_max_drop") or minetest.settings:get_bool("prevent_natural_damage") and 1000 or 5)
19 minetest.register_chatcommand("goto", {
20 description = "Go to a position (use pathfinding).",
22 func = function(param)
24 return false, "Goto is still active. Use .gotoabort to abort it."
26 local success, pos = minetest.parse_pos(param)
34 minetest.register_chatcommand("gotoabort", {
35 description = "Abort goto.",
37 func = function(param)
39 return false, "Goto is currently not running (and also not walking haha)"
41 minetest.set_keypress("forward", false)
42 minetest.set_keypress("sneak", false)
43 positions, index, global_goal = nil
44 return true, "Aborted."
48 minetest.register_globalstep(function(dtime)
50 minetest.set_keypress("forward", true)
51 minetest.set_keypress("sneak", false)
52 local player = minetest.localplayer
53 local pos = player:get_pos()
54 local goal, next_goal = positions[index], positions[index+1]
56 positions, index, global_goal = nil
57 minetest.set_keypress("forward", false)
58 minetest.display_chat_message("Reached goal.")
62 local d, dn = vector.subtract(pos, goal), vector.subtract(next_goal, goal)
63 for k, v in pairs(dn) do
64 if v ~= 0 and k ~= "y" then
66 if v > 0 and cv > 0 or v < 0 and cv < 0 then
74 local npos = vector.add(goal, {x = 0, y = 1, z = 0})
75 local node = minetest.get_node_or_nil(npos)
76 if node and node.name ~= air then
77 minetest.dig_node(npos)
79 local velocity = player:get_velocity()
81 if vector.length(velocity) < 0.1 then
85 local distance = vector.distance(pos, goal)
86 if not next_goal and distance < 1 then
89 local direction = vector.direction(pos, vector.new(goal.x, 0, goal.z))
90 local yaw = player:get_yaw() % 360
91 local goal_yaw = math.deg(math.atan2(-direction.x, direction.z)) % 360
92 local diff = math.abs(goal_yaw - yaw)
93 if diff > 175 and diff < 185 and distance < 1 then
95 elseif diff > 10 and diff < 350 then
96 if yaw < goal_yaw and diff < 180 or yaw > goal_yaw and diff > 180 then
98 elseif yaw < goal_yaw and diff > 180 or yaw > goal_yaw and diff < 180 then
101 if diff >= 90 and diff <= 270 then
102 minetest.set_keypress("sneak", true)
106 player:set_yaw(goal_yaw)