diff --git a/commands.lua b/commands.lua index 2aff995..ebeb570 100644 --- a/commands.lua +++ b/commands.lua @@ -21,34 +21,34 @@ local function pos_in_dir(obj, dir) -- position after we move in specified direc local yaw = obj:getyaw(); local pos = obj:getpos(); - if dir == 1 then -- left + if dir == 3 then -- left : 3 yaw = yaw + pi/2; - elseif dir == 2 then --right + elseif dir == 4 then --right: 4 yaw = yaw - pi/2; - elseif dir == 3 then -- forward - elseif dir == 4 then - yaw = yaw+pi; -- backward + elseif dir == 2 then -- forward: 1 + elseif dir == 1 then + yaw = yaw+pi; -- backward: 2 elseif dir == 5 then -- up pos.y=pos.y+1 elseif dir == 6 then -- down pos.y=pos.y-1 - elseif dir == 7 then -- left_down + elseif dir == 10 then -- left_down : 9 yaw = yaw + pi/2;pos.y=pos.y-1 - elseif dir == 8 then -- right_down + elseif dir == 9 then -- right_down: 10 yaw = yaw - pi/2;pos.y=pos.y-1 - elseif dir == 9 then -- forward_down + elseif dir == 7 then -- forward_down: 7 pos.y=pos.y-1 - elseif dir == 10 then -- backward_down + elseif dir == 8 then -- backward_down : 8 yaw = yaw + pi; pos.y=pos.y-1 - elseif dir == 11 then -- left_up + elseif dir == 14 then -- left_up: 13 yaw = yaw + pi/2;pos.y=pos.y+1 - elseif dir == 12 then -- right_up + elseif dir == 13 then -- right_up: 14 yaw = yaw - pi/2;pos.y=pos.y+1 - elseif dir == 13 then -- forward_up + elseif dir == 11 then -- forward_up : 11 pos.y=pos.y+1 - elseif dir == 14 then -- backward_up + elseif dir == 12 then -- backward_up: 12 yaw = yaw + pi; pos.y=pos.y+1 end @@ -540,7 +540,10 @@ basic_robot.commands.display_text = function(obj,text,linesize,size) if not size then return tex end if string.len(tex)<=1600 then - obj:set_properties({textures={"arrow.png","basic_machine_side.png",tex,"basic_machine_side.png","basic_machine_side.png","basic_machine_side.png"},visual_size = {x=size,y=size}}) + obj:set_properties({ + textures = {"topface.png","legs.png",tex,"face-back.png","left-hand.png","right-hand.png"}, + --textures={"arrow.png","basic_machine_side.png",tex,"basic_machine_side.png","basic_machine_side.png","basic_machine_side.png"}, + visual_size = {x=size,y=size}}) else self.label("error: string too long") end diff --git a/init.lua b/init.lua index 8defba6..da00ca6 100644 --- a/init.lua +++ b/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.version = "2018/07/27a"; +basic_robot.version = "2018/12/09a"; basic_robot.gui = {}; local robogui = basic_robot.gui -- gui management basic_robot.data = {}; -- stores all robot related data @@ -171,7 +171,7 @@ function getSandboxEnv (name) fire = function(speed, pitch,gravity, texture, is_entity) -- experimental: fires an projectile local obj = basic_robot.data[name].obj; local pos = obj:getpos(); - local yaw = obj:getyaw(); + local yaw = obj:getyaw()+ math.pi/2; pitch = pitch*math.pi/180 local velocity = {x=speed*math.cos(yaw)*math.cos(pitch), y=speed*math.sin(pitch),z=speed*math.sin(yaw)*math.cos(pitch)}; -- fire particle @@ -193,6 +193,7 @@ function getSandboxEnv (name) local obj = minetest.add_entity(pos, "basic_robot:projectile"); if not obj then return end obj:setvelocity(velocity); + obj:set_properties({textures = {texture or "default_furnace_fire_fg.png"}}) obj:setacceleration({x=0,y=-gravity,z=0}); local luaent = obj:get_luaentity(); luaent.name = name; @@ -910,7 +911,7 @@ minetest.register_entity("basic_robot:robot",{ --textures={"character.png"}, visual="cube", - textures={"topface.png","legs.png","face.png","face-back.png","left-hand.png","right-hand.png"}, + textures={"topface.png","legs.png","left-hand.png","right-hand.png","face.png","face-back.png"}, visual_size={x=1,y=1}, running = 0, -- does it run code or is it idle? @@ -1844,7 +1845,7 @@ minetest.register_entity( on_step = function(self, dtime) local vel = self.object:getvelocity(); - if (self.oldvel.x~=0 and vel.x==0) or (self.oldvel.y~=0 and vel.y==0) or (self.oldvel.z~=0 and vel.z==0) then + if (self.oldvel.x~=0 and vel.x==0) or (self.oldvel.y~=0 and vel.y==0) or (self.oldvel.z~=0 and vel.z==0) then -- hit local data = basic_robot.data[self.name]; if data then data.fire_pos = self.object:getpos(); diff --git a/scripts/games/sokoban_game.lua b/scripts/games/sokoban_game.lua index dfa0099..503d3c0 100644 --- a/scripts/games/sokoban_game.lua +++ b/scripts/games/sokoban_game.lua @@ -1,17 +1,20 @@ -- SOKOBAN GAME, by rnd, robots port + + if not sokoban then sokoban = {}; - local players = find_player(5); + local players = find_player(8); if not players then error("sokoban: no player near") end name = players[1]; - - self.show_form(name, - "size[2,1.25]".. - "label[0,0;SELECT LEVEL 1-90]".. - "field[0.25,1;1,1;LVL;LEVEL;1]".. - "button_exit[1.25,0.75;1,1;OK;OK]" - ) + + -- self.show_form(name, + -- "size[2,1.25]".. + -- "label[0,0;SELECT LEVEL 1-90]".. + -- "field[0.25,1;1,1;LVL;LEVEL;1]".. + -- "button_exit[1.25,0.75;1,1;OK;OK]" + -- ) state = 1 -- will wait for form receive otherwise game play + self.label("stand close to white box and punch it one time to push it. you can only push 1 box\nand cant pull. goal is to get all white boxes pushed on aspen blocks") player_ = puzzle.get_player(name); -- get player entity - player must be present in area player_:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0});player_:set_physics_override({jump=1}) -- reset player @@ -24,8 +27,8 @@ sokoban.load=0;sokoban.playername =""; sokoban.pos = {}; SOKOBAN_WALL = "moreblocks:cactus_brick" - SOKOBAN_FLOOR = "default:desert_sandstone" - SOKOBAN_GOAL = "moreblocks:wood_tile_center" + SOKOBAN_FLOOR = "default:silver_sandstone" + SOKOBAN_GOAL = "default:aspen_tree" SOKOBAN_BOX = "basic_robot:buttonFFFFFF" load_level = function(lvl) @@ -56,8 +59,8 @@ imax=i; file:close(); player_:set_physics_override({jump=0}) - player_:set_eye_offset({x=0,y=20,z=0},{x=0,y=0,z=0}) - say("games: sokoban level "..sokoban.level .." loaded by ".. name .. ". It has " .. sokoban.blocks .. " boxes to push. "); return + player_:set_eye_offset({x=0,y=20,z=0},{x=0,y=0,z=0}); + return end i=i+1; if string.len(str)>jmax then jmax = string.len(str) end -- determine max dimensions @@ -72,7 +75,7 @@ if s=="." then p.y=p.y-1;puzzle.set_node(p,{name=SOKOBAN_GOAL}); p.y=p.y+1;puzzle.set_node(p,{name="air"}) end --starting position if s=="@" then - player_:setpos({x=p.x,y=p.y+1,z=p.z}); -- move player to start position + player_:setpos({x=p.x,y=p.y-0.5,z=p.z}); -- move player to start position --p.y=p.y-1;puzzle.set_node(p,{name="default:glass"}); puzzle.set_node(p,{name="air"}) p.y=p.y+1;puzzle.set_node(p,{name="air"}) @@ -94,29 +97,21 @@ for i = 1, 20 do for j = 1,20 do local node = minetest.get_node({x=pos.x+i,y=pos.y-1,z=pos.z+j}).name - if node ~= "default:desert_sandstone" then minetest.set_node({x=pos.x+i,y=pos.y-1,z=pos.z+j}, {name = "default:desert_sandstone"}) end + if node ~= "default:silver_sandstone" then minetest.set_node({x=pos.x+i,y=pos.y-1,z=pos.z+j}, {name = "default:silver_sandstone"}) end node = minetest.get_node({x=pos.x+i,y=pos.y,z=pos.z+j}).name if node ~= "air" then minetest.set_node({x=pos.x+i,y=pos.y,z=pos.z+j}, {name = "air"}) end end end end - end if state == 1 then - sender,fields = self.read_form(); -- get fields from form submittal - if sender then - --say(serialize(fields)) - - if fields.LVL then - clear_game() - load_level((tonumber(fields.LVL) or 1)-1) - state = 0 - self.label("stand close to blue box and punch it one time to push it. you can only push 1 box\nand cant pull. goal is to get all boxes pushed on diamond blocks") - end - end + clear_game() + load_level(20) + state = 0 + self.label("stand close to white box and punch it one time to push it. you can only push 1 box\nand cant pull. goal is to get all white boxes pushed on aspen blocks") else local ppos = player_:getpos() @@ -174,6 +169,12 @@ else player_:set_physics_override({jump=1}) player_:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0}) + local player = _G.minetest.get_player_by_name(event.puncher); + if player then + local inv = player:get_inventory(); + inv:add_item("main",_G.ItemStack("skyblock:sokoban 4 ")) + end + local i,j; for i = 1,imax do for j=1,jmax do diff --git a/scripts/games/switching_game.lua b/scripts/games/switching_game.lua new file mode 100644 index 0000000..64c95d3 --- /dev/null +++ b/scripts/games/switching_game.lua @@ -0,0 +1,101 @@ +--[[ +SWITCHING GAME by rnd, 2018 + +lights: +0110 + +switches, each one toggles certain lights like: s1 1001 (toggles light with 1) + +PROBLEM: +hit switches in correct order to turn on all lights + +GENERATE RANDOM CHALLENGE: +start with all lights on and apply random sequence of switches + +TODO: instead of simply 0/1 switches have ones that advance +1 mod p (p can be say 3 or more) + + +REMARKS: application of 2 different switches is commutative ( obvious, since just x->x+1 mod p) +--]] +if not init then + +init = true +numlights = 2; +numswitches = 2; +states = 10; + +lights = {}; -- states of lights, initialy 1,1,...,1 +for i = 1, numlights do lights[i] = 0 end +switches = {} + +--switches = {{1,0,0,1},{1,1,1,1}}; +make_random_switches = function(lights, switches,count) + for i = 1, count do + switches[i] = {}; + local switch = switches[i]; + for j = 1, #lights do switch[j] = math.random(states)-1 end + end +end +make_random_switches(lights,switches, numswitches) + + +pos = self.spawnpos(); pos.x = pos.x + 1;-- pos.z = pos.z + 1 + +apply_switch = function(switches,lights,idx) + local switch = switches[idx]; + for i = 1, #switch do + local state = lights[i] + switch[i]; + if state >= states then state = state - states end + lights[i] = state + end +end + +randomize = function(switches, lights, steps) -- randomize lights + for i = 1, steps do + local idx = math.random(#switches); + apply_switch(switches,lights,idx); + end +end + +render_lights = function() for i = 1, #lights do keyboard.set({x=pos.x+i-1,y=pos.y+1, z=pos.z}, 7+lights[i]) end end +render_switches = function(mode) + if mode then + for i = 1, #switches do keyboard.set({x=pos.x+i-1,y=pos.y, z=pos.z}, 1+i) end + else + for i = 1, #switches do keyboard.set({x=pos.x+i-1,y=pos.y, z=pos.z}, 0) end + end +end + +check_lights = function() + for i = 1, #lights do if lights[i] ~= 0 then return false end end + return true +end +step = 0 + +randomize(switches,lights, math.min((#switches)^states,10000)) +if check_lights() then randomize(switches,lights, #switches + states) end + +render_lights(); render_switches(true) + + +self.label("GOAL OF GAME: punch buttons with numbers in correct order to turn all blocks to 0") + +--self.label(serialize(switches)) +end + + +event = keyboard.get() +if event then + local idx = event.x-pos.x+1; + if event.y==pos.y and idx>=1 and idx <= #switches then + apply_switch(switches, lights, idx) + render_lights() + step = step + 1 + if check_lights() then + self.label("DONE IN " .. step .. " STEPS !") + render_switches(false) + else + self.label("STEP " .. step) + end + end +end \ No newline at end of file diff --git a/scripts/graphics/painting.lua b/scripts/graphics/painting.lua new file mode 100644 index 0000000..0b7075e --- /dev/null +++ b/scripts/graphics/painting.lua @@ -0,0 +1,112 @@ +-- paint canvas by rnd, 2018 +if not init then + colors = { + "black","blue","brown","cyan","dark_green","dark_grey","green","grey", + "magenta","orange","pink","red","violet","white","yellow" + } + invcolors = {}; for i = 1,#colors do invcolors[colors[i]] = i end + + color = 1; + size = 16; + + init = true + + local ent = _G.basic_robot.data[self.name()].obj:get_luaentity(); + ent.timestep = 0.5 + + players = find_player(5); if not players then self.remove() end + player = _G.minetest.get_player_by_name(players[1]) + self.label("-> " .. players[1]) + + spos = self.spawnpos(); spos.y=spos.y+1; + + canvasn = "wool:white" + reset_canvas = function() + for i = 1, size do + for j = 1, size do + minetest.set_node({x=spos.x +i , y = spos.y + j, z = spos.z },{name = canvasn}) + end + end + end + reset_canvas() + + save_image = function() + local ret = {}; + for i = 1, size do + for j = 1, size do + local nname = string.sub(minetest.get_node({x=spos.x +i , y = spos.y + j, z = spos.z }).name,6) + local pcolor = invcolors[nname] or 1; + ret[#ret+1]= string.char(96+pcolor) + end + end + return table.concat(ret,"") + end + + load_image = function(image) + if not image then return end + local ret = {}; local k = 0; + for i = 1, size do + for j = 1, size do + k=k+1; + local pcolor = colors[string.byte(image,k)-96] or "black"; + minetest.set_node({x=spos.x +i , y = spos.y + j, z = spos.z },{name = "wool:"..pcolor}) + end + end + end + + + --draw buttons + for i = 1,#colors do + minetest.set_node({x=spos.x +i , y = spos.y , z = spos.z },{name = "wool:"..colors[i]}) + end + + minetest.set_node({x=spos.x +1 , y = spos.y-1 , z = spos.z },{name = "basic_robot:button_83"}) + minetest.set_node({x=spos.x +2 , y = spos.y-1 , z = spos.z },{name = "basic_robot:button_76"}) + + + vn = {x=0,y=0,z=1}; + T0 = {x=spos.x+0.5,y=spos.y+0.5,z=spos.z-0.5*vn.z}; + + get_intersect = function(vn, T0, p, v) + local a = (T0.x-p.x)*vn.x + (T0.y-p.y)*vn.y + (T0.z-p.z)*vn.z; + local b = vn.x*v.x + vn.y*v.y + vn.z*v.z + if b<=0 then return nil end + if a<=0 then return nil end + local t = a / b + return {x = p.x+v.x*t, y= p.y+v.y*t, z = p.z+v.z*t} + end + +end + +if player:get_player_control().LMB then -- player interacts with 'virtual canvas gui' + local v = player:get_look_dir(); + local p = player:get_pos(); p.y = p.y + 1.5 + local c = get_intersect(vn,T0,p,v); + if c then + + local x = c.x - T0.x; local y = c.y - T0.y + if x>0 and x-2 and y0 then -- above: painting + c.z = c.z+0.5 + minetest.set_node(c, {name = "wool:" .. colors[color]}) + elseif y>-1 then -- color selection + x = 1+math.floor(x) + if colors[x] then + color = x; + self.label(colors[x]) + end + else -- save,load button row + x = 1+math.floor(x) + if x==1 then + self.label("SAVED.") + book.write(1,"ROBOT_IMAGE",save_image()) + elseif x==2 then + local _,image = book.read(1) + load_image(image); + self.label("LOADED.") + end + end + end + + end +end \ No newline at end of file diff --git a/scripts/gui/file_manager.lua b/scripts/gui/file_manager.lua new file mode 100644 index 0000000..10205ba --- /dev/null +++ b/scripts/gui/file_manager.lua @@ -0,0 +1,57 @@ +-- file 'manager' by rnd + +if not init then + fmver = "2018/12/09" + local players = find_player(4); + if not players then self.remove() end + pname = players[1]; + size = 8; + vsize = 6.5; + + path = "/"; + pathlist = {} + folderlist = {}; + filelist = {}; + + render_page = function() + local foldlist = minetest.get_dir_list(path,true) -- only folders + if foldlist then folderlist = foldlist else folderlist = {} end + for i = 1,#foldlist do foldlist[i] = "*"..foldlist[i] end + foldlist[#foldlist+1] = "*.." + local fillist = minetest.get_dir_list(path,false) + if fillist then filelist = fillist else filelist = {} end + local content = table.concat(folderlist,",") .. ",-------------------," .. table.concat(filelist,",") + return "size[" .. size .. "," .. size .. "] label[0,-0.25;ROBOT FILE MANAGER " .. fmver .. " by rnd\nPATH " .. minetest.formspec_escape(path) .. "] textlist[-0.25,0.75;" .. (size+1) .. "," .. (vsize+1) .. ";wiki;".. content .. ";1]"; + end + + page = {} + self.show_form(pname,render_page()) + init = true + self.read_form() +end + +sender,fields = self.read_form() +if sender then + local fsel = fields.wiki; + if fsel and string.sub(fsel,1,3) == "DCL" then + local sel = tonumber(string.sub(fsel,5)) or 1; -- selected line + local fold = folderlist[sel]; + if fold and string.sub(fold,1,1) == "*" then + if fold == "*.." then -- go back + if #pathlist>0 then + local i = string.len(pathlist[#pathlist]); + if i>0 then + pathlist[#pathlist] = nil + path = string.sub(path,1,-i-2); + end + end + else + pathlist[#pathlist+1] = string.sub(fold,2) + path = path .. "/".. pathlist[#pathlist] + end + + self.show_form(pname,render_page()) + end + end + --self.label(fsel); +end \ No newline at end of file diff --git a/scripts/gui/gui_2player_coop_edit.lua b/scripts/gui/gui_2player_coop_edit.lua new file mode 100644 index 0000000..1b6759d --- /dev/null +++ b/scripts/gui/gui_2player_coop_edit.lua @@ -0,0 +1,57 @@ +-- gui demo by rnd +-- 2 player cooperative editing of image with 2 colors + +if not init then + _G.basic_robot.data[self.name()].obj:get_luaentity().timestep = 0.25 + init = true + name = "rnd" + otherrobotname = "rnd2" -- on other robot do name of this robot + drawcolor = 3; -- other robot has reversed colors + otherdrawcolor = 4 + + color = {"black","white","blue","green"} + data = {}; + n = 20; + + for i = 1,n do + data[i]={}; + --local y = math.floor(f(i)); + for j = 1,n do + data[i][j] = 1--(n-j>y) and 2 or 1 + end + end + + get_form = function() + local form = "size[10,10] "; ret = {}; + + for i = 1,n do + for j = 1,n do + ret[#ret+1] = "image_button["..((i-1)*0.5)..","..((j-1)*0.5)..";0.7,0.63;wool_"..color[data[i][j]]..".png;"..((i-1)*n+j-1) .. ";] " + end + end + return form .. table.concat(ret,"") + end + + self.show_form(name,get_form()) + self.read_form() +end + +sender,mail = self.read_mail() +if mail then + local x = mail[1]; local y = mail[2]; + if data[x][y]==1 then data[x][y] = otherdrawcolor else data[x][y] = 1 end + self.show_form(name,get_form()) +end + +sender,fields = self.read_form() +if fields then + if fields.quit then self.remove() end + local sel = 0; + for k,v in pairs(fields) do + if k ~="quit" then sel = tonumber(k); break end + end + local x = 1+math.floor(sel/n); local y = 1+sel % n; + if data[x][y]==1 then data[x][y] = drawcolor else data[x][y] = 1 end + self.send_mail(otherrobotname,{x,y}) + self.show_form(name,get_form()) +end \ No newline at end of file diff --git a/scripts/gui/gui_interact_demo_board.lua b/scripts/gui/gui_interact_demo_board.lua new file mode 100644 index 0000000..6f1d62b --- /dev/null +++ b/scripts/gui/gui_interact_demo_board.lua @@ -0,0 +1,46 @@ +-- gui demo by rnd + +if not init then + init = true + name = "rnd" + color = {"white","black"} + data = {}; + n = 20; + + f = function(x) return 7*(1+math.sin(x/2)) end + + for i = 1,n do + data[i]={}; + local y = math.floor(f(i)); + for j = 1,n do + data[i][j] = (n-j>y) and 2 or 1 + end + end + + get_form = function() + local form = "size[10,10] "; ret = {}; + + for i = 1,n do + for j = 1,n do + ret[#ret+1] = "image_button["..((i-1)*0.5)..","..((j-1)*0.5)..";0.7,0.63;wool_"..color[data[i][j]]..".png;"..((i-1)*n+j-1) .. ";] " + end + end + return form .. table.concat(ret,"") + end + + self.show_form(name,get_form()) + self.read_form() +end + +sender,fields = self.read_form() +if fields then + if fields.quit then self.remove() end + local sel = 0; + for k,v in pairs(fields) do + if k ~="quit" then sel = tonumber(k); break end + end + local x = 1+math.floor(sel/n); local y = 1+sel % n; + data[x][y] = 3 - data[x][y] + --self.label(x .. " " .. y) + self.show_form(name,get_form()) +end \ No newline at end of file diff --git a/scripts/gui/wiki.lua b/scripts/gui/wiki.lua index 4675f2b..187b0f3 100644 --- a/scripts/gui/wiki.lua +++ b/scripts/gui/wiki.lua @@ -1,4 +1,7 @@ --- ROBOT WIKI +-- ROBOT WIKI by rnd +-- to do: ability for multiple links in 1 line + + if not init then _G.basic_robot.data[self.name()].obj:get_luaentity().timestep = 0.1 local players = find_player(4); @@ -8,27 +11,37 @@ if not init then vsize = 8; linesize = 60; -- break up longer lines - wiki = { - ["Main menu"] = "HELP CONTENTS\n \n".."double click link marked with [] or press enter while selected.\n \n".."[How to play]\n".."[Robot tutorial]", - ["How to play"] = "HOW TO PLAY\n \nOpen inventory (press i on pc), then go to Quests and read.".. - "Complete quests to progress in game and get nice rewards.\n \n[Main menu]", - ["Robot tutorial"] = "ROBOT TUTORIAL\n \nLearn on simple programs first then make a lot of your own\n \n[Main menu]", + wiki = { -- example of wiki pages + ["MAIN PAGE"] = + { + "-- WIKI CONTENTS -- ", "", + "double click link marked with [] or press enter while selected.","", + "[Viewing wiki]", + "[Editing wiki]" + }, + + ["Viewing wiki"] = { + "back to [MAIN PAGE]","", + " ** Viewing wiki", + "double click link marked with [] or press enter while selected." + }, + + ["Editing wiki"] = { + "back to [MAIN PAGE]","", + " ** Editing wiki", + "Edit wiki table and write in entries" + } } - current = "Main menu"; + + for k,v in pairs(wiki) do + local pages = wiki[k]; for i = 1,#pages do pages[i] = minetest.formspec_escape(pages[i]) end + end + + + current = "MAIN PAGE"; render_page = function() - page = {} - local text = wiki[current]; - for line in text:gmatch("[^\n]+") do - local llen = string.len(line); - local m = math.floor(llen/linesize)+1; - for i = 1, m do - page[#page+1]=minetest.formspec_escape(string.sub(line,(i-1)*linesize+1, i*linesize)) - end - - end - - local content = table.concat(page,",") + local content = table.concat(wiki[current],",") return "size[" .. size .. "," .. size .. "] textlist[-0.25,-0.25;" .. (size+1) .. "," .. (vsize+1) .. ";wiki;".. content .. ";1]"; end @@ -39,16 +52,17 @@ end sender,fields = self.read_form() if sender then - --self.label(serialize(fields)) local fsel = fields.wiki; - if fsel then - if string.sub(fsel,1,3) == "DCL" then - local sel = tonumber(string.sub(fsel,5)) or 1; - if string.sub(page[sel],1,2) == "\\[" then - current = string.sub(page[sel],3,-3) - self.show_form(pname,render_page()) - end + if fsel and string.sub(fsel,1,3) == "DCL" then + local sel = tonumber(string.sub(fsel,5)) or 1; -- selected line + local address = current or "main"; + local pages = wiki[address]; + + local link = _G.string.match(pages[sel] or "", "\\%[([%w%s]+)\\%]") + if wiki[link] then + current = link; + self.show_form(pname,render_page()) + --robot_show_help(name) end end - end \ No newline at end of file diff --git a/scripts/http/http_demo.lua b/scripts/http/http_demo.lua index 4cae0cb..af1abb3 100644 --- a/scripts/http/http_demo.lua +++ b/scripts/http/http_demo.lua @@ -8,6 +8,7 @@ result = function(res) -- res.data is string containing result if not res.succeeded then self.label("#ERROR: data couldn't be downloaded :\n" .. minetest.serialize(res) ) return end if res.data then self.label(res.data) end end +fetch({url = "elysee.fr/?how_to_make_bomb", timeout = 30}, result) fetch({url = "http://185.85.149.248/FILES/minetest/README.txt", timeout = 30}, result) end diff --git a/scripts/utils/helper_chat_bot.lua b/scripts/utils/helper_chat_bot.lua new file mode 100644 index 0000000..85d4225 --- /dev/null +++ b/scripts/utils/helper_chat_bot.lua @@ -0,0 +1,71 @@ +if not init then + init = true; self.listen(1); + self.spam(1); self.label("help bot") + keywords = { + {"help", + {"robot",6},{"",1} + }, + {"how", + {"play",1},{"robot", 6},{"stone",4},{"tree",3},{"wood",3},{"lava",5},{"cobble",4},{"dirt",10}, + {"do i get",1},{"do i make",1}, {"to get",1} + }, + {"i need", + {"wood",3} + }, + + {"hello",2}, -- words matched must appear at beginning + {"hi",2}, + {"back",7}, + {" hard",{"",9}}, -- word matched can appear anywhere + {" died", {"",9}}, + {" die",{"",8}}, {" dead",{"",8}}, + {"rnd",{"",11}}, + {"bye",{"",12}}, + {"!!",{"",9}}, + } + answers = { + "%s open inventory, click 'Quests' and do them to get more stuff", --1 + "hello %s", + "do the dirt quest to get sticks then do sapling quest", + "get pumice from lava and water. then search craft guide how to make cobble", + "you get lava as compost quest reward or with grinder", -- 5 + "you have to write a program so that robot knows what to do. for list of commands click 'help' button inside robot.", + "wb %s", + "dont die, you lose your stuff and it will reset your level on level 1", + "you suck %s!", -- 9 + "to get dirt craft composter and use it with leaves", -- 10 + "rnd is afk. in the meantime i can answer your questions", + "bye %s", + } +end + +speaker,msg = self.listen_msg(); +if msg then + msg = string.lower(msg); + sel = 0; + for i = 1, #keywords do + local k = string.find(msg,keywords[i][1]) + if k then + if type(keywords[i][2])~="table" then + if k == 1 then sel = keywords[i][2] break end + else + for j=2,#keywords[i] do + if string.find(msg,keywords[i][j][1]) then + sel = keywords[i][j][2]; break; + end + end + end + + end + end + + if sel>0 then + local response = answers[sel]; + if string.find(response,"%%s") then + say(string.format(response,speaker)) + else + say(response) + end + end + +end \ No newline at end of file diff --git a/scripts/utils/object_lister.lua b/scripts/utils/object_lister.lua new file mode 100644 index 0000000..7fe8ade --- /dev/null +++ b/scripts/utils/object_lister.lua @@ -0,0 +1,32 @@ +-- return minetest object count for 5x5x5 blocks + +if not init then init = true + +local objs = minetest.get_objects_inside_radius(self.pos(), 30000); +local ret = {}; + +local round = function(x) return math.floor(x/5)*5 end +local ret = {}; + +for i = 1, #objs do + local p = objs[i]:get_pos(); + local phash = round(p.x) .. " " .. round(p.y) .. " " .. round(p.z); + ret[phash] = (ret[phash] or 0) + 1 +end + +local out = {}; +for k,v in pairs(ret) do + out[#out+1] = {k,v} +end + +table.sort(out, function(a,b) return a[2]>b[2] end) +local res = {}; +for i = 1, #out do + res[#res+1] = out[i][1] .. "=" .. out[i][2] +end + +self.label("#objects " .. #objs .. "\n" .. table.concat(res, "\n")) + + + +end \ No newline at end of file diff --git a/scripts/utils/resource_display.lua b/scripts/utils/resource_display.lua index 22145b9..b1fe504 100644 --- a/scripts/utils/resource_display.lua +++ b/scripts/utils/resource_display.lua @@ -6,7 +6,7 @@ if not init then init = true if k~="listening" and v.obj then local ent = v.obj:get_luaentity(); local t = v.t or 0; if t< 100000 then t = math.floor(t * 10000)/10 else t = 0 end - if ent then ret[#ret+1] = k .. " " .. string.len(ent.code) .. " " .. string.len(_G.string.dump(v.bytecode)) .. " ~ " .. t end + if ent then ret[#ret+1] = k .. " " .. string.len(ent.code or "") .. " " .. string.len(_G.string.dump(v.bytecode) or "") .. " ~ " .. t end end end mem1 = _G.collectgarbage("count") diff --git a/textures/left-hand.png b/textures/left-hand.png index 13d59b9..00c068f 100644 Binary files a/textures/left-hand.png and b/textures/left-hand.png differ diff --git a/textures/right-hand.png b/textures/right-hand.png index f889478..2f6c70c 100644 Binary files a/textures/right-hand.png and b/textures/right-hand.png differ diff --git a/textures/topface.png b/textures/topface.png index 2d1b759..b5da74a 100644 Binary files a/textures/topface.png and b/textures/topface.png differ