mirror of
https://github.com/kepler155c/opus
synced 2025-01-24 06:06:54 +00:00
builder improvements
This commit is contained in:
parent
3f66a9397c
commit
7f99c0c69a
@ -1,5 +1,39 @@
|
|||||||
local class = require('class')
|
local class = require('class')
|
||||||
local TableDB = require('tableDB')
|
local TableDB = require('tableDB')
|
||||||
|
local JSON = require('json')
|
||||||
|
|
||||||
|
-- see https://github.com/Khroki/MCEdit-Unified/blob/master/pymclevel/minecraft.yaml
|
||||||
|
-- see https://github.com/Khroki/MCEdit-Unified/blob/master/Items/minecraft/blocks.json
|
||||||
|
|
||||||
|
local nameDB = TableDB({
|
||||||
|
fileName = 'blocknames.db'
|
||||||
|
})
|
||||||
|
function nameDB:load(dir, blockDB)
|
||||||
|
self.fileName = fs.combine(dir, self.fileName)
|
||||||
|
if fs.exists(self.fileName) then
|
||||||
|
TableDB.load(self)
|
||||||
|
end
|
||||||
|
self.blockDB = blockDB
|
||||||
|
end
|
||||||
|
|
||||||
|
function nameDB:getName(id, dmg)
|
||||||
|
return self:lookupName(id, dmg) or id .. ':' .. dmg
|
||||||
|
end
|
||||||
|
|
||||||
|
function nameDB:lookupName(id, dmg)
|
||||||
|
-- is it in the name db ?
|
||||||
|
local name = self:get({ id, dmg })
|
||||||
|
if name then
|
||||||
|
return name
|
||||||
|
end
|
||||||
|
|
||||||
|
-- is it in the block db ?
|
||||||
|
for _,v in pairs(self.blockDB.data) do
|
||||||
|
if v.strId == id and v.dmg == dmg then
|
||||||
|
return v.name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local blockDB = TableDB({
|
local blockDB = TableDB({
|
||||||
fileName = 'block.db',
|
fileName = 'block.db',
|
||||||
@ -16,7 +50,7 @@ local blockDB = TableDB({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function blockDB:load(dir, sbDB, btDB)
|
function blockDB:load(dir)
|
||||||
self.fileName = fs.combine(dir, self.fileName)
|
self.fileName = fs.combine(dir, self.fileName)
|
||||||
if fs.exists(self.fileName) then
|
if fs.exists(self.fileName) then
|
||||||
TableDB.load(self)
|
TableDB.load(self)
|
||||||
@ -27,89 +61,25 @@ end
|
|||||||
|
|
||||||
function blockDB:seedDB(dir)
|
function blockDB:seedDB(dir)
|
||||||
|
|
||||||
-- http://lua-users.org/wiki/LuaCsv
|
local blocks = JSON.decodeFromFile(fs.combine('sys/etc', 'blocks.json'))
|
||||||
function ParseCSVLine (line,sep)
|
|
||||||
local res = {}
|
if not blocks then
|
||||||
local pos = 1
|
error('Unable to read blocks.json')
|
||||||
sep = sep or ','
|
end
|
||||||
while true do
|
|
||||||
local c = string.sub(line,pos,pos)
|
for strId, block in pairs(blocks) do
|
||||||
if (c == "") then break end
|
strId = 'minecraft:' .. strId
|
||||||
if (c == '"') then
|
if type(block.name) == 'string' then
|
||||||
-- quoted value (ignore separator within)
|
self:add(block.id, 0, block.name, strId)
|
||||||
local txt = ""
|
|
||||||
repeat
|
|
||||||
local startp,endp = string.find(line,'^%b""',pos)
|
|
||||||
txt = txt..string.sub(line,startp+1,endp-1)
|
|
||||||
pos = endp + 1
|
|
||||||
c = string.sub(line,pos,pos)
|
|
||||||
if (c == '"') then txt = txt..'"' end
|
|
||||||
-- check first char AFTER quoted string, if it is another
|
|
||||||
-- quoted string without separator, then append it
|
|
||||||
-- this is the way to "escape" the quote char in a quote. example:
|
|
||||||
-- value1,"blub""blip""boing",value3 will result in blub"blip"boing for the middle
|
|
||||||
until (c ~= '"')
|
|
||||||
table.insert(res,txt)
|
|
||||||
assert(c == sep or c == "")
|
|
||||||
pos = pos + 1
|
|
||||||
else
|
else
|
||||||
-- no quotes used, just look for the first separator
|
for nid,name in pairs(block.name) do
|
||||||
local startp,endp = string.find(line,sep,pos)
|
self:add(block.id, nid - 1, name, strId)
|
||||||
if (startp) then
|
|
||||||
table.insert(res,string.sub(line,pos,startp-1))
|
|
||||||
pos = endp + 1
|
|
||||||
else
|
|
||||||
-- no separator found -> use rest of string and terminate
|
|
||||||
table.insert(res,string.sub(line,pos))
|
|
||||||
break
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return res
|
|
||||||
end
|
|
||||||
|
|
||||||
local f = fs.open(fs.combine('sys/etc', 'blockIds.csv'), "r")
|
|
||||||
|
|
||||||
if not f then
|
|
||||||
error('unable to read blockIds.csv')
|
|
||||||
end
|
|
||||||
|
|
||||||
local lastID = nil
|
|
||||||
|
|
||||||
while true do
|
|
||||||
|
|
||||||
local data = f.readLine()
|
|
||||||
if not data then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
local line = ParseCSVLine(data, ',')
|
|
||||||
|
|
||||||
local strId = line[3] -- string ID
|
|
||||||
local nid -- schematic ID
|
|
||||||
local id = line[3]
|
|
||||||
local dmg = 0
|
|
||||||
local name = line[1]
|
|
||||||
|
|
||||||
if not strId or #strId == 0 then
|
|
||||||
strId = lastID
|
|
||||||
end
|
|
||||||
lastID = strId
|
|
||||||
|
|
||||||
local t = { }
|
|
||||||
string.gsub(line[2], '(%d+)', function(d) table.insert(t, d) end)
|
|
||||||
nid = tonumber(t[1])
|
|
||||||
dmg = 0
|
|
||||||
if t[2] then
|
|
||||||
dmg = tonumber(t[2])
|
|
||||||
end
|
|
||||||
self:add(nid, dmg, name, strId)
|
|
||||||
end
|
|
||||||
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
self.dirty = true
|
self.dirty = true
|
||||||
self:flush()
|
-- self:flush()
|
||||||
end
|
end
|
||||||
|
|
||||||
function blockDB:lookup(id, dmg)
|
function blockDB:lookup(id, dmg)
|
||||||
@ -117,27 +87,12 @@ function blockDB:lookup(id, dmg)
|
|||||||
if not id then
|
if not id then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if not id or not dmg then error('blockDB:lookup: nil passed', 2) end
|
if not id or not dmg then error('blockDB:lookup: nil passed', 2) end
|
||||||
local key = id .. ':' .. dmg
|
local key = id .. ':' .. dmg
|
||||||
|
|
||||||
return self.data[key]
|
return self.data[key]
|
||||||
end
|
end
|
||||||
|
|
||||||
function blockDB:getName(id, dmg)
|
|
||||||
return self:lookupName(id, dmg) or id .. ':' .. dmg
|
|
||||||
end
|
|
||||||
|
|
||||||
function blockDB:lookupName(id, dmg)
|
|
||||||
if not id or not dmg then error('blockDB:lookupName: nil passed', 2) end
|
|
||||||
|
|
||||||
for _,v in pairs(self.data) do
|
|
||||||
if v.strId == id and v.dmg == dmg then
|
|
||||||
return v.name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function blockDB:add(id, dmg, name, strId)
|
function blockDB:add(id, dmg, name, strId)
|
||||||
local key = id .. ':' .. dmg
|
local key = id .. ':' .. dmg
|
||||||
|
|
||||||
@ -170,7 +125,7 @@ function placementDB:load(dir, sbDB, btDB)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- testing
|
-- testing
|
||||||
-- self.dirty = true
|
self.dirty = true
|
||||||
--self:flush()
|
--self:flush()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -192,11 +147,12 @@ function placementDB:addSubsForBlockType(id, dmg, bt)
|
|||||||
odmg,
|
odmg,
|
||||||
sub.sid or strId,
|
sub.sid or strId,
|
||||||
sub.sdmg or dmg,
|
sub.sdmg or dmg,
|
||||||
sub.dir)
|
sub.dir,
|
||||||
|
sub.extra)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function placementDB:add(id, dmg, sid, sdmg, direction)
|
function placementDB:add(id, dmg, sid, sdmg, direction, extra)
|
||||||
if not id or not dmg then error('placementDB:add: nil passed', 2) end
|
if not id or not dmg then error('placementDB:add: nil passed', 2) end
|
||||||
|
|
||||||
local key = id .. ':' .. dmg
|
local key = id .. ':' .. dmg
|
||||||
@ -212,6 +168,7 @@ function placementDB:add(id, dmg, sid, sdmg, direction)
|
|||||||
sid = sid, -- string ID
|
sid = sid, -- string ID
|
||||||
sdmg = sdmg, -- dmg without placement info
|
sdmg = sdmg, -- dmg without placement info
|
||||||
direction = direction,
|
direction = direction,
|
||||||
|
extra = extra,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -286,7 +243,7 @@ function standardBlockDB:seedDB()
|
|||||||
[ '65:0' ] = 'wallsign-ladder',
|
[ '65:0' ] = 'wallsign-ladder',
|
||||||
[ '66:0' ] = 'rail',
|
[ '66:0' ] = 'rail',
|
||||||
[ '67:0' ] = 'stairs',
|
[ '67:0' ] = 'stairs',
|
||||||
[ '68:0' ] = 'wallsign',
|
[ '68:0' ] = 'wallsign-ladder',
|
||||||
[ '69:0' ] = 'lever',
|
[ '69:0' ] = 'lever',
|
||||||
[ '71:0' ] = 'door',
|
[ '71:0' ] = 'door',
|
||||||
[ '75:0' ] = 'torch',
|
[ '75:0' ] = 'torch',
|
||||||
@ -295,6 +252,7 @@ function standardBlockDB:seedDB()
|
|||||||
[ '78:0' ] = 'flatten',
|
[ '78:0' ] = 'flatten',
|
||||||
[ '81:0' ] = 'flatten',
|
[ '81:0' ] = 'flatten',
|
||||||
[ '83:0' ] = 'flatten',
|
[ '83:0' ] = 'flatten',
|
||||||
|
[ '84:0' ] = 'flatten', -- jukebox
|
||||||
[ '86:0' ] = 'pumpkin',
|
[ '86:0' ] = 'pumpkin',
|
||||||
[ '90:0' ] = 'air',
|
[ '90:0' ] = 'air',
|
||||||
[ '91:0' ] = 'pumpkin',
|
[ '91:0' ] = 'pumpkin',
|
||||||
@ -312,6 +270,7 @@ function standardBlockDB:seedDB()
|
|||||||
[ '115:0' ] = 'flatten',
|
[ '115:0' ] = 'flatten',
|
||||||
[ '117:0' ] = 'flatten',
|
[ '117:0' ] = 'flatten',
|
||||||
[ '118:0' ] = 'cauldron',
|
[ '118:0' ] = 'cauldron',
|
||||||
|
[ '120:0' ] = 'flatten', -- end portal
|
||||||
[ '126:0' ] = 'slab',
|
[ '126:0' ] = 'slab',
|
||||||
[ '126:1' ] = 'slab',
|
[ '126:1' ] = 'slab',
|
||||||
[ '126:2' ] = 'slab',
|
[ '126:2' ] = 'slab',
|
||||||
@ -339,7 +298,7 @@ function standardBlockDB:seedDB()
|
|||||||
[ '155:2' ] = 'quartz-pillar',
|
[ '155:2' ] = 'quartz-pillar',
|
||||||
[ '156:0' ] = 'stairs',
|
[ '156:0' ] = 'stairs',
|
||||||
[ '157:0' ] = 'adp-rail',
|
[ '157:0' ] = 'adp-rail',
|
||||||
[ '158:0' ] = 'hopper',
|
[ '158:0' ] = 'dispenser',
|
||||||
[ '161:0' ] = 'leaves',
|
[ '161:0' ] = 'leaves',
|
||||||
[ '161:1' ] = 'leaves',
|
[ '161:1' ] = 'leaves',
|
||||||
[ '162:0' ] = 'wood',
|
[ '162:0' ] = 'wood',
|
||||||
@ -347,15 +306,15 @@ function standardBlockDB:seedDB()
|
|||||||
[ '163:0' ] = 'stairs',
|
[ '163:0' ] = 'stairs',
|
||||||
[ '164:0' ] = 'stairs',
|
[ '164:0' ] = 'stairs',
|
||||||
[ '167:0' ] = 'trapdoor',
|
[ '167:0' ] = 'trapdoor',
|
||||||
[ '170:0' ] = 'quartz-pillar', -- hay bale
|
[ '170:0' ] = 'hay-bale', -- 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
|
||||||
[ '175:3' ] = 'largeplant',
|
[ '175:3' ] = 'largeplant',
|
||||||
[ '175:4' ] = 'largeplant',
|
[ '175:4' ] = 'largeplant',
|
||||||
[ '175:5' ] = 'largeplant',
|
[ '175:5' ] = 'largeplant',
|
||||||
[ '176:0' ] = 'banner',
|
[ '176:0' ] = 'signpost',
|
||||||
[ '177:0' ] = 'wall_banner',
|
[ '177:0' ] = 'wallsign-ladder',
|
||||||
[ '178:0' ] = 'truncate',
|
[ '178:0' ] = 'truncate',
|
||||||
[ '180:0' ] = 'stairs',
|
[ '180:0' ] = 'stairs',
|
||||||
[ '182:0' ] = 'slab',
|
[ '182:0' ] = 'slab',
|
||||||
@ -369,7 +328,7 @@ function standardBlockDB:seedDB()
|
|||||||
[ '195:0' ] = 'door',
|
[ '195:0' ] = 'door',
|
||||||
[ '196:0' ] = 'door',
|
[ '196:0' ] = 'door',
|
||||||
[ '197:0' ] = 'door',
|
[ '197:0' ] = 'door',
|
||||||
[ '198:0' ] = 'flatten',
|
[ '198:0' ] = 'end_rod', -- end rod
|
||||||
[ '205:0' ] = 'slab',
|
[ '205:0' ] = 'slab',
|
||||||
[ '210:0' ] = 'flatten',
|
[ '210:0' ] = 'flatten',
|
||||||
[ '355:0' ] = 'bed',
|
[ '355:0' ] = 'bed',
|
||||||
@ -377,7 +336,7 @@ function standardBlockDB:seedDB()
|
|||||||
[ '404:0' ] = 'comparator',
|
[ '404:0' ] = 'comparator',
|
||||||
}
|
}
|
||||||
self.dirty = true
|
self.dirty = true
|
||||||
self:flush()
|
-- self:flush()
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[-- BlockTypeDB --]]--
|
--[[-- BlockTypeDB --]]--
|
||||||
@ -415,7 +374,8 @@ function blockTypeDB:addTemp(blockType, subs)
|
|||||||
odmg = sub[1],
|
odmg = sub[1],
|
||||||
sid = sub[2],
|
sid = sub[2],
|
||||||
sdmg = sub[3],
|
sdmg = sub[3],
|
||||||
dir = sub[4]
|
dir = sub[4],
|
||||||
|
extra = sub[5]
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
self.dirty = true
|
self.dirty = true
|
||||||
@ -512,6 +472,11 @@ function blockTypeDB:seedDB()
|
|||||||
{ 3, nil, 2, 'north-south-block' },
|
{ 3, nil, 2, 'north-south-block' },
|
||||||
{ 4, nil, 2, 'east-west-block' }, -- should be east-west-block
|
{ 4, nil, 2, 'east-west-block' }, -- should be east-west-block
|
||||||
})
|
})
|
||||||
|
blockTypeDB:addTemp('hay-bale', {
|
||||||
|
{ 0, nil, 0 },
|
||||||
|
{ 4, nil, 0, 'east-west-block' }, -- should be east-west-block
|
||||||
|
{ 8, nil, 0, 'north-south-block' },
|
||||||
|
})
|
||||||
blockTypeDB:addTemp('button', {
|
blockTypeDB:addTemp('button', {
|
||||||
{ 1, nil, 0, 'west-block' },
|
{ 1, nil, 0, 'west-block' },
|
||||||
{ 2, nil, 0, 'east-block' },
|
{ 2, nil, 0, 'east-block' },
|
||||||
@ -526,14 +491,23 @@ function blockTypeDB:seedDB()
|
|||||||
{ 3, nil, 0 },
|
{ 3, nil, 0 },
|
||||||
})
|
})
|
||||||
blockTypeDB:addTemp('dispenser', {
|
blockTypeDB:addTemp('dispenser', {
|
||||||
{ 0, nil, 0 },
|
{ 0, nil, 0, 'wrench-down' },
|
||||||
{ 1, nil, 0 },
|
{ 1, nil, 0, 'wrench-up' },
|
||||||
{ 2, nil, 0, 'south' },
|
{ 2, nil, 0, 'south' },
|
||||||
{ 3, nil, 0, 'north' },
|
{ 3, nil, 0, 'north' },
|
||||||
{ 4, nil, 0, 'east' },
|
{ 4, nil, 0, 'east' },
|
||||||
{ 5, nil, 0, 'west' },
|
{ 5, nil, 0, 'west' },
|
||||||
{ 9, nil, 0 },
|
{ 9, nil, 0 },
|
||||||
})
|
})
|
||||||
|
blockTypeDB:addTemp('end_rod', {
|
||||||
|
{ 0, nil, 0, 'wrench-down' },
|
||||||
|
{ 1, nil, 0, 'wrench-up' },
|
||||||
|
{ 2, nil, 0, 'south-block-flip' },
|
||||||
|
{ 3, nil, 0, 'north-block-flip' },
|
||||||
|
{ 4, nil, 0, 'east-block-flip' },
|
||||||
|
{ 5, nil, 0, 'west-block-flip' },
|
||||||
|
{ 9, nil, 0 },
|
||||||
|
})
|
||||||
blockTypeDB:addTemp('hopper', {
|
blockTypeDB:addTemp('hopper', {
|
||||||
{ 0, nil, 0 },
|
{ 0, nil, 0 },
|
||||||
{ 1, nil, 0 },
|
{ 1, nil, 0 },
|
||||||
@ -541,6 +515,7 @@ function blockTypeDB:seedDB()
|
|||||||
{ 3, nil, 0, 'north-block' },
|
{ 3, nil, 0, 'north-block' },
|
||||||
{ 4, nil, 0, 'east-block' },
|
{ 4, nil, 0, 'east-block' },
|
||||||
{ 5, nil, 0, 'west-block' },
|
{ 5, nil, 0, 'west-block' },
|
||||||
|
{ 8, nil, 0 },
|
||||||
{ 9, nil, 0 },
|
{ 9, nil, 0 },
|
||||||
{ 10, nil, 0 },
|
{ 10, nil, 0 },
|
||||||
{ 11, nil, 0, 'south-block' },
|
{ 11, nil, 0, 'south-block' },
|
||||||
@ -583,22 +558,22 @@ function blockTypeDB:seedDB()
|
|||||||
{ 13, nil, 0, 'south' },
|
{ 13, nil, 0, 'south' },
|
||||||
})
|
})
|
||||||
blockTypeDB:addTemp('signpost', {
|
blockTypeDB:addTemp('signpost', {
|
||||||
{ 0, nil, 0, 'south' },
|
{ 0, nil, 0, 'north' },
|
||||||
{ 1, nil, 0, 'south' },
|
{ 1, nil, 0, 'north', { facing = 1 } },
|
||||||
{ 2, nil, 0, 'south' },
|
{ 2, nil, 0, 'north', { facing = 2 } },
|
||||||
{ 3, nil, 0, 'south' },
|
{ 3, nil, 0, 'north', { facing = 3 } },
|
||||||
{ 4, nil, 0, 'west' },
|
{ 4, nil, 0, 'east' },
|
||||||
{ 5, nil, 0, 'west' },
|
{ 5, nil, 0, 'east', { facing = 1 } },
|
||||||
{ 6, nil, 0, 'west' },
|
{ 6, nil, 0, 'east', { facing = 2 } },
|
||||||
{ 7, nil, 0, 'west' },
|
{ 7, nil, 0, 'east', { facing = 3 } },
|
||||||
{ 8, nil, 0, 'north' },
|
{ 8, nil, 0, 'south' },
|
||||||
{ 9, nil, 0, 'north' },
|
{ 9, nil, 0, 'south', { facing = 1 } },
|
||||||
{ 10, nil, 0, 'north' },
|
{ 10, nil, 0, 'south', { facing = 2 } },
|
||||||
{ 11, nil, 0, 'north' },
|
{ 11, nil, 0, 'south', { facing = 3 } },
|
||||||
{ 12, nil, 0, 'east' },
|
{ 12, nil, 0, 'west' },
|
||||||
{ 13, nil, 0, 'east' },
|
{ 13, nil, 0, 'west', { facing = 1 } },
|
||||||
{ 14, nil, 0, 'east' },
|
{ 14, nil, 0, 'west', { facing = 2 } },
|
||||||
{ 15, nil, 0, 'east' },
|
{ 15, nil, 0, 'west', { facing = 3 } },
|
||||||
})
|
})
|
||||||
blockTypeDB:addTemp('vine', {
|
blockTypeDB:addTemp('vine', {
|
||||||
{ 0, nil, 0 },
|
{ 0, nil, 0 },
|
||||||
@ -684,18 +659,12 @@ function blockTypeDB:seedDB()
|
|||||||
})
|
})
|
||||||
blockTypeDB:addTemp('wallsign-ladder', {
|
blockTypeDB:addTemp('wallsign-ladder', {
|
||||||
{ 0, nil, 0 },
|
{ 0, nil, 0 },
|
||||||
|
{ 1, nil, 0 },
|
||||||
{ 2, nil, 0, 'south-block' },
|
{ 2, nil, 0, 'south-block' },
|
||||||
{ 3, nil, 0, 'north-block' },
|
{ 3, nil, 0, 'north-block' },
|
||||||
{ 4, nil, 0, 'east-block' },
|
{ 4, nil, 0, 'east-block' },
|
||||||
{ 5, nil, 0, 'west-block' },
|
{ 5, nil, 0, 'west-block' },
|
||||||
})
|
})
|
||||||
blockTypeDB:addTemp('wallsign', {
|
|
||||||
{ 0, nil, 0 },
|
|
||||||
{ 2, 'minecraft:sign', 0, 'south-block' },
|
|
||||||
{ 3, 'minecraft:sign', 0, 'north-block' },
|
|
||||||
{ 4, 'minecraft:sign', 0, 'east-block' },
|
|
||||||
{ 5, 'minecraft:sign', 0, 'west-block' },
|
|
||||||
})
|
|
||||||
blockTypeDB:addTemp('chest-furnace', {
|
blockTypeDB:addTemp('chest-furnace', {
|
||||||
{ 0, nil, 0 },
|
{ 0, nil, 0 },
|
||||||
{ 2, nil, 0, 'south' },
|
{ 2, nil, 0, 'south' },
|
||||||
@ -817,32 +786,6 @@ function blockTypeDB:seedDB()
|
|||||||
{ 14,'minecraft:air', 0 },
|
{ 14,'minecraft:air', 0 },
|
||||||
{ 15,'minecraft:air', 0 },
|
{ 15,'minecraft:air', 0 },
|
||||||
})
|
})
|
||||||
blockTypeDB:addTemp('banner', {
|
|
||||||
{ 0, nil, 0, 'north' },
|
|
||||||
{ 1, nil, 0, 'east' },
|
|
||||||
{ 2, nil, 0, 'east' },
|
|
||||||
{ 3, nil, 0, 'east' },
|
|
||||||
{ 4, nil, 0, 'east' },
|
|
||||||
{ 5, nil, 0, 'east' },
|
|
||||||
{ 6, nil, 0, 'east' },
|
|
||||||
{ 7, nil, 0, 'east' },
|
|
||||||
{ 8, nil, 0, 'south' },
|
|
||||||
{ 9, nil, 0, 'west' },
|
|
||||||
{ 10, nil, 0, 'west' },
|
|
||||||
{ 11, nil, 0, 'west' },
|
|
||||||
{ 12, nil, 0, 'west' },
|
|
||||||
{ 13, nil, 0, 'west' },
|
|
||||||
{ 14, nil, 0, 'west' },
|
|
||||||
{ 15, nil, 0, 'west' },
|
|
||||||
})
|
|
||||||
blockTypeDB:addTemp('wall_banner', {
|
|
||||||
{ 0, nil, 0 },
|
|
||||||
{ 1, nil, 0 },
|
|
||||||
{ 2, nil, 0, 'south-block' },
|
|
||||||
{ 3, nil, 0, 'north-block' },
|
|
||||||
{ 4, nil, 0, 'east-block' },
|
|
||||||
{ 5, nil, 0, 'west-block' },
|
|
||||||
})
|
|
||||||
blockTypeDB:addTemp('cocoa', {
|
blockTypeDB:addTemp('cocoa', {
|
||||||
{ 0, nil, 0, 'south-block' },
|
{ 0, nil, 0, 'south-block' },
|
||||||
{ 1, nil, 0, 'west-block' },
|
{ 1, nil, 0, 'west-block' },
|
||||||
@ -858,7 +801,7 @@ function blockTypeDB:seedDB()
|
|||||||
{ 11, nil, 0, 'east-block' },
|
{ 11, nil, 0, 'east-block' },
|
||||||
})
|
})
|
||||||
self.dirty = true
|
self.dirty = true
|
||||||
self:flush()
|
-- self:flush()
|
||||||
end
|
end
|
||||||
|
|
||||||
local Blocks = class()
|
local Blocks = class()
|
||||||
@ -866,10 +809,12 @@ function Blocks:init(args)
|
|||||||
|
|
||||||
Util.merge(self, args)
|
Util.merge(self, args)
|
||||||
self.blockDB = blockDB
|
self.blockDB = blockDB
|
||||||
|
self.nameDB = nameDB
|
||||||
|
|
||||||
blockDB:load(self.dir)
|
blockDB:load(self.dir)
|
||||||
standardBlockDB:load(self.dir)
|
standardBlockDB:load(self.dir)
|
||||||
blockTypeDB:load(self.dir)
|
blockTypeDB:load(self.dir)
|
||||||
|
nameDB:load(self.dir, blockDB)
|
||||||
placementDB:load(self.dir, standardBlockDB, blockTypeDB)
|
placementDB:load(self.dir, standardBlockDB, blockTypeDB)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -878,7 +823,7 @@ function Blocks:getRealBlock(id, dmg)
|
|||||||
|
|
||||||
local p = placementDB:get({id, dmg})
|
local p = placementDB:get({id, dmg})
|
||||||
if p then
|
if p then
|
||||||
return { id = p.sid, dmg = p.sdmg, direction = p.direction }
|
return { id = p.sid, dmg = p.sdmg, direction = p.direction, extra = p.extra }
|
||||||
end
|
end
|
||||||
|
|
||||||
local b = blockDB:get({id, dmg})
|
local b = blockDB:get({id, dmg})
|
||||||
@ -886,6 +831,11 @@ function Blocks:getRealBlock(id, dmg)
|
|||||||
return { id = b.strId, dmg = b.dmg }
|
return { id = b.strId, dmg = b.dmg }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
b = blockDB:get({id, 0})
|
||||||
|
if b then
|
||||||
|
return { id = b.strId, dmg = b.dmg }
|
||||||
|
end
|
||||||
|
|
||||||
return { id = id, dmg = dmg }
|
return { id = id, dmg = dmg }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,65 +1,124 @@
|
|||||||
local class = require('class')
|
local class = require('class')
|
||||||
|
local TableDB = require('tableDB')
|
||||||
|
local Peripheral = require('peripheral')
|
||||||
|
|
||||||
local ChestProvider = class()
|
local ChestProvider = class()
|
||||||
|
|
||||||
|
local keys = Util.transpose({
|
||||||
|
'damage',
|
||||||
|
'displayName',
|
||||||
|
'maxCount',
|
||||||
|
'maxDamage',
|
||||||
|
'name',
|
||||||
|
'nbtHash',
|
||||||
|
})
|
||||||
|
|
||||||
function ChestProvider:init(args)
|
function ChestProvider:init(args)
|
||||||
|
|
||||||
args = args or { }
|
local defaults = {
|
||||||
|
items = { },
|
||||||
|
name = 'chest',
|
||||||
|
direction = 'up',
|
||||||
|
wrapSide = 'bottom',
|
||||||
|
}
|
||||||
|
Util.merge(self, defaults)
|
||||||
|
Util.merge(self, args)
|
||||||
|
|
||||||
self.items = { } -- consolidated item info
|
local chest = Peripheral.getBySide(self.wrapSide)
|
||||||
self.cache = { }
|
if chest then
|
||||||
self.name = 'chest'
|
Util.merge(self, chest)
|
||||||
self.direction = args.direction or 'up'
|
end
|
||||||
self.wrapSide = args.wrapSide or 'bottom'
|
|
||||||
self.p = peripheral.wrap(self.wrapSide)
|
if not self.itemInfoDB then
|
||||||
|
self.itemInfoDB = TableDB({
|
||||||
|
fileName = 'items.db'
|
||||||
|
})
|
||||||
|
|
||||||
|
self.itemInfoDB:load()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ChestProvider:isValid()
|
function ChestProvider:isValid()
|
||||||
return self.p and self.p.list
|
return not not self.list
|
||||||
end
|
end
|
||||||
|
|
||||||
function ChestProvider:refresh()
|
function ChestProvider:getCachedItemDetails(item, k)
|
||||||
if self.p then
|
local key = table.concat({ item.name, item.damage, item.nbtHash }, ':')
|
||||||
self.items = { }
|
|
||||||
for k,s in pairs(self.p.list()) do
|
|
||||||
|
|
||||||
local key = s.name .. ':' .. s.damage
|
local detail = self.itemInfoDB:get(key)
|
||||||
local entry = self.items[key]
|
if not detail then
|
||||||
|
pcall(function() detail = self.getItemMeta(k) end)
|
||||||
|
if not detail then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if detail.name ~= item.name then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if detail.maxDamage and detail.maxDamage > 0 and detail.damage > 0 then
|
||||||
|
detail.displayName = detail.displayName .. ' (damaged)'
|
||||||
|
end
|
||||||
|
|
||||||
|
for _,k in ipairs(Util.keys(detail)) do
|
||||||
|
if not keys[k] then
|
||||||
|
detail[k] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.itemInfoDB:add(key, detail)
|
||||||
|
end
|
||||||
|
if detail then
|
||||||
|
return Util.shallowCopy(detail)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ChestProvider:refresh(throttle)
|
||||||
|
return self:listItems(throttle)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- provide a consolidated list of items
|
||||||
|
function ChestProvider:listItems(throttle)
|
||||||
|
self.cache = { }
|
||||||
|
local items = { }
|
||||||
|
|
||||||
|
throttle = throttle or Util.throttle()
|
||||||
|
|
||||||
|
for k,v in pairs(self.list()) do
|
||||||
|
local key = table.concat({ v.name, v.damage, v.nbtHash }, ':')
|
||||||
|
|
||||||
|
local entry = self.cache[key]
|
||||||
if not entry then
|
if not entry then
|
||||||
entry = self.cache[key]
|
entry = self:getCachedItemDetails(v, k)
|
||||||
if not entry then
|
if entry then
|
||||||
local meta = self.p.getItemMeta(k) -- slow method.. cache for speed
|
entry.dmg = entry.damage
|
||||||
if meta then
|
entry.id = entry.name
|
||||||
entry = {
|
entry.count = 0
|
||||||
id = s.name,
|
entry.display_name = entry.displayName
|
||||||
dmg = s.damage,
|
entry.max_size = entry.maxCount
|
||||||
name = meta.displayName,
|
entry.nbt_hash = entry.nbtHash
|
||||||
max_size = meta.maxCount,
|
entry.lname = entry.displayName:lower()
|
||||||
}
|
|
||||||
self.cache[key] = entry
|
self.cache[key] = entry
|
||||||
|
table.insert(items, entry)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if entry then
|
|
||||||
entry = Util.shallowCopy(entry)
|
|
||||||
self.items[key] = entry
|
|
||||||
entry.qty = 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if entry then
|
|
||||||
entry.qty = entry.qty + s.count
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return self.items
|
|
||||||
end
|
|
||||||
|
|
||||||
function ChestProvider:getItemInfo(id, dmg)
|
if entry then
|
||||||
|
entry.count = entry.count + v.count
|
||||||
|
entry.qty = entry.count
|
||||||
|
end
|
||||||
|
throttle()
|
||||||
|
end
|
||||||
|
|
||||||
for key,item in pairs(self.items) do
|
self.itemInfoDB:flush()
|
||||||
if item.id == id and item.dmg == dmg then
|
|
||||||
return item
|
return items
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function ChestProvider:getItemInfo(id, dmg, nbtHash)
|
||||||
|
if not self.cache then
|
||||||
|
self:listItems()
|
||||||
end
|
end
|
||||||
|
local key = table.concat({ id, dmg, nbtHash }, ':')
|
||||||
|
return self.cache[key]
|
||||||
end
|
end
|
||||||
|
|
||||||
function ChestProvider:craft(id, dmg, qty)
|
function ChestProvider:craft(id, dmg, qty)
|
||||||
@ -69,12 +128,11 @@ function ChestProvider:craftItems(items)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function ChestProvider:provide(item, qty, slot)
|
function ChestProvider:provide(item, qty, slot)
|
||||||
if self.p then
|
local stacks = self.list()
|
||||||
local stacks = self.p.list()
|
|
||||||
for key,stack in pairs(stacks) do
|
for key,stack in pairs(stacks) do
|
||||||
if stack.name == item.id and stack.damage == item.dmg then
|
if stack.name == item.id and stack.damage == item.dmg then
|
||||||
local amount = math.min(qty, stack.count)
|
local amount = math.min(qty, stack.count)
|
||||||
self.p.pushItems(self.direction, key, amount, slot)
|
self.pushItems(self.direction, key, amount, slot)
|
||||||
qty = qty - amount
|
qty = qty - amount
|
||||||
if qty <= 0 then
|
if qty <= 0 then
|
||||||
break
|
break
|
||||||
@ -82,18 +140,13 @@ function ChestProvider:provide(item, qty, slot)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
function ChestProvider:extract(slot, qty)
|
function ChestProvider:extract(slot, qty)
|
||||||
if self.p then
|
self.pushItems(self.direction, slot, qty)
|
||||||
self.p.pushItems(self.direction, slot, qty)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function ChestProvider:insert(slot, qty)
|
function ChestProvider:insert(slot, qty)
|
||||||
if self.p then
|
self.pullItems(self.direction, slot, qty)
|
||||||
self.p.pullItems(self.direction, slot, qty)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return ChestProvider
|
return ChestProvider
|
||||||
|
@ -139,19 +139,27 @@ function Event.addThread(fn)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Event.pullEvents(...)
|
function Event.pullEvents(...)
|
||||||
Process:addThread(_pullEvents)
|
|
||||||
local routines = { ... }
|
local routines = { ... }
|
||||||
if #routines > 0 then
|
if #routines > 0 then
|
||||||
|
Process:addThread(_pullEvents)
|
||||||
for _, routine in ipairs(routines) do
|
for _, routine in ipairs(routines) do
|
||||||
Process:addThread(routine)
|
Process:addThread(routine)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
while true do
|
while true do
|
||||||
local e = Process:pullEvent()
|
local e = Process:pullEvent()
|
||||||
if exitPullEvents or e == 'terminate' then
|
if exitPullEvents or e == 'terminate' then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
while true do
|
||||||
|
local e = { os.pullEvent() }
|
||||||
|
Event.processEvent(e)
|
||||||
|
if exitPullEvents or e == 'terminate' then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Event.exitPullEvents()
|
function Event.exitPullEvents()
|
||||||
|
@ -205,7 +205,7 @@ end
|
|||||||
|
|
||||||
function json.decodeFromFile(path)
|
function json.decodeFromFile(path)
|
||||||
local file = assert(fs.open(path, "r"))
|
local file = assert(fs.open(path, "r"))
|
||||||
local decoded = decode(file.readAll())
|
local decoded = json.decode(file.readAll())
|
||||||
file.close()
|
file.close()
|
||||||
return decoded
|
return decoded
|
||||||
end
|
end
|
||||||
|
@ -51,6 +51,7 @@ function Peripheral.addDevice(deviceList, side)
|
|||||||
end
|
end
|
||||||
|
|
||||||
deviceList[name] = peripheral.wrap(side)
|
deviceList[name] = peripheral.wrap(side)
|
||||||
|
if deviceList[name] then
|
||||||
Util.merge(deviceList[name], {
|
Util.merge(deviceList[name], {
|
||||||
name = name,
|
name = name,
|
||||||
type = ptype,
|
type = ptype,
|
||||||
@ -59,6 +60,7 @@ function Peripheral.addDevice(deviceList, side)
|
|||||||
|
|
||||||
return deviceList[name]
|
return deviceList[name]
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function Peripheral.getBySide(side)
|
function Peripheral.getBySide(side)
|
||||||
return Util.find(getDeviceList(), 'side', side)
|
return Util.find(getDeviceList(), 'side', side)
|
||||||
|
@ -62,13 +62,6 @@ function RefinedProvider:getCachedItemDetails(item)
|
|||||||
end
|
end
|
||||||
detail.lname = detail.displayName:lower()
|
detail.lname = detail.displayName:lower()
|
||||||
|
|
||||||
-- backwards capability
|
|
||||||
detail.dmg = detail.damage
|
|
||||||
detail.id = detail.name
|
|
||||||
detail.qty = detail.count
|
|
||||||
detail.display_name = detail.displayName
|
|
||||||
detail.nbtHash = item.nbtHash
|
|
||||||
|
|
||||||
local t = { }
|
local t = { }
|
||||||
for _,key in pairs(keys) do
|
for _,key in pairs(keys) do
|
||||||
t[key] = detail[key]
|
t[key] = detail[key]
|
||||||
@ -76,8 +69,6 @@ function RefinedProvider:getCachedItemDetails(item)
|
|||||||
|
|
||||||
detail = t
|
detail = t
|
||||||
self.itemInfoDB:add(key, detail)
|
self.itemInfoDB:add(key, detail)
|
||||||
|
|
||||||
os.sleep(0) -- prevent timeout on large inventories
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if detail then
|
if detail then
|
||||||
|
@ -148,20 +148,18 @@ function Schematic:parse(a, h, containsName, spinner)
|
|||||||
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, throttle)
|
||||||
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 (k % 1000) == 0 then
|
if (k % 1000) == 0 then
|
||||||
spinner:spin()
|
throttle()
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Schematic:reload()
|
function Schematic:reload(throttle)
|
||||||
self.blocks = { }
|
self.blocks = { }
|
||||||
self:copyBlocks(self.originalBlocks, self.blocks)
|
self:copyBlocks(self.originalBlocks, self.blocks, throttle)
|
||||||
|
|
||||||
for _,ri in pairs(self.rowIndex) do
|
for _,ri in pairs(self.rowIndex) do
|
||||||
ri.loaded = false
|
ri.loaded = false
|
||||||
@ -283,7 +281,7 @@ function Schematic:loadpass(fh, spinner)
|
|||||||
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, function() spinner:spin() end)
|
||||||
|
|
||||||
spinner:stop()
|
spinner:stop()
|
||||||
end
|
end
|
||||||
@ -488,6 +486,37 @@ function Schematic:bestSide(b, chains, ...)
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Schematic:bestFlipSide(b, chains)
|
||||||
|
-- If there is a block to place this one against
|
||||||
|
|
||||||
|
local directions = {
|
||||||
|
[ 'east-block-flip' ] = 'east',
|
||||||
|
[ 'west-block-flip' ] = 'west',
|
||||||
|
[ 'north-block-flip' ] = 'north',
|
||||||
|
[ 'south-block-flip' ] = 'south',
|
||||||
|
}
|
||||||
|
|
||||||
|
local d = directions[b.direction]
|
||||||
|
local hi = turtle.getHeadingInfo(d)
|
||||||
|
local _, fb = self:findIndexAt(b.x + hi.xd, b.z + hi.zd, b.y)
|
||||||
|
|
||||||
|
if fb then
|
||||||
|
self:addPlacementChain(chains, {
|
||||||
|
{ 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 - hi.xd, z = b.z - hi.zd, y = b.y }, -- room for the turtle
|
||||||
|
})
|
||||||
|
b.direction = d .. '-block'
|
||||||
|
else
|
||||||
|
self:addPlacementChain(chains, {
|
||||||
|
{ 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 }, -- block we are placing against
|
||||||
|
})
|
||||||
|
b.direction = turtle.getHeadingInfo((hi.heading + 2) % 4).direction .. '-block'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function Schematic:bestOfTwoSides(b, chains, side1, side2) -- could be better
|
function Schematic:bestOfTwoSides(b, chains, side1, side2) -- could be better
|
||||||
|
|
||||||
local sb
|
local sb
|
||||||
@ -617,12 +646,23 @@ function Schematic:determineBlockPlacement(y)
|
|||||||
[ 'west-block-vine' ] = 'west-block',
|
[ 'west-block-vine' ] = 'west-block',
|
||||||
[ 'north-block-vine' ] = 'north-block'
|
[ 'north-block-vine' ] = 'north-block'
|
||||||
}
|
}
|
||||||
|
local flipDirections = {
|
||||||
|
[ 'east-block-flip' ] = 'east-block',
|
||||||
|
[ 'south-block-flip' ] = 'south-block',
|
||||||
|
[ 'west-block-flip' ] = 'west-block',
|
||||||
|
[ 'north-block-flip' ] = 'north-block'
|
||||||
|
}
|
||||||
|
|
||||||
local dirtyBlocks = {}
|
local dirtyBlocks = {}
|
||||||
local dirtyBlocks2 = {}
|
local dirtyBlocks2 = {}
|
||||||
local chains = {}
|
local chains = {}
|
||||||
|
|
||||||
local ri = self.rowIndex[y]
|
local ri = self.rowIndex[y]
|
||||||
|
if not ri then
|
||||||
|
ri = { s = -1, e = -2 }
|
||||||
|
self.rowIndex[y] = ri
|
||||||
|
end
|
||||||
|
|
||||||
for k = ri.s, ri.e do
|
for k = ri.s, ri.e do
|
||||||
local b = self.blocks[k]
|
local b = self.blocks[k]
|
||||||
local d = b.direction
|
local d = b.direction
|
||||||
@ -757,6 +797,8 @@ function Schematic:determineBlockPlacement(y)
|
|||||||
b.heading = (turtle.getHeadingInfo(sd[1]).heading + 2) % 4
|
b.heading = (turtle.getHeadingInfo(sd[1]).heading + 2) % 4
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
elseif flipDirections[d] then
|
||||||
|
self:bestFlipSide(b, chains)
|
||||||
end
|
end
|
||||||
|
|
||||||
if blockDirections[d] then
|
if blockDirections[d] then
|
||||||
@ -790,6 +832,7 @@ function Schematic:determineBlockPlacement(y)
|
|||||||
self:setPlacementOrder(spinner, chains)
|
self:setPlacementOrder(spinner, chains)
|
||||||
local plane = self:optimizeRoute(spinner, y)
|
local plane = self:optimizeRoute(spinner, y)
|
||||||
|
|
||||||
|
term.clearLine()
|
||||||
spinner:stop()
|
spinner:stop()
|
||||||
|
|
||||||
for k,b in ipairs(plane) do
|
for k,b in ipairs(plane) do
|
||||||
|
@ -331,7 +331,7 @@ function Manager:click(button, x, y)
|
|||||||
|
|
||||||
if button == 1 then
|
if button == 1 then
|
||||||
local c = os.clock()
|
local c = os.clock()
|
||||||
if self.doubleClickTimer and (c - self.doubleClickTimer < 1) and
|
if self.doubleClickTimer and (c - self.doubleClickTimer < 1.5) and
|
||||||
self.doubleClickX == x and self.doubleClickY == y and
|
self.doubleClickX == x and self.doubleClickY == y and
|
||||||
self.doubleClickElement == clickEvent.element then
|
self.doubleClickElement == clickEvent.element then
|
||||||
button = 3
|
button = 3
|
||||||
@ -1076,8 +1076,8 @@ end
|
|||||||
UI.TransitionSlideLeft = class()
|
UI.TransitionSlideLeft = class()
|
||||||
UI.TransitionSlideLeft.defaults = {
|
UI.TransitionSlideLeft.defaults = {
|
||||||
UIElement = 'TransitionSlideLeft',
|
UIElement = 'TransitionSlideLeft',
|
||||||
ticks = 12,
|
ticks = 4,
|
||||||
easing = 'outBounce',
|
easing = 'outQuint',
|
||||||
}
|
}
|
||||||
function UI.TransitionSlideLeft:init(args)
|
function UI.TransitionSlideLeft:init(args)
|
||||||
local defaults = UI:getDefaults(UI.TransitionSlideLeft, args)
|
local defaults = UI:getDefaults(UI.TransitionSlideLeft, args)
|
||||||
@ -1116,11 +1116,11 @@ end
|
|||||||
UI.TransitionSlideRight = class()
|
UI.TransitionSlideRight = class()
|
||||||
UI.TransitionSlideRight.defaults = {
|
UI.TransitionSlideRight.defaults = {
|
||||||
UIElement = 'TransitionSlideRight',
|
UIElement = 'TransitionSlideRight',
|
||||||
ticks = 12,
|
ticks = 4,
|
||||||
easing = 'outBounce',
|
easing = 'outQuint',
|
||||||
}
|
}
|
||||||
function UI.TransitionSlideRight:init(args)
|
function UI.TransitionSlideRight:init(args)
|
||||||
local defaults = UI:getDefaults(UI.TransitionSlideLeft, args)
|
local defaults = UI:getDefaults(UI.TransitionSlideRight, args)
|
||||||
UI.setProperties(self, defaults)
|
UI.setProperties(self, defaults)
|
||||||
|
|
||||||
self.pos = { x = self.x }
|
self.pos = { x = self.x }
|
||||||
@ -2520,6 +2520,72 @@ function UI.Notification:display(value, timeout)
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[[-- Throttle --]]--
|
||||||
|
UI.Throttle = class(UI.Window)
|
||||||
|
UI.Throttle.defaults = {
|
||||||
|
UIElement = 'Throttle',
|
||||||
|
backgroundColor = colors.gray,
|
||||||
|
height = 6,
|
||||||
|
width = 10,
|
||||||
|
timeout = .095,
|
||||||
|
ctr = 0,
|
||||||
|
image = {
|
||||||
|
' //) (O )~@ &~&-( ?Q ',
|
||||||
|
' //) (O )- @ \-( ?) && ',
|
||||||
|
' //) (O ), @ \-(?) && ',
|
||||||
|
' //) (O ). @ \-d ) (@ '
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function UI.Throttle:init(args)
|
||||||
|
local defaults = UI:getDefaults(UI.Throttle, args)
|
||||||
|
UI.Window.init(self, defaults)
|
||||||
|
end
|
||||||
|
|
||||||
|
function UI.Throttle:setParent()
|
||||||
|
self.x = math.ceil((self.parent.width - self.width) / 2)
|
||||||
|
self.y = math.ceil((self.parent.height - self.height) / 2)
|
||||||
|
UI.Window.setParent(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
function UI.Throttle:enable()
|
||||||
|
self.enabled = false
|
||||||
|
end
|
||||||
|
|
||||||
|
function UI.Throttle:disable()
|
||||||
|
if self.canvas then
|
||||||
|
self.enabled = false
|
||||||
|
self.canvas:removeLayer()
|
||||||
|
self.canvas = nil
|
||||||
|
self.c = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function UI.Throttle:update()
|
||||||
|
local cc = os.clock()
|
||||||
|
if not self.c then
|
||||||
|
self.c = cc
|
||||||
|
elseif cc > self.c + self.timeout then
|
||||||
|
os.sleep(0)
|
||||||
|
self.c = os.clock()
|
||||||
|
self.enabled = true
|
||||||
|
if not self.canvas then
|
||||||
|
self.canvas = UI.term.canvas:addLayer(self, self.backgroundColor, colors.cyan)
|
||||||
|
self.canvas:setVisible(true)
|
||||||
|
self:clear(colors.cyan)
|
||||||
|
end
|
||||||
|
local image = self.image[self.ctr + 1]
|
||||||
|
local width = self.width - 2
|
||||||
|
for i = 0, #self.image do
|
||||||
|
self:write(2, i + 2, image:sub(width * i + 1, width * i + width), colors.black, colors.white)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.ctr = (self.ctr + 1) % #self.image
|
||||||
|
|
||||||
|
self:sync()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--[[-- GridLayout --]]--
|
--[[-- GridLayout --]]--
|
||||||
UI.GridLayout = class(UI.Window)
|
UI.GridLayout = class(UI.Window)
|
||||||
UI.GridLayout.defaults = {
|
UI.GridLayout.defaults = {
|
||||||
|
@ -27,8 +27,8 @@ function Util.throttle(fn)
|
|||||||
return function(...)
|
return function(...)
|
||||||
local nts = os.clock()
|
local nts = os.clock()
|
||||||
if nts > ts + timeout then
|
if nts > ts + timeout then
|
||||||
ts = nts
|
|
||||||
os.sleep(0)
|
os.sleep(0)
|
||||||
|
ts = os.clock()
|
||||||
if fn then
|
if fn then
|
||||||
fn(...)
|
fn(...)
|
||||||
end
|
end
|
||||||
|
@ -160,10 +160,14 @@ end
|
|||||||
|
|
||||||
function page:runScript(scriptName)
|
function page:runScript(scriptName)
|
||||||
if self.turtle then
|
if self.turtle then
|
||||||
|
self.notification:info('Connecting')
|
||||||
|
self:sync()
|
||||||
|
|
||||||
local cmd = string.format('Script %d %s', self.turtle.id, scriptName)
|
local cmd = string.format('Script %d %s', self.turtle.id, scriptName)
|
||||||
local ot = term.redirect(nullTerm)
|
local ot = term.redirect(nullTerm)
|
||||||
pcall(function() shell.run(cmd) end)
|
pcall(function() shell.run(cmd) end)
|
||||||
term.redirect(ot)
|
term.redirect(ot)
|
||||||
|
self.notification:success('Sent')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -33,13 +33,12 @@ local schematic = Schematic()
|
|||||||
local blocks = Blocks({ dir = BUILDER_DIR })
|
local blocks = Blocks({ dir = BUILDER_DIR })
|
||||||
|
|
||||||
local Builder = {
|
local Builder = {
|
||||||
version = '1.70',
|
version = '1.71',
|
||||||
ccVersion = nil,
|
|
||||||
slots = { },
|
slots = { },
|
||||||
index = 1,
|
index = 1,
|
||||||
mode = 'build',
|
mode = 'build',
|
||||||
fuelItem = { id = 'minecraft:coal', dmg = 0 },
|
fuelItem = { id = 'minecraft:coal', dmg = 0 },
|
||||||
resourceSlots = 15,
|
resourceSlots = 14,
|
||||||
facing = 'south',
|
facing = 'south',
|
||||||
confirmFacing = false,
|
confirmFacing = false,
|
||||||
}
|
}
|
||||||
@ -49,16 +48,6 @@ local pistonFacings
|
|||||||
--[[-- SubDB --]]--
|
--[[-- SubDB --]]--
|
||||||
subDB = TableDB({
|
subDB = TableDB({
|
||||||
fileName = fs.combine(BUILDER_DIR, 'sub.db'),
|
fileName = fs.combine(BUILDER_DIR, 'sub.db'),
|
||||||
tabledef = {
|
|
||||||
autokeys = false,
|
|
||||||
columns = {
|
|
||||||
{ name = 'Key', type = 'key', length = 8 },
|
|
||||||
{ name = 'id', type = 'number', length = 5 },
|
|
||||||
{ name = 'dmg', type = 'number', length = 2 },
|
|
||||||
{ name = 'refid', type = 'number', length = 5 },
|
|
||||||
{ name = 'refdmg', type = 'number', length = 2 },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
function subDB:load()
|
function subDB:load()
|
||||||
@ -71,222 +60,66 @@ end
|
|||||||
|
|
||||||
function subDB:seedDB()
|
function subDB:seedDB()
|
||||||
self.data = {
|
self.data = {
|
||||||
[ "minecraft:redstone_wire:0" ] = {
|
[ "minecraft:redstone_wire:0" ] = "minecraft:redstone:0",
|
||||||
sdmg = 0,
|
[ "minecraft:wall_sign:0" ] = "minecraft:sign:0",
|
||||||
sid = "minecraft:redstone",
|
[ "minecraft:standing_sign:0" ] = "minecraft:sign:0",
|
||||||
dmg = 0,
|
[ "minecraft:potatoes:0" ] = "minecraft:potato:0",
|
||||||
id = "minecraft:redstone_wire",
|
[ "minecraft:unlit_redstone_torch:0" ] = "minecraft:redstone_torch:0",
|
||||||
},
|
[ "minecraft:powered_repeater:0" ] = "minecraft:repeater:0",
|
||||||
[ "minecraft:wall_sign:0" ] = {
|
[ "minecraft:unpowered_repeater:0" ] = "minecraft:repeater:0",
|
||||||
sdmg = 0,
|
[ "minecraft:carrots:0" ] = "minecraft:carrot:0",
|
||||||
sid = "minecraft:sign",
|
[ "minecraft:cocoa:0" ] = "minecraft:dye:3",
|
||||||
dmg = 0,
|
[ "minecraft:unpowered_comparator:0" ] = "minecraft:comparator:0",
|
||||||
id = "minecraft:wall_sign",
|
[ "minecraft:powered_comparator:0" ] = "minecraft:comparator:0",
|
||||||
},
|
[ "minecraft:piston_head:0" ] = "minecraft:air:0",
|
||||||
[ "minecraft:standing_sign:0" ] = {
|
[ "minecraft:double_wooden_slab:0" ] = "minecraft:planks:0",
|
||||||
sdmg = 0,
|
[ "minecraft:double_wooden_slab:1" ] = "minecraft:planks:1",
|
||||||
sid = "minecraft:sign",
|
[ "minecraft:double_wooden_slab:2" ] = "minecraft:planks:2",
|
||||||
dmg = 0,
|
[ "minecraft:double_wooden_slab:3" ] = "minecraft:planks:3",
|
||||||
id = "minecraft:standing_sign",
|
[ "minecraft:double_wooden_slab:4" ] = "minecraft:planks:4",
|
||||||
},
|
[ "minecraft:double_wooden_slab:5" ] = "minecraft:planks:5",
|
||||||
[ "minecraft:potatoes:0" ] = {
|
[ "minecraft:lit_redstone_lamp:0" ] = "minecraft:redstone_lamp:0",
|
||||||
sdmg = 0,
|
[ "minecraft:double_stone_slab:1" ] = "minecraft:sandstone:0",
|
||||||
sid = "minecraft:potato",
|
[ "minecraft:double_stone_slab:2" ] = "minecraft:planks:0",
|
||||||
dmg = 0,
|
[ "minecraft:double_stone_slab:3" ] = "minecraft:cobblestone:0",
|
||||||
id = "minecraft:potatoes",
|
[ "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:dirt:1" ] = {
|
[ "minecraft:double_stone_slab:7" ] = "minecraft:quartz_block:0",
|
||||||
sdmg = 0,
|
[ "minecraft:double_stone_slab:9" ] = "minecraft:sandstone:2",
|
||||||
sid = "minecraft:dirt",
|
[ "minecraft:double_stone_slab2:0" ] = "minecraft:sandstone:0",
|
||||||
dmg = 1,
|
[ "minecraft:stone_slab:2" ] = "minecraft:wooden_slab:0",
|
||||||
id = "minecraft:dirt",
|
[ "minecraft:wheat:0" ] = "minecraft:wheat_seeds:0",
|
||||||
},
|
[ "minecraft:flowing_water:0" ] = "minecraft:air:0",
|
||||||
]]--
|
[ "minecraft:lit_furnace:0" ] = "minecraft:furnace:0",
|
||||||
[ "minecraft:unlit_redstone_torch:0" ] = {
|
[ "minecraft:wall_banner:0" ] = "minecraft:banner:0",
|
||||||
sdmg = 0,
|
[ "minecraft:standing_banner:0" ] = "minecraft:banner:0",
|
||||||
sid = "minecraft:redstone",
|
[ "minecraft:tripwire:0" ] = "minecraft:string:0",
|
||||||
dmg = 0,
|
|
||||||
id = "minecraft:unlit_redstone_torch",
|
|
||||||
},
|
|
||||||
[ "minecraft:powered_repeater:0" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:repeater",
|
|
||||||
dmg = 0,
|
|
||||||
id = "minecraft:powered_repeater",
|
|
||||||
},
|
|
||||||
[ "minecraft:unpowered_repeater:0" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:repeater",
|
|
||||||
dmg = 0,
|
|
||||||
id = "minecraft:unpowered_repeater",
|
|
||||||
},
|
|
||||||
[ "minecraft:carrots:0" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:carrot",
|
|
||||||
dmg = 0,
|
|
||||||
id = "minecraft:carrots",
|
|
||||||
},
|
|
||||||
[ "minecraft:cocoa:0" ] = {
|
|
||||||
sdmg = 3,
|
|
||||||
sid = "minecraft:dye",
|
|
||||||
dmg = 0,
|
|
||||||
id = "minecraft:cocoa",
|
|
||||||
},
|
|
||||||
[ "minecraft:unpowered_comparator:0" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:comparator",
|
|
||||||
dmg = 0,
|
|
||||||
id = "minecraft:unpowered_comparator",
|
|
||||||
},
|
|
||||||
[ "minecraft:piston_head:0" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:air",
|
|
||||||
dmg = 0,
|
|
||||||
id = "minecraft:piston_head",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_wooden_slab:0" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:planks",
|
|
||||||
dmg = 0,
|
|
||||||
id = "minecraft:double_wooden_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_wooden_slab:1" ] = {
|
|
||||||
sdmg = 1,
|
|
||||||
sid = "minecraft:planks",
|
|
||||||
dmg = 1,
|
|
||||||
id = "minecraft:double_wooden_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_wooden_slab:2" ] = {
|
|
||||||
sdmg = 2,
|
|
||||||
sid = "minecraft:planks",
|
|
||||||
dmg = 2,
|
|
||||||
id = "minecraft:double_wooden_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_wooden_slab:3" ] = {
|
|
||||||
sdmg = 3,
|
|
||||||
sid = "minecraft:planks",
|
|
||||||
dmg = 3,
|
|
||||||
id = "minecraft:double_wooden_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_wooden_slab:4" ] = {
|
|
||||||
sdmg = 4,
|
|
||||||
sid = "minecraft:planks",
|
|
||||||
dmg = 4,
|
|
||||||
id = "minecraft:double_wooden_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_wooden_slab:5" ] = {
|
|
||||||
sdmg = 5,
|
|
||||||
sid = "minecraft:planks",
|
|
||||||
dmg = 5,
|
|
||||||
id = "minecraft:double_wooden_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:lit_redstone_lamp:0" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:redstone_lamp",
|
|
||||||
dmg = 0,
|
|
||||||
id = "minecraft:lit_redstone_lamp",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_stone_slab:1" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:sandstone",
|
|
||||||
dmg = 1,
|
|
||||||
id = "minecraft:double_stone_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_stone_slab:2" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:planks",
|
|
||||||
dmg = 2,
|
|
||||||
id = "minecraft:double_stone_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_stone_slab:3" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:cobblestone",
|
|
||||||
dmg = 3,
|
|
||||||
id = "minecraft:double_stone_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_stone_slab:4" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:brick_block",
|
|
||||||
dmg = 4,
|
|
||||||
id = "minecraft:double_stone_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_stone_slab:5" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:stonebrick",
|
|
||||||
dmg = 5,
|
|
||||||
id = "minecraft:double_stone_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_stone_slab:6" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:nether_brick",
|
|
||||||
dmg = 6,
|
|
||||||
id = "minecraft:double_stone_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_stone_slab:7" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:quartz_block",
|
|
||||||
dmg = 7,
|
|
||||||
id = "minecraft:double_stone_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_stone_slab:9" ] = {
|
|
||||||
sdmg = 2,
|
|
||||||
sid = "minecraft:sandstone",
|
|
||||||
dmg = 9,
|
|
||||||
id = "minecraft:double_stone_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:double_stone_slab2:0" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:sandstone",
|
|
||||||
dmg = 0,
|
|
||||||
id = "minecraft:double_stone_slab2",
|
|
||||||
},
|
|
||||||
[ "minecraft:stone_slab:2" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:wooden_slab",
|
|
||||||
dmg = 2,
|
|
||||||
id = "minecraft:stone_slab",
|
|
||||||
},
|
|
||||||
[ "minecraft:wheat:0" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:wheat_seeds",
|
|
||||||
dmg = 0,
|
|
||||||
id = "minecraft:wheat",
|
|
||||||
},
|
|
||||||
[ "minecraft:flowing_water:0" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:air",
|
|
||||||
dmg = 0,
|
|
||||||
id = "minecraft:flowing_water",
|
|
||||||
},
|
|
||||||
[ "minecraft:lit_furnace:0" ] = {
|
|
||||||
sdmg = 0,
|
|
||||||
sid = "minecraft:furnace",
|
|
||||||
dmg = 0,
|
|
||||||
id = "minecraft:lit_furnace",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
self.dirty = true
|
self.dirty = true
|
||||||
self:flush()
|
self:flush()
|
||||||
end
|
end
|
||||||
|
|
||||||
function subDB:add(s)
|
function subDB:add(s)
|
||||||
|
TableDB.add(self, { s.id, s.dmg }, table.concat({ s.sid, s.sdmg }, ':'))
|
||||||
TableDB.add(self, { s.id, s.dmg}, s)
|
|
||||||
self:flush()
|
self:flush()
|
||||||
end
|
end
|
||||||
|
|
||||||
function subDB:remove(s)
|
function subDB:remove(s)
|
||||||
|
|
||||||
-- TODO: tableDB.remove should take table key
|
-- TODO: tableDB.remove should take table key
|
||||||
TableDB.remove(self, s.id .. ':' .. s.dmg)
|
TableDB.remove(self, s.id .. ':' .. s.dmg)
|
||||||
self:flush()
|
self:flush()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function subDB:extract(s)
|
||||||
|
local id, dmg = s:match('(.+):(%d+)')
|
||||||
|
return id, tonumber(dmg)
|
||||||
|
end
|
||||||
|
|
||||||
function subDB:getSubstitutedItem(id, dmg)
|
function subDB:getSubstitutedItem(id, dmg)
|
||||||
local sub = TableDB.get(self, { id, dmg })
|
local sub = TableDB.get(self, { id, dmg })
|
||||||
if sub then
|
if sub then
|
||||||
return { id = sub.sid, dmg = sub.sdmg }
|
id, dmg = self:extract(sub)
|
||||||
end
|
end
|
||||||
return { id = id, dmg = dmg }
|
return { id = id, dmg = dmg }
|
||||||
end
|
end
|
||||||
@ -294,8 +127,10 @@ end
|
|||||||
function subDB:lookupBlocksForSub(sid, sdmg)
|
function subDB:lookupBlocksForSub(sid, sdmg)
|
||||||
local t = { }
|
local t = { }
|
||||||
for k,v in pairs(self.data) do
|
for k,v in pairs(self.data) do
|
||||||
if v.sid == sid and v.sdmg == sdmg then
|
local id, dmg = self:extract(v)
|
||||||
t[k] = 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
|
||||||
end
|
end
|
||||||
return t
|
return t
|
||||||
@ -304,14 +139,6 @@ end
|
|||||||
--[[-- maxStackDB --]]--
|
--[[-- maxStackDB --]]--
|
||||||
maxStackDB = TableDB({
|
maxStackDB = TableDB({
|
||||||
fileName = fs.combine(BUILDER_DIR, 'maxstack.db'),
|
fileName = fs.combine(BUILDER_DIR, '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)
|
function maxStackDB:get(id, dmg)
|
||||||
@ -348,8 +175,8 @@ function UI.Spinner:spin(text)
|
|||||||
end
|
end
|
||||||
term.write(str)
|
term.write(str)
|
||||||
self.spinIndex = self.spinIndex + 1
|
self.spinIndex = self.spinIndex + 1
|
||||||
self.c = cc
|
|
||||||
os.sleep(0)
|
os.sleep(0)
|
||||||
|
self.c = os.clock()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -395,7 +222,7 @@ function Builder:getBlockCounts()
|
|||||||
block.need = 0
|
block.need = 0
|
||||||
blocks[key] = block
|
blocks[key] = block
|
||||||
end
|
end
|
||||||
blocks[key].need = blocks[key].need + 1
|
block.need = block.need + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -532,15 +359,14 @@ function Builder:getGenericSupplyList(blockIndex)
|
|||||||
|
|
||||||
for _,s in pairs(slots) do
|
for _,s in pairs(slots) do
|
||||||
if s.id then
|
if s.id then
|
||||||
s.name = blocks.blockDB:getName(s.id, s.dmg)
|
s.name = blocks.nameDB:getName(s.id, s.dmg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return slots, lastBlock
|
return slots, lastBlock
|
||||||
end
|
end
|
||||||
|
|
||||||
function Builder:substituteBlocks()
|
function Builder:substituteBlocks(throttle)
|
||||||
local throttle = Util.throttle()
|
|
||||||
|
|
||||||
for _,b in pairs(schematic.blocks) do
|
for _,b in pairs(schematic.blocks) do
|
||||||
|
|
||||||
@ -550,13 +376,12 @@ function Builder:substituteBlocks()
|
|||||||
b.id = pb.id
|
b.id = pb.id
|
||||||
b.dmg = pb.dmg
|
b.dmg = pb.dmg
|
||||||
b.direction = pb.direction
|
b.direction = pb.direction
|
||||||
|
b.extra = pb.extra
|
||||||
|
|
||||||
local sub = subDB:get({ b.id, b.dmg })
|
local sub = subDB:get({ b.id, b.dmg })
|
||||||
if sub then
|
if sub then
|
||||||
b.id = sub.sid
|
b.id, b.dmg = subDB:extract(sub)
|
||||||
b.dmg = sub.sdmg
|
|
||||||
end
|
end
|
||||||
|
|
||||||
throttle()
|
throttle()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -619,7 +444,7 @@ function Builder:getSupplies()
|
|||||||
if s.need > 0 then
|
if s.need > 0 then
|
||||||
local item = self.itemProvider:getItemInfo(s.id, s.dmg)
|
local item = self.itemProvider:getItemInfo(s.id, s.dmg)
|
||||||
if item then
|
if item then
|
||||||
s.name = item.name
|
s.name = item.display_name
|
||||||
|
|
||||||
local qty = math.min(s.need - s.qty, item.qty)
|
local qty = math.min(s.need - s.qty, item.qty)
|
||||||
|
|
||||||
@ -635,7 +460,7 @@ function Builder:getSupplies()
|
|||||||
s.qty = turtle.getItemCount(s.index)
|
s.qty = turtle.getItemCount(s.index)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
s.name = blocks.blockDB:getName(s.id, s.dmg)
|
s.name = blocks.nameDB:getName(s.id, s.dmg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if s.qty < s.need then
|
if s.qty < s.need then
|
||||||
@ -730,7 +555,6 @@ function Builder:inAirDropoff()
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Builder:inAirResupply()
|
function Builder:inAirResupply()
|
||||||
@ -863,10 +687,10 @@ end
|
|||||||
function Builder:getWrenchSlot()
|
function Builder:getWrenchSlot()
|
||||||
|
|
||||||
local wrench = subDB:getSubstitutedItem('SubstituteAWrench', 0)
|
local wrench = subDB:getSubstitutedItem('SubstituteAWrench', 0)
|
||||||
|
|
||||||
return Builder:selectItem(wrench.id, wrench.dmg)
|
return Builder:selectItem(wrench.id, wrench.dmg)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- figure out our orientation in the world
|
||||||
function Builder:getTurtleFacing()
|
function Builder:getTurtleFacing()
|
||||||
|
|
||||||
if os.getVersion() == 1.8 then
|
if os.getVersion() == 1.8 then
|
||||||
@ -889,7 +713,7 @@ function Builder:getTurtleFacing()
|
|||||||
return Builder.facing
|
return Builder.facing
|
||||||
end
|
end
|
||||||
|
|
||||||
function Builder:wrenchBlock(side, facing)
|
function Builder:wrenchBlock(side, facing, cache)
|
||||||
|
|
||||||
local s = Builder:getWrenchSlot()
|
local s = Builder:getWrenchSlot()
|
||||||
|
|
||||||
@ -899,7 +723,8 @@ function Builder:wrenchBlock(side, facing)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local key = turtle.point.heading .. '-' .. facing
|
local key = turtle.point.heading .. '-' .. facing
|
||||||
local count = pistonFacings[side][key]
|
if cache then
|
||||||
|
local count = cache[side][key]
|
||||||
|
|
||||||
if count then
|
if count then
|
||||||
turtle.select(s.index)
|
turtle.select(s.index)
|
||||||
@ -908,6 +733,7 @@ function Builder:wrenchBlock(side, facing)
|
|||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local directions = {
|
local directions = {
|
||||||
[5] = 'east',
|
[5] = 'east',
|
||||||
@ -928,10 +754,11 @@ function Builder:wrenchBlock(side, facing)
|
|||||||
print('determining wrench count')
|
print('determining wrench count')
|
||||||
for i = 1, 6 do
|
for i = 1, 6 do
|
||||||
local _, bi = turtle.getAction(side).inspect()
|
local _, bi = turtle.getAction(side).inspect()
|
||||||
local pistonFacing = directions[bi.metadata]
|
|
||||||
|
|
||||||
if facing == pistonFacing then
|
if facing == directions[bi.metadata] then
|
||||||
pistonFacings[side][key] = count
|
if cache then
|
||||||
|
cache[side][key] = count
|
||||||
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
count = count + 1
|
count = count + 1
|
||||||
@ -941,6 +768,43 @@ function Builder:wrenchBlock(side, facing)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Builder:rotateBlock(side, facing)
|
||||||
|
|
||||||
|
local s = Builder:getWrenchSlot()
|
||||||
|
|
||||||
|
if not s then
|
||||||
|
b.needResupply = true
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, facing do
|
||||||
|
turtle.getAction(side).place()
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
|
--[[
|
||||||
|
local origFacing
|
||||||
|
while true do
|
||||||
|
local _, bi = turtle.getAction(side).inspect()
|
||||||
|
|
||||||
|
-- spin until it repeats
|
||||||
|
if not origFacing then
|
||||||
|
origFacing = bi.metadata
|
||||||
|
elseif bi.metadata == origFacing then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if facing == bi.metadata then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
turtle.getAction(side).place()
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
]]--
|
||||||
|
end
|
||||||
|
|
||||||
-- place piston, wrench piston to face downward, extend, remove piston
|
-- place piston, wrench piston to face downward, extend, remove piston
|
||||||
function Builder:placePiston(b)
|
function Builder:placePiston(b)
|
||||||
|
|
||||||
@ -957,7 +821,7 @@ function Builder:placePiston(b)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local success = self:wrenchBlock('forward', 'down') --wrench piston to point downwards
|
local success = self:wrenchBlock('forward', 'down', pistonFacings) --wrench piston to point downwards
|
||||||
|
|
||||||
rs.setOutput('front', true)
|
rs.setOutput('front', true)
|
||||||
os.sleep(.25)
|
os.sleep(.25)
|
||||||
@ -1151,7 +1015,29 @@ function Builder:placeDirectionalBlock(b, slot, travelPlane)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if self:placeDown(slot) then
|
if self:placeDown(slot) then
|
||||||
b.placed = self:wrenchBlock('down', pistonDirections[d])
|
b.placed = self:wrenchBlock('down', pistonDirections[d], pistonFacings)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local wrenchDirections = {
|
||||||
|
[ 'wrench-down' ] = 'down',
|
||||||
|
[ 'wrench-up' ] = 'up',
|
||||||
|
}
|
||||||
|
|
||||||
|
if wrenchDirections[d] then
|
||||||
|
|
||||||
|
local ws = Builder:getWrenchSlot()
|
||||||
|
|
||||||
|
if not ws then
|
||||||
|
b.needResupply = true
|
||||||
|
-- a hopper may have eaten the piston
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
self:gotoEx(b.x, b.z, b.y, nil, travelPlane)
|
||||||
|
|
||||||
|
if self:placeDown(slot) then
|
||||||
|
b.placed = self:wrenchBlock('down', wrenchDirections[d])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1179,6 +1065,10 @@ function Builder:placeDirectionalBlock(b, slot, travelPlane)
|
|||||||
b.placed = self:place(slot)
|
b.placed = self:place(slot)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if b.extra then
|
||||||
|
self:rotateBlock('down', b.extra.facing)
|
||||||
|
end
|
||||||
|
|
||||||
-- debug
|
-- debug
|
||||||
if d ~= 'top' and d ~= 'bottom' and not horizontalDirections[d] and not pistonDirections[d] then
|
if d ~= 'top' and d ~= 'bottom' and not horizontalDirections[d] and not pistonDirections[d] then
|
||||||
if not b.heading or turtle.getHeading() ~= b.heading then
|
if not b.heading or turtle.getHeading() ~= b.heading then
|
||||||
@ -1190,9 +1080,9 @@ end
|
|||||||
return b.placed
|
return b.placed
|
||||||
end
|
end
|
||||||
|
|
||||||
function Builder:reloadSchematic()
|
function Builder:reloadSchematic(throttle)
|
||||||
schematic:reload()
|
schematic:reload(throttle)
|
||||||
self:substituteBlocks()
|
self:substituteBlocks(throttle)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Builder:log(...)
|
function Builder:log(...)
|
||||||
@ -1424,7 +1314,7 @@ selectSubstitutionPage = UI.Page({
|
|||||||
{ heading = 'id', key = 'id' },
|
{ heading = 'id', key = 'id' },
|
||||||
{ heading = 'dmg', key = 'dmg' },
|
{ heading = 'dmg', key = 'dmg' },
|
||||||
},
|
},
|
||||||
sortColumn = 'odmg',
|
sortColumn = 'id',
|
||||||
height = UI.term.height-1,
|
height = UI.term.height-1,
|
||||||
autospace = true,
|
autospace = true,
|
||||||
y = 2,
|
y = 2,
|
||||||
@ -1451,32 +1341,33 @@ function selectSubstitutionPage:eventHandler(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--[[-- substitutionPage --]]--
|
--[[-- substitutionPage --]]--
|
||||||
substitutionPage = UI.Page({
|
substitutionPage = UI.Page {
|
||||||
backgroundColor = colors.gray,
|
backgroundColor = colors.gray,
|
||||||
titleBar = UI.TitleBar({
|
titleBar = UI.TitleBar {
|
||||||
previousPage = true,
|
previousPage = true,
|
||||||
title = 'Substitute a block'
|
title = 'Substitute a block'
|
||||||
}),
|
},
|
||||||
menuBar = UI.MenuBar({
|
menuBar = UI.MenuBar {
|
||||||
y = 2,
|
y = 2,
|
||||||
buttons = {
|
buttons = {
|
||||||
{ text = 'Accept', event = 'accept', help = 'Accept' },
|
{ text = 'Accept', event = 'accept', help = 'Accept' },
|
||||||
{ text = 'Revert', event = 'revert', help = 'Restore to original' },
|
{ text = 'Revert', event = 'revert', help = 'Restore to original' },
|
||||||
{ text = 'Air', event = 'air', help = 'Air' },
|
{ text = 'Air', event = 'air', help = 'Air' },
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
info = UI.Window({ y = 4, width = UI.term.width, height = 3 }),
|
info = UI.Window { y = 4, width = UI.term.width, height = 3 },
|
||||||
grid = UI.ScrollingGrid({
|
grid = UI.ScrollingGrid {
|
||||||
columns = {
|
columns = {
|
||||||
{ heading = 'Name', key = 'name', width = UI.term.width-9 },
|
{ heading = 'Name', key = 'display_name', width = UI.term.width-9 },
|
||||||
{ heading = 'Qty', key = 'fQty', width = 5 },
|
{ heading = 'Qty', key = 'fQty', width = 5 },
|
||||||
},
|
},
|
||||||
sortColumn = 'name',
|
sortColumn = 'name',
|
||||||
height = UI.term.height-7,
|
height = UI.term.height-7,
|
||||||
y = 7,
|
y = 7,
|
||||||
}),
|
},
|
||||||
statusBar = UI.StatusBar()
|
throttle = UI.Throttle { },
|
||||||
})
|
statusBar = UI.StatusBar { }
|
||||||
|
}
|
||||||
|
|
||||||
substitutionPage.menuBar:add({
|
substitutionPage.menuBar:add({
|
||||||
filterLabel = UI.Text({
|
filterLabel = UI.Text({
|
||||||
@ -1493,10 +1384,10 @@ substitutionPage.menuBar:add({
|
|||||||
function substitutionPage.info:draw()
|
function substitutionPage.info:draw()
|
||||||
|
|
||||||
local sub = self.parent.sub
|
local sub = self.parent.sub
|
||||||
local inName = blocks.blockDB:getName(sub.id, sub.dmg)
|
local inName = blocks.nameDB:getName(sub.id, sub.dmg)
|
||||||
local outName = ''
|
local outName = ''
|
||||||
if sub.sid then
|
if sub.sid then
|
||||||
outName = blocks.blockDB:getName(sub.sid, sub.sdmg)
|
outName = blocks.nameDB:getName(sub.sid, sub.sdmg)
|
||||||
end
|
end
|
||||||
|
|
||||||
self:clear()
|
self:clear()
|
||||||
@ -1512,7 +1403,7 @@ function substitutionPage:enable()
|
|||||||
self.grid.values = self.allItems
|
self.grid.values = self.allItems
|
||||||
for _,item in pairs(self.grid.values) do
|
for _,item in pairs(self.grid.values) do
|
||||||
item.key = item.id .. ':' .. item.dmg
|
item.key = item.id .. ':' .. item.dmg
|
||||||
item.lname = string.lower(item.name)
|
item.lname = string.lower(item.display_name)
|
||||||
item.fQty = Util.toBytes(item.qty)
|
item.fQty = Util.toBytes(item.qty)
|
||||||
end
|
end
|
||||||
self.grid:update()
|
self.grid:update()
|
||||||
@ -1543,9 +1434,9 @@ function substitutionPage:eventHandler(event)
|
|||||||
self.statusBar:draw()
|
self.statusBar:draw()
|
||||||
|
|
||||||
elseif event.type == 'grid_select' then
|
elseif event.type == 'grid_select' then
|
||||||
if not blocks.blockDB:lookupName(event.selected.id, event.selected.dmg) then
|
if not blocks.nameDB:lookupName(event.selected.id, event.selected.dmg) then
|
||||||
blocks.blockDB:add(event.selected.id, event.selected.dmg, event.selected.name, event.selected.id)
|
blocks.nameDB:add({event.selected.id, event.selected.dmg}, event.selected.name)
|
||||||
blocks.blockDB:flush()
|
blocks.nameDB:flush()
|
||||||
end
|
end
|
||||||
|
|
||||||
self:applySubstitute(event.selected.id, event.selected.dmg)
|
self:applySubstitute(event.selected.id, event.selected.dmg)
|
||||||
@ -1587,7 +1478,9 @@ function substitutionPage:eventHandler(event)
|
|||||||
subDB:add(self.sub)
|
subDB:add(self.sub)
|
||||||
end
|
end
|
||||||
|
|
||||||
Builder:reloadSchematic()
|
self.throttle:enable()
|
||||||
|
Builder:reloadSchematic(function() self.throttle:update() end)
|
||||||
|
self.throttle:disable()
|
||||||
UI:setPage('listing')
|
UI:setPage('listing')
|
||||||
|
|
||||||
elseif event.type == 'cancel' then
|
elseif event.type == 'cancel' then
|
||||||
@ -1598,12 +1491,12 @@ function substitutionPage:eventHandler(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--[[-- SupplyPage --]]--
|
--[[-- SupplyPage --]]--
|
||||||
supplyPage = UI.Page({
|
supplyPage = UI.Page {
|
||||||
titleBar = UI.TitleBar({
|
titleBar = UI.TitleBar {
|
||||||
title = 'Waiting for supplies',
|
title = 'Waiting for supplies',
|
||||||
previousPage = 'start'
|
previousPage = 'start'
|
||||||
}),
|
},
|
||||||
menuBar = UI.MenuBar({
|
menuBar = UI.MenuBar {
|
||||||
y = 2,
|
y = 2,
|
||||||
buttons = {
|
buttons = {
|
||||||
--{ text = 'Refresh', event = 'refresh', help = 'Refresh inventory' },
|
--{ text = 'Refresh', event = 'refresh', help = 'Refresh inventory' },
|
||||||
@ -1611,8 +1504,8 @@ supplyPage = UI.Page({
|
|||||||
{ text = 'Menu', event = 'menu', help = 'Return to main menu' },
|
{ text = 'Menu', event = 'menu', help = 'Return to main menu' },
|
||||||
{ text = 'Force Craft', event = 'craft', help = 'Request crafting (again)' },
|
{ text = 'Force Craft', event = 'craft', help = 'Request crafting (again)' },
|
||||||
}
|
}
|
||||||
}),
|
},
|
||||||
grid = UI.Grid({
|
grid = UI.Grid {
|
||||||
columns = {
|
columns = {
|
||||||
{ heading = 'Name', key = 'name', width = UI.term.width - 7 },
|
{ heading = 'Name', key = 'name', width = UI.term.width - 7 },
|
||||||
{ heading = 'Need', key = 'need', width = 4 },
|
{ heading = 'Need', key = 'need', width = 4 },
|
||||||
@ -1621,20 +1514,20 @@ supplyPage = UI.Page({
|
|||||||
y = 3,
|
y = 3,
|
||||||
width = UI.term.width,
|
width = UI.term.width,
|
||||||
height = UI.term.height - 3
|
height = UI.term.height - 3
|
||||||
}),
|
},
|
||||||
statusBar = UI.StatusBar({
|
statusBar = UI.StatusBar {
|
||||||
columns = {
|
columns = {
|
||||||
{ 'Help', 'help', UI.term.width - 13 },
|
{ 'Help', 'help', UI.term.width - 13 },
|
||||||
{ 'Fuel', 'fuel', 11 }
|
{ 'Fuel', 'fuel', 11 }
|
||||||
}
|
}
|
||||||
}),
|
},
|
||||||
accelerators = {
|
accelerators = {
|
||||||
c = 'craft',
|
c = 'craft',
|
||||||
r = 'refresh',
|
r = 'refresh',
|
||||||
b = 'build',
|
b = 'build',
|
||||||
m = 'menu',
|
m = 'menu',
|
||||||
},
|
},
|
||||||
})
|
}
|
||||||
|
|
||||||
function supplyPage:eventHandler(event)
|
function supplyPage:eventHandler(event)
|
||||||
|
|
||||||
@ -1756,8 +1649,8 @@ listingPage = UI.Page({
|
|||||||
fullList = true
|
fullList = true
|
||||||
})
|
})
|
||||||
|
|
||||||
function listingPage:enable()
|
function listingPage:enable(throttle)
|
||||||
listingPage:refresh()
|
listingPage:refresh(throttle)
|
||||||
UI.Page.enable(self)
|
UI.Page.enable(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1821,11 +1714,11 @@ function listingPage.grid:getRowTextColor(row, selected)
|
|||||||
return UI.Grid:getRowTextColor(row, selected)
|
return UI.Grid:getRowTextColor(row, selected)
|
||||||
end
|
end
|
||||||
|
|
||||||
function listingPage:refresh()
|
function listingPage:refresh(throttle)
|
||||||
|
|
||||||
local supplyList = Builder:getBlockCounts()
|
local supplyList = Builder:getBlockCounts()
|
||||||
|
|
||||||
Builder.itemProvider:refresh()
|
Builder.itemProvider:refresh(throttle)
|
||||||
|
|
||||||
for _,b in pairs(supplyList) do
|
for _,b in pairs(supplyList) do
|
||||||
if b.need > 0 then
|
if b.need > 0 then
|
||||||
@ -1834,19 +1727,22 @@ function listingPage:refresh()
|
|||||||
if item then
|
if item then
|
||||||
local block = blocks.blockDB:lookup(b.id, b.dmg)
|
local block = blocks.blockDB:lookup(b.id, b.dmg)
|
||||||
if not block then
|
if not block then
|
||||||
blocks.blockDB:add(b.id, b.dmg, item.name, b.id)
|
blocks.nameDB:add({b.id, b.dmg}, item.display_name)
|
||||||
elseif not block.name and item.name then
|
elseif not block.name and item.display_name then
|
||||||
blocks.blockDB:add(b.id, b.dmg, item.name, b.id)
|
blocks.nameDB:add({b.id, b.dmg}, item.display_name)
|
||||||
end
|
end
|
||||||
b.name = item.name
|
b.name = item.display_name
|
||||||
b.qty = item.qty
|
b.qty = item.qty
|
||||||
b.is_craftable = item.is_craftable
|
b.is_craftable = item.is_craftable
|
||||||
else
|
else
|
||||||
b.name = blocks.blockDB:getName(b.id, b.dmg)
|
b.name = blocks.nameDB:getName(b.id, b.dmg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if throttle then
|
||||||
|
throttle()
|
||||||
end
|
end
|
||||||
blocks.blockDB:flush()
|
end
|
||||||
|
blocks.nameDB:flush()
|
||||||
|
|
||||||
if self.fullList then
|
if self.fullList then
|
||||||
self.grid:setValues(supplyList)
|
self.grid:setValues(supplyList)
|
||||||
@ -1881,15 +1777,15 @@ function listingPage:manageBlock(selected)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--[[-- startPage --]]--
|
--[[-- startPage --]]--
|
||||||
local startPage = UI.Page({
|
local startPage = UI.Page {
|
||||||
-- titleBar = UI.TitleBar({ title = 'Builder v' .. Builder.version }),
|
-- titleBar = UI.TitleBar({ title = 'Builder v' .. Builder.version }),
|
||||||
window = UI.Window({
|
window = UI.Window {
|
||||||
x = UI.term.width-16,
|
x = UI.term.width-16,
|
||||||
y = 2,
|
y = 2,
|
||||||
width = 16,
|
width = 16,
|
||||||
height = UI.term.height-2,
|
height = UI.term.height-2,
|
||||||
backgroundColor = colors.gray,
|
backgroundColor = colors.gray,
|
||||||
grid = UI.Grid({
|
grid = UI.Grid {
|
||||||
columns = {
|
columns = {
|
||||||
{ heading = 'Name', key = 'name', width = 6 },
|
{ heading = 'Name', key = 'name', width = 6 },
|
||||||
{ heading = 'Value', key = 'value', width = 7 },
|
{ heading = 'Value', key = 'value', width = 7 },
|
||||||
@ -1903,9 +1799,9 @@ local startPage = UI.Page({
|
|||||||
--autospace = true,
|
--autospace = true,
|
||||||
selectable = false,
|
selectable = false,
|
||||||
backgroundColor = colors.gray
|
backgroundColor = colors.gray
|
||||||
}),
|
},
|
||||||
}),
|
},
|
||||||
menu = UI.Menu({
|
menu = UI.Menu {
|
||||||
x = 2,
|
x = 2,
|
||||||
y = 4,
|
y = 4,
|
||||||
menuItems = {
|
menuItems = {
|
||||||
@ -1917,12 +1813,13 @@ local startPage = UI.Page({
|
|||||||
{ prompt = 'Begin', event = 'begin' },
|
{ prompt = 'Begin', event = 'begin' },
|
||||||
{ prompt = 'Quit', event = 'quit' }
|
{ prompt = 'Quit', event = 'quit' }
|
||||||
}
|
}
|
||||||
}),
|
},
|
||||||
|
throttle = UI.Throttle { },
|
||||||
accelerators = {
|
accelerators = {
|
||||||
x = 'test',
|
x = 'test',
|
||||||
q = 'quit'
|
q = 'quit'
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
function startPage:draw()
|
function startPage:draw()
|
||||||
local fuel = turtle.getFuelLevel()
|
local fuel = turtle.getFuelLevel()
|
||||||
@ -2027,7 +1924,8 @@ function startPage:eventHandler(event)
|
|||||||
-- as the current level's route may or may not have been
|
-- as the current level's route may or may not have been
|
||||||
-- computed
|
-- computed
|
||||||
Builder:dumpInventory()
|
Builder:dumpInventory()
|
||||||
UI:setPage('listing')
|
UI:setPage('listing', function() self.throttle:update() end)
|
||||||
|
self.throttle:disable()
|
||||||
|
|
||||||
elseif event.type == 'toggleMode' then
|
elseif event.type == 'toggleMode' then
|
||||||
if Builder.mode == 'build' then
|
if Builder.mode == 'build' then
|
||||||
@ -2061,7 +1959,7 @@ function startPage:eventHandler(event)
|
|||||||
|
|
||||||
turtle.status = 'thinking'
|
turtle.status = 'thinking'
|
||||||
print('Reloading schematic')
|
print('Reloading schematic')
|
||||||
Builder:reloadSchematic()
|
Builder:reloadSchematic(Util.throttle())
|
||||||
Builder:dumpInventory()
|
Builder:dumpInventory()
|
||||||
Builder:refuel()
|
Builder:refuel()
|
||||||
|
|
||||||
@ -2095,13 +1993,6 @@ if #args < 1 then
|
|||||||
error('supply file name')
|
error('supply file name')
|
||||||
end
|
end
|
||||||
|
|
||||||
if os.version() == 'CraftOS 1.7' then
|
|
||||||
Builder.ccVersion = 1.7
|
|
||||||
Builder.resourceSlots = 14
|
|
||||||
else
|
|
||||||
error('Unsupported ComputerCraft version')
|
|
||||||
end
|
|
||||||
|
|
||||||
Builder.itemProvider = MEProvider()
|
Builder.itemProvider = MEProvider()
|
||||||
if not Builder.itemProvider:isValid() then
|
if not Builder.itemProvider:isValid() then
|
||||||
Builder.itemProvider = ChestProvider()
|
Builder.itemProvider = ChestProvider()
|
||||||
@ -2117,10 +2008,11 @@ subDB:load()
|
|||||||
|
|
||||||
UI.term:reset()
|
UI.term:reset()
|
||||||
turtle.status = 'reading'
|
turtle.status = 'reading'
|
||||||
print('Loading ' .. args[1])
|
print('Loading schematic')
|
||||||
schematic:load(args[1])
|
schematic:load(args[1])
|
||||||
print('Substituting blocks')
|
print('Substituting blocks')
|
||||||
Builder:substituteBlocks()
|
|
||||||
|
Builder:substituteBlocks(Util.throttle())
|
||||||
|
|
||||||
if not fs.exists(BUILDER_DIR) then
|
if not fs.exists(BUILDER_DIR) then
|
||||||
fs.makeDir(BUILDER_DIR)
|
fs.makeDir(BUILDER_DIR)
|
||||||
@ -2146,4 +2038,3 @@ turtle.run(function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
UI.term:reset()
|
UI.term:reset()
|
||||||
--turtle.status = 'idle'
|
|
||||||
|
@ -189,10 +189,10 @@ itemPage = UI.Page {
|
|||||||
backgroundColor = colors.green
|
backgroundColor = colors.green
|
||||||
},
|
},
|
||||||
displayName = UI.Window {
|
displayName = UI.Window {
|
||||||
x = 5, y = 3, width = UI.term.width - 10, height = 3,
|
x = 5, y = 2, width = UI.term.width - 10, height = 3,
|
||||||
},
|
},
|
||||||
form = UI.Form {
|
form = UI.Form {
|
||||||
x = 4, y = 6, height = 10, rex = -4,
|
x = 4, y = 4, height = 10, rex = -4,
|
||||||
[1] = UI.TextEntry {
|
[1] = UI.TextEntry {
|
||||||
width = 7,
|
width = 7,
|
||||||
backgroundColor = colors.gray,
|
backgroundColor = colors.gray,
|
||||||
|
350
sys/apps/shapes.lua
Normal file
350
sys/apps/shapes.lua
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
require = requireInjector(getfenv(1))
|
||||||
|
local UI = require('ui')
|
||||||
|
local GPS = require('gps')
|
||||||
|
local Socket = require('socket')
|
||||||
|
|
||||||
|
multishell.setTitle(multishell.getCurrent(), 'Shapes')
|
||||||
|
|
||||||
|
local args = { ... }
|
||||||
|
local turtleId = args[1] or error('Supply turtle ID')
|
||||||
|
turtleId = tonumber(turtleId)
|
||||||
|
|
||||||
|
local script = [[
|
||||||
|
|
||||||
|
require = requireInjector(getfenv(1))
|
||||||
|
local GPS = require('gps')
|
||||||
|
local ChestProvider = require('chestProvider18')
|
||||||
|
local Point = require('point')
|
||||||
|
|
||||||
|
local itemProvider
|
||||||
|
|
||||||
|
function dumpInventory()
|
||||||
|
|
||||||
|
for i = 1, 16 do
|
||||||
|
local qty = turtle.getItemCount(i)
|
||||||
|
if qty > 0 then
|
||||||
|
itemProvider:insert(i, qty)
|
||||||
|
end
|
||||||
|
if turtle.getItemCount(i) ~= 0 then
|
||||||
|
print('Provider is full or missing - make space or replace')
|
||||||
|
print('Press enter to continue')
|
||||||
|
read()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
turtle.select(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function refuel()
|
||||||
|
while turtle.getFuelLevel() < 4000 do
|
||||||
|
print('Refueling')
|
||||||
|
turtle.select(1)
|
||||||
|
|
||||||
|
itemProvider:provide({ id = 'minecraft:coal', dmg = 0 }, 64, 1)
|
||||||
|
if turtle.getItemCount(1) == 0 then
|
||||||
|
print('Out of fuel, add fuel to chest/ME system')
|
||||||
|
turtle.status = 'waiting'
|
||||||
|
os.sleep(5)
|
||||||
|
else
|
||||||
|
turtle.refuel(64)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function goto(pt)
|
||||||
|
while not turtle.gotoPoint(pt) do
|
||||||
|
print('stuck')
|
||||||
|
os.sleep(5)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function pathTo(pt)
|
||||||
|
while not turtle.pathfind(pt) do
|
||||||
|
print('stuck')
|
||||||
|
os.sleep(5)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function resupply()
|
||||||
|
|
||||||
|
if data.suppliesPt then
|
||||||
|
pathTo(data.suppliesPt)
|
||||||
|
|
||||||
|
itemProvider = ChestProvider({ direction = 'up', wrapSide = 'bottom' })
|
||||||
|
dumpInventory()
|
||||||
|
refuel()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function makePlane(y)
|
||||||
|
local pt = { x = math.min(data.startPt.x, data.endPt.x),
|
||||||
|
ex = math.max(data.startPt.x, data.endPt.x),
|
||||||
|
z = math.min(data.startPt.z, data.endPt.z),
|
||||||
|
ez = math.max(data.startPt.z, data.endPt.z) }
|
||||||
|
|
||||||
|
local blocks = { }
|
||||||
|
for z = pt.z, pt.ez do
|
||||||
|
for x = pt.x, pt.ex do
|
||||||
|
table.insert(blocks, { x = x, y = y, z = z })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return blocks
|
||||||
|
end
|
||||||
|
|
||||||
|
local function optimizeRoute(plane, ptb)
|
||||||
|
|
||||||
|
local maxDistance = 99999999
|
||||||
|
|
||||||
|
local function getNearestNeighbor(p, pt, threshold)
|
||||||
|
local key, block, heading
|
||||||
|
local moves = maxDistance
|
||||||
|
|
||||||
|
local function getMoves(b, k)
|
||||||
|
local distance = math.abs(pt.x - b.x) + math.abs(pt.z - b.z)
|
||||||
|
|
||||||
|
if distance < moves then
|
||||||
|
-- this operation is expensive - only run if distance is close
|
||||||
|
local c, h = Point.calculateMoves(pt, b, distance)
|
||||||
|
if c < moves then
|
||||||
|
block = b
|
||||||
|
key = k
|
||||||
|
moves = c
|
||||||
|
heading = h
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function blockReady(b)
|
||||||
|
return not b.u
|
||||||
|
end
|
||||||
|
|
||||||
|
local mid = pt.index
|
||||||
|
local forward = mid + 1
|
||||||
|
local backward = mid - 1
|
||||||
|
while forward <= #p or backward > 0 do
|
||||||
|
if forward <= #p then
|
||||||
|
local b = p[forward]
|
||||||
|
if blockReady(b) then
|
||||||
|
getMoves(b, forward)
|
||||||
|
if moves <= threshold then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if moves < maxDistance and math.abs(b.z - pt.z) > moves and pt.index > 0 then
|
||||||
|
forward = #p
|
||||||
|
end
|
||||||
|
end
|
||||||
|
forward = forward + 1
|
||||||
|
end
|
||||||
|
if backward > 0 then
|
||||||
|
local b = p[backward]
|
||||||
|
if blockReady(b) then
|
||||||
|
getMoves(b, backward)
|
||||||
|
if moves <= threshold then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if moves < maxDistance and math.abs(pt.z - b.z) > moves then
|
||||||
|
backward = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
backward = backward - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
pt.x = block.x
|
||||||
|
pt.z = block.z
|
||||||
|
pt.y = block.y
|
||||||
|
pt.heading = heading
|
||||||
|
pt.index = key
|
||||||
|
block.u = true
|
||||||
|
return block
|
||||||
|
end
|
||||||
|
|
||||||
|
local throttle = Util.throttle()
|
||||||
|
local t = { }
|
||||||
|
ptb.index = 0
|
||||||
|
local threshold = 0
|
||||||
|
for i = 1, #plane do
|
||||||
|
local b = getNearestNeighbor(plane, ptb, threshold)
|
||||||
|
table.insert(t, b)
|
||||||
|
throttle()
|
||||||
|
threshold = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
local function clear()
|
||||||
|
|
||||||
|
local pt = Util.shallowCopy(data.startPt)
|
||||||
|
pt.y = math.min(data.startPt.y, data.endPt.y)
|
||||||
|
pt.heading = 0
|
||||||
|
|
||||||
|
local osy = pt.y
|
||||||
|
local sy = osy + 1
|
||||||
|
local ey = math.max(data.startPt.y, data.endPt.y)
|
||||||
|
local firstPlane = true
|
||||||
|
|
||||||
|
resupply()
|
||||||
|
|
||||||
|
while true do
|
||||||
|
|
||||||
|
if sy > ey then
|
||||||
|
sy = ey
|
||||||
|
end
|
||||||
|
|
||||||
|
local plane = makePlane(sy)
|
||||||
|
plane = optimizeRoute(plane, pt)
|
||||||
|
|
||||||
|
if firstPlane then
|
||||||
|
turtle.pathfind(plane[1])
|
||||||
|
turtle.setPolicy(turtle.policies.digAttack)
|
||||||
|
firstPlane = false
|
||||||
|
end
|
||||||
|
|
||||||
|
for _,b in ipairs(plane) do
|
||||||
|
turtle.gotoPoint(b)
|
||||||
|
if sy < ey then
|
||||||
|
turtle.digUp()
|
||||||
|
end
|
||||||
|
if sy > osy then
|
||||||
|
turtle.digDown()
|
||||||
|
end
|
||||||
|
if turtle.abort then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if turtle.abort then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if sy + 1 >= ey then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
sy = sy + 3
|
||||||
|
end
|
||||||
|
turtle.setPolicy(turtle.policies.none)
|
||||||
|
resupply()
|
||||||
|
end
|
||||||
|
|
||||||
|
turtle.run(function()
|
||||||
|
turtle.status = 'Clearing'
|
||||||
|
|
||||||
|
if turtle.enableGPS() then
|
||||||
|
|
||||||
|
local pt = Util.shallowCopy(turtle.point)
|
||||||
|
local s, m = pcall(clear)
|
||||||
|
pathTo(pt)
|
||||||
|
|
||||||
|
if not s and m then
|
||||||
|
error(m)
|
||||||
|
read()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
]]
|
||||||
|
|
||||||
|
local data = Util.readTable('/usr/config/shapes') or { }
|
||||||
|
|
||||||
|
local page = UI.Page {
|
||||||
|
titleBar = UI.TitleBar { title = 'Shapes' },
|
||||||
|
info = UI.Window { x = 5, y = 3, height = 1 },
|
||||||
|
startCoord = UI.Button { x = 2, y = 6, text = 'Start ', event = 'startCoord' },
|
||||||
|
endCoord = UI.Button { x = 2, y = 8, text = 'End ', event = 'endCoord' },
|
||||||
|
supplies = UI.Button { x = 2, y = 10, text = 'Supplies', event = 'supplies' },
|
||||||
|
cancel = UI.Button { rx = 2, ry = -2, text = 'Abort', event = 'cancel' },
|
||||||
|
begin = UI.Button { rx = -7, ry = -2, text = 'Begin', event = 'begin' },
|
||||||
|
accelerators = { q = 'quit' },
|
||||||
|
notification = UI.Notification(),
|
||||||
|
statusBar = UI.StatusBar(),
|
||||||
|
}
|
||||||
|
|
||||||
|
function page.info:draw()
|
||||||
|
|
||||||
|
local function size(a, b)
|
||||||
|
return (math.abs(a.x - b.x) + 1) *
|
||||||
|
(math.abs(a.y - b.y) + 1) *
|
||||||
|
(math.abs(a.z - b.z) + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:clear()
|
||||||
|
if not data.startPt then
|
||||||
|
self:write(1, 1, 'Set starting corner')
|
||||||
|
elseif not data.endPt then
|
||||||
|
self:write(1, 1, 'Set ending corner')
|
||||||
|
else
|
||||||
|
self:write(1, 1, 'Blocks: ' .. size(data.startPt, data.endPt))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function page:getPoint()
|
||||||
|
local pt = GPS.getPoint()
|
||||||
|
if not pt then
|
||||||
|
self.notification:error('GPS not available')
|
||||||
|
end
|
||||||
|
return pt
|
||||||
|
end
|
||||||
|
|
||||||
|
function page:runFunction(id, script)
|
||||||
|
|
||||||
|
self.notification:info('Connecting')
|
||||||
|
local fn, msg = loadstring(script, 'script')
|
||||||
|
if not fn then
|
||||||
|
self.notification:error('Error in script')
|
||||||
|
debug(msg)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local socket = Socket.connect(id, 161)
|
||||||
|
if not socket then
|
||||||
|
self.notification:error('Unable to connect')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
socket:write({ type = 'script', args = script })
|
||||||
|
socket:close()
|
||||||
|
|
||||||
|
self.notification:success('Sent')
|
||||||
|
end
|
||||||
|
|
||||||
|
function page:eventHandler(event)
|
||||||
|
if event.type == 'startCoord' then
|
||||||
|
data.startPt = self:getPoint()
|
||||||
|
if data.startPt then
|
||||||
|
self.statusBar:setStatus('starting corner set')
|
||||||
|
Util.writeTable('/usr/config/shapes', data)
|
||||||
|
end
|
||||||
|
self:draw()
|
||||||
|
elseif event.type == 'endCoord' then
|
||||||
|
data.endPt = self:getPoint()
|
||||||
|
if data.endPt then
|
||||||
|
self.statusBar:setStatus('ending corner set')
|
||||||
|
Util.writeTable('/usr/config/shapes', data)
|
||||||
|
end
|
||||||
|
self:draw()
|
||||||
|
elseif event.type == 'supplies' then
|
||||||
|
data.suppliesPt = self:getPoint()
|
||||||
|
if data.suppliesPt then
|
||||||
|
self.statusBar:setStatus('supplies location set')
|
||||||
|
Util.writeTable('/usr/config/shapes', data)
|
||||||
|
end
|
||||||
|
elseif event.type == 'begin' then
|
||||||
|
if data.startPt and data.endPt then
|
||||||
|
local s = 'local data = ' .. textutils.serialize(data) .. script
|
||||||
|
self:runFunction(turtleId, s)
|
||||||
|
else
|
||||||
|
self.notification:error('Corners not set')
|
||||||
|
end
|
||||||
|
self.statusBar:setStatus('')
|
||||||
|
elseif event.type == 'cancel' then
|
||||||
|
self:runFunction(turtleId, 'turtle.abortAction()')
|
||||||
|
self.statusBar:setStatus('')
|
||||||
|
else
|
||||||
|
return UI.Page.eventHandler(self, event)
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
UI:setPage(page)
|
||||||
|
|
||||||
|
UI:pullEvents()
|
||||||
|
UI.term:reset()
|
@ -4,10 +4,14 @@ local Event = require('event')
|
|||||||
local UI = require('ui')
|
local UI = require('ui')
|
||||||
local RefinedProvider = require('refinedProvider')
|
local RefinedProvider = require('refinedProvider')
|
||||||
local MEProvider = require('meProvider')
|
local MEProvider = require('meProvider')
|
||||||
|
local ChestProvider = require('chestProvider18')
|
||||||
|
|
||||||
local storage = RefinedProvider()
|
local storage = RefinedProvider()
|
||||||
if not storage:isValid() then
|
if not storage:isValid() then
|
||||||
storage = MEProvider()
|
storage = MEProvider()
|
||||||
|
if not storage:isValid() then
|
||||||
|
storage = ChestProvider()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not storage:isValid() then
|
if not storage:isValid() then
|
||||||
@ -106,7 +110,7 @@ local function uniqueKey(item)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function changedPage:refresh()
|
function changedPage:refresh()
|
||||||
local t = storage:listItems('all')
|
local t = storage:listItems()
|
||||||
|
|
||||||
if not t or Util.empty(t) then
|
if not t or Util.empty(t) then
|
||||||
self:clear()
|
self:clear()
|
||||||
|
@ -31,6 +31,7 @@ Logger.filter('modem_send', 'event', 'ui')
|
|||||||
Logger.setWirelessLogging()
|
Logger.setWirelessLogging()
|
||||||
|
|
||||||
local __BUILDER_ID = 6
|
local __BUILDER_ID = 6
|
||||||
|
local itemInfoDB
|
||||||
|
|
||||||
local Builder = {
|
local Builder = {
|
||||||
version = '1.70',
|
version = '1.70',
|
||||||
@ -116,7 +117,7 @@ function Builder:refuel()
|
|||||||
self.itemProvider:provide(self.fuelItem, 64, 1)
|
self.itemProvider:provide(self.fuelItem, 64, 1)
|
||||||
if turtle.getItemCount(1) == 0 then
|
if turtle.getItemCount(1) == 0 then
|
||||||
Builder:log('Out of fuel, add coal to chest/ME system')
|
Builder:log('Out of fuel, add coal to chest/ME system')
|
||||||
turtle.setHeading(0)
|
--turtle.setHeading(0)
|
||||||
os.sleep(5)
|
os.sleep(5)
|
||||||
else
|
else
|
||||||
turtle.refuel(64)
|
turtle.refuel(64)
|
||||||
@ -160,6 +161,11 @@ function Builder:getSupplies()
|
|||||||
if s.qty < s.need then
|
if s.qty < s.need then
|
||||||
table.insert(t, s)
|
table.insert(t, s)
|
||||||
local name = s.name or s.id .. ':' .. s.dmg
|
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)
|
Builder:log('Need %d %s', s.need - s.qty, name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -400,6 +406,12 @@ __BUILDER_ID = tonumber(args[1])
|
|||||||
|
|
||||||
maxStackDB:load()
|
maxStackDB:load()
|
||||||
|
|
||||||
|
itemInfoDB = TableDB({
|
||||||
|
fileName = 'items.db'
|
||||||
|
})
|
||||||
|
|
||||||
|
itemInfoDB:load()
|
||||||
|
|
||||||
Builder.itemProvider = MEProvider({ direction = args[2] })
|
Builder.itemProvider = MEProvider({ direction = args[2] })
|
||||||
if not Builder.itemProvider:isValid() then
|
if not Builder.itemProvider:isValid() then
|
||||||
local sides = {
|
local sides = {
|
||||||
|
@ -45,6 +45,7 @@ Leaves (Spruce),18:1,,Solid Block
|
|||||||
Leaves (Birch),18:2,,Solid Block
|
Leaves (Birch),18:2,,Solid Block
|
||||||
Leaves (Jungle),18:3,,Solid Block
|
Leaves (Jungle),18:3,,Solid Block
|
||||||
Sponge,19,minecraft:sponge,Solid Block
|
Sponge,19,minecraft:sponge,Solid Block
|
||||||
|
Wet Sponge,19:1,minecraft:sponge,Solid Block
|
||||||
Glass,20,minecraft:glass,Solid Block
|
Glass,20,minecraft:glass,Solid Block
|
||||||
Lapis Lazuli Ore,21,minecraft:lapis_ore,Solid Block
|
Lapis Lazuli Ore,21,minecraft:lapis_ore,Solid Block
|
||||||
Lapis Lazuli Block,22,minecraft:lapis_block,Solid Block
|
Lapis Lazuli Block,22,minecraft:lapis_block,Solid Block
|
||||||
|
|
1775
sys/etc/blocks.json
Normal file
1775
sys/etc/blocks.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -72,10 +72,10 @@ function turtle.run(fn, ...)
|
|||||||
local s, m = pcall(function() fn(unpack(args)) end)
|
local s, m = pcall(function() fn(unpack(args)) end)
|
||||||
turtle.abort = false
|
turtle.abort = false
|
||||||
releaseTicket(ticketId)
|
releaseTicket(ticketId)
|
||||||
|
os.queueEvent('turtle_response')
|
||||||
if not s and m then
|
if not s and m then
|
||||||
printError(m)
|
printError(m)
|
||||||
end
|
end
|
||||||
os.queueEvent('turtle_response')
|
|
||||||
return s, m
|
return s, m
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -30,6 +30,6 @@ end
|
|||||||
function turtle.setGPSHome()
|
function turtle.setGPSHome()
|
||||||
if turtle.enableGPS() then
|
if turtle.enableGPS() then
|
||||||
turtle.storeLocation('gpsHome', turtle.point)
|
turtle.storeLocation('gpsHome', turtle.point)
|
||||||
turtle.gotoPoint(tturtle.point)
|
turtle.gotoPoint(turtle.point)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -19,6 +19,8 @@ Event.addHandler('peripheral', function(event, side)
|
|||||||
term.setTextColor(attachColor)
|
term.setTextColor(attachColor)
|
||||||
Util.print('[%s] %s attached', dev.side, dev.name)
|
Util.print('[%s] %s attached', dev.side, dev.name)
|
||||||
os.queueEvent('device_attach', dev.name)
|
os.queueEvent('device_attach', dev.name)
|
||||||
|
else
|
||||||
|
Util.print('[%s] attached failed', side)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user