mirror of https://github.com/kepler155c/opus
builder improvements
This commit is contained in:
parent
71cbf34ade
commit
3f66a9397c
|
@ -347,7 +347,7 @@ function standardBlockDB:seedDB()
|
||||||
[ '163:0' ] = 'stairs',
|
[ '163:0' ] = 'stairs',
|
||||||
[ '164:0' ] = 'stairs',
|
[ '164:0' ] = 'stairs',
|
||||||
[ '167:0' ] = 'trapdoor',
|
[ '167:0' ] = 'trapdoor',
|
||||||
[ '170:0' ] = 'flatten',
|
[ '170:0' ] = 'quartz-pillar', -- hay bale
|
||||||
[ '175:0' ] = 'largeplant',
|
[ '175:0' ] = 'largeplant',
|
||||||
[ '175:1' ] = 'largeplant',
|
[ '175:1' ] = 'largeplant',
|
||||||
[ '175:2' ] = 'largeplant', -- double tallgrass - an alternative would be to use grass as the bottom part, bonemeal as top part
|
[ '175:2' ] = 'largeplant', -- double tallgrass - an alternative would be to use grass as the bottom part, bonemeal as top part
|
||||||
|
|
|
@ -29,20 +29,25 @@ function ChestProvider:refresh()
|
||||||
entry = self.cache[key]
|
entry = self.cache[key]
|
||||||
if not entry then
|
if not entry then
|
||||||
local meta = self.p.getItemMeta(k) -- slow method.. cache for speed
|
local meta = self.p.getItemMeta(k) -- slow method.. cache for speed
|
||||||
entry = {
|
if meta then
|
||||||
id = s.name,
|
entry = {
|
||||||
dmg = s.damage,
|
id = s.name,
|
||||||
name = meta.displayName,
|
dmg = s.damage,
|
||||||
max_size = meta.maxCount,
|
name = meta.displayName,
|
||||||
}
|
max_size = meta.maxCount,
|
||||||
self.cache[key] = entry
|
}
|
||||||
|
self.cache[key] = entry
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if entry then
|
||||||
|
entry = Util.shallowCopy(entry)
|
||||||
|
self.items[key] = entry
|
||||||
|
entry.qty = 0
|
||||||
end
|
end
|
||||||
entry = Util.shallowCopy(entry)
|
|
||||||
self.items[key] = entry
|
|
||||||
entry.qty = 0
|
|
||||||
end
|
end
|
||||||
|
if entry then
|
||||||
entry.qty = entry.qty + s.count
|
entry.qty = entry.qty + s.count
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return self.items
|
return self.items
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
local class = require('class')
|
local class = require('class')
|
||||||
local DEFLATE = require('deflatelua')
|
local DEFLATE = require('deflatelua')
|
||||||
local UI = require('ui')
|
local UI = require('ui')
|
||||||
local Logger = require('logger')
|
|
||||||
local Profile = require('profile')
|
|
||||||
local Point = require('point')
|
local Point = require('point')
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
|
@ -17,7 +15,6 @@ function Schematic:init(args)
|
||||||
self.blocks = { }
|
self.blocks = { }
|
||||||
self.damages = { }
|
self.damages = { }
|
||||||
self.originalBlocks = { }
|
self.originalBlocks = { }
|
||||||
self.placementChains = { }
|
|
||||||
self.x, self.y, self.z = 0, 0, 0
|
self.x, self.y, self.z = 0, 0, 0
|
||||||
self.height = 0
|
self.height = 0
|
||||||
self.index = 1
|
self.index = 1
|
||||||
|
@ -29,7 +26,7 @@ end
|
||||||
|
|
||||||
Some parts of the file reader code was modified from the original
|
Some parts of the file reader code was modified from the original
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
function Schematic:discardBytes(h, n, spinner)
|
function Schematic:discardBytes(h, n, spinner)
|
||||||
for i = 1,n do
|
for i = 1,n do
|
||||||
h:readbyte()
|
h:readbyte()
|
||||||
|
@ -38,17 +35,17 @@ function Schematic:discardBytes(h, n, spinner)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:readname(h)
|
function Schematic:readname(h)
|
||||||
local n1 = h:readbyte(h)
|
local n1 = h:readbyte(h)
|
||||||
local n2 = h:readbyte(h)
|
local n2 = h:readbyte(h)
|
||||||
|
|
||||||
if(n1 == nil or n2 == nil) then
|
if(n1 == nil or n2 == nil) then
|
||||||
return ""
|
return ""
|
||||||
end
|
end
|
||||||
|
|
||||||
local n = n1*256 + n2
|
local n = n1*256 + n2
|
||||||
|
|
||||||
local str = ""
|
local str = ""
|
||||||
for i=1,n do
|
for i=1,n do
|
||||||
local c = h:readbyte(h)
|
local c = h:readbyte(h)
|
||||||
|
@ -59,13 +56,13 @@ function Schematic:readname(h)
|
||||||
end
|
end
|
||||||
return str
|
return str
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:parse(a, h, containsName, spinner)
|
function Schematic:parse(a, h, containsName, spinner)
|
||||||
|
|
||||||
if a==0 then
|
if a==0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local name
|
local name
|
||||||
if containsName then
|
if containsName then
|
||||||
name = self:readname(h)
|
name = self:readname(h)
|
||||||
|
@ -150,9 +147,8 @@ function Schematic:parse(a, h, containsName, spinner)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- end http://www.computercraft.info/forums2/index.php?/topic/1949-turtle-schematic-file-builder/
|
-- end http://www.computercraft.info/forums2/index.php?/topic/1949-turtle-schematic-file-builder/
|
||||||
|
|
||||||
function Schematic:copyBlocks(iblocks, oblocks, spinner)
|
function Schematic:copyBlocks(iblocks, oblocks, spinner)
|
||||||
Profile.start('copyBlocks')
|
|
||||||
for k,b in ipairs(iblocks) do
|
for k,b in ipairs(iblocks) do
|
||||||
oblocks[k] = Util.shallowCopy(b)
|
oblocks[k] = Util.shallowCopy(b)
|
||||||
if spinner then
|
if spinner then
|
||||||
|
@ -161,29 +157,20 @@ function Schematic:copyBlocks(iblocks, oblocks, spinner)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Profile.stop('copyBlocks')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:reload()
|
function Schematic:reload()
|
||||||
self.placementChains = {}
|
|
||||||
self.blocks = { }
|
self.blocks = { }
|
||||||
self:copyBlocks(self.originalBlocks, self.blocks)
|
self:copyBlocks(self.originalBlocks, self.blocks)
|
||||||
--[[
|
|
||||||
self.planes = { }
|
for _,ri in pairs(self.rowIndex) do
|
||||||
for i = 0, self.height - 1 do
|
ri.loaded = false
|
||||||
self.planes[i] = { }
|
|
||||||
end
|
end
|
||||||
for k,b in ipairs(self.blocks) do
|
|
||||||
if not self.planes[b.y].start then
|
|
||||||
self.planes[b.y].start = k
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--]]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:getMagic(fh)
|
function Schematic:getMagic(fh)
|
||||||
fh:open()
|
fh:open()
|
||||||
|
|
||||||
local magic = fh:readbyte() * 256 + fh:readbyte()
|
local magic = fh:readbyte() * 256 + fh:readbyte()
|
||||||
|
|
||||||
fh:close()
|
fh:close()
|
||||||
|
@ -192,12 +179,12 @@ function Schematic:getMagic(fh)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:isCompressed(filename)
|
function Schematic:isCompressed(filename)
|
||||||
local h = fs.open(filename, "rb")
|
local h = fs.open(filename, "rb")
|
||||||
|
|
||||||
if not h then
|
if not h then
|
||||||
error('unable to open: ' .. filename)
|
error('unable to open: ' .. filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
local magic = h.read() * 256 + h.read()
|
local magic = h.read() * 256 + h.read()
|
||||||
|
|
||||||
h.close()
|
h.close()
|
||||||
|
@ -206,7 +193,7 @@ function Schematic:isCompressed(filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:checkFileType(fh)
|
function Schematic:checkFileType(fh)
|
||||||
|
|
||||||
local magic = self:getMagic(fh)
|
local magic = self:getMagic(fh)
|
||||||
if magic ~= schematicMagic then
|
if magic ~= schematicMagic then
|
||||||
error('Unknown file type')
|
error('Unknown file type')
|
||||||
|
@ -253,8 +240,6 @@ end
|
||||||
|
|
||||||
function Schematic:decompress(ifname, spinner)
|
function Schematic:decompress(ifname, spinner)
|
||||||
|
|
||||||
Profile.start('decompress')
|
|
||||||
|
|
||||||
local ifh = fs.open(ifname, "rb")
|
local ifh = fs.open(ifname, "rb")
|
||||||
if not ifh then
|
if not ifh then
|
||||||
error('Unable to open ' .. ifname)
|
error('Unable to open ' .. ifname)
|
||||||
|
@ -271,20 +256,17 @@ function Schematic:decompress(ifname, spinner)
|
||||||
ifh.close()
|
ifh.close()
|
||||||
|
|
||||||
spinner:stop()
|
spinner:stop()
|
||||||
Profile.stop('decompress')
|
|
||||||
|
|
||||||
return mh
|
return mh
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:loadpass(fh, spinner)
|
function Schematic:loadpass(fh, spinner)
|
||||||
|
|
||||||
Profile.start('load')
|
|
||||||
|
|
||||||
fh:open()
|
fh:open()
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
local a = fh:readbyte()
|
local a = fh:readbyte()
|
||||||
|
|
||||||
if not a then
|
if not a then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
@ -297,13 +279,11 @@ function Schematic:loadpass(fh, spinner)
|
||||||
end
|
end
|
||||||
|
|
||||||
fh:close()
|
fh:close()
|
||||||
Profile.stop('load')
|
|
||||||
|
|
||||||
self:assignDamages(spinner)
|
self:assignDamages(spinner)
|
||||||
self.damages = nil
|
self.damages = nil
|
||||||
|
|
||||||
self:copyBlocks(self.blocks, self.originalBlocks, spinner)
|
self:copyBlocks(self.blocks, self.originalBlocks, spinner)
|
||||||
Profile.display()
|
|
||||||
|
|
||||||
spinner:stop()
|
spinner:stop()
|
||||||
end
|
end
|
||||||
|
@ -316,7 +296,7 @@ function Schematic:load(filename)
|
||||||
y = cursorY - 1
|
y = cursorY - 1
|
||||||
})
|
})
|
||||||
local f
|
local f
|
||||||
|
|
||||||
if self:isCompressed(filename) then
|
if self:isCompressed(filename) then
|
||||||
local originalFile = filename
|
local originalFile = filename
|
||||||
filename = originalFile .. '.uncompressed'
|
filename = originalFile .. '.uncompressed'
|
||||||
|
@ -335,28 +315,6 @@ function Schematic:load(filename)
|
||||||
|
|
||||||
self:checkFileType(f)
|
self:checkFileType(f)
|
||||||
|
|
||||||
--[[
|
|
||||||
local size = fs.getSize(filename)
|
|
||||||
|
|
||||||
local buffer = {
|
|
||||||
h = h,
|
|
||||||
i = 1,
|
|
||||||
s = { },
|
|
||||||
l = size,
|
|
||||||
}
|
|
||||||
|
|
||||||
for i = 1,size do
|
|
||||||
buffer.s[i] = h.read()
|
|
||||||
end
|
|
||||||
|
|
||||||
function buffer:readbyte()
|
|
||||||
--return self.h.read()
|
|
||||||
local b = self.s[self.i]
|
|
||||||
self.i = self.i + 1
|
|
||||||
return b
|
|
||||||
end
|
|
||||||
]]--
|
|
||||||
|
|
||||||
print('Initial pass ')
|
print('Initial pass ')
|
||||||
self:loadpass(f, spinner)
|
self:loadpass(f, spinner)
|
||||||
|
|
||||||
|
@ -365,7 +323,6 @@ function Schematic:load(filename)
|
||||||
self.blocks = { }
|
self.blocks = { }
|
||||||
self.damages = { }
|
self.damages = { }
|
||||||
self.originalBlocks = { }
|
self.originalBlocks = { }
|
||||||
self.placementChains = { }
|
|
||||||
self.x, self.y, self.z = 0, 0, 0
|
self.x, self.y, self.z = 0, 0, 0
|
||||||
self.height = 0
|
self.height = 0
|
||||||
self.index = 1
|
self.index = 1
|
||||||
|
@ -373,6 +330,18 @@ function Schematic:load(filename)
|
||||||
print('Second pass ')
|
print('Second pass ')
|
||||||
self:loadpass(f, spinner)
|
self:loadpass(f, spinner)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.rowIndex = { }
|
||||||
|
for k,b in ipairs(self.blocks) do
|
||||||
|
local ri = self.rowIndex[b.y]
|
||||||
|
if not ri then
|
||||||
|
self.rowIndex[b.y] = { s = k, e = k }
|
||||||
|
else
|
||||||
|
ri.e = k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.cache = Util.readTable('usr/builder/' .. self.filename .. '.cache') or { }
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:assignCoord(i, id)
|
function Schematic:assignCoord(i, id)
|
||||||
|
@ -400,13 +369,11 @@ function Schematic:assignCoord(i, id)
|
||||||
self.height = self.y + 1
|
self.height = self.y + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:assignDamages(spinner)
|
function Schematic:assignDamages(spinner)
|
||||||
local i = 0
|
|
||||||
|
|
||||||
Profile.start('assignDamages')
|
|
||||||
print('Assigning damages')
|
print('Assigning damages')
|
||||||
|
|
||||||
|
local i = 0
|
||||||
for _,b in pairs(self.blocks) do
|
for _,b in pairs(self.blocks) do
|
||||||
b.dmg = self.damages[b.index] or 0
|
b.dmg = self.damages[b.index] or 0
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
@ -414,7 +381,6 @@ function Schematic:assignDamages(spinner)
|
||||||
spinner:spin()
|
spinner:spin()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Profile.stop('assignDamages')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:findIndexAt(x, z, y)
|
function Schematic:findIndexAt(x, z, y)
|
||||||
|
@ -445,8 +411,8 @@ function Schematic:findBlockAtSide(b, side)
|
||||||
return self.blocks[index] -- could be better
|
return self.blocks[index] -- could be better
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:addPlacementChain(chain)
|
function Schematic:addPlacementChain(chains, chain)
|
||||||
local t = { }
|
local t = { }
|
||||||
for _,v in ipairs(chain) do
|
for _,v in ipairs(chain) do
|
||||||
local k = self:findIndexAt(v.x, v.z, v.y)
|
local k = self:findIndexAt(v.x, v.z, v.y)
|
||||||
|
@ -461,17 +427,17 @@ function Schematic:addPlacementChain(chain)
|
||||||
for _,b in pairs(t) do
|
for _,b in pairs(t) do
|
||||||
keys[b.index] = true
|
keys[b.index] = true
|
||||||
end
|
end
|
||||||
table.insert(self.placementChains, {
|
table.insert(chains, {
|
||||||
blocks = t,
|
blocks = t,
|
||||||
keys = keys
|
keys = keys
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:bestSide(b, ...)
|
function Schematic:bestSide(b, chains, ...)
|
||||||
local directions = { ... }
|
local directions = { ... }
|
||||||
local blocks = { }
|
local blocks = { }
|
||||||
|
|
||||||
for k,d in pairs(directions) do
|
for k,d in pairs(directions) do
|
||||||
local hi = turtle.getHeadingInfo(d)
|
local hi = turtle.getHeadingInfo(d)
|
||||||
local sb = self:findIndexAt(b.x - hi.xd, b.z - hi.zd, b.y)
|
local sb = self:findIndexAt(b.x - hi.xd, b.z - hi.zd, b.y)
|
||||||
|
@ -486,7 +452,7 @@ function Schematic:bestSide(b, ...)
|
||||||
d = d
|
d = d
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
local bestBlock
|
local bestBlock
|
||||||
for _,sb in ipairs(blocks) do
|
for _,sb in ipairs(blocks) do
|
||||||
if not sb.b.direction then -- could be better
|
if not sb.b.direction then -- could be better
|
||||||
|
@ -494,7 +460,7 @@ function Schematic:bestSide(b, ...)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not bestBlock then
|
if not bestBlock then
|
||||||
local sideDirections = {
|
local sideDirections = {
|
||||||
[ 'east-block' ] = 'east',
|
[ 'east-block' ] = 'east',
|
||||||
|
@ -512,17 +478,17 @@ function Schematic:bestSide(b, ...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local hi = bestBlock.hi
|
local hi = bestBlock.hi
|
||||||
b.heading = hi.heading -- ?????????????????????????????????
|
b.heading = hi.heading -- ?????????????????????????????????
|
||||||
b.direction = bestBlock.d .. '-block'
|
b.direction = bestBlock.d .. '-block'
|
||||||
self:addPlacementChain({
|
self:addPlacementChain(chains, {
|
||||||
{ x = b.x, z = b.z, y = b.y },
|
{ x = b.x, z = b.z, y = b.y },
|
||||||
{ x = b.x - hi.xd, z = b.z - hi.zd, y = b.y }
|
{ x = b.x - hi.xd, z = b.z - hi.zd, y = b.y }
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:bestOfTwoSides(b, side1, side2) -- could be better
|
function Schematic:bestOfTwoSides(b, chains, side1, side2) -- could be better
|
||||||
|
|
||||||
local sb
|
local sb
|
||||||
local fb = b -- first block
|
local fb = b -- first block
|
||||||
|
@ -567,7 +533,7 @@ function Schematic:bestOfTwoSides(b, side1, side2) -- could be better
|
||||||
b = self:findBlockAtSide(b, side2)
|
b = self:findBlockAtSide(b, side2)
|
||||||
end
|
end
|
||||||
|
|
||||||
self:addPlacementChain(pc)
|
self:addPlacementChain(chains, pc)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- can we place the first block from the side (instead of using piston) ?
|
-- can we place the first block from the side (instead of using piston) ?
|
||||||
|
@ -599,12 +565,14 @@ function Schematic:bestOfTwoSides(b, side1, side2) -- could be better
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Determine the best way to place each block
|
-- Determine the best way to place each block
|
||||||
function Schematic:determineBlockPlacement(row)
|
function Schematic:determineBlockPlacement(y)
|
||||||
|
|
||||||
-- NOTE: blocks are evaluated top to bottom
|
-- NOTE: blocks are evaluated top to bottom
|
||||||
|
|
||||||
|
print('Processing level ' .. y)
|
||||||
|
|
||||||
local spinner = UI.Spinner({
|
local spinner = UI.Spinner({
|
||||||
x = 1,
|
x = 1,
|
||||||
spinSymbols = { 'o.....', '.o....', '..o...', '...o..', '....o.', '.....o' }
|
spinSymbols = { 'o.....', '.o....', '..o...', '...o..', '....o.', '.....o' }
|
||||||
|
@ -649,21 +617,14 @@ function Schematic:determineBlockPlacement(row)
|
||||||
[ 'west-block-vine' ] = 'west-block',
|
[ 'west-block-vine' ] = 'west-block',
|
||||||
[ 'north-block-vine' ] = 'north-block'
|
[ 'north-block-vine' ] = 'north-block'
|
||||||
}
|
}
|
||||||
|
|
||||||
local dirtyBlocks = {}
|
local dirtyBlocks = {}
|
||||||
local dirtyBlocks2 = {}
|
local dirtyBlocks2 = {}
|
||||||
|
local chains = {}
|
||||||
|
|
||||||
self.rowIndex = { }
|
local ri = self.rowIndex[y]
|
||||||
for k,b in ipairs(self.blocks) do
|
for k = ri.s, ri.e do
|
||||||
local ri = self.rowIndex[b.y]
|
local b = self.blocks[k]
|
||||||
if not ri then
|
|
||||||
self.rowIndex[b.y] = { s = k, e = k }
|
|
||||||
else
|
|
||||||
ri.e = k
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for k,b in ipairs(self.blocks) do
|
|
||||||
local d = b.direction
|
local d = b.direction
|
||||||
|
|
||||||
if d then
|
if d then
|
||||||
|
@ -724,23 +685,23 @@ function Schematic:determineBlockPlacement(row)
|
||||||
local d = b.direction or ''
|
local d = b.direction or ''
|
||||||
|
|
||||||
spinner:spin(#dirtyBlocks + #dirtyBlocks2 .. ' blocks remaining ')
|
spinner:spin(#dirtyBlocks + #dirtyBlocks2 .. ' blocks remaining ')
|
||||||
|
|
||||||
if directions[d] then
|
if directions[d] then
|
||||||
b.heading = turtle.getHeadingInfo(directions[d]).heading
|
b.heading = turtle.getHeadingInfo(directions[d]).heading
|
||||||
end
|
end
|
||||||
|
|
||||||
if doorDirections[d] then
|
if doorDirections[d] then
|
||||||
|
|
||||||
local hi = turtle.getHeadingInfo(doorDirections[d])
|
local hi = turtle.getHeadingInfo(doorDirections[d])
|
||||||
b.heading = hi.heading
|
b.heading = hi.heading
|
||||||
b.twoHigh = true
|
b.twoHigh = true
|
||||||
|
|
||||||
self:addPlacementChain({
|
self:addPlacementChain(chains, {
|
||||||
{ x = b.x, z = b.z, y = b.y },
|
{ x = b.x, z = b.z, y = b.y },
|
||||||
{ x = b.x - hi.xd, z = b.z - hi.zd, y = b.y },
|
{ x = b.x - hi.xd, z = b.z - hi.zd, y = b.y },
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
if stairDownDirections[d] then
|
if stairDownDirections[d] then
|
||||||
if not self:findIndexAt(b.x, b.z, b.y-1) then
|
if not self:findIndexAt(b.x, b.z, b.y-1) then
|
||||||
b.direction = stairDownDirections[b.direction]
|
b.direction = stairDownDirections[b.direction]
|
||||||
|
@ -749,7 +710,7 @@ function Schematic:determineBlockPlacement(row)
|
||||||
b.heading = turtle.getHeadingInfo(stairDownDirections[b.direction]).heading
|
b.heading = turtle.getHeadingInfo(stairDownDirections[b.direction]).heading
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if d == 'bottom' then
|
if d == 'bottom' then
|
||||||
-- slab occupying bottom of voxel
|
-- slab occupying bottom of voxel
|
||||||
-- can be placed from top if a block is below
|
-- can be placed from top if a block is below
|
||||||
|
@ -761,7 +722,7 @@ function Schematic:determineBlockPlacement(row)
|
||||||
-- no block below, place from side
|
-- no block below, place from side
|
||||||
|
|
||||||
-- took care of all other cases above
|
-- took care of all other cases above
|
||||||
self:bestSide(b, 'east', 'south', 'west', 'north')
|
self:bestSide(b, chains, 'east', 'south', 'west', 'north')
|
||||||
|
|
||||||
-- elseif not db.direction or db.direction ~= 'bottom' then
|
-- elseif not db.direction or db.direction ~= 'bottom' then
|
||||||
-- not a slab below, ok to place from above
|
-- not a slab below, ok to place from above
|
||||||
|
@ -781,7 +742,7 @@ function Schematic:determineBlockPlacement(row)
|
||||||
-- all other directions are fine
|
-- all other directions are fine
|
||||||
-- any stair southwards that can't be placed against another block must be pistoned
|
-- any stair southwards that can't be placed against another block must be pistoned
|
||||||
local sd = stairUpDirections[d]
|
local sd = stairUpDirections[d]
|
||||||
|
|
||||||
if self:findIndexAt(b.x, b.z, b.y-1) then
|
if self:findIndexAt(b.x, b.z, b.y-1) then
|
||||||
-- there's a block below
|
-- there's a block below
|
||||||
b.direction = sd[1]
|
b.direction = sd[1]
|
||||||
|
@ -802,14 +763,14 @@ function Schematic:determineBlockPlacement(row)
|
||||||
-- placing a block from the side
|
-- placing a block from the side
|
||||||
local hi = turtle.getHeadingInfo(blockDirections[d])
|
local hi = turtle.getHeadingInfo(blockDirections[d])
|
||||||
b.heading = hi.heading
|
b.heading = hi.heading
|
||||||
self:addPlacementChain({
|
self:addPlacementChain(chains, {
|
||||||
{ x = b.x + hi.xd, z = b.z + hi.zd, y = b.y }, -- block we are placing against
|
{ x = b.x + hi.xd, z = b.z + hi.zd, y = b.y }, -- block we are placing against
|
||||||
{ x = b.x, z = b.z, y = b.y }, -- the block (or torch, etc)
|
{ x = b.x, z = b.z, y = b.y }, -- the block (or torch, etc)
|
||||||
{ x = b.x - hi.xd, z = b.z - hi.zd, y = b.y } -- room for the turtle
|
{ x = b.x - hi.xd, z = b.z - hi.zd, y = b.y } -- room for the turtle
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- pass 3
|
-- pass 3
|
||||||
while #dirtyBlocks2 > 0 do
|
while #dirtyBlocks2 > 0 do
|
||||||
local b = table.remove(dirtyBlocks2)
|
local b = table.remove(dirtyBlocks2)
|
||||||
|
@ -818,26 +779,50 @@ function Schematic:determineBlockPlacement(row)
|
||||||
spinner:spin(#dirtyBlocks2 .. ' blocks remaining ')
|
spinner:spin(#dirtyBlocks2 .. ' blocks remaining ')
|
||||||
|
|
||||||
if d == 'east-west-block' then
|
if d == 'east-west-block' then
|
||||||
self:bestOfTwoSides(b, 'east', 'west')
|
self:bestOfTwoSides(b, chains, 'east', 'west')
|
||||||
elseif d == 'north-south-block' then
|
elseif d == 'north-south-block' then
|
||||||
self:bestOfTwoSides(b, 'north', 'south')
|
self:bestOfTwoSides(b, chains, 'north', 'south')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
spinner:stop()
|
|
||||||
term.clearLine()
|
term.clearLine()
|
||||||
|
|
||||||
|
self:setPlacementOrder(spinner, chains)
|
||||||
|
local plane = self:optimizeRoute(spinner, y)
|
||||||
|
|
||||||
|
spinner:stop()
|
||||||
|
|
||||||
|
for k,b in ipairs(plane) do
|
||||||
|
self.blocks[ri.s + k - 1] = b
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Schematic:getComputedBlock(i)
|
||||||
|
local b = self.blocks[i]
|
||||||
|
|
||||||
|
-- has this level been computed ?
|
||||||
|
if not self.rowIndex[b.y].loaded then
|
||||||
|
-- compute each level up til this one (unless saved in cache)
|
||||||
|
for y = 0, b.y - 1 do
|
||||||
|
if not self.cache[y] then
|
||||||
|
self:determineBlockPlacement(y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self:determineBlockPlacement(b.y)
|
||||||
|
-- get the block now at the computed location
|
||||||
|
b = self.blocks[i]
|
||||||
|
end
|
||||||
|
|
||||||
|
return b
|
||||||
|
end
|
||||||
|
|
||||||
-- set the order for block dependencies
|
-- set the order for block dependencies
|
||||||
function Schematic:setPlacementOrder()
|
function Schematic:setPlacementOrder(spinner, placementChains)
|
||||||
|
|
||||||
local cursorX, cursorY = term.getCursorPos()
|
local cursorX, cursorY = term.getCursorPos()
|
||||||
local spinner = UI.Spinner({
|
|
||||||
x = 1
|
|
||||||
})
|
|
||||||
|
|
||||||
Profile.start('overlapping')
|
|
||||||
-- optimize for overlapping check
|
-- optimize for overlapping check
|
||||||
for _,chain in pairs(self.placementChains) do
|
for _,chain in pairs(placementChains) do
|
||||||
for index,_ in pairs(chain.keys) do
|
for index,_ in pairs(chain.keys) do
|
||||||
if not chain.startRow or (index < chain.startRow) then
|
if not chain.startRow or (index < chain.startRow) then
|
||||||
chain.startRow = index
|
chain.startRow = index
|
||||||
|
@ -847,10 +832,10 @@ function Schematic:setPlacementOrder()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function groupOverlappingChains(t, groupedChain, chain, spinner)
|
local function groupOverlappingChains(t, groupedChain, chain, spinner)
|
||||||
local found = true
|
local found = true
|
||||||
|
|
||||||
local function overlaps(chain1, chain2)
|
local function overlaps(chain1, chain2)
|
||||||
if chain1.startRow > chain2.endRow or
|
if chain1.startRow > chain2.endRow or
|
||||||
chain2.startRow > chain1.endRow then
|
chain2.startRow > chain1.endRow then
|
||||||
|
@ -862,7 +847,7 @@ function Schematic:setPlacementOrder()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
while found do
|
while found do
|
||||||
found = false
|
found = false
|
||||||
for k, v in pairs(t) do
|
for k, v in pairs(t) do
|
||||||
|
@ -881,16 +866,15 @@ function Schematic:setPlacementOrder()
|
||||||
|
|
||||||
-- group together any placement chains with overlapping blocks
|
-- group together any placement chains with overlapping blocks
|
||||||
local groupedChains = {}
|
local groupedChains = {}
|
||||||
while #self.placementChains > 0 do
|
while #placementChains > 0 do
|
||||||
local groupedChain = {}
|
local groupedChain = {}
|
||||||
local chain = table.remove(self.placementChains)
|
local chain = table.remove(placementChains)
|
||||||
table.insert(groupedChain, chain)
|
table.insert(groupedChain, chain)
|
||||||
table.insert(groupedChains, groupedChain)
|
table.insert(groupedChains, groupedChain)
|
||||||
groupOverlappingChains(self.placementChains, groupedChain, chain, spinner)
|
groupOverlappingChains(placementChains, groupedChain, chain, spinner)
|
||||||
spinner:spin('chains: ' .. #groupedChains .. ' ' .. #self.placementChains .. ' ')
|
spinner:spin('chains: ' .. #groupedChains .. ' ' .. #placementChains .. ' ')
|
||||||
end
|
end
|
||||||
Profile.stop('overlapping')
|
|
||||||
|
|
||||||
--Logger.log('schematic', 'groups: ' .. #groupedChains)
|
--Logger.log('schematic', 'groups: ' .. #groupedChains)
|
||||||
--Logger.setFileLogging('chains')
|
--Logger.setFileLogging('chains')
|
||||||
|
|
||||||
|
@ -961,7 +945,7 @@ function Schematic:setPlacementOrder()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
while #chains > 0 do
|
while #chains > 0 do
|
||||||
for k,chain in pairs(chains) do
|
for k,chain in pairs(chains) do
|
||||||
if splice(masterChain.blocks, chain.blocks) then
|
if splice(masterChain.blocks, chain.blocks) then
|
||||||
|
@ -983,16 +967,14 @@ function Schematic:setPlacementOrder()
|
||||||
|
|
||||||
return masterChain
|
return masterChain
|
||||||
end
|
end
|
||||||
|
|
||||||
-- combine the individual overlapping placement chains into 1 long master chain
|
-- combine the individual overlapping placement chains into 1 long master chain
|
||||||
Profile.start('masterchains')
|
|
||||||
local masterChains = {}
|
local masterChains = {}
|
||||||
for _,group in pairs(groupedChains) do
|
for _,group in pairs(groupedChains) do
|
||||||
spinner:spin('chains: ' .. #masterChains)
|
spinner:spin('chains: ' .. #masterChains)
|
||||||
table.insert(masterChains, mergeChains(group))
|
table.insert(masterChains, mergeChains(group))
|
||||||
end
|
end
|
||||||
Profile.stop('masterchains')
|
|
||||||
|
|
||||||
local function removeDuplicates(chain)
|
local function removeDuplicates(chain)
|
||||||
for k,v in ipairs(chain) do
|
for k,v in ipairs(chain) do
|
||||||
for i = #chain, k+1, -1 do
|
for i = #chain, k+1, -1 do
|
||||||
|
@ -1003,10 +985,9 @@ v.info = 'Unplaceable'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- any chains with duplicates cannot be placed correctly
|
-- any chains with duplicates cannot be placed correctly
|
||||||
-- there are some cases where a turtle cannot place blocks the same as a player
|
-- there are some cases where a turtle cannot place blocks the same as a player
|
||||||
Profile.start('duplicates')
|
|
||||||
for _,chain in pairs(masterChains) do
|
for _,chain in pairs(masterChains) do
|
||||||
removeDuplicates(chain.blocks)
|
removeDuplicates(chain.blocks)
|
||||||
spinner:spin('chains: ' .. #masterChains)
|
spinner:spin('chains: ' .. #masterChains)
|
||||||
|
@ -1020,52 +1001,26 @@ v.info = 'Unplaceable'
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
end
|
end
|
||||||
Profile.stop('duplicates')
|
|
||||||
term.clearLine()
|
term.clearLine()
|
||||||
|
|
||||||
-- adjust row indices as blocks are being moved
|
-- set dependent blocks for optimize routine
|
||||||
Profile.start('reordering')
|
|
||||||
for k,chain in pairs(masterChains) do
|
for k,chain in pairs(masterChains) do
|
||||||
spinner:spin('chains: ' .. #masterChains - k)
|
spinner:spin('chains: ' .. #masterChains - k)
|
||||||
|
|
||||||
local startBlock = table.remove(chain.blocks, 1)
|
local prev
|
||||||
startBlock.movedBlocks = chain.blocks
|
for k,b in ipairs(chain.blocks) do
|
||||||
|
b.prev = prev
|
||||||
for _,b in pairs(chain.blocks) do
|
b.next = chain.blocks[k + 1]
|
||||||
b.moved = true
|
prev = b
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local t = { }
|
|
||||||
for k,b in ipairs(self.blocks) do
|
|
||||||
|
|
||||||
-- adjust y so the turtle travels above the two high blocks
|
|
||||||
if b.twoHigh then
|
|
||||||
b.y = b.y + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
spinner:spin('blocks: ' .. #self.blocks - k .. ' ')
|
|
||||||
if not b.moved then
|
|
||||||
table.insert(t, b)
|
|
||||||
end
|
|
||||||
if b.movedBlocks then
|
|
||||||
for _,mb in ipairs(b.movedBlocks) do
|
|
||||||
table.insert(t, mb)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
self.blocks = t
|
|
||||||
|
|
||||||
Profile.stop('reordering')
|
|
||||||
|
|
||||||
--Logger.setWirelessLogging()
|
|
||||||
|
|
||||||
term.clearLine()
|
term.clearLine()
|
||||||
spinner:stop()
|
|
||||||
|
return t
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:optimizeRoute()
|
function Schematic:optimizeRoute(spinner, y)
|
||||||
|
|
||||||
local function getNearestNeighbor(p, pt, maxDistance)
|
local function getNearestNeighbor(p, pt, maxDistance)
|
||||||
local key, block, heading
|
local key, block, heading
|
||||||
|
@ -1085,14 +1040,24 @@ function Schematic:optimizeRoute()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function blockReady(b)
|
||||||
|
if b.u then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if b.prev and not b.prev.u then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
local mid = pt.index
|
local mid = pt.index
|
||||||
local forward = mid + 1
|
local forward = mid + 1
|
||||||
local backward = mid - 1
|
local backward = mid - 1
|
||||||
while forward <= #p or backward > 0 do
|
while forward <= #p or backward > 0 do
|
||||||
if forward <= #p then
|
if forward <= #p then
|
||||||
local b = p[forward]
|
local b = p[forward]
|
||||||
if not b.u then
|
if blockReady(b) then
|
||||||
getMoves(b, forward)
|
getMoves(b, forward)
|
||||||
if moves <= 1 then
|
if moves <= 1 then
|
||||||
break
|
break
|
||||||
|
@ -1105,7 +1070,7 @@ function Schematic:optimizeRoute()
|
||||||
end
|
end
|
||||||
if backward > 0 then
|
if backward > 0 then
|
||||||
local b = p[backward]
|
local b = p[backward]
|
||||||
if not b.u then
|
if blockReady(b) then
|
||||||
getMoves(b, backward)
|
getMoves(b, backward)
|
||||||
if moves <= 1 then
|
if moves <= 1 then
|
||||||
break
|
break
|
||||||
|
@ -1125,54 +1090,62 @@ function Schematic:optimizeRoute()
|
||||||
block.u = true
|
block.u = true
|
||||||
return block
|
return block
|
||||||
end
|
end
|
||||||
|
|
||||||
local pt = { x = -1, z = -1, y = 0, heading = 0 }
|
local pt = Util.shallowCopy(self.cache[y - 1] or turtle.point)
|
||||||
local t = {}
|
local t = {}
|
||||||
local cursorX, cursorY = term.getCursorPos()
|
local ri = self.rowIndex[y]
|
||||||
local spinner = UI.Spinner({
|
local blockCount = ri.e - ri.s + 1
|
||||||
x = 0,
|
|
||||||
y = cursorY
|
local function extractPlane()
|
||||||
})
|
|
||||||
|
|
||||||
local function extractPlane(y)
|
|
||||||
local t = {}
|
local t = {}
|
||||||
local dt = {}
|
local dt = {}
|
||||||
for _, b in pairs(self.blocks) do
|
for i = ri.s, ri.e do
|
||||||
if b.y == y then
|
local b = self.blocks[i]
|
||||||
if b.twoHigh then
|
if b.twoHigh then
|
||||||
table.insert(dt, b)
|
b.last = true
|
||||||
else
|
while b.next do
|
||||||
table.insert(t, b)
|
b = b.next
|
||||||
|
b.last = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
for i = ri.s, ri.e do
|
||||||
|
local b = self.blocks[i]
|
||||||
|
if b.last then
|
||||||
|
table.insert(dt, b)
|
||||||
|
else
|
||||||
|
table.insert(t, b)
|
||||||
|
end
|
||||||
|
end
|
||||||
return t, dt
|
return t, dt
|
||||||
end
|
end
|
||||||
|
|
||||||
local maxDistance = self.width*self.length
|
local maxDistance = self.width*self.length
|
||||||
Profile.start('optimize')
|
local plane, doors = extractPlane(y)
|
||||||
for y = 0, self.height do
|
spinner:spin(percent)
|
||||||
local percent = math.floor(#t * 100 / #self.blocks) .. '%'
|
pt.index = 0
|
||||||
spinner:spin(percent)
|
for i = 1, #plane do
|
||||||
local plane, doors = extractPlane(y)
|
local b = getNearestNeighbor(plane, pt, maxDistance)
|
||||||
pt.index = 0
|
table.insert(t, b)
|
||||||
for i = 1, #plane do
|
local percent = math.floor(#t * 100 / blockCount) .. '%'
|
||||||
local b = getNearestNeighbor(plane, pt, maxDistance)
|
spinner:spin(percent .. ' ' .. blockCount - i .. ' ')
|
||||||
table.insert(t, b)
|
end
|
||||||
spinner:spin(percent .. ' ' .. #plane - i .. ' ')
|
-- all two high blocks are placed last on each plane
|
||||||
end
|
pt.index = 0
|
||||||
-- all two high blocks are placed last on each plane
|
for i = 1, #doors do
|
||||||
pt.index = 0
|
local b = getNearestNeighbor(doors, pt, maxDistance)
|
||||||
for i = 1, #doors do
|
table.insert(t, b)
|
||||||
local b = getNearestNeighbor(doors, pt, maxDistance)
|
local percent = math.floor(#t * 100 / blockCount) .. '%'
|
||||||
table.insert(t, b)
|
spinner:spin(percent .. ' ' .. blockCount - #plane - i .. ' ')
|
||||||
spinner:spin(percent .. ' ' .. #doors - i .. ' ')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Profile.stop('optimize')
|
self.rowIndex[y].loaded = true
|
||||||
self.blocks = t
|
if not self.cache[y] then
|
||||||
spinner:stop(' ')
|
self.cache[y] = Util.shallowCopy(pt)
|
||||||
|
Util.writeTable('usr/builder/' .. self.filename .. '.cache', self.cache)
|
||||||
|
end
|
||||||
|
|
||||||
|
return t
|
||||||
end
|
end
|
||||||
|
|
||||||
return Schematic
|
return Schematic
|
||||||
|
|
|
@ -9,7 +9,6 @@ local Message = require('message')
|
||||||
local Logger = require('logger')
|
local Logger = require('logger')
|
||||||
local UI = require('ui')
|
local UI = require('ui')
|
||||||
local Schematic = require('schematic')
|
local Schematic = require('schematic')
|
||||||
local Profile = require('profile')
|
|
||||||
local TableDB = require('tableDB')
|
local TableDB = require('tableDB')
|
||||||
local MEProvider = require('meProvider')
|
local MEProvider = require('meProvider')
|
||||||
local Blocks = require('blocks')
|
local Blocks = require('blocks')
|
||||||
|
@ -520,7 +519,7 @@ function Builder:getGenericSupplyList(blockIndex)
|
||||||
local lastBlock = blockIndex
|
local lastBlock = blockIndex
|
||||||
for k = blockIndex, #schematic.blocks do
|
for k = blockIndex, #schematic.blocks do
|
||||||
lastBlock = k
|
lastBlock = k
|
||||||
local b = schematic.blocks[k]
|
local b = schematic:getComputedBlock(k)
|
||||||
|
|
||||||
if b.id ~= 'minecraft:air' then
|
if b.id ~= 'minecraft:air' then
|
||||||
local slot = getSlot(b.id, b.dmg)
|
local slot = getSlot(b.id, b.dmg)
|
||||||
|
@ -1164,16 +1163,8 @@ function Builder:placeDirectionalBlock(b, slot, travelPlane)
|
||||||
}
|
}
|
||||||
if doorDirections[d] then
|
if doorDirections[d] then
|
||||||
local hi = turtle.getHeadingInfo(doorDirections[d])
|
local hi = turtle.getHeadingInfo(doorDirections[d])
|
||||||
self:gotoEx(b.x - hi.xd, b.z - hi.zd, b.y - 2, hi.heading, travelPlane)
|
self:gotoEx(b.x - hi.xd, b.z - hi.zd, b.y - 1, hi.heading, travelPlane)
|
||||||
-- if not turtle.detectDown() then
|
b.placed = self:place(slot)
|
||||||
-- if turtle.down() then
|
|
||||||
-- if not turtle.detectDown() then
|
|
||||||
-- if turtle.down() then
|
|
||||||
b.placed = self:place(slot)
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local blockDirections = {
|
local blockDirections = {
|
||||||
|
@ -1251,15 +1242,19 @@ function Builder:findTravelPlane(index)
|
||||||
for i = index, 1, -1 do
|
for i = index, 1, -1 do
|
||||||
local b = schematic.blocks[i]
|
local b = schematic.blocks[i]
|
||||||
|
|
||||||
if not travelPlane or b.y > travelPlane then
|
local y = b.y
|
||||||
|
if b.twoHigh then
|
||||||
|
y = y + 1
|
||||||
|
end
|
||||||
|
if not travelPlane or y > travelPlane then
|
||||||
-- if not b.twoHigh then
|
-- if not b.twoHigh then
|
||||||
travelPlane = b.y
|
travelPlane = y
|
||||||
|
|
||||||
Logger.log('builder', 'adjusting travelPlane')
|
Logger.log('builder', 'adjusting travelPlane')
|
||||||
Logger.log('builder', b)
|
Logger.log('builder', b)
|
||||||
--read()
|
--read()
|
||||||
-- end
|
-- end
|
||||||
elseif travelPlane and travelPlane - b.y > 2 then
|
elseif travelPlane and travelPlane - y > 2 then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1300,11 +1295,12 @@ function Builder:build()
|
||||||
|
|
||||||
for i = self.index, last, direction do
|
for i = self.index, last, direction do
|
||||||
self.index = i
|
self.index = i
|
||||||
local b = schematic.blocks[i]
|
local b = schematic:getComputedBlock(i)
|
||||||
|
|
||||||
if b.id ~= 'minecraft:air' then
|
if b.id ~= 'minecraft:air' then
|
||||||
|
|
||||||
if self.mode == 'destroy' then
|
if self.mode == 'destroy' then
|
||||||
|
|
||||||
b.heading = nil -- don't make the supplier follow the block heading
|
b.heading = nil -- don't make the supplier follow the block heading
|
||||||
self:logBlock(self.index, b)
|
self:logBlock(self.index, b)
|
||||||
if b.y ~= turtle.getPoint().y then
|
if b.y ~= turtle.getPoint().y then
|
||||||
|
@ -1337,8 +1333,12 @@ function Builder:build()
|
||||||
self:resupply()
|
self:resupply()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if b.y > travelPlane then
|
local y = b.y
|
||||||
travelPlane = b.y
|
if b.twoHigh then
|
||||||
|
y = b.y + 1
|
||||||
|
end
|
||||||
|
if y > travelPlane then
|
||||||
|
travelPlane = y
|
||||||
end
|
end
|
||||||
|
|
||||||
self:logBlock(self.index, b)
|
self:logBlock(self.index, b)
|
||||||
|
@ -1995,8 +1995,8 @@ function startPage:eventHandler(event)
|
||||||
height = 7,
|
height = 7,
|
||||||
form = UI.Form {
|
form = UI.Form {
|
||||||
y = 3, x = 2, height = 4,
|
y = 3, x = 2, height = 4,
|
||||||
text = UI.Text { x = 5, y = 1, value = '1 - ' .. #schematic.blocks, textColor = colors.gray },
|
text = UI.Text { x = 2, y = 1, value = '1 - ' .. #schematic.blocks, textColor = colors.gray },
|
||||||
textEntry = UI.TextEntry { x = 15, y = 1, value = tostring(Builder.index), width = 7 }
|
textEntry = UI.TextEntry { x = 16, y = 1, value = tostring(Builder.index), width = 10, limit = 8 }
|
||||||
},
|
},
|
||||||
statusBar = UI.StatusBar(),
|
statusBar = UI.StatusBar(),
|
||||||
}
|
}
|
||||||
|
@ -2023,6 +2023,9 @@ function startPage:eventHandler(event)
|
||||||
UI:setPage(dialog)
|
UI:setPage(dialog)
|
||||||
|
|
||||||
elseif event.type == 'assignBlocks' then
|
elseif event.type == 'assignBlocks' then
|
||||||
|
-- this might be an approximation of the blocks needed
|
||||||
|
-- as the current level's route may or may not have been
|
||||||
|
-- computed
|
||||||
Builder:dumpInventory()
|
Builder:dumpInventory()
|
||||||
UI:setPage('listing')
|
UI:setPage('listing')
|
||||||
|
|
||||||
|
@ -2059,12 +2062,6 @@ function startPage:eventHandler(event)
|
||||||
turtle.status = 'thinking'
|
turtle.status = 'thinking'
|
||||||
print('Reloading schematic')
|
print('Reloading schematic')
|
||||||
Builder:reloadSchematic()
|
Builder:reloadSchematic()
|
||||||
print('Determining block placement')
|
|
||||||
schematic:determineBlockPlacement()
|
|
||||||
print('Optimizing route (' .. #schematic.blocks .. ' blocks)')
|
|
||||||
schematic:optimizeRoute()
|
|
||||||
print('Adjusting route')
|
|
||||||
schematic:setPlacementOrder()
|
|
||||||
Builder:dumpInventory()
|
Builder:dumpInventory()
|
||||||
Builder:refuel()
|
Builder:refuel()
|
||||||
|
|
||||||
|
@ -2084,7 +2081,6 @@ function startPage:eventHandler(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
Builder:build()
|
Builder:build()
|
||||||
Profile.display()
|
|
||||||
|
|
||||||
elseif event.type == 'quit' then
|
elseif event.type == 'quit' then
|
||||||
Event.exitPullEvents()
|
Event.exitPullEvents()
|
||||||
|
@ -2098,9 +2094,6 @@ local args = {...}
|
||||||
if #args < 1 then
|
if #args < 1 then
|
||||||
error('supply file name')
|
error('supply file name')
|
||||||
end
|
end
|
||||||
--if #args > 1 then
|
|
||||||
Profile.enable()
|
|
||||||
--end
|
|
||||||
|
|
||||||
if os.version() == 'CraftOS 1.7' then
|
if os.version() == 'CraftOS 1.7' then
|
||||||
Builder.ccVersion = 1.7
|
Builder.ccVersion = 1.7
|
||||||
|
|
|
@ -6,6 +6,18 @@ local Point = require('point')
|
||||||
local TableDB = require('tableDB')
|
local TableDB = require('tableDB')
|
||||||
local MEProvider = require('meProvider')
|
local MEProvider = require('meProvider')
|
||||||
|
|
||||||
|
--[[
|
||||||
|
A supplier turtle for the builder turtle. For larger builds, use
|
||||||
|
ender modems.
|
||||||
|
|
||||||
|
Setup:
|
||||||
|
|
||||||
|
1. chest or ME interface at level 0 (bottom of build area)
|
||||||
|
2. builder turtle on top facing the build area
|
||||||
|
3. If facing the build turtle, the supplier turtle is to the right
|
||||||
|
pointing at the chest/interface
|
||||||
|
]]--
|
||||||
|
|
||||||
local ChestProvider = require('chestProvider')
|
local ChestProvider = require('chestProvider')
|
||||||
if os.getVersion() == 1.8 then
|
if os.getVersion() == 1.8 then
|
||||||
ChestProvider = require('chestProvider18')
|
ChestProvider = require('chestProvider18')
|
||||||
|
@ -70,7 +82,7 @@ function Builder:dumpInventoryWithCheck()
|
||||||
Builder:log('Unable to dump inventory')
|
Builder:log('Unable to dump inventory')
|
||||||
print('Provider is full or missing - make space or replace')
|
print('Provider is full or missing - make space or replace')
|
||||||
print('Press enter to continue')
|
print('Press enter to continue')
|
||||||
turtle.setHeading(0)
|
--turtle.setHeading(0)
|
||||||
self.ready = false
|
self.ready = false
|
||||||
read()
|
read()
|
||||||
end
|
end
|
||||||
|
@ -397,9 +409,9 @@ if not Builder.itemProvider:isValid() then
|
||||||
south = 'north',
|
south = 'north',
|
||||||
}
|
}
|
||||||
|
|
||||||
Builder.itemProvider = ChestProvider({ direction = sides[args[2]], wrapSide = args[2] })
|
Builder.itemProvider = ChestProvider({ direction = sides[args[2]], wrapSide = 'front' })
|
||||||
if not Builder.itemProvider:isValid() then
|
if not Builder.itemProvider:isValid() then
|
||||||
error('A chest or ME interface must be below turtle')
|
error('A chest or ME interface must be in front of turtle')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue