Merge branch 'master' into master
commit
890058b4bd
90
commands.lua
90
commands.lua
|
@ -825,6 +825,84 @@ basic_robot.commands.craft = function(item, mode, idx,amount, name)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--pathfinding: find_path, walk_path
|
||||||
|
basic_robot.commands.find_path = function(name,pos2)
|
||||||
|
local obj = basic_robot.data[name].obj;
|
||||||
|
local pos1 = obj:getpos();
|
||||||
|
|
||||||
|
if (pos1.x-pos2.x)^2+(pos1.y-pos2.y)^2+(pos1.z-pos2.z)^2> 50^2 then
|
||||||
|
return nil,"2: distance too large"
|
||||||
|
end
|
||||||
|
check_operations(name,6,true)
|
||||||
|
local data = basic_robot.data[name]
|
||||||
|
energy = data.menergy or 0; -- machine energy
|
||||||
|
if energy<1 then
|
||||||
|
return nil,"1: not enough energy"
|
||||||
|
end
|
||||||
|
data.menergy = energy - 1
|
||||||
|
--{current pathnode, path}
|
||||||
|
|
||||||
|
--start position is very sensitive, noninteger coordinates do not seem to work
|
||||||
|
local round = math.floor
|
||||||
|
pos1.x = pos1.x>0 and round(pos1.x+0.5) or -round(-pos1.x+0.5)
|
||||||
|
pos1.y = pos1.y>0 and round(pos1.y+0.5) or -round(-pos1.y+0.5)
|
||||||
|
pos1.z = pos1.z>0 and round(pos1.z+0.5) or -round(-pos1.z+0.5)
|
||||||
|
|
||||||
|
--TODO: tweak parameters, minetest find_path seems sometimes buggy
|
||||||
|
local path = minetest.find_path(pos1,pos2,10,1,1,"Dijkstra"); -- pos1,pos2, search_distance, max_jump, max_drop
|
||||||
|
basic_robot.data[name].pathdata = {1,path}
|
||||||
|
|
||||||
|
if path then return #path else return nil end -- return length of found path or nil
|
||||||
|
end
|
||||||
|
|
||||||
|
basic_robot.commands.walk_path = function(name)
|
||||||
|
check_operations(name,2,true)
|
||||||
|
|
||||||
|
local pathdata = basic_robot.data[name].pathdata;
|
||||||
|
if not pathdata then return nil end
|
||||||
|
local path = pathdata[2];
|
||||||
|
if not path then return 0 end
|
||||||
|
|
||||||
|
local idx = pathdata[1];
|
||||||
|
if idx > #path then return 0 end -- reached end of path
|
||||||
|
|
||||||
|
local pos2 = path[idx]
|
||||||
|
local obj = basic_robot.data[name].obj;
|
||||||
|
local pos1 = obj:getpos();
|
||||||
|
|
||||||
|
local ndist = (pos1.x-pos2.x)^2+(pos1.y-pos2.y)^2+(pos1.z-pos2.z)^2
|
||||||
|
if ndist> 4 then return -ndist end -- too far away from next node
|
||||||
|
|
||||||
|
--turn in correct direction according to movement
|
||||||
|
pos1.x = pos2.x-pos1.x; pos1.z = pos2.z-pos1.z
|
||||||
|
local yaw = 0
|
||||||
|
if math.abs(pos1.x)> math.abs(pos1.z) then
|
||||||
|
if pos1.x>0 then
|
||||||
|
yaw = 0;
|
||||||
|
-- {1,0}
|
||||||
|
else
|
||||||
|
yaw = math.pi;
|
||||||
|
-- {-1,0}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if pos1.z>0 then
|
||||||
|
-- {0,1}
|
||||||
|
yaw = math.pi/2
|
||||||
|
else
|
||||||
|
-- {0,-1}
|
||||||
|
yaw = -math.pi/2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
yaw = yaw - math.pi/2
|
||||||
|
obj:setyaw(yaw);
|
||||||
|
|
||||||
|
pathdata[1] = idx + 1 -- target next node
|
||||||
|
obj:moveto(pos2, true)
|
||||||
|
|
||||||
|
return #path-idx+1 -- return remaining length of path
|
||||||
|
end
|
||||||
|
|
||||||
--FORMS
|
--FORMS
|
||||||
basic_robot.commands.show_form = function(name, playername, form)
|
basic_robot.commands.show_form = function(name, playername, form)
|
||||||
minetest.show_formspec(playername, "robot_form".. name, form)
|
minetest.show_formspec(playername, "robot_form".. name, form)
|
||||||
|
@ -1473,14 +1551,4 @@ end
|
||||||
function Vplayer:get_eye_offset() end
|
function Vplayer:get_eye_offset() end
|
||||||
|
|
||||||
|
|
||||||
-- code for act borrowed from: https://github.com/minetest-mods/pipeworks/blob/fa4817136c8d1e62dafd6ab694821cba255b5206/wielder.lua, line 372
|
-- code for act borrowed from: https://github.com/minetest-mods/pipeworks/blob/fa4817136c8d1e62dafd6ab694821cba255b5206/wielder.lua, line 372
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
46
init.lua
46
init.lua
|
@ -25,7 +25,7 @@ basic_robot.bad_inventory_blocks = { -- disallow taking from these nodes invento
|
||||||
|
|
||||||
basic_robot.http_api = minetest.request_http_api();
|
basic_robot.http_api = minetest.request_http_api();
|
||||||
|
|
||||||
basic_robot.version = "2019/06/03a";
|
basic_robot.version = "2019/09/27a";
|
||||||
|
|
||||||
basic_robot.gui = {}; local robogui = basic_robot.gui -- gui management
|
basic_robot.gui = {}; local robogui = basic_robot.gui -- gui management
|
||||||
basic_robot.data = {}; -- stores all robot related data
|
basic_robot.data = {}; -- stores all robot related data
|
||||||
|
@ -217,6 +217,13 @@ function getSandboxEnv (name)
|
||||||
return commands.display_text(obj,text,linesize,size)
|
return commands.display_text(obj,text,linesize,size)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
find_path = function(pos) -- compute path
|
||||||
|
return commands.find_path(name,pos)
|
||||||
|
end,
|
||||||
|
|
||||||
|
walk_path = function() -- walk to next node of path
|
||||||
|
return commands.walk_path(name)
|
||||||
|
end,
|
||||||
},
|
},
|
||||||
|
|
||||||
machine = {-- adds technic like functionality to robots: power generation, smelting, grinding, compressing
|
machine = {-- adds technic like functionality to robots: power generation, smelting, grinding, compressing
|
||||||
|
@ -554,7 +561,7 @@ end
|
||||||
|
|
||||||
check_code = function(code)
|
check_code = function(code)
|
||||||
--"while ", "for ", "do ","goto ",
|
--"while ", "for ", "do ","goto ",
|
||||||
local bad_code = {"repeat", "until", "_c_", "_G", "while%(", "while{", "pcall","%.%."} --,"\\\"", "%[=*%[","--[["}
|
local bad_code = {"repeat", "until", "_c_", "_G", "while%(", "while{", "pcall","%.%.[^%.]"} --,"\\\"", "%[=*%[","--[["}
|
||||||
for _, v in pairs(bad_code) do
|
for _, v in pairs(bad_code) do
|
||||||
if string.find(code, v) then
|
if string.find(code, v) then
|
||||||
return v .. " is not allowed!";
|
return v .. " is not allowed!";
|
||||||
|
@ -635,8 +642,6 @@ end
|
||||||
|
|
||||||
-- COMPILATION
|
-- COMPILATION
|
||||||
|
|
||||||
--todo: 2018/12 this suddenly stopped working, wtf??
|
|
||||||
|
|
||||||
preprocess_code = function(script, call_limit) -- version 07/24/2018
|
preprocess_code = function(script, call_limit) -- version 07/24/2018
|
||||||
|
|
||||||
--[[ idea: in each local a = function (args) ... end insert counter like:
|
--[[ idea: in each local a = function (args) ... end insert counter like:
|
||||||
|
@ -645,7 +650,6 @@ preprocess_code = function(script, call_limit) -- version 07/24/2018
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
script = script:gsub("%-%-%[%[.*%-%-%]%]",""):gsub("%-%-[^\n]*\n","\n") -- strip comments
|
script = script:gsub("%-%-%[%[.*%-%-%]%]",""):gsub("%-%-[^\n]*\n","\n") -- strip comments
|
||||||
script="_c_ = 0; " .. script;
|
|
||||||
|
|
||||||
-- process script to insert call counter in every function
|
-- process script to insert call counter in every function
|
||||||
local _increase_ccounter = " _c_ = _c_ + 1; if _c_ > " .. call_limit ..
|
local _increase_ccounter = " _c_ = _c_ + 1; if _c_ > " .. call_limit ..
|
||||||
|
@ -703,9 +707,14 @@ preprocess_code = function(script, call_limit) -- version 07/24/2018
|
||||||
i1 = i2+1;
|
i1 = i2+1;
|
||||||
end
|
end
|
||||||
ret[#ret+1] = string.sub(script,i1);
|
ret[#ret+1] = string.sub(script,i1);
|
||||||
|
|
||||||
script = table.concat(ret,_increase_ccounter)
|
script = table.concat(ret,_increase_ccounter)
|
||||||
return script:gsub("pause%(%)", "_c_ = 0; pause()") -- reset ccounter at pause
|
|
||||||
|
-- must reset ccounter when paused, but user should not be able to force reset by modifying pause!
|
||||||
|
-- (suggestion about 'pause' by Kimapr, 09/26/2019)
|
||||||
|
|
||||||
|
return "_c_ = 0 local _pause_ = pause pause = function() _c_ = 0; _pause_() end " .. script;
|
||||||
|
|
||||||
|
--return script:gsub("pause%(%)", "_c_ = 0; pause()") -- reset ccounter at pause
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -882,7 +891,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local function init_robot(obj)
|
local function init_robot(obj, resetSandbox)
|
||||||
|
|
||||||
local self = obj:get_luaentity();
|
local self = obj:get_luaentity();
|
||||||
local name = self.name; -- robot name
|
local name = self.name; -- robot name
|
||||||
|
@ -898,10 +907,9 @@ local function init_robot(obj)
|
||||||
obj:set_properties({infotext = "robot " .. name});
|
obj:set_properties({infotext = "robot " .. name});
|
||||||
obj:set_properties({nametag = "[" .. name.."]",nametag_color = "LawnGreen"});
|
obj:set_properties({nametag = "[" .. name.."]",nametag_color = "LawnGreen"});
|
||||||
obj:set_armor_groups({fleshy=0})
|
obj:set_armor_groups({fleshy=0})
|
||||||
|
|
||||||
if not basic_robot.data[name].sandbox then
|
if resetSandbox then initSandbox ( name ) end
|
||||||
initSandbox ( name )
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_entity("basic_robot:robot",{
|
minetest.register_entity("basic_robot:robot",{
|
||||||
|
@ -945,7 +953,7 @@ minetest.register_entity("basic_robot:robot",{
|
||||||
self.authlevel = data.authlevel;
|
self.authlevel = data.authlevel;
|
||||||
|
|
||||||
self.spawnpos = {x=data.spawnpos.x,y=data.spawnpos.y,z=data.spawnpos.z};
|
self.spawnpos = {x=data.spawnpos.x,y=data.spawnpos.y,z=data.spawnpos.z};
|
||||||
init_robot(self.object);
|
init_robot(self.object, false); -- do not reset sandbox to keep all variables, just wake up
|
||||||
self.running = 1;
|
self.running = 1;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1067,7 +1075,7 @@ local spawn_robot = function(pos,node,ttl)
|
||||||
local name = owner..id;
|
local name = owner..id;
|
||||||
|
|
||||||
|
|
||||||
if id <= 0 then -- just compile code and run it, no robot spawn
|
if id <= 0 then -- just compile code and run it, no robot entity spawn
|
||||||
local codechange = false;
|
local codechange = false;
|
||||||
if meta:get_int("codechange") == 1 then
|
if meta:get_int("codechange") == 1 then
|
||||||
meta:set_int("codechange",0);
|
meta:set_int("codechange",0);
|
||||||
|
@ -1076,7 +1084,7 @@ local spawn_robot = function(pos,node,ttl)
|
||||||
-- compile code & run it
|
-- compile code & run it
|
||||||
local err;
|
local err;
|
||||||
local data = basic_robot.data[name];
|
local data = basic_robot.data[name];
|
||||||
if codechange or (not data) then
|
if codechange or (not data) then -- reset all, sandbox will change too
|
||||||
basic_robot.data[name] = {}; data = basic_robot.data[name];
|
basic_robot.data[name] = {}; data = basic_robot.data[name];
|
||||||
meta:set_string("infotext",minetest.get_gametime().. " code changed ")
|
meta:set_string("infotext",minetest.get_gametime().. " code changed ")
|
||||||
data.owner = owner;
|
data.owner = owner;
|
||||||
|
@ -1140,10 +1148,10 @@ local spawn_robot = function(pos,node,ttl)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end -- end of entityless robot code
|
||||||
|
|
||||||
|
|
||||||
-- if robot already exists do nothing
|
-- if robot entity already exists refresh it
|
||||||
if basic_robot.data[name] and basic_robot.data[name].obj then
|
if basic_robot.data[name] and basic_robot.data[name].obj then
|
||||||
minetest.chat_send_player(owner,"#ROBOT: ".. name .. " already active, removing ")
|
minetest.chat_send_player(owner,"#ROBOT: ".. name .. " already active, removing ")
|
||||||
basic_robot.data[name].obj:remove();
|
basic_robot.data[name].obj:remove();
|
||||||
|
@ -1180,7 +1188,7 @@ local spawn_robot = function(pos,node,ttl)
|
||||||
data.spawnpos = {x=pos.x,y=pos.y-1,z=pos.z};
|
data.spawnpos = {x=pos.x,y=pos.y-1,z=pos.z};
|
||||||
|
|
||||||
|
|
||||||
init_robot(obj); -- set properties, init sandbox
|
init_robot(obj,true); -- set properties, resetSandbox = true
|
||||||
|
|
||||||
local self = obj:get_luaentity();
|
local self = obj:get_luaentity();
|
||||||
local err = setCode( self.name, self.code ); -- compile code
|
local err = setCode( self.name, self.code ); -- compile code
|
||||||
|
@ -1626,7 +1634,7 @@ minetest.register_on_chat_message(
|
||||||
function(name, message)
|
function(name, message)
|
||||||
local hidden = false;
|
local hidden = false;
|
||||||
if string.sub(message,1,1) == "\\" then hidden = true; message = string.sub(message,2) end
|
if string.sub(message,1,1) == "\\" then hidden = true; message = string.sub(message,2) end
|
||||||
local listeners = basic_robot.data.listening;
|
local listeners = basic_robot.data.listening; -- which robots are listening?
|
||||||
for pname,_ in pairs(listeners) do
|
for pname,_ in pairs(listeners) do
|
||||||
local data = basic_robot.data[pname];
|
local data = basic_robot.data[pname];
|
||||||
data.listen_msg = message;
|
data.listen_msg = message;
|
||||||
|
|
|
@ -232,6 +232,10 @@ local help_pages = {
|
||||||
" self.label(text) changes robot label",
|
" self.label(text) changes robot label",
|
||||||
" self.display_text(text,linesize,size) displays text instead of robot face,",
|
" self.display_text(text,linesize,size) displays text instead of robot face,",
|
||||||
" if no size just return texture string",
|
" if no size just return texture string",
|
||||||
|
" self.find_path(pos) attempts to find path to pos (coordinates must be",
|
||||||
|
" integer). On success return length of path, otherwise nil",
|
||||||
|
" self.walk_path() attempts to walk path it previously found. On success ",
|
||||||
|
" returns number of remaining nodes, on fail it returns -next node distance or 0",
|
||||||
" self.sound(sample,volume, opt. pos) plays sound named 'sample' at",
|
" self.sound(sample,volume, opt. pos) plays sound named 'sample' at",
|
||||||
" robot, location (optional pos)",
|
" robot, location (optional pos)",
|
||||||
" rom is aditional table that can store persistent data, like rom.x=1",
|
" rom is aditional table that can store persistent data, like rom.x=1",
|
||||||
|
|
Loading…
Reference in New Issue