improved operations per step check

This commit is contained in:
rnd1 2017-08-02 12:48:33 +02:00
parent 0084718815
commit c7d0c2bee8
2 changed files with 128 additions and 22 deletions

View File

@ -44,10 +44,10 @@ local function pos_in_dir(obj, dir) -- position after we move in specified direc
return pos return pos
end end
local check_operations = function(name, quit) local check_operations = function(name, amount, quit)
if basic_robot.maxoperations~=0 then if basic_robot.maxoperations~=0 then
local data = basic_robot.data[name]; local data = basic_robot.data[name];
local operations = data.operations-1; local operations = data.operations-amount;
if operations >= 0 then if operations >= 0 then
data.operations = operations data.operations = operations
else else
@ -104,7 +104,7 @@ basic_robot.digcosts = { -- 1 energy = 1 coal
basic_robot.commands.dig = function(name,dir) basic_robot.commands.dig = function(name,dir)
local energy = 0; local energy = 0;
check_operations(name,true) check_operations(name,2,true)
local obj = basic_robot.data[name].obj; local obj = basic_robot.data[name].obj;
local pos = pos_in_dir(obj, dir) local pos = pos_in_dir(obj, dir)
@ -363,7 +363,7 @@ end
basic_robot.commands.attack = function(name, target) -- attack range 4, damage 5 basic_robot.commands.attack = function(name, target) -- attack range 4, damage 5
local energy = 0; local energy = 0;
check_operations(name,true); check_operations(name,2,true);
local reach = 4; local reach = 4;
local damage = 5; local damage = 5;
@ -787,7 +787,7 @@ basic_robot.commands.machine = {
-- convert fuel into energy -- convert fuel into energy
generate_power = function(name,input, amount) -- fuel used, if no fuel then amount specifies how much energy builtin generator should produce generate_power = function(name,input, amount) -- fuel used, if no fuel then amount specifies how much energy builtin generator should produce
check_operations(name, true) check_operations(name,1.5, true)
if amount and amount>0 then -- attempt to generate power from builtin generator if amount and amount>0 then -- attempt to generate power from builtin generator
local pos = basic_robot.data[name].spawnpos; -- position of spawner block local pos = basic_robot.data[name].spawnpos; -- position of spawner block
@ -834,7 +834,7 @@ basic_robot.commands.machine = {
smelt = function(name,input,amount) -- input material, amount of energy used for smelt smelt = function(name,input,amount) -- input material, amount of energy used for smelt
local energy = 0; -- can only do one step at a run time local energy = 0; -- can only do one step at a run time
check_operations(name,true) check_operations(name,2,true)
if string.find(input," ") then return nil, "0: only one item per smelt" end if string.find(input," ") then return nil, "0: only one item per smelt" end
@ -958,7 +958,7 @@ basic_robot.commands.machine = {
if not tdata then return nil, "target inactive" end if not tdata then return nil, "target inactive" end
local energy = 0; -- can only do one step at a run time local energy = 0; -- can only do one step at a run time
check_operations(name, true); check_operations(name,0.5, true);
energy = data.menergy or 0; energy = data.menergy or 0;
if amount>energy then return nil,"energy too low" end if amount>energy then return nil,"energy too low" end
@ -1028,7 +1028,7 @@ basic_robot.commands.machine = {
for i=1, string.len(input) do for i=1, string.len(input) do
offset = math.random(n+math.random(2+(i+offset+block_offset)^2)); -- yay, nested nonlinearity is fun and makes cryptanalysis 'trivial' hehe offset = math.random(n+math.random(2+(i+offset+block_offset)^2)); -- yay, nested nonlinearity is fun and makes cryptanalysis 'trivial' hehe
if i%8 == 1 then -- every 8 characters new offset using strong hash function incorporation recent offset in nonlinear way if i%8 == 1 then -- every 8 characters new offset using strong hash function incorporating recent offsets in nonlinear way
block_offset = get_hash(_G.minetest.get_password_hash("",i*(offset+1)..password .. (block_offset^2)),n); -- composite fun with more serious hash function block_offset = get_hash(_G.minetest.get_password_hash("",i*(offset+1)..password .. (block_offset^2)),n); -- composite fun with more serious hash function
math.randomseed(rndseed+ block_offset) -- time for change of tune, can you keep up ? :) math.randomseed(rndseed+ block_offset) -- time for change of tune, can you keep up ? :)
if math.random(100)>50 then block_offset = block_offset*math.random(n*(1+block_offset)) end -- extra fun, why not if math.random(100)>50 then block_offset = block_offset*math.random(n*(1+block_offset)) end -- extra fun, why not

134
init.lua
View File

@ -4,17 +4,20 @@
basic_robot = {}; basic_robot = {};
---- SETTINGS ------ ---- SETTINGS ------
basic_robot.call_limit = 48; -- how many execution calls per script run allowed basic_robot.call_limit = 48; -- how many execution calls per script run allowed
basic_robot.entry_count = 2
basic_robot.advanced_count = 16
basic_robot.bad_inventory_blocks = { -- disallow taking from these nodes inventories basic_robot.bad_inventory_blocks = { -- disallow taking from these nodes inventories
["craft_guide:sign_wall"] = true, ["craft_guide:sign_wall"] = true,
} }
basic_robot.maxoperations = 1; -- how many operations (dig, generate energy,..) available per run, 0 = unlimited basic_robot.maxoperations = 2; -- how many operations (dig, generate energy,..) available per run, 0 = unlimited
basic_robot.dig_require_energy = true; -- does robot require energy to dig? basic_robot.dig_require_energy = true; -- does robot require energy to dig?
---------------------- ----------------------
basic_robot.version = "06/18a"; basic_robot.version = "2017/07/18a";
basic_robot.data = {}; -- stores all robot data basic_robot.data = {}; -- stores all robot data
--[[ --[[
@ -103,7 +106,7 @@ function getSandboxEnv (name)
backward = function(itemname, inventory,i) return commands.check_inventory(name,itemname, inventory,i,4) end, backward = function(itemname, inventory,i) return commands.check_inventory(name,itemname, inventory,i,4) end,
down = function(itemname, inventory,i) return commands.check_inventory(name,itemname, inventory,i,6) end, down = function(itemname, inventory,i) return commands.check_inventory(name,itemname, inventory,i,6) end,
up = function(itemname, inventory,i) return commands.check_inventory(name,itemname, inventory,i,5) end, up = function(itemname, inventory,i) return commands.check_inventory(name,itemname, inventory,i,5) end,
forward_down = function(item, inventory,i) return commands.check_inventory(name,itemname, inventory,i,7) end, forward_down = function(itemname, inventory,i) return commands.check_inventory(name,itemname, inventory,i,7) end,
self = function(itemname, inventory,i) return commands.check_inventory(name,itemname, inventory,i,0) end, self = function(itemname, inventory,i) return commands.check_inventory(name,itemname, inventory,i,0) end,
}, },
@ -671,7 +674,7 @@ local function runSandbox( name)
end end
data.ccounter = 0; data.ccounter = 0;
data.operations = 1; data.operations = basic_robot.maxoperations;
setfenv( ScriptFunc, data.sandbox ) setfenv( ScriptFunc, data.sandbox )
@ -687,8 +690,8 @@ end
local function setupid(owner) local function setupid(owner)
local privs = minetest.get_player_privs(owner); if not privs then return end local privs = minetest.get_player_privs(owner); if not privs then return end
local maxid = 2; local maxid = basic_robot.entry_count;
if privs.robot then maxid = 16 end -- max id's per user if privs.robot then maxid = basic_robot.advanced_count end -- max id's per user
basic_robot.ids[owner] = {id = 1, maxid = maxid}; --active id for remove control basic_robot.ids[owner] = {id = 1, maxid = maxid}; --active id for remove control
end end
@ -708,7 +711,8 @@ local robot_spawner_update_form = function (pos, mode)
form = form =
"size[9.5,8]" .. -- width, height "size[9.5,8]" .. -- width, height
"textarea[1.25,-0.25;8.75,9.8;code;;".. code.."]".. "textarea[1.25,-0.25;8.75,9.8;code;;".. code.."]"..
"button_exit[-0.25,-0.25;1.25,1;OK;SAVE]".. "button[-0.25,7.5;1.25,1;EDIT;EDIT]"..
"button_exit[-0.25,-0.25;1.25,1;OK;SAVE]"..
"button_exit[-0.25, 0.75;1.25,1;spawn;START]".. "button_exit[-0.25, 0.75;1.25,1;spawn;START]"..
"button[-0.25, 1.75;1.25,1;despawn;STOP]".. "button[-0.25, 1.75;1.25,1;despawn;STOP]"..
"field[0.25,3.;1.,1;id;id;"..id.."]".. "field[0.25,3.;1.,1;id;id;"..id.."]"..
@ -733,6 +737,41 @@ local robot_spawner_update_form = function (pos, mode)
end end
basic_robot.editor = {};
editor_get_lines = function(text,name)
local data = basic_robot.editor[name];
if not data then
basic_robot.editor[name] = {};
basic_robot.editor[name].lines = {};
basic_robot.editor[name].selection = 1;
data = basic_robot.editor[name];
else
data.lines = {};
end
local lines = data.lines;
for line in string.gmatch(text,"[^\r\n]+") do lines[#lines+1] = line end
end
code_edit_form = function(pos,name)
local lines = basic_robot.editor[name].lines;
local input = minetest.formspec_escape(basic_robot.editor[name].input or "");
local selection = basic_robot.editor[name].selection or 1;
local list = "";
for _,line in pairs(lines) do list = list .. minetest.formspec_escape(line) .. "," end
local form = "size[12,9.25]" .. "textlist[0,0;12,8;listname;" .. list .. ";"..selection..";false]" ..
"button[10,8;2,1;INSERT;INSERT LINE]" ..
"button[10,8.75;2,1;DELETE;DELETE LINE]" ..
"button_exit[2,8.75;2,1;SAVE;SAVE CODE]" ..
"button[0,8.75;2,1;UPDATE;UPDATE LINE]"..
"textarea[0.25,8;10,1;input;;".. input .. "]"
return form
end
local function init_robot(obj) local function init_robot(obj)
local self = obj:get_luaentity(); local self = obj:get_luaentity();
@ -754,7 +793,7 @@ local function init_robot(obj)
end end
minetest.register_entity("basic_robot:robot",{ minetest.register_entity("basic_robot:robot",{
operations = 1, operations = basic_robot.maxoperations,
owner = "", owner = "",
name = "", name = "",
hp_max = 100, hp_max = 100,
@ -807,7 +846,6 @@ minetest.register_entity("basic_robot:robot",{
end end
-- lost robots -- lost robots
--minetest.chat_send_all("D R " .. self.owner)
--if not self.spawnpos then self.object:remove() return end --if not self.spawnpos then self.object:remove() return end
@ -965,7 +1003,7 @@ local spawn_robot = function(pos,node,ttl)
if not data.sandbox then data.sandbox = getSandboxEnv (name) end if not data.sandbox then data.sandbox = getSandboxEnv (name) end
-- actual code run process -- actual code run process
data.ccounter = 0;data.operations = 1; data.ccounter = 0;data.operations = basic_robot.maxoperations;
setfenv(data.bytecode, data.sandbox ) setfenv(data.bytecode, data.sandbox )
@ -1095,7 +1133,7 @@ local on_receive_robot_form = function(pos, formname, fields, sender)
local id = math.floor(tonumber(fields.id) or 1); local id = math.floor(tonumber(fields.id) or 1);
local owner = meta:get_string("owner") local owner = meta:get_string("owner")
if not basic_robot.ids[owner] then setupid(owner) end if not basic_robot.ids[owner] then setupid(owner) end
if id<-1000 and id>basic_robot.ids[owner].maxid then if id<-1000 or id>basic_robot.ids[owner].maxid then
local privs = minetest.get_player_privs(name); local privs = minetest.get_player_privs(name);
if not privs.privs then return end if not privs.privs then return end
end end
@ -1107,6 +1145,26 @@ local on_receive_robot_form = function(pos, formname, fields, sender)
return return
end end
if fields.EDIT then
local meta = minetest.get_meta(pos);if not meta then return end
if meta:get_int("admin") == 1 then
local privs = minetest.get_player_privs(name); -- only admin can edit admin robot code
if not privs.privs then
return
end
end
local code = meta:get_string("code");
editor_get_lines(code,name);
local form = code_edit_form(pos,name);
minetest.after(0, -- why it ignores this form sometimes? old form interfering?
function()
minetest.show_formspec(name, "robot_editor_:"..minetest.pos_to_string(pos), form);
end
)
return
end
if fields.help then if fields.help then
local text = "BASIC LUA SYNTAX\n \nif x==1 then A else B end".. local text = "BASIC LUA SYNTAX\n \nif x==1 then A else B end"..
@ -1342,15 +1400,15 @@ minetest.register_on_player_receive_fields(
elseif fields.right then elseif fields.right then
pcall(function () commands.move(name,2) end) pcall(function () commands.move(name,2) end)
elseif fields.dig then elseif fields.dig then
pcall(function () basic_robot.data[name].operations = 1; commands.dig(name,3) end) pcall(function () basic_robot.data[name].operations = basic_robot.maxoperations; commands.dig(name,3) end)
elseif fields.up then elseif fields.up then
pcall(function () commands.move(name,5) end) pcall(function () commands.move(name,5) end)
elseif fields.down then elseif fields.down then
pcall(function () commands.move(name,6) end) pcall(function () commands.move(name,6) end)
elseif fields.digdown then elseif fields.digdown then
pcall(function () basic_robot.data[name].operations = 1; commands.dig(name,6) end) pcall(function () basic_robot.data[name].operations = basic_robot.maxoperations; commands.dig(name,6) end)
elseif fields.digup then elseif fields.digup then
pcall(function () basic_robot.data[name].operations = 1; commands.dig(name,5) end) pcall(function () basic_robot.data[name].operations = basic_robot.maxoperations; commands.dig(name,5) end)
end end
return return
end end
@ -1389,6 +1447,54 @@ minetest.register_on_player_receive_fields(
return return
end end
local robot_formname = "robot_editor_"; -- editor gui TODO
if string.find(formname,robot_formname) then
local name = player:get_player_name();
local p = string.find(formname,":");
local pos = minetest.string_to_pos(string.sub(formname, p+1));
if fields.listname then
local list = fields.listname;
if string.sub(list,1,3) == "CHG" then
local selection = tonumber(string.sub(list,5)) or 1
basic_robot.editor[name].selection = selection;
local lines = basic_robot.editor[name].lines;
basic_robot.editor[name].input = lines[selection] or "";
minetest.show_formspec(name, "robot_editor_:"..minetest.pos_to_string(pos), code_edit_form(pos,name));
end
elseif fields.UPDATE then
local lines = basic_robot.editor[name].lines or {};
local selection = basic_robot.editor[name].selection or 1;
fields.input = fields.input or "";
fields.input = string.gsub(fields.input, '\\([%[%]\\,;])', '%1') -- dumb minetest POSTS escaped stuff...
lines[selection] = fields.input
basic_robot.editor[name].input = lines[selection];
minetest.show_formspec(name, "robot_editor_:"..minetest.pos_to_string(pos), code_edit_form(pos,name));
elseif fields.DELETE then
local selection = basic_robot.editor[name].selection or 1;
table.remove(basic_robot.editor[name].lines,selection);
minetest.show_formspec(name, "robot_editor_:"..minetest.pos_to_string(pos), code_edit_form(pos,name));
elseif fields.INSERT then
local selection = basic_robot.editor[name].selection or 1;
table.insert(basic_robot.editor[name].lines,selection,"")
minetest.show_formspec(name, "robot_editor_:"..minetest.pos_to_string(pos), code_edit_form(pos,name));
elseif fields.SAVE then
local selection = basic_robot.editor[name].selection or 1;
local lines = basic_robot.editor[name].lines or {};
if fields.input and fields.input~="" then
fields.input = string.gsub(fields.input, '\\([%[%]\\,;])', '%1') -- dumb minetest POSTS escaped stuff...
lines[selection]= fields.input
end
local meta = minetest.get_meta(pos);
local code = table.concat(lines,"\n");
meta:set_string("code",code);
basic_robot.editor[name].lines = {};
robot_spawner_update_form(pos,0);
end
return
end
local robot_formname = "robot_book_"; -- book editing gui local robot_formname = "robot_book_"; -- book editing gui
if string.find(formname,robot_formname) then if string.find(formname,robot_formname) then
local p = string.find(formname,":"); local p = string.find(formname,":");