Advertisement
Vrill

Computercraft: Sphere Builder

Nov 19th, 2013
521
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.18 KB | None | 0 0
  1. --------------------------------------------
  2. -- Vril's sphere building program v 1.1.1 --
  3. --------------------------------------------
  4.  
  5. --[[   
  6. Why do I use diameter and not radius?
  7. 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! ;)
  8. --]]
  9.  
  10. function recalcWork(start,finish)
  11.  local x,y,z
  12.  
  13.  count=0
  14.  for z=1,size do
  15.   for x=1,size do
  16.    for y=1,size do
  17.     if z<=start or z>finish+1 then matr[z][x][y]=false end
  18.     if matr[z][x][y] then count=count+1 end
  19.    end
  20.   end
  21.  end
  22. end
  23.  
  24. function findeNearestPlot(height)
  25.  local x,y
  26.  local res={-1,-1}
  27.  local mindist=math.huge
  28.  local dist=0
  29.  
  30.  for x=1,size do
  31.   for y=1,size do
  32.    if matr[height][x][y] then
  33.     dist=(x-tX)*(x-tX) + (y-tY)*(y-tY)
  34.     if dist<mindist then
  35.      mindist=dist
  36.      res[1],res[2]=x,y
  37.     end
  38.    end
  39.   end
  40.  end
  41.  
  42.  return res
  43. end
  44.        
  45. function isInSphere(x,y,z)
  46.  local radiusSq=diameter*diameter/4.0
  47.  local offset=0
  48.  
  49.  if math.fmod(diameter, 2) == 0 then
  50.   offset = math.floor(size/2 +0.5)+0.5
  51.  else
  52.   offset = math.floor(size/2 +0.5)
  53.  end
  54.  x=x-offset;
  55.  y=y-offset;
  56.  z=z-offset;
  57.  x=x*x;
  58.  y=y*y;
  59.  z=z*z;
  60.  return x+y+z < radiusSq;
  61. end    
  62.        
  63. function generateBlocks()
  64.  local blks={}
  65.  local x,y,z=0,0,0
  66.  
  67.  for z=1,size do
  68.   blks[z]={}
  69.   for x=1,size do
  70.    blks[z][x]={}
  71.    for y=1,size do
  72.     blks[z][x][y]=isInSphere(x,y,z)
  73.    end
  74.   end
  75.  end
  76.  return blks;
  77. end
  78.  
  79. function purgeBlocks()
  80.  local newblocks={}
  81.  local blocks={}
  82.  local x,y,z=0,0,0
  83.  count=0
  84.  
  85.  blocks=generateBlocks()
  86.  for z=1,size do
  87.   newblocks[z]={}
  88.   for x=1,size do
  89.    newblocks[z][x]={}
  90.    for y=1,size do
  91.     if x==1 or x==size or y==1 or y==size or z==1 or z==size then
  92.      newblocks[z][x][y]=blocks[z][x][y]
  93.     else
  94.      newblocks[z][x][y]=blocks[z][x][y] and (
  95.         not blocks[z-1][x][y] or
  96.         not blocks[z+1][x][y] or
  97.         not blocks[z][x-1][y] or
  98.         not blocks[z][x+1][y] or
  99.         not blocks[z][x][y-1] or
  100.         not blocks[z][x][y+1] )
  101.     end  
  102.     if newblocks[z][x][y] then count=count+1 end
  103.    end
  104.   end
  105.  end
  106.  return newblocks
  107. end
  108.    
  109. function forceDigFront()
  110.  while turtle.detect() do
  111.   turtle.dig()
  112.   sleep(0.2)
  113.  end
  114. end
  115.  
  116. function forceDigUp()
  117.  while turtle.detectUp() do
  118.   turtle.digUp()
  119.   sleep(0.2)
  120.  end
  121. end
  122.  
  123. function forceMoveForward()
  124.  local can_move=true
  125.  can_move=turtle.forward()
  126.  while not can_move do
  127.   print("ERR: There is a something on my way!")
  128.   sleep(0.5)
  129.   --
  130.   turtle.dig()
  131.   turtle.attack()
  132.   --
  133.   can_move=turtle.forward()
  134.  end
  135. end
  136.  
  137. function forceMoveBack()
  138.  local can_move=true
  139.  can_move=turtle.back()
  140.  while not can_move do
  141.   print("ERR: There is a something on my way!")
  142.   sleep(0.5)
  143.   can_move=turtle.back()
  144.  end
  145. end
  146.  
  147. function forceMoveUp()
  148.  local can_move=true
  149.  can_move=turtle.up()
  150.  while not can_move do
  151.   print("ERR: There is a something on my way!")
  152.   sleep(0.5)
  153.   --
  154.   turtle.digUp()
  155.   turtle.attackUp()
  156.   --
  157.   can_move=turtle.up()
  158.  end
  159. end
  160.  
  161. function forceMoveDown()
  162.  local can_move=true
  163.  can_move=turtle.down()
  164.  while not can_move do
  165.   print("ERR: There is a something on my way!")
  166.   sleep(0.5)
  167.   --
  168.   turtle.digDown()
  169.   turtle.attackDown()
  170.   --
  171.   can_move=turtle.down()
  172.  end
  173. end
  174.  
  175. function unloadAll()
  176.  local i
  177.  for i=16,1,-1 do
  178.   turtle.select(i)
  179.   turtle.dropDown()
  180.  end
  181.  slot=1
  182. end
  183.  
  184. function isFull()
  185.  local i
  186.  local num
  187.  for i=1,16 do
  188.   num=turtle.getItemCount(i)
  189.   if num==0 then
  190.    return false
  191.   end
  192.  end
  193.  return true
  194. end
  195.  
  196. function left()
  197.  if tD[1]==1 and tD[2]==0 then
  198.   tD[1]=0
  199.   tD[2]=-1
  200.  elseif tD[1]==0 and tD[2]==-1 then
  201.   tD[1]=-1
  202.   tD[2]=0
  203.  elseif tD[1]==-1 and tD[2]==0 then
  204.   tD[1]=0
  205.   tD[2]=1
  206.  elseif tD[1]==0 and tD[2]==1 then
  207.   tD[1]=1
  208.   tD[2]=0
  209.  end
  210.  turtle.turnLeft()
  211. end
  212.  
  213. function right()
  214.  if tD[1]==1 and tD[2]==0 then
  215.   tD[1]=0
  216.   tD[2]=1
  217.  elseif tD[1]==0 and tD[2]==1 then
  218.   tD[1]=-1
  219.   tD[2]=0
  220.  elseif tD[1]==-1 and tD[2]==0 then
  221.   tD[1]=0
  222.   tD[2]=-1
  223.  elseif tD[1]==0 and tD[2]==-1 then
  224.   tD[1]=1
  225.   tD[2]=0
  226.  end
  227.  turtle.turnRight()
  228. end
  229.  
  230. function turnL(num1,num2)
  231.  while tD[1]~=num1 or tD[2]~=num2 do
  232.   left()
  233.  end
  234. end
  235.  
  236. function turnR(num1,num2)
  237.  while tD[1]~=num1 or tD[2]~=num2 do
  238.   right()
  239.  end
  240. end
  241.  
  242. function turnB(num1,num2)
  243.  if math.abs(num1-tD[1])==2 then
  244.   turnR(num1,num2)
  245.  
  246.  elseif math.abs(num2-tD[2])==2 then
  247.   turnL(num1,num2)
  248.  
  249.  elseif tD[1]==1 then
  250.   if num2==1 then
  251.    turnR(num1,num2)
  252.   elseif num2==-1 then
  253.    turnL(num1,num2)
  254.   end
  255.  
  256.  elseif tD[1]==-1 then
  257.   if num2==-1 then
  258.    turnR(num1,num2)
  259.   elseif num2==1 then
  260.    turnL(num1,num2)
  261.   end
  262.  
  263.  elseif tD[2]==1 then
  264.   if num1==-1 then
  265.    turnR(num1,num2)
  266.   elseif num1==1 then
  267.    turnL(num1,num2)
  268.   end
  269.  
  270.  elseif tD[2]==-1 then
  271.   if num1==1 then
  272.    turnR(num1,num2)
  273.   elseif num1==-1 then
  274.    turnL(num1,num2)
  275.   end
  276.  
  277.  end
  278. end
  279.  
  280. function moveXYZ(lx,ly,lz)
  281.  local i
  282.  
  283.  if tZ<lz then
  284.   for i=1,lz-tZ do
  285.    forceMoveUp()
  286.   end
  287.  else
  288.   for i=1,tZ-lz do
  289.    forceMoveDown()
  290.   end
  291.  end
  292.  
  293.  if tY<ly then
  294.   turnB(0,1)
  295.   for i=1,ly-tY do
  296.    forceMoveForward()
  297.   end
  298.  elseif tY>ly then
  299.   turnB(0,-1)
  300.   for i=1,tY-ly do
  301.    forceMoveForward()
  302.   end
  303.  end
  304.  
  305.  if tX<lx then
  306.   turnB(1,0)
  307.   for i=1,lx-tX do
  308.    forceMoveForward()
  309.   end
  310.  elseif tX>lx then
  311.   turnB(-1,0)
  312.   for i=1,tX-lx do
  313.    forceMoveForward()
  314.   end
  315.  end
  316.  
  317.  tX,tY,tZ=lx,ly,lz
  318. end
  319.  
  320. function toBase()
  321.  local x,y,z=tX,tY,tZ
  322.  
  323.  x=math.ceil(diameter/2)+1
  324.  y=math.ceil(diameter/2)+1
  325.  moveXYZ(1,1,z)
  326.  moveXYZ(1,1,strt-hWork)
  327.  moveXYZ(x,y,strt-hWork)
  328.  turnB(1,0)
  329. end
  330.  
  331. function toWork(x,y,z,d)
  332.  moveXYZ(1,1,strt-hWork)
  333.  moveXYZ(1,1,z)
  334.  moveXYZ(x,y,z)
  335.  turnB(d[1],d[2])
  336. end
  337.  
  338. function suckNItems(num)
  339.  local sum=0
  340.  local prevsum=0
  341.  local i
  342.  
  343.  while sum<num do
  344.   turtle.suckDown()
  345.   sum=0
  346.   for i=1,16 do
  347.    sum=sum+turtle.getItemCount(i)
  348.   end
  349.   if sum==prevsum then
  350.    return false
  351.   end
  352.   prevsum=sum
  353.  end
  354.  return true
  355. end
  356.  
  357. function loadBlocks()
  358.  local num
  359.  local succes=true
  360.  
  361.  unloadAll()
  362.  num=math.min(count,15*64) --
  363.  succes=suckNItems(num)
  364.  while not succes do
  365.   print("!!! Not enough blocks in the chest!")
  366.   print("!!! I need ",num," more blocks to continue!")
  367.   print("   (",math.floor(num/64)," stacks + ",num-64*math.floor(num/64),").")
  368.   sleep(20)
  369.   succes=suckNItems(num)
  370.  end
  371.  slot=1
  372.  turtle.select(slot)
  373. end
  374.  
  375. function placeBlock(x2,y2,z2)
  376.  local num
  377.  local x,y,z,d
  378.  local d={}
  379.  local succes=true
  380.  
  381.  num=turtle.getItemCount(slot)
  382.  if slot>=16 and num==0 then
  383.   -----------work break start
  384.    x,y,z,d[1],d[2]=tX,tY,tZ,tD[1],tD[2]
  385.    toBase()
  386.    loadBlocks()
  387.    toWork(x,y,z,d)
  388.    num=turtle.getItemCount(slot)
  389.   -----------work break end
  390.  end
  391.  
  392.  if num>0 then
  393.   turtle.digDown()
  394.   succes=turtle.placeDown()
  395.   if succes then
  396.    matr[z2][x2][y2]=false
  397.    count=count-1
  398.   else
  399.    sleep(3)
  400.    ERRcnt=ERRcnt+1
  401.    if ERRcnt>3 then
  402.     ERRcnt=0
  403.     --high chance for BAD BLOCK
  404.     print("ERR: dropping out BAD BLOCK!")
  405.     turtle.dropUp()
  406.    end  
  407.   end
  408.  elseif slot<16 then
  409.   while num==0 and slot<16 do
  410.    slot=slot+1
  411.    num=turtle.getItemCount(slot)
  412.   end
  413.  
  414.   if slot<17 and num>0 then
  415.    turtle.select(slot)
  416.    turtle.digDown()
  417.    succes=turtle.placeDown()
  418.    if succes then
  419.     matr[z2][x2][y2]=false
  420.     count=count-1
  421.    else
  422.     sleep(3)
  423.     ERRcnt=ERRcnt+1
  424.     if ERRcnt>3 then
  425.      ERRcnt=0
  426.      --high chance for BAD BLOCK
  427.      print("ERR: dropping out BAD BLOCK!")
  428.      turtle.dropUp()
  429.     end
  430.    end
  431.   end
  432.   -----------work break start
  433.   if num==0 then
  434.    x,y,z,d[1],d[2]=tX,tY,tZ,tD[1],tD[2]
  435.    toBase()
  436.    loadBlocks()
  437.    toWork(x,y,z,d)
  438.   end
  439.   -----------work break end
  440.    
  441.  end
  442. end
  443.  
  444. function buildSphere(start)
  445.  local i
  446.  local pos={}
  447.  
  448.  for i=start+1,size-1 do
  449.   pos=findeNearestPlot(i)
  450.    while pos[1]~= -1 do
  451.     moveXYZ(pos[1],pos[2],i+1)
  452.     placeBlock(pos[1],pos[2],i)
  453.     pos=findeNearestPlot(i)
  454.    end
  455.  end
  456. end
  457.  
  458. ------------------------------------
  459.  
  460. --global variables:
  461. tX,tY,tZ=1,1,1
  462. tD={1,0}
  463. diameter=10
  464. size=12
  465. matr={}
  466. count=0
  467. slot=1
  468. ERRcnt=0
  469. strt,fnsh=1,1
  470. hWork=0
  471.  
  472. --Locals:
  473. local i
  474. local x,y,z=0,0,0
  475. local key,p1="y","y"
  476. local args={...}
  477.  
  478. if #args <1 or args[1]=="?" then
  479.  print("Usage:  sphere <diameter> [<height>] [<start>] [<finish>]")
  480.  print("  <diameter> - diameter of the sphere.")
  481.  print("  [<height>] - (optional)The height of construction above the turtle.")
  482.  print("  [<start>] - (optional)The layer number from which the turtle will start construction (1 <= start <= diameter).")
  483.  print("  [<finish>] - (optional)The layer number on which the turtle will stop construction (1 <= finish <= diameter).")
  484.  print("-=press ENTER to continue=-") read()
  485.  print("  Example 1: 'sphere 15' - turtle will construct sphere with diameter 15.")
  486.  print("  Example 2: 'sphere 34 10 19' - turtle will construct dome with diameter 34 on height 10.")
  487.  print("  Example 3: 'sphere 64 0 31 33' - turtle will construct ring with diameter 64.")
  488.  return
  489. end
  490. print("*'sphere building' prog. is active!")
  491. print("  * ## Label: ",os.getComputerLabel())
  492. print("  * ^# Fuel Level:",turtle.getFuelLevel())
  493. diameter=tonumber(args[1])
  494. if diameter<1 then diameter=1 end
  495. if diameter>64 then
  496.  print("!!! The diameter is too big!")
  497.  print("Are you sure I must try to build this? (Y/N)")
  498.  key, p1 = os.pullEvent("char")
  499. end
  500.  
  501. if p1~="y" then return end
  502. tX=math.ceil(diameter/2)+1
  503. tY=math.ceil(diameter/2)+1
  504. size=diameter+2
  505. matr=purgeBlocks()
  506. turtle.select(slot)
  507.  
  508. if args[2]~=nil then
  509.  hWork=math.floor(tonumber(args[2]))
  510.  tZ=1-hWork
  511. end
  512.  
  513. if args[3]~=nil then
  514.  strt=math.floor(tonumber(args[3]))
  515.  fnsh=diameter
  516.  if strt<1 or strt>diameter then strt=1 end
  517.  if args[4]~=nil then
  518.  fnsh=math.floor(tonumber(args[4]))
  519.  if fnsh<strt or fnsh>diameter then fnsh=diameter end
  520.  end
  521.  tZ=strt-hWork
  522.  recalcWork(strt,fnsh)
  523. end
  524.  
  525. print("I need ",count," blocks for this work")
  526. print("  (",math.floor(count/64)," stacks + ",count-64*math.floor(count/64),").")
  527. print("-=press ENTER to continue=-") read()
  528.  
  529. loadBlocks()
  530. --------------
  531. x,y,z=tX,tY,tZ
  532. x=x+1
  533. y=y+1
  534. moveXYZ(x,y,z)
  535. --------------
  536. buildSphere(strt)
  537. toBase()
  538. unloadAll()
  539.  
  540. print("  *'sphere building' application quits!")
  541. print("  *Fuel level=",turtle.getFuelLevel())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement