techage_modpack/signs_bot/cmd_move.lua

361 lines
10 KiB
Lua
Raw Permalink Normal View History

2020-05-31 23:31:18 +03:00
--[[
Signs Bot
=========
2024-08-25 20:49:57 +03:00
Copyright (C) 2019-2024 Joachim Stolberg
2020-05-31 23:31:18 +03:00
GPL v3
See LICENSE.txt for more information
2022-09-24 12:01:30 +03:00
2020-05-31 23:31:18 +03:00
Bot move commands
]]--
2021-05-14 19:50:16 +03:00
-- Load support for I18n.
local S = signs_bot.S
2020-05-31 23:31:18 +03:00
local lib = signs_bot.lib
2021-02-07 16:37:07 +03:00
local get_node_lvm = tubelib2.get_node_lvm
2020-05-31 23:31:18 +03:00
local function node_and_pos(pos)
return get_node_lvm(pos), pos
end
-- Positions to check:
2022-09-24 12:01:30 +03:00
-- 5 6
-- [R]1
2020-05-31 23:31:18 +03:00
-- 3 2
2022-09-24 12:01:30 +03:00
-- 4
2020-05-31 23:31:18 +03:00
function signs_bot.move_robot(mem)
local param2 = mem.robot_param2
local pos = mem.robot_pos
local node1, pos1 = node_and_pos(lib.next_pos(pos, param2))
local node2, pos2 = node_and_pos({x=pos1.x, y=pos1.y-1, z=pos1.z})
local node3, pos3 = node_and_pos({x=pos.x, y=pos.y-1, z=pos.z})
2022-09-24 12:01:30 +03:00
2020-05-31 23:31:18 +03:00
--
-- One step forward (pos1)
--
if lib.check_pos(pos1, node1, node2, param2) or
lib.check_pos(pos1, node1, node3, param2) then
if node3.name == "signs_bot:robot_foot" then
minetest.swap_node(pos3, mem.stored_node or {name = "air"})
minetest.remove_node(pos)
elseif node3.name == "signs_bot:robot_leg" then
local node4, pos4 = node_and_pos({x=pos.x, y=pos.y-2, z=pos.z})
if node4.name == "signs_bot:robot_foot" then
minetest.swap_node(pos4, mem.stored_node or {name = "air"})
end
2022-12-31 12:51:49 +03:00
minetest.swap_node(pos3, {name = "air"})
2020-05-31 23:31:18 +03:00
minetest.remove_node(pos)
else
minetest.swap_node(pos, mem.stored_node or {name = "air"})
end
mem.stored_node = node1
minetest.set_node(pos1, {name="signs_bot:robot", param2=param2})
minetest.sound_play('signs_bot_step', {pos = pos1})
return pos1
end
2022-09-24 12:01:30 +03:00
2020-05-31 23:31:18 +03:00
--
-- One step up (pos5)
--
local node6, pos6 = node_and_pos({x=pos1.x, y=pos1.y+1, z=pos1.z})
if lib.check_pos(pos6, node6, node1, param2) then
local node5, pos5 = node_and_pos({x=pos.x, y=pos.y+1, z=pos.z})
2022-09-24 12:01:30 +03:00
if node5.name == "air" then
if node3.name == "signs_bot:robot_leg" then
2020-05-31 23:31:18 +03:00
return nil
2022-09-24 12:01:30 +03:00
elseif node3.name == "signs_bot:robot_foot" then
2020-05-31 23:31:18 +03:00
minetest.swap_node(pos3, {name="signs_bot:robot_leg"})
else
minetest.swap_node(pos, {name="signs_bot:robot_foot"})
end
minetest.set_node(pos5, {name="signs_bot:robot", param2=param2})
minetest.sound_play('signs_bot_step', {pos = pos5})
return pos5
end
end
2022-09-24 12:01:30 +03:00
2020-05-31 23:31:18 +03:00
--
-- One step down I (pos3)
--
local node4, pos4 = node_and_pos({x=pos.x, y=pos.y-2, z=pos.z})
2022-09-24 12:01:30 +03:00
if lib.check_pos(pos3, node3, node4, param2) then --
2020-05-31 23:31:18 +03:00
minetest.remove_node(pos)
minetest.set_node(pos3, {name="signs_bot:robot", param2=param2})
minetest.sound_play('signs_bot_step', {pos = pos3})
mem.stored_node = node3
return pos3
end
--
-- One step down II (pos3)
--
if node3.name == "signs_bot:robot_foot" or node3.name == "signs_bot:robot_leg" then
minetest.remove_node(pos)
minetest.set_node(pos3, {name="signs_bot:robot", param2=param2})
minetest.sound_play('signs_bot_step', {pos = pos3})
return pos3
end
2022-09-24 12:01:30 +03:00
end
2020-05-31 23:31:18 +03:00
local function backward_robot(mem)
local param2 = mem.robot_param2
local pos = mem.robot_pos
local node1, pos1 = node_and_pos(lib.next_pos(pos, (param2 + 2) % 4))
local node2, pos2 = node_and_pos({x=pos1.x, y=pos1.y-1, z=pos1.z})
local node3, pos3 = node_and_pos({x=pos.x, y=pos.y-1, z=pos.z})
local node4, pos4 = node_and_pos({x=pos.x, y=pos.y-2, z=pos.z})
local new_pos = nil
2022-09-24 12:01:30 +03:00
2020-05-31 23:31:18 +03:00
if lib.check_pos(pos1, node1, node2, param2) then
if node3.name == "signs_bot:robot_foot" or node3.name == "signs_bot:robot_leg" then
minetest.remove_node(pos3)
if node4.name == "signs_bot:robot_foot" then
minetest.remove_node(pos4)
end
end
minetest.swap_node(pos, mem.stored_node or {name = "air"})
minetest.set_node(pos1, {name="signs_bot:robot", param2=param2})
minetest.sound_play('signs_bot_step', {pos = pos1})
mem.stored_node = node1
return pos1
end
2022-09-24 12:01:30 +03:00
end
2020-05-31 23:31:18 +03:00
signs_bot.register_botcommand("backward", {
mod = "move",
params = "",
num_param = 0,
2021-05-14 19:50:16 +03:00
description = S("Move the robot one step back"),
2020-05-31 23:31:18 +03:00
cmnd = function(base_pos, mem)
local new_pos = backward_robot(mem)
if new_pos then -- not blocked?
mem.robot_pos = new_pos
end
return signs_bot.DONE
end,
})
local function turn_robot(pos, param2, dir)
if dir == "R" then
param2 = (param2 + 1) % 4
else
param2 = (param2 + 3) % 4
end
minetest.swap_node(pos, {name="signs_bot:robot", param2=param2})
minetest.sound_play('signs_bot_step', {pos = pos, gain = 0.6})
return param2
2022-09-24 12:01:30 +03:00
end
2020-05-31 23:31:18 +03:00
signs_bot.register_botcommand("turn_left", {
mod = "move",
params = "",
num_param = 0,
2021-05-14 19:50:16 +03:00
description = S("Turn the robot to the left"),
2020-05-31 23:31:18 +03:00
cmnd = function(base_pos, mem)
mem.robot_param2 = turn_robot(mem.robot_pos, mem.robot_param2, "L")
return signs_bot.DONE
end,
})
signs_bot.register_botcommand("turn_right", {
mod = "move",
params = "",
num_param = 0,
2021-05-14 19:50:16 +03:00
description = S("Turn the robot to the right"),
2020-05-31 23:31:18 +03:00
cmnd = function(base_pos, mem)
mem.robot_param2 = turn_robot(mem.robot_pos, mem.robot_param2, "R")
return signs_bot.DONE
end,
})
signs_bot.register_botcommand("turn_around", {
mod = "move",
params = "",
num_param = 0,
2021-05-14 19:50:16 +03:00
description = S("Turn the robot around"),
2020-05-31 23:31:18 +03:00
cmnd = function(base_pos, mem)
mem.robot_param2 = turn_robot(mem.robot_pos, mem.robot_param2, "R")
mem.robot_param2 = turn_robot(mem.robot_pos, mem.robot_param2, "R")
return signs_bot.DONE
end,
})
-- Positions to check:
-- 1
2022-09-24 12:01:30 +03:00
-- [R]
2020-05-31 23:31:18 +03:00
-- 2
local function robot_up(pos, param2)
local node1, pos1 = node_and_pos({x=pos.x, y=pos.y+1, z=pos.z})
local node2, pos2 = node_and_pos({x=pos.x, y=pos.y-1, z=pos.z})
if lib.check_pos(pos1, node1, node2, param2) then
2022-09-24 12:01:30 +03:00
if node2.name == "signs_bot:robot_leg" then
2020-05-31 23:31:18 +03:00
return nil
2022-09-24 12:01:30 +03:00
elseif node2.name == "signs_bot:robot_foot" then
2020-05-31 23:31:18 +03:00
minetest.swap_node(pos, {name="signs_bot:robot_leg"})
else
minetest.swap_node(pos, {name="signs_bot:robot_foot"})
end
minetest.set_node(pos1, {name="signs_bot:robot", param2=param2})
minetest.sound_play('signs_bot_step', {pos = pos1})
return pos1
end
return nil
2022-09-24 12:01:30 +03:00
end
2020-05-31 23:31:18 +03:00
signs_bot.register_botcommand("move_up", {
mod = "move",
params = "",
num_param = 0,
2021-05-14 19:50:16 +03:00
description = S("Move the robot upwards"),
2020-05-31 23:31:18 +03:00
cmnd = function(base_pos, mem)
local new_pos = robot_up(mem.robot_pos, mem.robot_param2)
if new_pos then -- not blocked?
mem.robot_pos = new_pos
end
return signs_bot.DONE
end,
})
-- Positions to check:
2022-09-24 12:01:30 +03:00
-- [R]
2020-05-31 23:31:18 +03:00
-- 1
-- 2
-- 3
local function robot_down(pos, param2)
local node1, pos1 = node_and_pos({x=pos.x, y=pos.y-1, z=pos.z})
local node2, pos2 = node_and_pos({x=pos.x, y=pos.y-2, z=pos.z})
local node3, pos3 = node_and_pos({x=pos.x, y=pos.y-3, z=pos.z})
2022-09-24 12:01:30 +03:00
if lib.check_pos(pos1, node1, node2, param2)
2020-05-31 23:31:18 +03:00
or (node1.name == "air" and lib.check_pos(pos2, node2, node3, param2))
or (node1.name == "signs_bot:robot_leg" or node1.name == "signs_bot:robot_foot") then
minetest.remove_node(pos)
minetest.set_node(pos1, {name="signs_bot:robot", param2=param2})
minetest.sound_play('signs_bot_step', {pos = pos1})
return pos1
end
return nil
2022-09-24 12:01:30 +03:00
end
2020-05-31 23:31:18 +03:00
signs_bot.register_botcommand("move_down", {
mod = "move",
params = "",
num_param = 0,
2021-05-14 19:50:16 +03:00
description = S("Move the robot down"),
2020-05-31 23:31:18 +03:00
cmnd = function(base_pos, mem)
local new_pos = robot_down(mem.robot_pos, mem.robot_param2)
if new_pos then -- not blocked?
mem.robot_pos = new_pos
end
return signs_bot.DONE
end,
})
2022-09-24 12:01:30 +03:00
signs_bot.register_botcommand("fall_down", {
mod = "move",
params = "",
num_param = 0,
description = S("Fall into a hole/chasm (up to 10 blocks)"),
cmnd = function(base_pos, mem)
if not mem.bot_falling then
2024-08-25 20:49:57 +03:00
--Run a while loop that checks the 10 nodes below bot for a node with the walkable property, breaking the loop once it finds a walkable node.
local fallcounter = 0
local fallnode = {walkable = false}
while fallcounter <= 9 and fallnode.walkable == false do
fallcounter = fallcounter + 1
--Pulls the node name from the next position, then assigns the node definintion to the fallnode variable.
fallnode = minetest.get_node_or_nil({x=mem.robot_pos.x, y=mem.robot_pos.y-fallcounter, z=mem.robot_pos.z})
fallnode = minetest.registered_nodes[fallnode.name]
end
--If the first nine nodes below the bot are not walkable, then it should assign the definintion to the 10th node. If it too is not walkable, then a "Too Deep" error is returned.
if fallnode.walkable == false then
return signs_bot.ERROR, "Too deep"
end
--Designates the node above the walkable node as the new location for the bot.
local pos3 = {x=mem.robot_pos.x, y=mem.robot_pos.y-fallcounter+1, z=mem.robot_pos.z}
--Turns the bot into a falling node.
local sts, _ = minetest.spawn_falling_node(mem.robot_pos)
--Stores the data for the node the bot will land in and replaces it with air. This way if the node the bot lands in is occupied by an unwalkable node, such as a rail or sign,
--it will be repalced when the bot moves.
mem.stored_node = get_node_lvm(pos3)
minetest.swap_node(pos3, {name="air"})
if sts then
mem.bot_falling = 2
mem.robot_pos = {x=pos3.x, y=pos3.y, z=pos3.z}
return signs_bot.BUSY
2022-09-24 12:01:30 +03:00
end
else
mem.bot_falling = mem.bot_falling - 1
if mem.bot_falling <= 0 then
mem.bot_falling = nil
return signs_bot.DONE
end
return signs_bot.BUSY
end
end,
})
2020-05-31 23:31:18 +03:00
signs_bot.register_botcommand("pause", {
mod = "move",
params = "<sec>",
num_param = 1,
2021-05-14 19:50:16 +03:00
description = S("Stop the robot for <sec> seconds\n(1..9999)"),
2020-05-31 23:31:18 +03:00
check = function(sec)
sec = tonumber(sec) or 1
return sec and sec > 0 and sec < 10000
end,
cmnd = function(base_pos, mem, sec)
if not mem.steps then
2021-05-14 19:50:16 +03:00
mem.steps = tonumber(sec) or 1
2020-05-31 23:31:18 +03:00
end
mem.steps = mem.steps - 1
if mem.steps == 0 then
mem.steps = nil
return signs_bot.DONE
end
2020-06-19 00:23:53 +03:00
if mem.capa then
mem.capa = mem.capa + 1
end
2020-05-31 23:31:18 +03:00
return signs_bot.BUSY
end,
})
signs_bot.register_botcommand("stop", {
mod = "move",
params = "",
num_param = 0,
2021-05-14 19:50:16 +03:00
description = S("Stop the robot."),
2020-05-31 23:31:18 +03:00
cmnd = function(base_pos, mem, slot)
2023-08-26 11:27:15 +03:00
local param2 = mem.robot_param2
local pos = mem.robot_pos
local node1, pos1 = node_and_pos(lib.next_pos(pos, param2))
2020-06-19 00:23:53 +03:00
if mem.capa then
mem.capa = mem.capa + 2
end
2023-08-26 11:27:15 +03:00
if node1 and node1.name ~= "signs_bot:sign_stop" then
return signs_bot.DONE
end
2022-12-31 12:51:49 +03:00
return signs_bot.BUSY
2020-05-31 23:31:18 +03:00
end,
})
signs_bot.register_botcommand("turn_off", {
mod = "move",
params = "",
num_param = 0,
2021-05-14 19:50:16 +03:00
description = S("Turn the robot off\n"..
2020-05-31 23:31:18 +03:00
"and put it back in the box."),
cmnd = function(base_pos, mem)
signs_bot.stop_robot(base_pos, mem)
return signs_bot.TURN_OFF
end,
})
2022-09-24 12:01:30 +03:00