mapmodel direction fixes (mapmodel moves in same direction as it faces)

fire action fix
new scripts
master
rnd 2018-12-09 23:42:54 +01:00
parent 6b185ba155
commit 9e17cb46b9
16 changed files with 569 additions and 73 deletions

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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<size and y>-2 and y<size then
if y>0 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 B

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 B

After

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 303 B