Skip to content

Instantly share code, notes, and snippets.

@mkarneim
Last active February 12, 2017 09:18
Show Gist options
  • Save mkarneim/8deed890e0d92ef19506e889819b2e97 to your computer and use it in GitHub Desktop.
Save mkarneim/8deed890e0d92ef19506e889819b2e97 to your computer and use it in GitHub Desktop.
Sample Prog
require "gist.4d55b3573209200edcf73e1dbbd442ce.sample-lib"
BLOCK = {
hasName = function(exp)
return function(act)
return act.name == exp
end
end,
is = function(exp)
return function(act)
return act.name == exp.name
end
end,
isOneOf = function(...)
local vararg = {...}
return function(act)
for _,exp in pairs(vararg) do
if act.name == exp.name then
return true
end
end
return false
end
end,
hasNameOneOf = function(...)
local vararg = {...}
return function(act)
for _,exp in pairs(vararg) do
if act.name == exp then
return true
end
end
return false
end
end,
notIs = function(exp)
return function(act)
return act.name ~= exp.name
end
end,
notHasName = function(exp)
return function(act)
return act.name ~= exp
end
end,
blocksMovement = function(exp)
return function(act)
return act.material.blocksMovement == exp
end
end
}
POS = {
is = function(exp)
return function(act)
return exp.x == act.x
and exp.y == act.y
and exp.z == act.z
end
end,
notIs = function(exp)
return function(act)
return exp.x ~= act.x
or exp.y ~= act.y
or exp.z ~= act.z
end
end,
isInSphere = function(r,exp)
exp = exp or vec3(getWorldPos())
return function(act)
local x = act.x - exp.x
local y = act.y - exp.y
local z = act.z - exp.z
return x*x+y*y+z*z < r*r
end
end,
isInBox = function(r,exp)
exp = exp or vec3(getWorldPos())
local min = {x=exp.x-r,y=exp.y-r,z=exp.z-r}
local max = {x=exp.x+r,y=exp.y+r,z=exp.z+r}
return POS.isInBounds(min,max)
end,
isInBounds = function(min,max)
return function(act)
return min.x <= act.x and act.x <= max.x
and min.y <= act.y and act.y <= max.y
and min.z <= act.z and act.z <= max.z
end
end,
isInPlane = function(plane,exp)
exp = exp or vec3(getWorldPos())
if "x" == plane then
return function(act)
return act.x == exp.x
end
end
if "y" == plane then
return function(act)
return act.y == exp.y
end
end
if "z" == plane then
return function(act)
return act.z == exp.z
end
end
error("expected plane x, y, or z!")
end,
isAbove = function(exp)
exp = exp or vec3(getWorldPos())
return function(act)
return act.y >= exp.y
end
end
}
function sortpos(p1,p2)
local r1 = vec3(math.min(p1.x,p2.x), math.min(p1.y,p2.y), math.min(p1.z,p2.z) )
local r2 = vec3(math.max(p1.x,p2.x), math.max(p1.y,p2.y), math.max(p1.z,p2.z) )
return r1,r2
end
function floor(l,w,blk)
blk = blk or getBlock();
local dz = 1
if l<0 then
dz=-1
l=dz*l
end
local dx = 1
if w<0 then
dx=-1
w=dx*w
end
pushLoc()
for x=1,w do
for z=1,l do
place(blk)
move(FORWARD,dz)
sleep(0)
end
move(BACK,dz*l)
move(RIGHT,dx)
end
popLoc()
end
function pillar(h,blk)
h = math.min(h, 255)
blk = blk or getBlock()
local dy = 1
if h < 0 then
dy = -1
h=h*dy
end
for i=1,h do
place(blk)
sleep(0)
move(UP,dy)
end
move(DOWN,dy*h)
end
function bar(l)
blk = blk or getBlock()
for i=1,l do
place(blk)
move(SURFACE)
sleep(0)
end
move(SURFACE,-l)
end
function wall(l,h,blk)
blk = blk or getBlock()
local dz = 1
if l<0 then
dz=-1
l=dz*l
end
for i=1,l do
pillar(h,blk)
move(FORWARD,dz)
end
cursor.move(BACK,dz*l)
end
function box(l,w,h,blk)
blk = blk or getBlock()
local dx = 1
if w<0 then
dx=-1
w=dx*w
end
for x=1,w do
wall(l,h,blk)
move(RIGHT,dx)
end
move(LEFT,dx*w)
end
-- /lua sphere(5,'sandstone')
function sphere(r,blk)
blk = blk or getBlock()
pushLoc()
local d=2*r
for y=-r,r do
for z=-r,r do
for x=-r,r do
setPos(x,y,z)
if x*x+y*y+z*z < r*r then
place(blk)
end
sleep(0)
end
end
end
popLoc()
end
-- /lua pyramid(21,'sandstone')
function pyramid(w,blk)
blk = blk or getBlock()
pushLoc()
local lev = 0
while w>1 do
floor(w,w,blk)
lev=lev+1
moveBy(1,1,-1)
w=w-2
end
if w==1 then
if blk ~= nil then
place(blk)
else
paste(snap)
end
lev=lev+1
end
popLoc()
end
-- /lua skyscraper(6,5,3,"stone")
function skyscraper(w,fh,f,blk)
blk = blk or getBlock()
local h = f*fh
local l = w
pushLoc()
pillar(h,blk)
move(FORWARD,w-1)
pillar(h,blk)
move(RIGHT,w-1)
pillar(h,blk)
move(BACK,w-1)
pillar(h,blk)
move(LEFT,w-1)
if w > 4 and h > 3 then
move(FORWARD)
box(w-2,w,h-1,"glass")
move(BACK)
move(RIGHT)
box(l,w-2,h-1,"glass")
move(FORWARD)
box(l-2,w-2,h-1,"air")
move(BACK)
move(LEFT)
end
local y = 0
while y < h do
floor(l,w,blk)
y=y+fh
move(UP,fh)
end
popLoc()
end
-- /lua enlight(11,11)
-- /lua enlight(5,5,1)
-- /lua enlight(3,3,2)
function enlight(l,w,d)
plantfield(l,w,d,"torch")
end
function plantfield(l,w,d,blk)
blk = blk or getBlock()
d = d or 5
pushLoc()
local restw = w
while restw >= 1 do
plantrow(l,d,blk)
local dist = walk(RIGHT,d)
if dist ~= d then
break
end
restw = restw - d
end
popLoc()
end
-- /lua dist=findNext(DOWN,BLOCK.notHasName("air"));print(dist)
-- /lua dist=findNext(DOWN,BLOCK.hasName("dirt"));print(dist)
function findNext(dir,blockPredicate)
pushLoc()
local result = 0
while not blockPredicate(getBlock()) do
move(dir)
result = result + 1
local _,y,_ = getWorldPos()
if y > 255 or y < 0 then
popLoc()
return nil
end
end
popLoc()
return result
end
-- /lua plantrow(16,5,"sapling")
-- /lua plantrow(5,1,"sapling")
-- /lua plantrow(3,1,"torch")
function plantrow(l,d,blk)
blk = blk or getBlock()
d = d or 1
pushLoc()
if moveToGround() then
local rest = l
while rest >= 1 do
place(blk)
sleep(0)
local dist = walk(FORWARD,d)
if dist ~= d then
break
end
rest = rest - d
end
end
popLoc()
end
-- /lua walk(FORWARD,5);place("standing_sign")
function walk(dir,l,maxJumpHeight)
if not moveToGround(maxJumpHeight) then
return 0
end
for z=0,l-1 do
move(dir)
if not moveToGround(maxJumpHeight) then
move(dir,-1)
return z
end
end
return l
end
-- /lua moveToGround();place("standing_sign")
function moveToGround(maxJumpHeight)
maxJumpHeight = maxJumpHeight or 256
local dist = findNext(DOWN,BLOCK.notHasName("air"))
if dist ~= nil and dist > 0 and dist <= maxJumpHeight then
move(DOWN,dist-1)
end
local isBlocking = BLOCK.blocksMovement(true)
local notIsBlocking = BLOCK.blocksMovement(false)
if isBlocking(getBlock()) then
local dist2 = findNext(UP,notIsBlocking)
if dist2 ~= nil and dist2 > 0 and dist2 <= maxJumpHeight then
move(UP,dist2)
end
end
return isOnGround()
end
function isOnGround()
local isBlocking = BLOCK.blocksMovement(true)
local notIsBlocking = BLOCK.blocksMovement(false)
pushLoc()
if isBlocking(getBlock()) then
popLoc()
return false
end
move(DOWN)
if notIsBlocking(getBlock()) then
popLoc()
return false
end
popLoc()
return true
end
function sun()
cmd("time set day")
cmd("weather clear")
end
function frame(l,w,blk)
blk = blk or getBlock()
for i=1,l-1 do
place(blk)
move(FORWARD)
end
for i=1,w-1 do
place(blk)
move(RIGHT)
end
for i=1,l-1 do
place(blk)
move(BACK)
end
for i=1,w-1 do
place(blk)
move(LEFT)
end
end
function disk(r,blk)
blk = blk or getBlock()
pushLoc()
for x=-r,r do
for z=-r,r do
if x*x+z*z <= r*r then
setPos(x,0,z)
place(blk)
end
sleep(0)
end
end
popLoc()
end
function ferrari()
local x,y,z = getWorldPos()
local command = '/summon Boat '..x..' '..(y+0.5)..' '..z..' {CustomName:"Ferrari",CustomNameVisible:1,NoGravity:1b,Type:"birch"}'
cmd(command)
end
function runco1(len)
co1 = coroutine.create(
function ()
while true do
place("gravel")
coroutine.yield()
place("sand")
coroutine.yield()
end
end
)
for z=1,len do
coroutine.resume(co1)
move(FORWARD)
end
end
function runblock(width,times,delay,blk)
times = times or 10
delay = delay or 1
blk = blk or getBlock()
for i=1,times do
for l=1,width do
local orig = getBlock()
place(blk)
sleep(delay)
place(orig)
move(FORWARD)
end
rotate(CLOCKWISE_90)
end
end
function runblock2(maxlen,delay,blk)
blk = blk or getBlock()
maxlen = maxlen or 64
delay = delay or 1
pushLoc()
for l=1,maxlen do
local orig = getBlock()
place(blk)
sleep(delay)
place(orig)
move(FORWARD)
while getBlock().name ~= "air" do
move(BACK)
rotate(CLOCKWISE_90)
move(FORWARD)
end
end
popLoc()
place(blk)
end
function boom(times,delay)
delay = 100 or delay
for i=1,times do
pushLoc()
place("tnt")
move(DOWN)
place("redstone_block")
sleep(delay)
popLoc()
end
end
function counter(num,delay)
local blk = "sandstone"
delay = delay or 20
local w = 0
pushLoc()
local i = 1
pillar(1,blk)
print(i)
sleep(delay)
if num > 1 then
while true do
w=w+1
for c=1,2 do
for x=1,w do
move(FORWARD)
i=i+1
pillar(1,blk)
print(i)
sleep(delay)
if i>=num then
popLoc()
return
end
end
rotate(CLOCKWISE_90)
end
end
end
end
function hollowpyramid(w,blk)
blk = blk or getBlock()
pushLoc()
local lev = 0
floor(w,w,blk)
while w>1 do
frame(w,w,blk)
lev=lev+1
moveBy(1,1,-1)
w=w-2
end
if w==1 then
place(blk)
lev=lev+1
end
popLoc()
end
function multirunblock()
cmd('lua runblock(10,100,"stone")')
rotate(CLOCKWISE_90)
cmd('lua runblock(10,100,"stone")')
rotate(CLOCKWISE_90)
cmd('lua runblock(10,100,"stone")')
rotate(CLOCKWISE_90)
cmd('lua runblock(10,100,"stone")')
end
function randomwalk(times,delay,maxJumpHeight,blk)
times = times or 10
delay = delay or 0
maxJumpHeight = maxJumpHeight or 256
blk = blk or getBlock()
local max = 10
local dirs = {NORTH,"NORTH_EAST",EAST,"SOUTH_EAST",SOUTH,"SOUTH_WEST",WEST,"NORTH_WEST"}--,UP,DOWN}
for i=1,times do
local dist = math.random(1,max)
local dirIdx = math.random(1,#dirs)
local dir = dirs[dirIdx]
local d1,d2 = splittext(dir,"_")
for d=1,dist do
local dst = walk(d1,1,2,maxJumpHeight)
if d2 ~= nil then
dst = dst + walk(d2,1,maxJumpHeight)
end
sleep(delay)
if dst == 0 then
break
end
place(blk)
end
end
end
function sign(text,action)
text = text or "Click Me!"
action = action or "/lua bolt()"
text = replacetext(text,'"','\\\\"')
action = replacetext(action,'"','\\\\"')
--local cmdText = '/setblock ~ ~ ~ standing_sign 0 replace {Text1:"{\\"text\\":\\"Click Me!\\",\\"clickEvent\\":{\\"action\\":\\"run_command\\",\\"value\\":\\"/lua bolt()\\"}}"}'
local cmdText = '/setblock ~ ~ ~ standing_sign 0 replace {Text1:"{\\"text\\":\\"'..text..'\\",\\"clickEvent\\":{\\"action\\":\\"run_command\\",\\"value\\":\\"'..action..'\\"}}"}'
cmd(cmdText)
end
function wallsign(text,action)
text = text or "Click Me!"
action = action or "/lua bolt()"
text = replacetext(text,'"','\\\\"')
action = replacetext(action,'"','\\\\"')
sleep(1)
--local cmdText = '/setblock ~ ~ ~ standing_sign 0 replace {Text1:"{\\"text\\":\\"Click Me!\\",\\"clickEvent\\":{\\"action\\":\\"run_command\\",\\"value\\":\\"/lua bolt()\\"}}"}'
local rot = cursor.getRotation()
local rotval = 0
if rot == CLOCKWISE_180 then
rotval = 2
elseif rot == CLOCKWISE_90 then
rotval = 4
elseif rot == NONE then
rotval = 3
elseif rot == COUNTERCLOCKWISE_90 then
rotval = 5
end
local cmdText = '/setblock ~ ~ ~ wall_sign '..rotval..' replace {Text1:"{\\"text\\":\\"'..text..'\\",\\"clickEvent\\":{\\"action\\":\\"run_command\\",\\"value\\":\\"'..action..'\\"}}"}'
cmd(cmdText)
end
function replacetext(txt,a,b)
return string.gsub(txt, a, b)
end
function splittext(str,delim)
local i1,i2 = string.find(str, delim)
if i1 == nil then
return str
end
return string.sub(str, 1, i1-1), string.sub(str, i1+#delim, #str)
end
function moveToSurface()
local s = getSurface()
if s ~= nil then
move(s)
end
end
function waitForChat(e,m,timeout)
timeout = timeout or nil
local evt = nil
local chat = register(CHAT)
while evt == nil or evt.sender ~= e or evt.message ~= m do
evt = chat.next(timeout)
if evt == nil then
return false
end
end
return true
end
function aura(p1,e)
p1 = p1 or "enchantmenttable"
e = e or cursor.getOwnerName()
while true do
local x=math.random()-0.5
local y=math.random()
local z=math.random()-0.5
cmd("/execute "..e.." ~"..x.." ~"..y.." ~"..z.." particle "..p1.." ~ ~ ~ 0 1 0 1.5 4")
sleep(8)
end
end
function follow(blk,count)
count = count or 1000
local x,y,z = getOwnerPos()
for i=1,count do
local mx,my,mz = getPos()
if mx ~= x or my ~= y or mz ~= z then
setPos(x,y,z)
move(DOWN)
place(blk)
move(UP)
end
sleep(1)
end
end
function building(blk)
blk = blk or getBlock()
local h = 6
local w = 6
pushLoc()
for i=1,4 do
wall(w,h,"glass")
move(FORWARD,w)
rotate(CLOCKWISE_90)
end
popLoc()
pushLoc()
for i=1,4 do
pillar(h,blk)
move(FORWARD,6)
rotate(CLOCKWISE_90)
end
popLoc()
end
function room(blk)
blk = blk or getBlock()
local h = 6
local w = 6
pushLoc()
for i=1,4 do
wall(w,h,"glass")
move(FORWARD,w)
rotate(CLOCKWISE_90)
end
popLoc()
pushLoc()
for i=1,4 do
pillar(h,blk)
move(FORWARD,6)
rotate(CLOCKWISE_90)
end
popLoc()
pushLoc()
floor(w+1,w+1,blk)
move(UP,h)
floor(w+1,w+1,blk)
popLoc()
end
function tntcloud(drops,size,delay)
drops = drops or 5
size = size or 5
delay = delay or 5
local len = math.floor(size/2)
for i=1,drops do
setPos(getOwnerPos())
local dx = math.random(-len,len)
local dz = math.random(-len,len)
moveBy(dx,0,dz)
moveToGround()
move(UP,55)
sleep(delay)
cmd("/summon PrimedTnt ~ ~ ~ {Fuse:70}")
end
end
function spherewalk(r,count,delay)
r = r or 4
count = count or 100
delay = delay or 5
for i=1,count do
sphere(r,"air")
sleep(delay)
end
end
function city(l,b,f)
pushLoc()
for z=1,l do
pushLoc()
for x=1,b do
skyscraper(8,5,f,"stone")
move(FORWARD,16)
end
popLoc()
move(RIGHT,16)
end
popLoc()
end
function following(count,blk)
blk = blk or getBlock()
count = count or 500
local delay = 1
local name = "minecraft:"..blk.name
local offy = 1
local x,y,z = getOwnerPos()
y = y + offy
cmd('summon FallingSand '..x..' '..y..' '..z..' {Block:"'..name..'",Time:1,NoGravity:1,Tags:["following"]}')
sleep(1)
for i=1,count do
local r = cmd('execute @e[type=FallingSand,tag=following] ~ ~ ~ help');
if r == 0 then
break
end
cmd('entitydata @e[type=FallingSand,tag=following] {Pos:['..x..'d,'..y..'d,'..z..'d]}')
local cx,cy,cz = getOwnerPos()
cy = cy + offy
local dx = (cx-x)/(delay+1)
local dy = (cy-y)/(delay+1)
local dz = (cz-z)/(delay+1)
x = cx
y = cy
z = cz
--cmd('/entitydata @e[type=FallingSand,tag=following] {Pos:['..x..'d,'..y..'d,'..z..'d]}')
--cmd('/entitydata @e[type=FallingSand,tag=following] {Motion:['..dx..'d,'..dy..'d,'..dz..'d]}')
--sleep(1)
--cmd('/entitydata @e[type=FallingSand,tag=following] {Motion:[0.1d,0.1d,0.1d]}')
--cmd('/entitydata @e[type=FallingSand,tag=following] {Pos:['..x..'d,'..y..'d,'..z..'d],Motion:['..dx..'d,'..dy..'d,'..dz..'d]}')
cmd('entitydata @e[type=FallingSand,tag=following] {Motion:['..dx..'d,'..dy..'d,'..dz..'d]}')
print(dx,dy,dz)
sleep(delay)
end
end
function exists(plr)
local r = cmd('execute @e[type=Player,name='..plr..'] ~ ~ ~ help');print(r)
print("r",r)
return r
end
-- /lua placeOnMessage(4,"stone")
-- /msg @e[name=Lua-34] hi
function placeOnMessage(times,blk)
blk = blk or getBlock()
pushLoc()
blk = blk or "stone"
times = times or 1
local whisper = register(WHISPER)
local chat = register(CHAT)
for i=1,times do
local evt=nil
while evt==nil do
evt=whisper.next(2)
if evt==nil then
evt=chat.next(2)
end
end
place(blk)
move(UP)
end
popLoc()
end
function door(w,h,times,blk)
blk = blk or getBlock()
w = w or 3
h = h or 3
times = times or 100
local chat = register(CHAT)
for i=1,times do
local evt = nil
while evt == nil do
evt = chat.next()
if evt.message == "open" then
box(1,w,h,"air")
elseif evt.message == "close" then
box(1,w,h,blk)
end
end
end
end
function quiz(name,q,a)
local r
say(q)
local chat = register(CHAT)
local evt = nil
while evt == nil or evt.sender ~= name do
evt = chat.next()
end
if evt.message == a then
r = true
else
r = false
end
chat.deregister()
return r
end
function summonItem(name)
name = name or "golden_carrot"
sleep(1)
cmd("/summon Item ~0 ~0 ~0 {Item:{id:"..name..",Count:1}}")
end
function isInside(p,o1,o2)
o1,o2 = sortpos(o1,o2)
return o1.x <= p.x and p.x <= o2.x
and o1.y <= p.y and p.y <= o2.y
and o1.z <= p.z and p.z <= o2.z
end
function replace(sel,blk)
pushLoc()
for _,v in pairs(sel) do
setWorldPos(v.x,v.y,v.z)
place(blk)
end
popLoc()
end
function replaceWith(blk,max)
max = max or 16
local cur = getBlock()
local sel=selectAdjoining(BLOCK.is(cur),POS.isInBox(max));
replace(sel,blk)
end
function getNeighbours(predicate)
pushLoc()
local dirs = {NORTH,EAST,SOUTH,WEST,UP,DOWN}
local result = {}
for _,dir in ipairs(dirs) do
move(dir)
local blk = getBlock()
if predicate==nil or predicate(blk) then
local pos = vec3(getWorldPos())
table.insert(result,pos)
end
move(dir,-1)
end
popLoc()
return result
end
function select(s,pos)
pos = pos or vec3(getWorldPos())
table.insert(s,pos)
end
function selectBox(l,w,h)
local dx = 1
if w<0 then
dx=-1
w=dx*w
end
local dy = 1
if h<0 then
dy=-1
h=dy*h
end
local dz = 1
if l<0 then
dz=-1
l=dz*l
end
pushLoc()
local s = {}
for y=0,h-1 do
for x=0,w-1 do
for z=0,l-1 do
setPos(x*dx,y*dy,-z*dz)
select(s)
sleep(0)
end
end
end
popLoc()
return s
end
-- sel = selectBox(6,6,6);copyClip(sel)
-- pasteClip()
function copyClip(sel,name)
name = name or ""
local snap = copy(sel)
clipboard.put(name,snap)
return snap
end
function pasteClip(name)
name = name or ""
local snap = clipboard.get(name)
paste(snap)
end
function distance(dir,max)
dir = dir or SURFACE
max = max or 256
pushLoc()
local i = 0
move(dir)
while getBlock().name == "air" and i<=max do
move(dir)
i=i+1
end
popLoc()
return i
end
function fillwall()
local h=distance(UP)+1
local l=distance(SURFACE)+1
pillar(h)
for y=1,h do
bar(l)
move(UP)
end
end
function flow(n,count)
n = n or getOwnerName()
count = count or 10
for i=1,count do
cmd("effect @e[name="..n.."] minecraft:levitation 1 2")
sleep(25)
end
end
invisibility = {
stop = function(n)
n = n or getOwnerName()
events.fire("invisibility",n)
end,
start = function(n,p)
n = n or getOwnerName()
p = p or "smoke"
local queue = events.register("invisibility")
while true do
cmd("effect @e[name="..n.."] minecraft:invisibility 1 0 true")
for k=1,10 do
local dy = 0
for i=1,10 do
dy = dy + 0.15
local dx = math.random()*0.5-0.25
local dz = math.random()*0.5-0.25
cmd("/execute "..n.." ~ ~ ~ particle "..p.." ~"..dx.." ~"..dy.." ~"..dz.." 0 0.1 0 0 1 force")
end
local evt = queue.next(1)
if evt ~= nil and evt.message == n then
return
end
end
end
end
}
function particletrail(n,t,p)
n = n or getOwnerName()
p = p or "fireworksSpark"
t = t or 10
for j=1,t do
for k=1,10 do
local dy = 0
for i=1,10 do
dy = dy + 0.15
local dx = math.random()*0.5
local dz = math.random()*0.5
cmd("/execute "..n.." ~ ~ ~ particle "..p.." ~"..dx.." ~"..dy.." ~"..dz.." 0 0.1 0 0 1 force")
end
sleep(1)
end
end
end
-- sel=selectAdjoining(BLOCK.hasName("stone"),POS.isInBox(10));replace(sel,"grass")
-- sel=selectAdjoining(BLOCK.hasName("air"),POS.isInPlane("x"));replace(sel,"glass")
-- sel=selectAdjoining(BLOCK.is(getBlock()),POS.isInBox(10)); replace(sel,"air")
function selectAdjoining(blockPredicate,posPredicate,maxSel)
maxSel = maxSel or 16*16*16
maxy = maxy or 255
pushLoc()
local startpos=vec3(getWorldPos())
blockPredicate = blockPredicate or function(blk)
return blk.name ~= "air"
end
posPredicate = posPredicate or POS.isInBox(startpos,16)
local todo = {}
local done = {} -- hashset
local result = {}
local blk = getBlock()
function askey(p)
return p.x.."/"..p.y.."/"..p.z
end
local checks = 0
if blk == nil then
error("blk is nil!")
end
local pos = vec3(getWorldPos())
table.insert(todo,pos)
checks=checks+1
while #todo>0 do
sleep(0)
pos = table.remove(todo)
setWorldPos(pos.x,pos.y,pos.z)
if posPredicate(pos) then
blk = getBlock()
if blockPredicate(blk) then
table.insert(result,pos)
if #result > maxSel then
error("Can't select that many blocks! maxSel="..maxSel)
end
local neighbours = getNeighbours(blockPredicate)
for _,npos in ipairs(neighbours) do
local k = askey(npos)
local isdone
if done[k]==1 then
isdone = true
else
isdone = false
end
if not isdone then
table.insert(todo,npos)
done[k]=1
checks=checks+1
end
end
end
end
end
popLoc()
return result
end
function replacebox(l,w,h,blk,predicate)
if blk == nil then
error("blk is nil")
end
local dz = 1
if l<0 then
dz=-1
l=dz*l
end
local dx = 1
if w<0 then
dx=-1
w=dx*w
end
local dy = 1
if h<0 then
dy=-1
h=dy*h
end
for y=0,h-1 do
for z=0,l-1 do
for x=0,w-1 do
setPos(x*dx,y*dy,-z*dz)
if predicate == null or predicate(getBlock()) then
place(blk)
end
end
end
end
end
function give(item,n)
n = n or 1
cmd('give '..getOwnerName()..' '..item..' '..n)
end
function clicktest()
local click = events.register(RIGHT_CLICK, LEFT_CLICK)
for event in click.next do
local pos = event.pos
setWorldPos(pos.x, pos.y, pos.z)
local blk = getBlock()
print("event",event.type,event.id,event.face, blk.name)
move(event.face)
local blk2 = getBlock()
print("blk2",blk2.name)
end
end
function bless(pname,tag)
local p = players.getByName(pname)
if p ~= nil then
if p.addTag(tag) then
events.fire("bless",{player=pname,tag=tag})
end
end
end
function unbless(pname,tag)
local p = players.getByName(pname)
if p ~= nil then
if p.removeTag(tag) then
events.fire("unbless",{player=pname,tag=tag})
end
end
end
function isBlessed(pname,tag)
local p = players.getByName(pname)
if p ~= nil then
for _,ptag in pairs(p.tags) do
if ptag == tag then
return true
end
end
end
return false
end
function enableSayError()
local oldError = error;
error = function(t)
say("Error:",t)
oldError(t)
end
end
architect = {
stop = function (pname)
pname = pname or getOwnerName()
local ARCHITECT = "architect-control"
events.fire(ARCHITECT,{player=pname,command="STOP"})
end
,
start = function(pname)
pname = pname or getOwnerName()
local ARCHITECT = "architect-control"
local STOP = "STOP"
local MODE = "MODE"
local OFF = "OFF"
local BAR = "BAR"
local FLOOR = "FLOOR"
local WALL = "WALL"
local COPY = "COPY"
local CUT = "CUT"
local PASTE = "PASTE"
local REPLACE = "REPLACE"
local CUBE = "CUBE"
local DELETE = "DELETE"
local mode = OFF
local barmode = {
n=5
}
local cubemode = {
n=2
}
local replacemode = {
max=8
}
local deletemode = {
max=8
}
local copymode = {
max=16*16*16
}
local cutmode = {
max=16*16*16
}
bless(pname,"architect")
events.fire("architect",{player=pname})
local eventqueue = events.register(RIGHT_CLICK,CHAT,ARCHITECT)
for event in eventqueue.next do
if event.type == ARCHITECT then
if event.command == "STOP" and event.player == pname then
unbless(pname,"architect")
events.fire("architect",{player=pname})
return
end
end
if event.type == CHAT and event.sender == pname then
--print("chat", event.message)
if event.message == STOP then
unbless(pname,"architect")
events.fire("architect",{player=pname})
return;
elseif event.message == MODE then
msg(pname,mode)
elseif event.message == OFF then
mode = OFF
elseif event.message == BAR then
mode = BAR
elseif string.starts(event.message,BAR.." ") then
mode = BAR
local numstr = string.gmatch(event.message,"%d+")()
if numstr ~= nil then
barmode.n = tonumber(numstr)
end
elseif event.message == CUBE then
mode = CUBE
elseif string.starts(event.message,CUBE.." ") then
mode = CUBE
local numstr = string.gmatch(event.message,"%d+")()
if numstr ~= nil then
cubemode.n = tonumber(numstr)
end
elseif event.message == FLOOR then
mode = FLOOR
elseif event.message == WALL then
mode = WALL
elseif event.message == CUT then
mode = CUT
elseif string.starts(event.message,CUT.." ") then
mode = CUT
local numstr = string.gmatch(event.message,"%d+")()
if numstr ~= nil then
cutmode.max = tonumber(numstr)
end
elseif event.message == COPY then
mode = COPY
elseif string.starts(event.message,COPY.." ") then
mode = COPY
local numstr = string.gmatch(event.message,"%d+")()
if numstr ~= nil then
copymode.max = tonumber(numstr)
end
elseif event.message == PASTE then
mode = PASTE
elseif event.message == REPLACE then
mode = REPLACE
elseif string.starts(event.message,REPLACE.." ") then
mode = REPLACE
local numstr = string.gmatch(event.message,"%d+")()
if numstr ~= nil then
replacemode.max = tonumber(numstr)
end
elseif event.message == DELETE then
mode = DELETE
elseif string.starts(event.message,DELETE.." ") then
mode = DELETE
local numstr = string.gmatch(event.message,"%d+")()
if numstr ~= nil then
deletemode.max = tonumber(numstr)
end
end
end
if event.type == RIGHT_CLICK and event.player.name == pname then
--print("click", event.type, event.pos.x, event.pos.y, event.pos.z, event.player.name, event.player.orientation)
local p = "vec3("..event.pos.x..", "..event.pos.y..", "..event.pos.z..")"
if mode == BAR then
cmd("lua enableSayError(); a_bar("..p..","..event.face..","..barmode.n..")")
elseif mode == FLOOR then
cmd("lua enableSayError(); a_floor("..p..","..event.face..")")
elseif mode == WALL then
cmd("lua enableSayError(); a_wall("..p..","..event.face..")")
elseif mode == CUT then
local c = "lua enableSayError(); a_cut("..p..","..event.face..","..event.player.orientation..",'"..event.player.name.."',"..cutmode.max..")"
cmd(c)
elseif mode == COPY then
local c = "lua enableSayError(); a_copy("..p..","..event.face..","..event.player.orientation..",'"..event.player.name.."',"..copymode.max..")"
cmd(c)
elseif mode == PASTE then
local c = "lua enableSayError(); a_paste("..p..","..event.face..","..event.player.orientation..",'"..event.player.name.."')"
cmd(c)
elseif mode == REPLACE then
cmd("lua enableSayError(); a_replace("..p..","..event.face..","..replacemode.max..")")
elseif mode == DELETE then
cmd("lua enableSayError(); a_delete("..p..","..event.face..","..deletemode.max..")")
elseif mode == CUBE then
cmd("lua enableSayError(); a_cube("..p..","..event.face..","..event.player.orientation..","..cubemode.n..")")
end
end
end
end
}
function a_replace(pos,dir,max)
max = max or 8
setWorldPos(pos.x,pos.y,pos.z)
move(dir)
local blk = getBlock()
place("air")
move(dir,-1)
local cur = getBlock()
local sel=selectAdjoining(BLOCK.is(cur),POS.isInSphere(max));
for _,v in pairs(sel) do
setWorldPos(v.x,v.y,v.z)
place(blk)
sleep(0)
end
end
function a_delete(pos,dir,max)
max = max or 8
setWorldPos(pos.x,pos.y,pos.z)
move(dir)
place("air")
move(dir,-1)
local cur = getBlock()
local sel=selectAdjoining(BLOCK.is(cur),POS.isInSphere(max));
for _,v in pairs(sel) do
setWorldPos(v.x,v.y,v.z)
place("air")
sleep(0)
end
end
function a_bar(pos,dir,n)
if n > 256 then
error("n must not be greater than 256")
end
setWorldPos(pos.x,pos.y,pos.z)
move(dir)
local blk = getBlock()
for i=1,n do
place(blk)
move(dir)
end
setWorldPos(pos.x,pos.y,pos.z)
end
function a_floor(pos,dir)
setWorldPos(pos.x,pos.y,pos.z)
move(dir)
local blk = getBlock()
place("air")
--local sel = selectAdjoining(BLOCK.hasNameOneOf("air","water","flowing_water"),POS.isInPlane("y"))
local sel = selectAdjoining(BLOCK.blocksMovement(false),POS.isInPlane("y"))
for _,p in pairs(sel) do
setWorldPos(p.x,p.y,p.z)
place(blk)
end
end
function a_wall(pos,dir)
if dir ~= NORTH and dir ~= EAST and dir ~= SOUTH and dir ~= WEST then
error("dir must be one of NORTH, EAST, SOUTH, WEST, but was: "..dir)
end
setWorldPos(pos.x,pos.y,pos.z)
move(dir)
local blk = getBlock()
place("air")
local plane
if dir == NORTH or dir == SOUTH then
plane = "x"
else
plane = "z"
end
local sel = selectAdjoining(BLOCK.blocksMovement(false),POS.isInPlane(plane))
for _,p in pairs(sel) do
setWorldPos(p.x,p.y,p.z)
place(blk)
end
end
function a_copy(pos,dir,orientation,pname,maxsel)
setWorldPos(pos.x,pos.y,pos.z)
setOrientation(orientation)
move(dir)
place("air")
setWorldPos(pos.x,pos.y,pos.z)
local sel=selectAdjoining(BLOCK.notHasName("air"),POS.isAbove(),maxsel);
local snap = copy(sel)
clipboard.put(pname..".architect.snap",snap)
say(#sel.." blocks copied.")
end
function a_cut(pos,dir,orientation,pname,maxsel)
setWorldPos(pos.x,pos.y,pos.z)
setOrientation(orientation)
move(dir)
place("air")
setWorldPos(pos.x,pos.y,pos.z)
local sel=selectAdjoining(BLOCK.notHasName("air"),POS.isAbove(),maxsel);
local snap = cut(sel)
clipboard.put(pname..".architect.snap",snap)
say(#sel.." blocks copied.")
end
function a_paste(pos,dir,orientation,pname)
setWorldPos(pos.x,pos.y,pos.z)
setOrientation(orientation)
move(dir)
local snap = clipboard.get(pname..".architect.snap")
paste(snap)
end
function a_cube(pos,dir,orientation,n)
if n > 32 then
error("n must not be greater than 32")
end
setWorldPos(pos.x,pos.y,pos.z)
setOrientation(orientation)
move(dir)
local blk = getBlock()
local l = n
local w = n
local h = n
if dir == DOWN then
h = -h
end
if OPPOSITE[dir] == orientation then
l = -l
end
if ROTATE90CW[dir] == orientation then
w = -w
end
local s = selectBox(l,w,h)
fill(s,blk)
end
function fill(sel,blk)
pushLoc()
for _,v in pairs(sel) do
setWorldPos(v.x,v.y,v.z)
place(blk)
sleep(0)
end
popLoc()
end
function attack(p)
local x,y,z = getWorldPos()
local tag = "aaa"..x.."a"..y.."a"..z.."a"
cmd('/summon Zombie '..x..' '..y..' '..z..' {Tags:["'..tag..'"],ArmorItems:[{},{},{},{Count:1,id:diamond_helmet}],HandItems:[{Count:1,id:diamond_sword},{Count:1,id:shield}]}')
sleep(6);
cmd('/execute @e[tag='..tag..'] ~ ~ ~ /summon Snowball '..(x+3)..' '..(y+0.8)..' '..z..' {ownerName:"'..p..'",NoGravity:1,Motion:[-1.0d,0.0d,0.0d]}')
end
function protect()
local eventqueue = events.register(LEFT_CLICK)
for event in eventqueue.next do
--print(event.id,event.player.name)
local name = event.player.name
setWorldPos(event.pos.x,event.pos.y+1,event.pos.z)
local dist = findNext(DOWN,BLOCK.notHashName("air"))
if dist ~= nil and dist > 0 and dist <= 4 then
move(DOWN,dist-1)
msg(name,"Damaging anything is prohibited!")
attack(name)
else
dist = findNext(UP,BLOCK.hasName("air"))
if dist ~= nil and dist > 0 and dist <= 4 then
move(UP,dist)
msg(name,"Damaging anything is prohibited!")
attack(name)
end
end
end
end
function wandOfEffects()
local eventqueue = events.register(LEFT_CLICK)
for event in eventqueue.next do
print(event.id,event.type,event.player.name,event.player.gamemode)
if event.item ~= nil and event.item.name == 'minecraft:stick' then
setWorldPos(event.pos.x, event.pos.y, event.pos.z)
particle()
end
end
end
function printPos(pos)
print(pos.x, pos.y, pos.z)
end
function lightbar(v,max)
pushLoc()
box(v,1,1,"sea_lantern")
move(FORWARD,v)
box(max-v,1,1,"air")
popLoc()
end
function lift(l,w,h)
if l<2 then
error("l must be >=2")
end
if w<2 then
error("w must be >=2")
end
if h<1 then
error("h must be >=1")
end
while true do
pushLoc()
local s1 = vec3(getWorldPos())
move(FORWARD,1)
move(RIGHT,1)
local s2 = vec3(getWorldPos())
move(FORWARD,l-3)
move(RIGHT,w-3)
move(UP,h)
local e2 = vec3(getWorldPos())
move(FORWARD,1)
move(RIGHT,1)
local e1 = vec3(getWorldPos())
popLoc()
local targets = {}
for _,name in pairs(players.names()) do
if isPlayerInside(name,s1,e1) and not isPlayerInside(name,s2,e2) then
--say("Player "..name.." is inside!")
table.insert(targets,name)
end
end
for _,name in pairs(targets) do
cmd("effect @e[name="..name.."] minecraft:levitation 1 15 true")
end
sleep(15)
end
end
function tobox(p1,p2)
p1 = p1 or getWorldPosVec3()
p2 = p2 or p1
p1,p2 = sortpos(p1,p2)
return {p1=p1,p2=p2}
end
function toboxDelta(p1,dx,dy,dz)
p1,p2 = sortpos(p1,vec3(p1.x+dx,p1.y+dy,p1.z+dz))
return {p1=p1,p2=p2}
end
function asBox(dx,dy,dz)
local p1 = getWorldPosVec3()
local p2 = {x=p1.x+dx, y=p1.y+dy, z=p1.z+dz}
return {p1=p1,p2=p2}
end
function selectInBox(inBox)
local s = {}
for y=inBox.p1.y,inBox.p2.y do
for x=inBox.p1.x,inBox.p2.x do
for z=inBox.p1.z,inBox.p2.z do
local p = vec3(x,y,z)
table.insert(s,p)
end
end
end
return s
end
function detectPlayers(inBox)
inBox = inBox or tobox()
local result = {}
local plist = players.names()
for _,name in pairs(plist) do
if isPlayerInside(name,inBox.p1,inBox.p2) then
table.insert(result,name)
end
end
return result
end
function teleport(names,x,y,z)
if names == nil then
error("names is nil")
end
for _,name in pairs(names) do
cmd('tp '..name..' '..x..' '..y..' '..z)
end
end
function isPlayerInside(name,o1,o2)
local p = players.getByName(name)
if p ~= nil then
return isInside(p.blockPos, o1, o2)
end
return false
end
-- onDetectPlayersTeleport(-1075,88,233)
-- onDetectPlayersTeleport(-88, 63, 262)
function onDetectPlayersTeleport(x,y,z)
while true do
teleport(detectPlayers(),x,y,z)
sleep(10)
end
end
function printEntity(n)
local e = entities.get(n)
if e == nil then
print("<none>")
else
print(str(e))
end
end
function putEntity(n,data)
entities.put(n,data)
end
function stringOf(obj,vis,indent)
str(obj,vis,indent)
end
function str(obj,vis,indent)
vis = vis or {}
indent = indent or ""
if obj == nil then
return "nil"
end
if type(obj) == "table" and #obj > 0 and vis[obj] == obj then
return "<skipping endless recursion>"
end
vis[obj] = obj
if type(obj)=="table" then
local res = "{"
indent = indent.." "
for k,v in pairs(obj) do
if #res > 1 then
res = res..","
end
res = res.."\n"..indent
res = res..k.."="..str(v,vis,indent)
end
res = res.."}"
return res
elseif type(obj)=="boolean" then
return tostring(obj)
elseif type(obj)=="number" then
return obj
elseif type(obj)=="string" then
return "'"..obj.."'"
else
return type(obj)
end
end
function island(r,h)
local blk = "sand"
for i=1,h do
for d=1,3 do
disk(r,blk)
local dx = math.random(-2, 2)
local dz = math.random(-2, 2)
moveBy(dx,1,dz)
r=r-(dx*dx+dz*dz)/2
if r < 0 then
return
end
end
end
end
function sphere2(r,predicate)
local blk = getBlock()
pushLoc()
local d=2*r
for y=-r,r do
for z=-r,r do
for x=-r,r do
setPos(x,y,z)
if x*x+y*y+z*z < r*r then
local currBlk = getBlock()
if predicate == nil or predicate(currBlk) then
place(blk)
end
end
end
end
end
popLoc()
end
function printPlayer()
local name = getOwnerName()
local p = players.getByName(name)
local str = stringOf(p)
print(str)
end
function foo()
local i = 1
print("foo", i)
coroutine.yield()
i = i +1
print("foo", i)
end
function runfoo()
local co = coroutine.create(foo)
coroutine.resume(co)
sleep(20)
coroutine.resume(co)
end
function shoot(dist,pt)
dist = dist or 20
pt = pt or "smoke"
local p = players.getByName(getOwnerName())
local footPos = p.pos
local pos1 = vec3( footPos.x, footPos.y+1.8, footPos.z)
local factor = 5
local steps = dist * factor
local dx = p.lookVec.x / factor
local dy = p.lookVec.y / factor
local dz = p.lookVec.z / factor
local x = pos1.x + dx * factor
local y = pos1.y + dy * factor
local z = pos1.z + dz * factor
for i=1,steps do
cmd("particle "..pt.." "..x.." "..y.." "..z.." 0 0 0 0 0 force")
x = x + dx
y = y + dy
z = z + dz
if i % factor == 0 then
sleep(1)
end
setWorldPos(x,y,z)
if getBlock().name ~= "air" then
sleep(1)
cmd("/summon PrimedTnt ~ ~ ~ {Fuse:1}")
return
end
end
end
function jump(dist)
dist = dist or 16
local p = players.getByName(getOwnerName())
local pname = p.name
local footPos = p.pos
local lookVec = p.lookVec
local pos1 = vec3( footPos.x, footPos.y+1.8, footPos.z)
local factor = 5
local steps = dist * factor
local dx = lookVec.x / factor
local dy = lookVec.y / factor
local dz = lookVec.z / factor
local x = pos1.x + dx * factor
local y = pos1.y + dy * factor
local z = pos1.z + dz * factor
for i=1,steps do
x = x + dx
y = y + dy
z = z + dz
setWorldPos(x,y,z)
sleep(0)
if getBlock().name ~= "air" then
x = x - dx
y = y - dy
z = z - dz
cmd("tp "..pname.." "..x.." "..y.." "..z)
sleep(1)
return
end
end
cmd("tp "..pname.." "..x.." "..y.." "..z)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment