Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --------------------------------------------
- -- Vril's sphere building program v 1.1.1 --
- --------------------------------------------
- --[[
- Why do I use diameter and not radius?
- It's simple! Radius 5 = diameter 10, Radius 6 = diameter 12. And where is my sphere with a diameter of 11? In minecraft, only an integer number of blocks is possible! ;)
- --]]
- function recalcWork(start,finish)
- local x,y,z
- count=0
- for z=1,size do
- for x=1,size do
- for y=1,size do
- if z<=start or z>finish+1 then matr[z][x][y]=false end
- if matr[z][x][y] then count=count+1 end
- end
- end
- end
- end
- function findeNearestPlot(height)
- local x,y
- local res={-1,-1}
- local mindist=math.huge
- local dist=0
- for x=1,size do
- for y=1,size do
- if matr[height][x][y] then
- dist=(x-tX)*(x-tX) + (y-tY)*(y-tY)
- if dist<mindist then
- mindist=dist
- res[1],res[2]=x,y
- end
- end
- end
- end
- return res
- end
- function isInSphere(x,y,z)
- local radiusSq=diameter*diameter/4.0
- local offset=0
- if math.fmod(diameter, 2) == 0 then
- offset = math.floor(size/2 +0.5)+0.5
- else
- offset = math.floor(size/2 +0.5)
- end
- x=x-offset;
- y=y-offset;
- z=z-offset;
- x=x*x;
- y=y*y;
- z=z*z;
- return x+y+z < radiusSq;
- end
- function generateBlocks()
- local blks={}
- local x,y,z=0,0,0
- for z=1,size do
- blks[z]={}
- for x=1,size do
- blks[z][x]={}
- for y=1,size do
- blks[z][x][y]=isInSphere(x,y,z)
- end
- end
- end
- return blks;
- end
- function purgeBlocks()
- local newblocks={}
- local blocks={}
- local x,y,z=0,0,0
- count=0
- blocks=generateBlocks()
- for z=1,size do
- newblocks[z]={}
- for x=1,size do
- newblocks[z][x]={}
- for y=1,size do
- if x==1 or x==size or y==1 or y==size or z==1 or z==size then
- newblocks[z][x][y]=blocks[z][x][y]
- else
- newblocks[z][x][y]=blocks[z][x][y] and (
- not blocks[z-1][x][y] or
- not blocks[z+1][x][y] or
- not blocks[z][x-1][y] or
- not blocks[z][x+1][y] or
- not blocks[z][x][y-1] or
- not blocks[z][x][y+1] )
- end
- if newblocks[z][x][y] then count=count+1 end
- end
- end
- end
- return newblocks
- end
- function forceDigFront()
- while turtle.detect() do
- turtle.dig()
- sleep(0.2)
- end
- end
- function forceDigUp()
- while turtle.detectUp() do
- turtle.digUp()
- sleep(0.2)
- end
- end
- function forceMoveForward()
- local can_move=true
- can_move=turtle.forward()
- while not can_move do
- print("ERR: There is a something on my way!")
- sleep(0.5)
- --
- turtle.dig()
- turtle.attack()
- --
- can_move=turtle.forward()
- end
- end
- function forceMoveBack()
- local can_move=true
- can_move=turtle.back()
- while not can_move do
- print("ERR: There is a something on my way!")
- sleep(0.5)
- can_move=turtle.back()
- end
- end
- function forceMoveUp()
- local can_move=true
- can_move=turtle.up()
- while not can_move do
- print("ERR: There is a something on my way!")
- sleep(0.5)
- --
- turtle.digUp()
- turtle.attackUp()
- --
- can_move=turtle.up()
- end
- end
- function forceMoveDown()
- local can_move=true
- can_move=turtle.down()
- while not can_move do
- print("ERR: There is a something on my way!")
- sleep(0.5)
- --
- turtle.digDown()
- turtle.attackDown()
- --
- can_move=turtle.down()
- end
- end
- function unloadAll()
- local i
- for i=16,1,-1 do
- turtle.select(i)
- turtle.dropDown()
- end
- slot=1
- end
- function isFull()
- local i
- local num
- for i=1,16 do
- num=turtle.getItemCount(i)
- if num==0 then
- return false
- end
- end
- return true
- end
- function left()
- if tD[1]==1 and tD[2]==0 then
- tD[1]=0
- tD[2]=-1
- elseif tD[1]==0 and tD[2]==-1 then
- tD[1]=-1
- tD[2]=0
- elseif tD[1]==-1 and tD[2]==0 then
- tD[1]=0
- tD[2]=1
- elseif tD[1]==0 and tD[2]==1 then
- tD[1]=1
- tD[2]=0
- end
- turtle.turnLeft()
- end
- function right()
- if tD[1]==1 and tD[2]==0 then
- tD[1]=0
- tD[2]=1
- elseif tD[1]==0 and tD[2]==1 then
- tD[1]=-1
- tD[2]=0
- elseif tD[1]==-1 and tD[2]==0 then
- tD[1]=0
- tD[2]=-1
- elseif tD[1]==0 and tD[2]==-1 then
- tD[1]=1
- tD[2]=0
- end
- turtle.turnRight()
- end
- function turnL(num1,num2)
- while tD[1]~=num1 or tD[2]~=num2 do
- left()
- end
- end
- function turnR(num1,num2)
- while tD[1]~=num1 or tD[2]~=num2 do
- right()
- end
- end
- function turnB(num1,num2)
- if math.abs(num1-tD[1])==2 then
- turnR(num1,num2)
- elseif math.abs(num2-tD[2])==2 then
- turnL(num1,num2)
- elseif tD[1]==1 then
- if num2==1 then
- turnR(num1,num2)
- elseif num2==-1 then
- turnL(num1,num2)
- end
- elseif tD[1]==-1 then
- if num2==-1 then
- turnR(num1,num2)
- elseif num2==1 then
- turnL(num1,num2)
- end
- elseif tD[2]==1 then
- if num1==-1 then
- turnR(num1,num2)
- elseif num1==1 then
- turnL(num1,num2)
- end
- elseif tD[2]==-1 then
- if num1==1 then
- turnR(num1,num2)
- elseif num1==-1 then
- turnL(num1,num2)
- end
- end
- end
- function moveXYZ(lx,ly,lz)
- local i
- if tZ<lz then
- for i=1,lz-tZ do
- forceMoveUp()
- end
- else
- for i=1,tZ-lz do
- forceMoveDown()
- end
- end
- if tY<ly then
- turnB(0,1)
- for i=1,ly-tY do
- forceMoveForward()
- end
- elseif tY>ly then
- turnB(0,-1)
- for i=1,tY-ly do
- forceMoveForward()
- end
- end
- if tX<lx then
- turnB(1,0)
- for i=1,lx-tX do
- forceMoveForward()
- end
- elseif tX>lx then
- turnB(-1,0)
- for i=1,tX-lx do
- forceMoveForward()
- end
- end
- tX,tY,tZ=lx,ly,lz
- end
- function toBase()
- local x,y,z=tX,tY,tZ
- x=math.ceil(diameter/2)+1
- y=math.ceil(diameter/2)+1
- moveXYZ(1,1,z)
- moveXYZ(1,1,strt-hWork)
- moveXYZ(x,y,strt-hWork)
- turnB(1,0)
- end
- function toWork(x,y,z,d)
- moveXYZ(1,1,strt-hWork)
- moveXYZ(1,1,z)
- moveXYZ(x,y,z)
- turnB(d[1],d[2])
- end
- function suckNItems(num)
- local sum=0
- local prevsum=0
- local i
- while sum<num do
- turtle.suckDown()
- sum=0
- for i=1,16 do
- sum=sum+turtle.getItemCount(i)
- end
- if sum==prevsum then
- return false
- end
- prevsum=sum
- end
- return true
- end
- function loadBlocks()
- local num
- local succes=true
- unloadAll()
- num=math.min(count,15*64) --
- succes=suckNItems(num)
- while not succes do
- print("!!! Not enough blocks in the chest!")
- print("!!! I need ",num," more blocks to continue!")
- print(" (",math.floor(num/64)," stacks + ",num-64*math.floor(num/64),").")
- sleep(20)
- succes=suckNItems(num)
- end
- slot=1
- turtle.select(slot)
- end
- function placeBlock(x2,y2,z2)
- local num
- local x,y,z,d
- local d={}
- local succes=true
- num=turtle.getItemCount(slot)
- if slot>=16 and num==0 then
- -----------work break start
- x,y,z,d[1],d[2]=tX,tY,tZ,tD[1],tD[2]
- toBase()
- loadBlocks()
- toWork(x,y,z,d)
- num=turtle.getItemCount(slot)
- -----------work break end
- end
- if num>0 then
- turtle.digDown()
- succes=turtle.placeDown()
- if succes then
- matr[z2][x2][y2]=false
- count=count-1
- else
- sleep(3)
- ERRcnt=ERRcnt+1
- if ERRcnt>3 then
- ERRcnt=0
- --high chance for BAD BLOCK
- print("ERR: dropping out BAD BLOCK!")
- turtle.dropUp()
- end
- end
- elseif slot<16 then
- while num==0 and slot<16 do
- slot=slot+1
- num=turtle.getItemCount(slot)
- end
- if slot<17 and num>0 then
- turtle.select(slot)
- turtle.digDown()
- succes=turtle.placeDown()
- if succes then
- matr[z2][x2][y2]=false
- count=count-1
- else
- sleep(3)
- ERRcnt=ERRcnt+1
- if ERRcnt>3 then
- ERRcnt=0
- --high chance for BAD BLOCK
- print("ERR: dropping out BAD BLOCK!")
- turtle.dropUp()
- end
- end
- end
- -----------work break start
- if num==0 then
- x,y,z,d[1],d[2]=tX,tY,tZ,tD[1],tD[2]
- toBase()
- loadBlocks()
- toWork(x,y,z,d)
- end
- -----------work break end
- end
- end
- function buildSphere(start)
- local i
- local pos={}
- for i=start+1,size-1 do
- pos=findeNearestPlot(i)
- while pos[1]~= -1 do
- moveXYZ(pos[1],pos[2],i+1)
- placeBlock(pos[1],pos[2],i)
- pos=findeNearestPlot(i)
- end
- end
- end
- ------------------------------------
- --global variables:
- tX,tY,tZ=1,1,1
- tD={1,0}
- diameter=10
- size=12
- matr={}
- count=0
- slot=1
- ERRcnt=0
- strt,fnsh=1,1
- hWork=0
- --Locals:
- local i
- local x,y,z=0,0,0
- local key,p1="y","y"
- local args={...}
- if #args <1 or args[1]=="?" then
- print("Usage: sphere <diameter> [<height>] [<start>] [<finish>]")
- print(" <diameter> - diameter of the sphere.")
- print(" [<height>] - (optional)The height of construction above the turtle.")
- print(" [<start>] - (optional)The layer number from which the turtle will start construction (1 <= start <= diameter).")
- print(" [<finish>] - (optional)The layer number on which the turtle will stop construction (1 <= finish <= diameter).")
- print("-=press ENTER to continue=-") read()
- print(" Example 1: 'sphere 15' - turtle will construct sphere with diameter 15.")
- print(" Example 2: 'sphere 34 10 19' - turtle will construct dome with diameter 34 on height 10.")
- print(" Example 3: 'sphere 64 0 31 33' - turtle will construct ring with diameter 64.")
- return
- end
- print("*'sphere building' prog. is active!")
- print(" * ## Label: ",os.getComputerLabel())
- print(" * ^# Fuel Level:",turtle.getFuelLevel())
- diameter=tonumber(args[1])
- if diameter<1 then diameter=1 end
- if diameter>64 then
- print("!!! The diameter is too big!")
- print("Are you sure I must try to build this? (Y/N)")
- key, p1 = os.pullEvent("char")
- end
- if p1~="y" then return end
- tX=math.ceil(diameter/2)+1
- tY=math.ceil(diameter/2)+1
- size=diameter+2
- matr=purgeBlocks()
- turtle.select(slot)
- if args[2]~=nil then
- hWork=math.floor(tonumber(args[2]))
- tZ=1-hWork
- end
- if args[3]~=nil then
- strt=math.floor(tonumber(args[3]))
- fnsh=diameter
- if strt<1 or strt>diameter then strt=1 end
- if args[4]~=nil then
- fnsh=math.floor(tonumber(args[4]))
- if fnsh<strt or fnsh>diameter then fnsh=diameter end
- end
- tZ=strt-hWork
- recalcWork(strt,fnsh)
- end
- print("I need ",count," blocks for this work")
- print(" (",math.floor(count/64)," stacks + ",count-64*math.floor(count/64),").")
- print("-=press ENTER to continue=-") read()
- loadBlocks()
- --------------
- x,y,z=tX,tY,tZ
- x=x+1
- y=y+1
- moveXYZ(x,y,z)
- --------------
- buildSphere(strt)
- toBase()
- unloadAll()
- print(" *'sphere building' application quits!")
- print(" *Fuel level=",turtle.getFuelLevel())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement