local Q={ O={}, -- queue objects P=0, -- queue position p=false, -- paused palette={}, -- blocks we've placed (for chat filtering) T=0.0, -- time since last block E=0.0, -- time elapsed S=1.25, -- time limit } --TODO: add negotiation w/ server? --TODO: add undo by logging original block in the queue then reversing queue direction minetest.register_globalstep(function(t) if not Q.p and #Q.O > Q.P then Q.T=Q.T+t if Q.T>Q.S then Q.E=Q.E+t Q.T=0 Q.P=Q.P+1 local qe=Q.O[Q.P] local cmd, ca="setblock", qe.x..","..qe.y..","..qe.z.." "..qe.block minetest.send_chat_message("/"..cmd.." "..ca) Q.palette[qe.block]=true -- minetest.display_chat_message("/"..cmd.." "..ca) -- minetest.run_server_chatcommand(cmd, ca) end end end) minetest.register_on_receiving_chat_message(function(msg) for k, v in pairs(Q.palette) do if msg=="\27(T@mcl_commands)\27F"..k.."\27E spawned.\27E" then -- I have no idea what this string is. return true end end end) minetest.register_chatcommand("block", { params = " [ ]", description = "Build a rectangle of at ,,", func = function(params) local p,op={}, {} _, _, op.Block, op.X, op.Y, op.Z, op.W, op.H, op.L=string.find(params, "([%S]+) ([-%d]+) ([-%d]+) ([-%d]+) ?([-%d]*) ?([-%d]*) ?([-%d]*)") for k, v in pairs(op) do if v~="" then p[k]=tonumber(v) or v end end if not p.Block or not p.X or not p.Y or not p.Z then return false, "[Error: bad command]: missing "..((not p.Block) and "Block ") .. ((not p.X) and "X ") .. ((not p.Y) and "Y ") .. ((not p.Z) and "Z") end if p.W < 0 then p.W=-p.W p.X=p.X-p.W end if p.H < 0 then p.H=-p.H p.Y=p.Y-p.H end if p.L < 0 then p.L=-p.L p.Z=p.Z-p.L end for x=0,p.W do for y=0,p.H do for z=0,p.L do table.insert(Q.O, {block=p.Block, x=p.X+x-1, y=p.Y+y-1, z=p.Z+z-1}) end end end end, }) -- TODO: add runtime pattern (re)loading -- TODO: make different types of patterns available -- - delta coords, generator functions, "XXXXyXXXX" {X="mcl_core:dirt", y="mcl_core:cobble"}, etc. gme_designs={ ["spiral3x3"]={ {x=-1, y= 0, z=-1}, {x=-1, y= 0, z= 0}, {x=-1, y= 1, z= 1}, {x= 0, y= 1, z= 1}, {x= 1, y= 2, z= 1}, {x= 1, y= 2, z= 0}, {x= 1, y= 3, z=-1}, {x= 0, y= 3, z=-1}, }, }, minetest.register_chatcommand("spiral3x3", { params = " [ ]", description = "Build a powered rail spiral at ×4 block high at ,, or your current position.", func = function(params) local p,op={}, {} _, _, op.Block, op.H, op.X, op.Y, op.Z=string.find(params, "([%S]+) ([%d]+) ?([-%d]*) ?([-%d]*) ?([-%d]*)") for k, v in pairs(op) do if v~="" then p[k]=tonumber(v) or v end end if not p.Block or not p.H then return false, "[Error: bad command]: missing "..((not p.Block) and "Block ") .. ((not p.H) and "H ") end if not p.X or not p.Y or not p.Z then local pp=minetest.localplayer:get_pos() p.X, p.Y, p.Z=pp.x, pp.y, pp.z end for n=0,p.H do for k, v in ipairs(gme_designs["spiral"]) do table.insert(Q.O, {block=p.Block, x=p.X+v.x, y=p.Y+v.y+(n*4), z=p.Z+v.z}) table.insert(Q.O, {block="mcl_minecarts:golden_rail", x=p.X+v.x, y=p.Y+v.y+1+(n*4), z=p.Z+v.z}) end end end, }) minetest.register_chatcommand("spiral5x5", { params = " [ ]", description = "Build a powered rail spiral at ×4 block high at ,, or your current position.", func = function(params) local p,op={}, {} _, _, op.Block, op.H, op.X, op.Y, op.Z=string.find(params, "([%S]+) ([%d]+) ?([-%d]*) ?([-%d]*) ?([-%d]*)") for k, v in pairs(op) do if v~="" then p[k]=tonumber(v) or v end end if not p.Block or not p.H then return false, "[Error: bad command]: missing "..((not p.Block) and "Block ") .. ((not p.H) and "H ") end if not p.X or not p.Y or not p.Z then local pp=minetest.localplayer:get_pos() p.X, p.Y, p.Z=pp.x, pp.y, pp.z end local dm, dmi={ {x= 1,z= 0}, {x= 0,z= 1}, {x=-1,z= 0}, {x= 0,z=-1}, }, 1 local l={x=p.X+2, y=p.Y, z=p.Z-2} for n=0,p.H+math.floor(p.H/4) do local nd=math.floor(n/4)+1 dmi=(nd%#dm)+1 -- print("dmi:", n, nd, dmi, dump2(dm[dmi])) local nl={ x=l.x+dm[dmi].x, y=l.y+1, z=l.z+dm[dmi].z, } if n%4==0 then nl.y=l.y else if n%5~=0 then table.insert(Q.O, {block="mcl_ocean:sea_lantern", x=p.X, y=nl.y, z=p.Z}) end table.insert(Q.O, {block=p.Block, x=nl.x, y=nl.y-1, z=nl.z}) end table.insert(Q.O, {block=p.Block, x=nl.x, y=nl.y, z=nl.z}) table.insert(Q.O, {block="mcl_minecarts:golden_rail", x=nl.x, y=nl.y+1, z=nl.z}) l=nl end end, }) minetest.register_chatcommand("delay", { params = "", description = "Set delay to S seconds per-operation (Default of 1.25s)", func = function(param) Q.S=tonumber(param) return true, "[Delay set]" end, }) minetest.register_chatcommand("pause", { description = "Toggle execution of the GWB queue", func = function(param) Q.p=not Q.p if Q.p then return true, "[Queue paused]" else return true, "[Queue resumed]" end end, }) minetest.register_chatcommand("abort", { description = "Clear the current GWB edit queue", func = function(param) Q.O={} Q.P=0 Q.T=0.0 Q.palette={} return true, "[Queue cleared]" end, }) minetest.register_chatcommand("status", { description = "View the current queue status", func = function(param) return true, "Queue:\n".. (#Q.O).." operations ("..(#Q.O-Q.P).." remaining) = "..((Q.P/#Q.O)*100).."%\n".. Q.S.."s per operation\n".. "~"..((#Q.O-Q.P)*Q.S).."s remaining" end, })