spaces->tab, equipper improvements, supertreefarm rewrite, follow improvements, sensor cleanup, milo multiple items allowed in recipes, remote canvas access
This commit is contained in:
@@ -15,37 +15,37 @@ local os = _G.os
|
||||
local alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
|
||||
local function sixBitToBase64(input)
|
||||
return _sub(alphabet, input+1, input+1)
|
||||
return _sub(alphabet, input+1, input+1)
|
||||
end
|
||||
|
||||
local function base64ToSixBit(input)
|
||||
for i=1, 64 do
|
||||
if input == _sub(alphabet, i, i) then
|
||||
return i-1
|
||||
end
|
||||
end
|
||||
for i=1, 64 do
|
||||
if input == _sub(alphabet, i, i) then
|
||||
return i-1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function octetToBase64(o1, o2, o3)
|
||||
local i1 = sixBitToBase64(_brshift(_band(o1, 0xFC), 2))
|
||||
local i2
|
||||
local i3 = "="
|
||||
local i4 = "="
|
||||
if o2 then
|
||||
i2 = sixBitToBase64(_bor( _blshift(_band(o1, 3), 4), _brshift(_band(o2, 0xF0), 4) ))
|
||||
if not o3 then
|
||||
i3 = sixBitToBase64(_blshift(_band(o2, 0x0F), 2))
|
||||
else
|
||||
i3 = sixBitToBase64(_bor( _blshift(_band(o2, 0x0F), 2), _brshift(_band(o3, 0xC0), 6) ))
|
||||
end
|
||||
else
|
||||
i2 = sixBitToBase64(_blshift(_band(o1, 3), 4))
|
||||
end
|
||||
if o3 then
|
||||
i4 = sixBitToBase64(_band(o3, 0x3F))
|
||||
end
|
||||
local i1 = sixBitToBase64(_brshift(_band(o1, 0xFC), 2))
|
||||
local i2
|
||||
local i3 = "="
|
||||
local i4 = "="
|
||||
if o2 then
|
||||
i2 = sixBitToBase64(_bor( _blshift(_band(o1, 3), 4), _brshift(_band(o2, 0xF0), 4) ))
|
||||
if not o3 then
|
||||
i3 = sixBitToBase64(_blshift(_band(o2, 0x0F), 2))
|
||||
else
|
||||
i3 = sixBitToBase64(_bor( _blshift(_band(o2, 0x0F), 2), _brshift(_band(o3, 0xC0), 6) ))
|
||||
end
|
||||
else
|
||||
i2 = sixBitToBase64(_blshift(_band(o1, 3), 4))
|
||||
end
|
||||
if o3 then
|
||||
i4 = sixBitToBase64(_band(o3, 0x3F))
|
||||
end
|
||||
|
||||
return i1..i2..i3..i4
|
||||
return i1..i2..i3..i4
|
||||
end
|
||||
|
||||
-- octet 1 needs characters 1/2
|
||||
@@ -53,61 +53,61 @@ end
|
||||
-- octet 3 needs characters 3/4
|
||||
|
||||
local function base64ToThreeOctet(s1)
|
||||
local c1 = base64ToSixBit(_sub(s1, 1, 1))
|
||||
local c2 = base64ToSixBit(_sub(s1, 2, 2))
|
||||
local c3
|
||||
local c4
|
||||
local o1
|
||||
local o2
|
||||
local o3
|
||||
if _sub(s1, 3, 3) == "=" then
|
||||
c3 = nil
|
||||
c4 = nil
|
||||
elseif _sub(s1, 4, 4) == "=" then
|
||||
c3 = base64ToSixBit(_sub(s1, 3, 3))
|
||||
c4 = nil
|
||||
else
|
||||
c3 = base64ToSixBit(_sub(s1, 3, 3))
|
||||
c4 = base64ToSixBit(_sub(s1, 4, 4))
|
||||
end
|
||||
o1 = _bor( _blshift(c1, 2), _brshift(_band( c2, 0x30 ), 4) )
|
||||
if c3 then
|
||||
o2 = _bor( _blshift(_band(c2, 0x0F), 4), _brshift(_band( c3, 0x3C ), 2) )
|
||||
else
|
||||
o2 = nil
|
||||
end
|
||||
if c4 then
|
||||
o3 = _bor( _blshift(_band(c3, 3), 6), c4 )
|
||||
else
|
||||
o3 = nil
|
||||
end
|
||||
return o1, o2, o3
|
||||
local c1 = base64ToSixBit(_sub(s1, 1, 1))
|
||||
local c2 = base64ToSixBit(_sub(s1, 2, 2))
|
||||
local c3
|
||||
local c4
|
||||
local o1
|
||||
local o2
|
||||
local o3
|
||||
if _sub(s1, 3, 3) == "=" then
|
||||
c3 = nil
|
||||
c4 = nil
|
||||
elseif _sub(s1, 4, 4) == "=" then
|
||||
c3 = base64ToSixBit(_sub(s1, 3, 3))
|
||||
c4 = nil
|
||||
else
|
||||
c3 = base64ToSixBit(_sub(s1, 3, 3))
|
||||
c4 = base64ToSixBit(_sub(s1, 4, 4))
|
||||
end
|
||||
o1 = _bor( _blshift(c1, 2), _brshift(_band( c2, 0x30 ), 4) )
|
||||
if c3 then
|
||||
o2 = _bor( _blshift(_band(c2, 0x0F), 4), _brshift(_band( c3, 0x3C ), 2) )
|
||||
else
|
||||
o2 = nil
|
||||
end
|
||||
if c4 then
|
||||
o3 = _bor( _blshift(_band(c3, 3), 6), c4 )
|
||||
else
|
||||
o3 = nil
|
||||
end
|
||||
return o1, o2, o3
|
||||
end
|
||||
|
||||
local function splitIntoBlocks(bytes)
|
||||
local blockNum = 1
|
||||
local blocks = {}
|
||||
for i=1, #bytes, 3 do
|
||||
blocks[blockNum] = {bytes[i], bytes[i+1], bytes[i+2]}
|
||||
--[[
|
||||
if #blocks[blockNum] < 3 then
|
||||
for j=#blocks[blockNum]+1, 3 do
|
||||
table.insert(blocks[blockNum], 0)
|
||||
end
|
||||
end
|
||||
]]
|
||||
blockNum = blockNum+1
|
||||
end
|
||||
return blocks
|
||||
local blockNum = 1
|
||||
local blocks = {}
|
||||
for i=1, #bytes, 3 do
|
||||
blocks[blockNum] = {bytes[i], bytes[i+1], bytes[i+2]}
|
||||
--[[
|
||||
if #blocks[blockNum] < 3 then
|
||||
for j=#blocks[blockNum]+1, 3 do
|
||||
table.insert(blocks[blockNum], 0)
|
||||
end
|
||||
end
|
||||
]]
|
||||
blockNum = blockNum+1
|
||||
end
|
||||
return blocks
|
||||
end
|
||||
|
||||
function Base64.encode(bytes)
|
||||
local blocks = splitIntoBlocks(bytes)
|
||||
local output = ""
|
||||
for i=1, #blocks do
|
||||
output = output..octetToBase64( unpack(blocks[i]) )
|
||||
end
|
||||
return output
|
||||
local blocks = splitIntoBlocks(bytes)
|
||||
local output = ""
|
||||
for i=1, #blocks do
|
||||
output = output..octetToBase64( unpack(blocks[i]) )
|
||||
end
|
||||
return output
|
||||
end
|
||||
|
||||
local function Throttle()
|
||||
@@ -123,32 +123,32 @@ local function Throttle()
|
||||
end
|
||||
|
||||
function Base64.decode(str)
|
||||
local bytes = {}
|
||||
local blocks = {}
|
||||
local blockNum = 1
|
||||
local throttle = Throttle()
|
||||
for i=1, #str, 4 do
|
||||
blocks[blockNum] = _sub(str, i, i+3)
|
||||
blockNum = blockNum+1
|
||||
end
|
||||
for i=1, #blocks do
|
||||
local o1, o2, o3 = base64ToThreeOctet(blocks[i])
|
||||
table.insert(bytes, o1)
|
||||
table.insert(bytes, o2)
|
||||
table.insert(bytes, o3)
|
||||
throttle()
|
||||
end
|
||||
-- Remove padding:
|
||||
--[[
|
||||
for i=#bytes, 1, -1 do
|
||||
if bytes[i] ~= 0 then
|
||||
break
|
||||
else
|
||||
bytes[i] = nil
|
||||
end
|
||||
end
|
||||
]]
|
||||
return bytes
|
||||
local bytes = {}
|
||||
local blocks = {}
|
||||
local blockNum = 1
|
||||
local throttle = Throttle()
|
||||
for i=1, #str, 4 do
|
||||
blocks[blockNum] = _sub(str, i, i+3)
|
||||
blockNum = blockNum+1
|
||||
end
|
||||
for i=1, #blocks do
|
||||
local o1, o2, o3 = base64ToThreeOctet(blocks[i])
|
||||
table.insert(bytes, o1)
|
||||
table.insert(bytes, o2)
|
||||
table.insert(bytes, o3)
|
||||
throttle()
|
||||
end
|
||||
-- Remove padding:
|
||||
--[[
|
||||
for i=#bytes, 1, -1 do
|
||||
if bytes[i] ~= 0 then
|
||||
break
|
||||
else
|
||||
bytes[i] = nil
|
||||
end
|
||||
end
|
||||
]]
|
||||
return bytes
|
||||
end
|
||||
|
||||
return Base64
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,10 +9,10 @@ local turtle = _G.turtle
|
||||
|
||||
local Builder = class()
|
||||
Util.merge(Builder, {
|
||||
isCommandComputer = not turtle,
|
||||
loc = { },
|
||||
index = 1,
|
||||
mode = 'build',
|
||||
isCommandComputer = not turtle,
|
||||
loc = { },
|
||||
index = 1,
|
||||
mode = 'build',
|
||||
})
|
||||
|
||||
local BUILDER_DIR = 'usr/builder'
|
||||
@@ -20,82 +20,82 @@ local BUILDER_DIR = 'usr/builder'
|
||||
local blockInfo = Blocks()
|
||||
|
||||
function Builder:getBlockCounts()
|
||||
local blocks = { }
|
||||
local blocks = { }
|
||||
|
||||
for k = self.index, #self.schematic.blocks do
|
||||
local b = self.schematic.blocks[k]
|
||||
local key = tostring(b.id) .. ':' .. b.dmg
|
||||
local block = blocks[key]
|
||||
if not block then
|
||||
block = Util.shallowCopy(b)
|
||||
block.qty = 0
|
||||
block.need = 0
|
||||
blocks[key] = block
|
||||
end
|
||||
block.need = block.need + 1
|
||||
end
|
||||
for k = self.index, #self.schematic.blocks do
|
||||
local b = self.schematic.blocks[k]
|
||||
local key = tostring(b.id) .. ':' .. b.dmg
|
||||
local block = blocks[key]
|
||||
if not block then
|
||||
block = Util.shallowCopy(b)
|
||||
block.qty = 0
|
||||
block.need = 0
|
||||
blocks[key] = block
|
||||
end
|
||||
block.need = block.need + 1
|
||||
end
|
||||
|
||||
return blocks
|
||||
return blocks
|
||||
end
|
||||
|
||||
function Builder:substituteBlocks(throttle)
|
||||
for _,b in pairs(self.schematic.blocks) do
|
||||
for _,b in pairs(self.schematic.blocks) do
|
||||
|
||||
-- replace schematic block type with substitution
|
||||
local pb = blockInfo:getPlaceableBlock(b.id, b.dmg)
|
||||
-- replace schematic block type with substitution
|
||||
local pb = blockInfo:getPlaceableBlock(b.id, b.dmg)
|
||||
|
||||
Util.merge(b, pb)
|
||||
Util.merge(b, pb)
|
||||
|
||||
b.odmg = pb.odmg or pb.dmg
|
||||
b.odmg = pb.odmg or pb.dmg
|
||||
|
||||
local sub = self.subDB:get({ b.id, b.dmg })
|
||||
if sub then
|
||||
b.id, b.dmg = self.subDB:extract(sub)
|
||||
end
|
||||
throttle()
|
||||
end
|
||||
local sub = self.subDB:get({ b.id, b.dmg })
|
||||
if sub then
|
||||
b.id, b.dmg = self.subDB:extract(sub)
|
||||
end
|
||||
throttle()
|
||||
end
|
||||
end
|
||||
|
||||
function Builder:reloadSchematic(throttle)
|
||||
self.schematic:reload(throttle)
|
||||
self:substituteBlocks(throttle)
|
||||
self.schematic:reload(throttle)
|
||||
self:substituteBlocks(throttle)
|
||||
end
|
||||
|
||||
function Builder:log(...)
|
||||
Util.print(...)
|
||||
Util.print(...)
|
||||
end
|
||||
|
||||
function Builder:dumpInventory()
|
||||
end
|
||||
|
||||
function Builder:logBlock(index, b)
|
||||
local bdir = b.direction or ''
|
||||
local logText = string.format('%d %s:%d (x:%d,z:%d:y:%d) %s',
|
||||
index, b.id, b.dmg, b.x, b.z, b.y, bdir)
|
||||
self:log(logText)
|
||||
-- self:log(b.index) -- unique identifier of block
|
||||
local bdir = b.direction or ''
|
||||
local logText = string.format('%d %s:%d (x:%d,z:%d:y:%d) %s',
|
||||
index, b.id, b.dmg, b.x, b.z, b.y, bdir)
|
||||
self:log(logText)
|
||||
-- self:log(b.index) -- unique identifier of block
|
||||
|
||||
if device.wireless_modem then
|
||||
Message.broadcast('builder', { x = b.x, y = b.y, z = b.z, heading = b.heading })
|
||||
end
|
||||
if device.wireless_modem then
|
||||
Message.broadcast('builder', { x = b.x, y = b.y, z = b.z, heading = b.heading })
|
||||
end
|
||||
end
|
||||
|
||||
function Builder:saveProgress(index)
|
||||
Util.writeTable(
|
||||
fs.combine(BUILDER_DIR, self.schematic.filename .. '.progress'),
|
||||
{ index = index, loc = self.loc }
|
||||
)
|
||||
Util.writeTable(
|
||||
fs.combine(BUILDER_DIR, self.schematic.filename .. '.progress'),
|
||||
{ index = index, loc = self.loc }
|
||||
)
|
||||
end
|
||||
|
||||
function Builder:loadProgress(filename)
|
||||
local progress = Util.readTable(fs.combine(BUILDER_DIR, filename))
|
||||
if progress then
|
||||
self.index = progress.index
|
||||
if self.index > #self.schematic.blocks then
|
||||
self.index = 1
|
||||
end
|
||||
self.loc = progress.loc or { }
|
||||
end
|
||||
local progress = Util.readTable(fs.combine(BUILDER_DIR, filename))
|
||||
if progress then
|
||||
self.index = progress.index
|
||||
if self.index > #self.schematic.blocks then
|
||||
self.index = 1
|
||||
end
|
||||
self.loc = progress.loc or { }
|
||||
end
|
||||
end
|
||||
|
||||
return Builder
|
||||
|
||||
@@ -8,77 +8,77 @@ local os = _G.os
|
||||
local read = _G.read
|
||||
|
||||
function Builder:begin()
|
||||
local direction = 1
|
||||
local last = #self.schematic.blocks
|
||||
local throttle = Util.throttle()
|
||||
local direction = 1
|
||||
local last = #self.schematic.blocks
|
||||
local throttle = Util.throttle()
|
||||
|
||||
local cx, cy, cz = commands.getBlockPosition()
|
||||
if self.loc.x then
|
||||
cx, cy, cz = self.loc.rx, self.loc.ry, self.loc.rz
|
||||
end
|
||||
local cx, cy, cz = commands.getBlockPosition()
|
||||
if self.loc.x then
|
||||
cx, cy, cz = self.loc.rx, self.loc.ry, self.loc.rz
|
||||
end
|
||||
|
||||
if self.mode == 'destroy' then
|
||||
direction = -1
|
||||
last = 1
|
||||
end
|
||||
if self.mode == 'destroy' then
|
||||
direction = -1
|
||||
last = 1
|
||||
end
|
||||
|
||||
for i = self.index, last, direction do
|
||||
self.index = i
|
||||
for i = self.index, last, direction do
|
||||
self.index = i
|
||||
|
||||
local b = self.schematic:getComputedBlock(i)
|
||||
local b = self.schematic:getComputedBlock(i)
|
||||
|
||||
if b.id ~= 'minecraft:air' then
|
||||
if b.id ~= 'minecraft:air' then
|
||||
|
||||
self:logBlock(self.index, b)
|
||||
self:logBlock(self.index, b)
|
||||
|
||||
local id = b.id
|
||||
if self.mode == 'destroy' then
|
||||
id = 'minecraft:air'
|
||||
end
|
||||
local id = b.id
|
||||
if self.mode == 'destroy' then
|
||||
id = 'minecraft:air'
|
||||
end
|
||||
|
||||
local function placeBlock(bid, dmg, x, y, z)
|
||||
local command = table.concat({
|
||||
"setblock",
|
||||
cx + x + 1,
|
||||
cy + y,
|
||||
cz + z + 1,
|
||||
bid,
|
||||
dmg,
|
||||
}, ' ')
|
||||
local function placeBlock(bid, dmg, x, y, z)
|
||||
local command = table.concat({
|
||||
"setblock",
|
||||
cx + x + 1,
|
||||
cy + y,
|
||||
cz + z + 1,
|
||||
bid,
|
||||
dmg,
|
||||
}, ' ')
|
||||
|
||||
commands.execAsync(command)
|
||||
commands.execAsync(command)
|
||||
|
||||
local result = { os.pullEvent("task_complete") }
|
||||
if not result[4] then
|
||||
Util.print(result[5])
|
||||
if self.mode ~= 'destroy' then
|
||||
read()
|
||||
end
|
||||
end
|
||||
end
|
||||
local result = { os.pullEvent("task_complete") }
|
||||
if not result[4] then
|
||||
Util.print(result[5])
|
||||
if self.mode ~= 'destroy' then
|
||||
read()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
placeBlock(id, b.odmg, b.x, b.y, b.z)
|
||||
placeBlock(id, b.odmg, b.x, b.y, b.z)
|
||||
|
||||
if b.twoHigh then
|
||||
local _, topBlock = self.schematic:findIndexAt(b.x, b.z, b.y + 1, true)
|
||||
if topBlock then
|
||||
placeBlock(id, topBlock.odmg, b.x, b.y + 1, b.z)
|
||||
end
|
||||
end
|
||||
if b.twoHigh then
|
||||
local _, topBlock = self.schematic:findIndexAt(b.x, b.z, b.y + 1, true)
|
||||
if topBlock then
|
||||
placeBlock(id, topBlock.odmg, b.x, b.y + 1, b.z)
|
||||
end
|
||||
end
|
||||
|
||||
if self.mode == 'destroy' then
|
||||
self:saveProgress(math.max(self.index, 1))
|
||||
else
|
||||
self:saveProgress(self.index + 1)
|
||||
end
|
||||
else
|
||||
throttle() -- sleep in case there are a large # of skipped blocks
|
||||
end
|
||||
end
|
||||
if self.mode == 'destroy' then
|
||||
self:saveProgress(math.max(self.index, 1))
|
||||
else
|
||||
self:saveProgress(self.index + 1)
|
||||
end
|
||||
else
|
||||
throttle() -- sleep in case there are a large # of skipped blocks
|
||||
end
|
||||
end
|
||||
|
||||
fs.delete(self.schematic.filename .. '.progress')
|
||||
print('Finished')
|
||||
Event.exitPullEvents()
|
||||
fs.delete(self.schematic.filename .. '.progress')
|
||||
print('Finished')
|
||||
Event.exitPullEvents()
|
||||
end
|
||||
|
||||
return Builder
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1136
builder/builder.lua
1136
builder/builder.lua
File diff suppressed because it is too large
Load Diff
@@ -10,390 +10,390 @@ local os = _G.os
|
||||
local turtle = _G.turtle
|
||||
|
||||
--[[
|
||||
A supplier turtle for the builder turtle. For larger builds, use
|
||||
ender modems.
|
||||
A supplier turtle for the builder turtle. For larger builds, use
|
||||
ender modems.
|
||||
|
||||
Setup:
|
||||
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
|
||||
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('core.chestProvider')
|
||||
if Util.getVersion() == 1.8 then
|
||||
ChestProvider = require('core.chestProvider18')
|
||||
ChestProvider = require('core.chestProvider18')
|
||||
end
|
||||
|
||||
if not device.wireless_modem then
|
||||
error('No wireless modem detected')
|
||||
error('No wireless modem detected')
|
||||
end
|
||||
|
||||
local __BUILDER_ID = 6
|
||||
local itemInfoDB
|
||||
|
||||
local Builder = {
|
||||
version = '1.70',
|
||||
ccVersion = nil,
|
||||
slots = { },
|
||||
index = 1,
|
||||
fuelItem = { id = 'minecraft:coal', dmg = 0 },
|
||||
resupplying = true,
|
||||
ready = true,
|
||||
version = '1.70',
|
||||
ccVersion = nil,
|
||||
slots = { },
|
||||
index = 1,
|
||||
fuelItem = { id = 'minecraft:coal', dmg = 0 },
|
||||
resupplying = true,
|
||||
ready = true,
|
||||
}
|
||||
|
||||
--[[-- maxStackDB --]]--
|
||||
local maxStackDB = TableDB({
|
||||
fileName = 'maxstack.db',
|
||||
tabledef = {
|
||||
autokeys = false,
|
||||
type = 'simple',
|
||||
columns = {
|
||||
{ label = 'Key', type = 'key', length = 8 },
|
||||
{ label = 'Quantity', type = 'number', length = 2 }
|
||||
}
|
||||
}
|
||||
fileName = 'maxstack.db',
|
||||
tabledef = {
|
||||
autokeys = false,
|
||||
type = 'simple',
|
||||
columns = {
|
||||
{ label = 'Key', type = 'key', length = 8 },
|
||||
{ label = 'Quantity', type = 'number', length = 2 }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function maxStackDB:get(id, dmg)
|
||||
return self.data[id .. ':' .. dmg] or 64
|
||||
return self.data[id .. ':' .. dmg] or 64
|
||||
end
|
||||
|
||||
function Builder:dumpInventory()
|
||||
|
||||
local success = true
|
||||
local success = true
|
||||
|
||||
for i = 1, 16 do
|
||||
local qty = turtle.getItemCount(i)
|
||||
if qty > 0 then
|
||||
self.itemProvider:insert(i, qty)
|
||||
end
|
||||
if turtle.getItemCount(i) ~= 0 then
|
||||
success = false
|
||||
end
|
||||
end
|
||||
turtle.select(1)
|
||||
for i = 1, 16 do
|
||||
local qty = turtle.getItemCount(i)
|
||||
if qty > 0 then
|
||||
self.itemProvider:insert(i, qty)
|
||||
end
|
||||
if turtle.getItemCount(i) ~= 0 then
|
||||
success = false
|
||||
end
|
||||
end
|
||||
turtle.select(1)
|
||||
|
||||
return success
|
||||
return success
|
||||
end
|
||||
|
||||
function Builder:dumpInventoryWithCheck()
|
||||
while not self:dumpInventory() do
|
||||
Builder:log('Unable to dump inventory')
|
||||
print('Provider is full or missing - make space or replace')
|
||||
print('Press enter to continue')
|
||||
--turtle.setHeading(0)
|
||||
self.ready = false
|
||||
_G.read()
|
||||
end
|
||||
self.ready = true
|
||||
while not self:dumpInventory() do
|
||||
Builder:log('Unable to dump inventory')
|
||||
print('Provider is full or missing - make space or replace')
|
||||
print('Press enter to continue')
|
||||
--turtle.setHeading(0)
|
||||
self.ready = false
|
||||
_G.read()
|
||||
end
|
||||
self.ready = true
|
||||
end
|
||||
|
||||
function Builder:autocraft(supplies)
|
||||
local t = { }
|
||||
local t = { }
|
||||
|
||||
for _,s in pairs(supplies) do
|
||||
local key = s.id .. ':' .. s.dmg
|
||||
local item = t[key]
|
||||
if not item then
|
||||
item = {
|
||||
id = s.id,
|
||||
dmg = s.dmg,
|
||||
qty = 0,
|
||||
}
|
||||
t[key] = item
|
||||
end
|
||||
item.qty = item.qty + (s.need-s.qty)
|
||||
end
|
||||
for _,s in pairs(supplies) do
|
||||
local key = s.id .. ':' .. s.dmg
|
||||
local item = t[key]
|
||||
if not item then
|
||||
item = {
|
||||
id = s.id,
|
||||
dmg = s.dmg,
|
||||
qty = 0,
|
||||
}
|
||||
t[key] = item
|
||||
end
|
||||
item.qty = item.qty + (s.need-s.qty)
|
||||
end
|
||||
|
||||
Builder.itemProvider:craftItems(t)
|
||||
Builder.itemProvider:craftItems(t)
|
||||
end
|
||||
|
||||
function Builder:refuel()
|
||||
while turtle.getFuelLevel() < 4000 and self.fuelItem do
|
||||
Builder:log('Refueling')
|
||||
turtle.select(1)
|
||||
self.itemProvider:provide(self.fuelItem, 64, 1)
|
||||
if turtle.getItemCount(1) == 0 then
|
||||
Builder:log('Out of fuel, add coal to chest/ME system')
|
||||
--turtle.setHeading(0)
|
||||
os.sleep(5)
|
||||
else
|
||||
turtle.refuel(64)
|
||||
end
|
||||
end
|
||||
while turtle.getFuelLevel() < 4000 and self.fuelItem do
|
||||
Builder:log('Refueling')
|
||||
turtle.select(1)
|
||||
self.itemProvider:provide(self.fuelItem, 64, 1)
|
||||
if turtle.getItemCount(1) == 0 then
|
||||
Builder:log('Out of fuel, add coal to chest/ME system')
|
||||
--turtle.setHeading(0)
|
||||
os.sleep(5)
|
||||
else
|
||||
turtle.refuel(64)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Builder:log(...)
|
||||
Util.print(...)
|
||||
Util.print(...)
|
||||
end
|
||||
|
||||
function Builder:getSupplies()
|
||||
|
||||
Builder.itemProvider:refresh()
|
||||
Builder.itemProvider:refresh()
|
||||
|
||||
local t = { }
|
||||
for _,s in ipairs(self.slots) do
|
||||
if s.need > 0 then
|
||||
local item = Builder.itemProvider:getItemInfo(s)
|
||||
if item then
|
||||
if item.name then
|
||||
s.name = item.name
|
||||
end
|
||||
local t = { }
|
||||
for _,s in ipairs(self.slots) do
|
||||
if s.need > 0 then
|
||||
local item = Builder.itemProvider:getItemInfo(s)
|
||||
if item then
|
||||
if item.name then
|
||||
s.name = item.name
|
||||
end
|
||||
|
||||
local qty = math.min(s.need-s.qty, item.qty)
|
||||
local qty = math.min(s.need-s.qty, item.qty)
|
||||
|
||||
if qty + s.qty > item.max_size then
|
||||
maxStackDB:add({ s.id, s.dmg }, item.max_size)
|
||||
maxStackDB.dirty = true
|
||||
maxStackDB:flush()
|
||||
qty = item.max_size
|
||||
s.need = qty
|
||||
end
|
||||
if qty > 0 then
|
||||
self.itemProvider:provide(item, qty, s.index)
|
||||
s.qty = turtle.getItemCount(s.index)
|
||||
end
|
||||
end
|
||||
end
|
||||
if s.qty < s.need then
|
||||
table.insert(t, s)
|
||||
local name = s.name or s.id .. ':' .. s.dmg
|
||||
local item = itemInfoDB:get({ s.id, s.dmg })
|
||||
if item then
|
||||
name = item.displayName
|
||||
end
|
||||
if qty + s.qty > item.max_size then
|
||||
maxStackDB:add({ s.id, s.dmg }, item.max_size)
|
||||
maxStackDB.dirty = true
|
||||
maxStackDB:flush()
|
||||
qty = item.max_size
|
||||
s.need = qty
|
||||
end
|
||||
if qty > 0 then
|
||||
self.itemProvider:provide(item, qty, s.index)
|
||||
s.qty = turtle.getItemCount(s.index)
|
||||
end
|
||||
end
|
||||
end
|
||||
if s.qty < s.need then
|
||||
table.insert(t, s)
|
||||
local name = s.name or s.id .. ':' .. s.dmg
|
||||
local item = itemInfoDB:get({ s.id, s.dmg })
|
||||
if item then
|
||||
name = item.displayName
|
||||
end
|
||||
|
||||
Builder:log('Need %d %s', s.need - s.qty, name)
|
||||
end
|
||||
end
|
||||
Builder:log('Need %d %s', s.need - s.qty, name)
|
||||
end
|
||||
end
|
||||
|
||||
return t
|
||||
return t
|
||||
end
|
||||
|
||||
local function moveTowardsX(dx)
|
||||
|
||||
local direction = dx - turtle.point.x
|
||||
local move
|
||||
local direction = dx - turtle.point.x
|
||||
local move
|
||||
|
||||
if direction == 0 then
|
||||
return false
|
||||
end
|
||||
if direction == 0 then
|
||||
return false
|
||||
end
|
||||
|
||||
if direction > 0 and turtle.point.heading == 0 or
|
||||
direction < 0 and turtle.point.heading == 2 then
|
||||
move = turtle.forward
|
||||
else
|
||||
move = turtle.back
|
||||
end
|
||||
if direction > 0 and turtle.point.heading == 0 or
|
||||
direction < 0 and turtle.point.heading == 2 then
|
||||
move = turtle.forward
|
||||
else
|
||||
move = turtle.back
|
||||
end
|
||||
|
||||
return move()
|
||||
return move()
|
||||
end
|
||||
|
||||
local function moveTowardsZ(dz)
|
||||
|
||||
local direction = dz - turtle.point.z
|
||||
local move
|
||||
local direction = dz - turtle.point.z
|
||||
local move
|
||||
|
||||
if direction == 0 then
|
||||
return false
|
||||
end
|
||||
if direction == 0 then
|
||||
return false
|
||||
end
|
||||
|
||||
if direction > 0 and turtle.point.heading == 1 or
|
||||
direction < 0 and turtle.point.heading == 3 then
|
||||
move = turtle.forward
|
||||
else
|
||||
move = turtle.back
|
||||
end
|
||||
if direction > 0 and turtle.point.heading == 1 or
|
||||
direction < 0 and turtle.point.heading == 3 then
|
||||
move = turtle.forward
|
||||
else
|
||||
move = turtle.back
|
||||
end
|
||||
|
||||
return move()
|
||||
return move()
|
||||
end
|
||||
|
||||
function Builder:finish()
|
||||
Builder.resupplying = true
|
||||
Builder.ready = false
|
||||
if turtle.gotoLocation('supplies') then
|
||||
turtle.setHeading(1)
|
||||
os.sleep(.1) -- random 'Computer is not connected' error...
|
||||
Builder:dumpInventory()
|
||||
Event.exitPullEvents()
|
||||
print('Finished')
|
||||
end
|
||||
Builder.resupplying = true
|
||||
Builder.ready = false
|
||||
if turtle.gotoLocation('supplies') then
|
||||
turtle.setHeading(1)
|
||||
os.sleep(.1) -- random 'Computer is not connected' error...
|
||||
Builder:dumpInventory()
|
||||
Event.exitPullEvents()
|
||||
print('Finished')
|
||||
end
|
||||
end
|
||||
|
||||
function Builder:gotoBuilder()
|
||||
if Builder.lastPoint then
|
||||
turtle.setStatus('tracking')
|
||||
while true do
|
||||
local pt = Point.copy(Builder.lastPoint)
|
||||
pt.y = pt.y + 3
|
||||
if turtle.point.y ~= pt.y then
|
||||
turtle.gotoY(pt.y)
|
||||
else
|
||||
local distance = Point.turtleDistance(turtle.point, pt)
|
||||
if distance <= 3 then
|
||||
Builder:log('Synchronized')
|
||||
break
|
||||
end
|
||||
if Builder.lastPoint then
|
||||
turtle.setStatus('tracking')
|
||||
while true do
|
||||
local pt = Point.copy(Builder.lastPoint)
|
||||
pt.y = pt.y + 3
|
||||
if turtle.point.y ~= pt.y then
|
||||
turtle.gotoY(pt.y)
|
||||
else
|
||||
local distance = Point.turtleDistance(turtle.point, pt)
|
||||
if distance <= 3 then
|
||||
Builder:log('Synchronized')
|
||||
break
|
||||
end
|
||||
|
||||
if turtle.point.heading % 2 == 0 then
|
||||
if turtle.point.x == pt.x then
|
||||
turtle.headTowardsZ(pt.z)
|
||||
moveTowardsZ(pt.z)
|
||||
else
|
||||
moveTowardsX(pt.x)
|
||||
end
|
||||
elseif turtle.point.z ~= pt.z then
|
||||
moveTowardsZ(pt.z)
|
||||
else
|
||||
turtle.headTowardsX(pt.x)
|
||||
moveTowardsX(pt.x)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if turtle.point.heading % 2 == 0 then
|
||||
if turtle.point.x == pt.x then
|
||||
turtle.headTowardsZ(pt.z)
|
||||
moveTowardsZ(pt.z)
|
||||
else
|
||||
moveTowardsX(pt.x)
|
||||
end
|
||||
elseif turtle.point.z ~= pt.z then
|
||||
moveTowardsZ(pt.z)
|
||||
else
|
||||
turtle.headTowardsX(pt.x)
|
||||
moveTowardsX(pt.x)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Message.addHandler('builder',
|
||||
function(_, id, msg)
|
||||
if not id or id ~= __BUILDER_ID then
|
||||
return
|
||||
end
|
||||
function(_, id, msg)
|
||||
if not id or id ~= __BUILDER_ID then
|
||||
return
|
||||
end
|
||||
|
||||
if not Builder.resupplying then
|
||||
local pt = msg.contents
|
||||
pt.y = pt.y + 3
|
||||
if not Builder.resupplying then
|
||||
local pt = msg.contents
|
||||
pt.y = pt.y + 3
|
||||
|
||||
turtle.setStatus('supervising')
|
||||
turtle.gotoYfirst(pt)
|
||||
end
|
||||
end)
|
||||
turtle.setStatus('supervising')
|
||||
turtle.gotoYfirst(pt)
|
||||
end
|
||||
end)
|
||||
|
||||
Message.addHandler('supplyList',
|
||||
function(_, id, msg)
|
||||
if not id or id ~= __BUILDER_ID then
|
||||
return
|
||||
end
|
||||
function(_, id, msg)
|
||||
if not id or id ~= __BUILDER_ID then
|
||||
return
|
||||
end
|
||||
|
||||
turtle.setStatus('resupplying')
|
||||
Builder.resupplying = true
|
||||
Builder.slots = msg.contents.slots
|
||||
Builder.slotUid = msg.contents.uid
|
||||
turtle.setStatus('resupplying')
|
||||
Builder.resupplying = true
|
||||
Builder.slots = msg.contents.slots
|
||||
Builder.slotUid = msg.contents.uid
|
||||
|
||||
Builder:log('Received supply list ' .. Builder.slotUid)
|
||||
Builder:log('Received supply list ' .. Builder.slotUid)
|
||||
|
||||
os.sleep(0)
|
||||
if not turtle.gotoLocation('supplies') then
|
||||
Builder:log('Failed to go to supply location')
|
||||
Builder.ready = false
|
||||
Event.exitPullEvents()
|
||||
end
|
||||
turtle.setHeading(1)
|
||||
os.sleep(.2) -- random 'Computer is not connected' error...
|
||||
Builder:dumpInventoryWithCheck()
|
||||
Builder:refuel()
|
||||
os.sleep(0)
|
||||
if not turtle.gotoLocation('supplies') then
|
||||
Builder:log('Failed to go to supply location')
|
||||
Builder.ready = false
|
||||
Event.exitPullEvents()
|
||||
end
|
||||
turtle.setHeading(1)
|
||||
os.sleep(.2) -- random 'Computer is not connected' error...
|
||||
Builder:dumpInventoryWithCheck()
|
||||
Builder:refuel()
|
||||
|
||||
while true do
|
||||
local supplies = Builder:getSupplies()
|
||||
if #supplies == 0 then
|
||||
break
|
||||
end
|
||||
Builder:autocraft(supplies)
|
||||
turtle.setStatus('waiting')
|
||||
os.sleep(5)
|
||||
end
|
||||
Builder:log('Got all supplies')
|
||||
os.sleep(0)
|
||||
Builder:gotoBuilder()
|
||||
Builder.resupplying = false
|
||||
end)
|
||||
while true do
|
||||
local supplies = Builder:getSupplies()
|
||||
if #supplies == 0 then
|
||||
break
|
||||
end
|
||||
Builder:autocraft(supplies)
|
||||
turtle.setStatus('waiting')
|
||||
os.sleep(5)
|
||||
end
|
||||
Builder:log('Got all supplies')
|
||||
os.sleep(0)
|
||||
Builder:gotoBuilder()
|
||||
Builder.resupplying = false
|
||||
end)
|
||||
|
||||
Message.addHandler('needSupplies',
|
||||
function(_, id, msg)
|
||||
if not id or id ~= __BUILDER_ID then
|
||||
return
|
||||
end
|
||||
function(_, id, msg)
|
||||
if not id or id ~= __BUILDER_ID then
|
||||
return
|
||||
end
|
||||
|
||||
if Builder.resupplying or msg.contents.uid ~= Builder.slotUid then
|
||||
Builder:log('No supplies ready')
|
||||
Message.send(__BUILDER_ID, 'gotSupplies')
|
||||
else
|
||||
turtle.setStatus('supplying')
|
||||
Builder:log('Supplying')
|
||||
os.sleep(0)
|
||||
if Builder.resupplying or msg.contents.uid ~= Builder.slotUid then
|
||||
Builder:log('No supplies ready')
|
||||
Message.send(__BUILDER_ID, 'gotSupplies')
|
||||
else
|
||||
turtle.setStatus('supplying')
|
||||
Builder:log('Supplying')
|
||||
os.sleep(0)
|
||||
|
||||
local pt = msg.contents.point
|
||||
pt.y = turtle.getPoint().y
|
||||
pt.heading = nil
|
||||
if not turtle.gotoYfirst(pt) then -- location of builder
|
||||
Builder.resupplying = true
|
||||
Message.send(__BUILDER_ID, 'gotSupplies')
|
||||
os.sleep(0)
|
||||
if not turtle.gotoLocation('supplies') then
|
||||
Builder:log('failed to go to supply location')
|
||||
Event.exitPullEvents()
|
||||
end
|
||||
turtle.setHeading(1)
|
||||
return
|
||||
end
|
||||
pt.y = pt.y - 2 -- location where builder should go for the chest to be above
|
||||
local pt = msg.contents.point
|
||||
pt.y = turtle.getPoint().y
|
||||
pt.heading = nil
|
||||
if not turtle.gotoYfirst(pt) then -- location of builder
|
||||
Builder.resupplying = true
|
||||
Message.send(__BUILDER_ID, 'gotSupplies')
|
||||
os.sleep(0)
|
||||
if not turtle.gotoLocation('supplies') then
|
||||
Builder:log('failed to go to supply location')
|
||||
Event.exitPullEvents()
|
||||
end
|
||||
turtle.setHeading(1)
|
||||
return
|
||||
end
|
||||
pt.y = pt.y - 2 -- location where builder should go for the chest to be above
|
||||
|
||||
turtle.select(15)
|
||||
turtle.placeDown()
|
||||
os.sleep(.1) -- random computer not connected error
|
||||
local p = ChestProvider({ direction = 'up', wrapSide = 'bottom' })
|
||||
for i = 1, 16 do
|
||||
p:insert(i, 64)
|
||||
end
|
||||
turtle.select(15)
|
||||
turtle.placeDown()
|
||||
os.sleep(.1) -- random computer not connected error
|
||||
local p = ChestProvider({ direction = 'up', wrapSide = 'bottom' })
|
||||
for i = 1, 16 do
|
||||
p:insert(i, 64)
|
||||
end
|
||||
|
||||
Message.send(__BUILDER_ID, 'gotSupplies', { supplies = true, point = pt })
|
||||
Message.send(__BUILDER_ID, 'gotSupplies', { supplies = true, point = pt })
|
||||
|
||||
Message.waitForMessage('thanks', 5, __BUILDER_ID)
|
||||
--os.sleep(0)
|
||||
Message.waitForMessage('thanks', 5, __BUILDER_ID)
|
||||
--os.sleep(0)
|
||||
|
||||
--p.condenseItems()
|
||||
for i = 1, 16 do
|
||||
p:extract(i, 64)
|
||||
end
|
||||
turtle.digDown()
|
||||
turtle.setStatus('waiting')
|
||||
end
|
||||
end)
|
||||
--p.condenseItems()
|
||||
for i = 1, 16 do
|
||||
p:extract(i, 64)
|
||||
end
|
||||
turtle.digDown()
|
||||
turtle.setStatus('waiting')
|
||||
end
|
||||
end)
|
||||
|
||||
Message.addHandler('finished',
|
||||
function(_, id)
|
||||
if not id or id ~= __BUILDER_ID then
|
||||
return
|
||||
end
|
||||
Builder:finish()
|
||||
end)
|
||||
function(_, id)
|
||||
if not id or id ~= __BUILDER_ID then
|
||||
return
|
||||
end
|
||||
Builder:finish()
|
||||
end)
|
||||
|
||||
Event.on('turtle_abort',
|
||||
function()
|
||||
turtle.abort(false)
|
||||
turtle.setStatus('aborting')
|
||||
Builder:finish()
|
||||
end)
|
||||
function()
|
||||
turtle.abort(false)
|
||||
turtle.setStatus('aborting')
|
||||
Builder:finish()
|
||||
end)
|
||||
|
||||
local function onTheWay() -- parallel routine
|
||||
while true do
|
||||
local _, _, _, id, msg, _ = os.pullEvent('modem_message')
|
||||
if Builder.ready then
|
||||
if id == __BUILDER_ID and msg and msg.type then
|
||||
if msg.type == 'needSupplies' then
|
||||
Message.send(__BUILDER_ID, 'gotSupplies', { supplies = true })
|
||||
elseif msg.type == 'builder' then
|
||||
Builder.lastPoint = msg.contents
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
while true do
|
||||
local _, _, _, id, msg, _ = os.pullEvent('modem_message')
|
||||
if Builder.ready then
|
||||
if id == __BUILDER_ID and msg and msg.type then
|
||||
if msg.type == 'needSupplies' then
|
||||
Message.send(__BUILDER_ID, 'gotSupplies', { supplies = true })
|
||||
elseif msg.type == 'builder' then
|
||||
Builder.lastPoint = msg.contents
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local args = {...}
|
||||
if #args < 2 then
|
||||
error('syntax: <builder id> <facing>')
|
||||
error('syntax: <builder id> <facing>')
|
||||
end
|
||||
|
||||
__BUILDER_ID = tonumber(args[1])
|
||||
@@ -401,30 +401,30 @@ __BUILDER_ID = tonumber(args[1])
|
||||
maxStackDB:load()
|
||||
|
||||
itemInfoDB = TableDB({
|
||||
fileName = 'items.db'
|
||||
fileName = 'items.db'
|
||||
})
|
||||
|
||||
itemInfoDB:load()
|
||||
|
||||
Builder.itemProvider = MEProvider({ direction = args[2] })
|
||||
if not Builder.itemProvider:isValid() then
|
||||
local sides = {
|
||||
east = 'west',
|
||||
west = 'east',
|
||||
north = 'south',
|
||||
south = 'north',
|
||||
}
|
||||
local sides = {
|
||||
east = 'west',
|
||||
west = 'east',
|
||||
north = 'south',
|
||||
south = 'north',
|
||||
}
|
||||
|
||||
Builder.itemProvider = ChestProvider({ direction = sides[args[2]], wrapSide = 'front' })
|
||||
if not Builder.itemProvider:isValid() then
|
||||
error('A chest or ME interface must be in front of turtle')
|
||||
end
|
||||
Builder.itemProvider = ChestProvider({ direction = sides[args[2]], wrapSide = 'front' })
|
||||
if not Builder.itemProvider:isValid() then
|
||||
error('A chest or ME interface must be in front of turtle')
|
||||
end
|
||||
end
|
||||
|
||||
turtle.run(function()
|
||||
turtle.setPoint({ x = -1, z = -2, y = -1, heading = 1 })
|
||||
turtle.setPoint({ x = -1, z = -2, y = -1, heading = 1 })
|
||||
|
||||
turtle.saveLocation('supplies')
|
||||
turtle.saveLocation('supplies')
|
||||
|
||||
Event.pullEvents(onTheWay)
|
||||
Event.pullEvents(onTheWay)
|
||||
end)
|
||||
|
||||
@@ -13,15 +13,15 @@ local function Syntax(msg)
|
||||
* Entity sensor
|
||||
* Introspection module
|
||||
]])
|
||||
error(msg)
|
||||
error(msg)
|
||||
end
|
||||
|
||||
local neural = device['neuralInterface'] or Syntax('Must be run on a neural interface')
|
||||
|
||||
local function assertModule(module, name)
|
||||
if not neural.hasModule(module) then
|
||||
Syntax('Missing: ' .. name)
|
||||
end
|
||||
if not neural.hasModule(module) then
|
||||
Syntax('Missing: ' .. name)
|
||||
end
|
||||
end
|
||||
assertModule('plethora:glasses', 'Overlay glasses')
|
||||
assertModule('plethora:sensor', 'Entity sensor')
|
||||
@@ -31,102 +31,102 @@ local BUILDER_DIR = 'usr/builder'
|
||||
|
||||
--[[-- SubDB --]]--
|
||||
local subDB = TableDB({
|
||||
fileName = fs.combine(BUILDER_DIR, 'sub.db'),
|
||||
fileName = fs.combine(BUILDER_DIR, 'sub.db'),
|
||||
})
|
||||
|
||||
function subDB:load()
|
||||
if fs.exists(self.fileName) then
|
||||
TableDB.load(self)
|
||||
elseif not Builder.isCommandComputer then
|
||||
self:seedDB()
|
||||
end
|
||||
if fs.exists(self.fileName) then
|
||||
TableDB.load(self)
|
||||
elseif not Builder.isCommandComputer then
|
||||
self:seedDB()
|
||||
end
|
||||
end
|
||||
|
||||
function subDB:seedDB()
|
||||
self.data = {
|
||||
[ "minecraft:redstone_wire:0" ] = "minecraft:redstone:0",
|
||||
[ "minecraft:wall_sign:0" ] = "minecraft:sign:0",
|
||||
[ "minecraft:standing_sign:0" ] = "minecraft:sign:0",
|
||||
[ "minecraft:potatoes:0" ] = "minecraft:potato:0",
|
||||
[ "minecraft:unlit_redstone_torch:0" ] = "minecraft:redstone_torch:0",
|
||||
[ "minecraft:powered_repeater:0" ] = "minecraft:repeater:0",
|
||||
[ "minecraft:unpowered_repeater:0" ] = "minecraft:repeater:0",
|
||||
[ "minecraft:carrots:0" ] = "minecraft:carrot:0",
|
||||
[ "minecraft:cocoa:0" ] = "minecraft:dye:3",
|
||||
[ "minecraft:unpowered_comparator:0" ] = "minecraft:comparator:0",
|
||||
[ "minecraft:powered_comparator:0" ] = "minecraft:comparator:0",
|
||||
[ "minecraft:piston_head:0" ] = "minecraft:air:0",
|
||||
[ "minecraft:piston_extension:0" ] = "minecraft:air:0",
|
||||
[ "minecraft:portal:0" ] = "minecraft:air:0",
|
||||
[ "minecraft:double_wooden_slab:0" ] = "minecraft:planks:0",
|
||||
[ "minecraft:double_wooden_slab:1" ] = "minecraft:planks:1",
|
||||
[ "minecraft:double_wooden_slab:2" ] = "minecraft:planks:2",
|
||||
[ "minecraft:double_wooden_slab:3" ] = "minecraft:planks:3",
|
||||
[ "minecraft:double_wooden_slab:4" ] = "minecraft:planks:4",
|
||||
[ "minecraft:double_wooden_slab:5" ] = "minecraft:planks:5",
|
||||
[ "minecraft:lit_redstone_lamp:0" ] = "minecraft:redstone_lamp:0",
|
||||
[ "minecraft:double_stone_slab:1" ] = "minecraft:sandstone:0",
|
||||
[ "minecraft:double_stone_slab:2" ] = "minecraft:planks:0",
|
||||
[ "minecraft:double_stone_slab:3" ] = "minecraft:cobblestone:0",
|
||||
[ "minecraft:double_stone_slab:4" ] = "minecraft:brick_block:0",
|
||||
[ "minecraft:double_stone_slab:5" ] = "minecraft:stonebrick:0",
|
||||
[ "minecraft:double_stone_slab:6" ] = "minecraft:nether_brick:0",
|
||||
[ "minecraft:double_stone_slab:7" ] = "minecraft:quartz_block:0",
|
||||
[ "minecraft:double_stone_slab:9" ] = "minecraft:sandstone:2",
|
||||
[ "minecraft:double_stone_slab2:0" ] = "minecraft:sandstone:0",
|
||||
[ "minecraft:stone_slab:2" ] = "minecraft:wooden_slab:0",
|
||||
[ "minecraft:wheat:0" ] = "minecraft:wheat_seeds:0",
|
||||
[ "minecraft:flowing_water:0" ] = "minecraft:air:0",
|
||||
[ "minecraft:lit_furnace:0" ] = "minecraft:furnace:0",
|
||||
[ "minecraft:wall_banner:0" ] = "minecraft:banner:0",
|
||||
[ "minecraft:standing_banner:0" ] = "minecraft:banner:0",
|
||||
[ "minecraft:tripwire:0" ] = "minecraft:string:0",
|
||||
[ "minecraft:pumpkin_stem:0" ] = "minecraft:pumpkin_seeds:0",
|
||||
}
|
||||
self.dirty = true
|
||||
self:flush()
|
||||
self.data = {
|
||||
[ "minecraft:redstone_wire:0" ] = "minecraft:redstone:0",
|
||||
[ "minecraft:wall_sign:0" ] = "minecraft:sign:0",
|
||||
[ "minecraft:standing_sign:0" ] = "minecraft:sign:0",
|
||||
[ "minecraft:potatoes:0" ] = "minecraft:potato:0",
|
||||
[ "minecraft:unlit_redstone_torch:0" ] = "minecraft:redstone_torch:0",
|
||||
[ "minecraft:powered_repeater:0" ] = "minecraft:repeater:0",
|
||||
[ "minecraft:unpowered_repeater:0" ] = "minecraft:repeater:0",
|
||||
[ "minecraft:carrots:0" ] = "minecraft:carrot:0",
|
||||
[ "minecraft:cocoa:0" ] = "minecraft:dye:3",
|
||||
[ "minecraft:unpowered_comparator:0" ] = "minecraft:comparator:0",
|
||||
[ "minecraft:powered_comparator:0" ] = "minecraft:comparator:0",
|
||||
[ "minecraft:piston_head:0" ] = "minecraft:air:0",
|
||||
[ "minecraft:piston_extension:0" ] = "minecraft:air:0",
|
||||
[ "minecraft:portal:0" ] = "minecraft:air:0",
|
||||
[ "minecraft:double_wooden_slab:0" ] = "minecraft:planks:0",
|
||||
[ "minecraft:double_wooden_slab:1" ] = "minecraft:planks:1",
|
||||
[ "minecraft:double_wooden_slab:2" ] = "minecraft:planks:2",
|
||||
[ "minecraft:double_wooden_slab:3" ] = "minecraft:planks:3",
|
||||
[ "minecraft:double_wooden_slab:4" ] = "minecraft:planks:4",
|
||||
[ "minecraft:double_wooden_slab:5" ] = "minecraft:planks:5",
|
||||
[ "minecraft:lit_redstone_lamp:0" ] = "minecraft:redstone_lamp:0",
|
||||
[ "minecraft:double_stone_slab:1" ] = "minecraft:sandstone:0",
|
||||
[ "minecraft:double_stone_slab:2" ] = "minecraft:planks:0",
|
||||
[ "minecraft:double_stone_slab:3" ] = "minecraft:cobblestone:0",
|
||||
[ "minecraft:double_stone_slab:4" ] = "minecraft:brick_block:0",
|
||||
[ "minecraft:double_stone_slab:5" ] = "minecraft:stonebrick:0",
|
||||
[ "minecraft:double_stone_slab:6" ] = "minecraft:nether_brick:0",
|
||||
[ "minecraft:double_stone_slab:7" ] = "minecraft:quartz_block:0",
|
||||
[ "minecraft:double_stone_slab:9" ] = "minecraft:sandstone:2",
|
||||
[ "minecraft:double_stone_slab2:0" ] = "minecraft:sandstone:0",
|
||||
[ "minecraft:stone_slab:2" ] = "minecraft:wooden_slab:0",
|
||||
[ "minecraft:wheat:0" ] = "minecraft:wheat_seeds:0",
|
||||
[ "minecraft:flowing_water:0" ] = "minecraft:air:0",
|
||||
[ "minecraft:lit_furnace:0" ] = "minecraft:furnace:0",
|
||||
[ "minecraft:wall_banner:0" ] = "minecraft:banner:0",
|
||||
[ "minecraft:standing_banner:0" ] = "minecraft:banner:0",
|
||||
[ "minecraft:tripwire:0" ] = "minecraft:string:0",
|
||||
[ "minecraft:pumpkin_stem:0" ] = "minecraft:pumpkin_seeds:0",
|
||||
}
|
||||
self.dirty = true
|
||||
self:flush()
|
||||
end
|
||||
|
||||
function subDB:add(s)
|
||||
TableDB.add(self, { s.id, s.dmg }, table.concat({ s.sid, s.sdmg }, ':'))
|
||||
self:flush()
|
||||
TableDB.add(self, { s.id, s.dmg }, table.concat({ s.sid, s.sdmg }, ':'))
|
||||
self:flush()
|
||||
end
|
||||
|
||||
function subDB:remove(s)
|
||||
-- TODO: tableDB.remove should take table key
|
||||
TableDB.remove(self, s.id .. ':' .. s.dmg)
|
||||
self:flush()
|
||||
-- TODO: tableDB.remove should take table key
|
||||
TableDB.remove(self, s.id .. ':' .. s.dmg)
|
||||
self:flush()
|
||||
end
|
||||
|
||||
function subDB:extract(s)
|
||||
local id, dmg = s:match('(.+):(%d+)')
|
||||
return id, tonumber(dmg)
|
||||
local id, dmg = s:match('(.+):(%d+)')
|
||||
return id, tonumber(dmg)
|
||||
end
|
||||
|
||||
function subDB:getSubstitutedItem(id, dmg)
|
||||
local sub = TableDB.get(self, { id, dmg })
|
||||
if sub then
|
||||
id, dmg = self:extract(sub)
|
||||
end
|
||||
return { id = id, dmg = dmg }
|
||||
local sub = TableDB.get(self, { id, dmg })
|
||||
if sub then
|
||||
id, dmg = self:extract(sub)
|
||||
end
|
||||
return { id = id, dmg = dmg }
|
||||
end
|
||||
|
||||
function subDB:lookupBlocksForSub(sid, sdmg)
|
||||
local t = { }
|
||||
for k,v in pairs(self.data) do
|
||||
local id, dmg = self:extract(v)
|
||||
if id == sid and dmg == sdmg then
|
||||
id, dmg = self:extract(k)
|
||||
t[k] = { id = id, dmg = dmg, sid = sid, sdmg = sdmg }
|
||||
end
|
||||
end
|
||||
return t
|
||||
local t = { }
|
||||
for k,v in pairs(self.data) do
|
||||
local id, dmg = self:extract(v)
|
||||
if id == sid and dmg == sdmg then
|
||||
id, dmg = self:extract(k)
|
||||
t[k] = { id = id, dmg = dmg, sid = sid, sdmg = sdmg }
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
--[[-- startup logic --]]--
|
||||
local args = {...}
|
||||
if #args < 1 then
|
||||
error('supply file name')
|
||||
error('supply file name')
|
||||
end
|
||||
|
||||
subDB:load()
|
||||
@@ -142,18 +142,18 @@ Builder:substituteBlocks(Util.throttle())
|
||||
local cn = neural.canvas3d().create()
|
||||
local pos = neural.getMetaOwner().withinBlock
|
||||
|
||||
cn.recenter({-(pos.x + .5), -(pos.y + 2) + .5, -(pos.z + .5) })
|
||||
cn.recenter({-pos.x + .5, -(pos.y + 2) + .5, -pos.z + .5 })
|
||||
|
||||
for i = 1, #Builder.schematic.blocks do
|
||||
local b = Builder.schematic:getComputedBlock(i)
|
||||
if b.id ~= "minecraft:air" and b.id ~= 'minecraft:water' then
|
||||
local s, m = pcall(function()
|
||||
cn.addItem({ b.x, b.y, b.z }, b.id, b.dmg)
|
||||
end)
|
||||
if not s and m then
|
||||
_G.printError(m)
|
||||
end
|
||||
end
|
||||
local b = Builder.schematic:getComputedBlock(i)
|
||||
if b.id ~= "minecraft:air" and b.id ~= 'minecraft:water' then
|
||||
local s, m = pcall(function()
|
||||
cn.addItem({ b.x, b.y, b.z }, b.id, b.dmg)
|
||||
end)
|
||||
if not s and m then
|
||||
_G.printError(m)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
pcall(_G.read)
|
||||
|
||||
Reference in New Issue
Block a user