Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- vos.loadApi('ui.api')
- vos.loadApi('tl2.api')
- vos.loadApi('schematic.api')
- vos.loadApi('profile.api')
- vos.loadApi('tableDB.api')
- Logger.disable()
- if Peripheral.isPresent('wireless_modem') then
- Logger.filter('rednet_message', 'event', 'ui')
- Message.enableWirelessLogging()
- end
- schematic = Schematic()
- Builder = {
- version = '0.05',
- ccVersion = nil,
- slots = { },
- index = 1,
- mode = 'build',
- fuelItem = { id = 263, dmg = 0 },
- resourceSlots = 15,
- }
- --[[-- blockDB --]]--
- blockDB = TableDB({
- fileName = 'block.db',
- tabledef = {
- autokeys = false,
- columns = {
- { name = 'key', type = 'key', length = 8 },
- { name = 'id', type = 'number', length = 5 },
- { name = 'dmg', type = 'number', length = 2 },
- { name = 'name', type = 'string', length = 35 },
- { name = 'refname', type = 'string', length = 35 },
- }
- }
- })
- function blockDB:load(sbDB, btDB)
- if fs.exists(self.fileName) then
- TableDB.load(self)
- else
- self:seedDB()
- end
- end
- function blockDB:seedDB()
- self:add(9, 0, 'Stationary Water')
- self:add(18, 0, 'Oak Leaves')
- self:add(18, 1, 'Spruce Leaves')
- self:add(18, 2, 'Birch Leaves')
- self:add(18, 3, 'Jungle Leaves')
- self:add(26, 0, 'Bed Block')
- self:add(27, 0, 'Powered Rail')
- self:add(28, 0, 'Detector Rail')
- self:add(29, 0, 'Sticky Piston')
- self:add(30, 0, 'Web')
- self:add(31, 0, 'Dead Shrub')
- self:add(31, 1, 'Grass')
- self:add(31, 2, 'Fern')
- self:add(32, 0, 'Dead Shrub')
- self:add(33, 0, 'Piston')
- self:add(34, 0, 'Piston Head')
- self:add(35, 0, 'White Wool')
- self:add(35, 1, 'Orange Wool')
- self:add(35, 2, 'Magenta Wool')
- self:add(35, 3, 'Light Blue Wool')
- self:add(35, 4, 'Yellow Wool')
- self:add(35, 5, 'Lime Wool')
- self:add(35, 6, 'Pink Wool')
- self:add(35, 7, 'Gray Wool')
- self:add(35, 8, 'Light Gray Wool')
- self:add(35, 9, 'Cyan Wool')
- self:add(35, 10, 'Purple Wool')
- self:add(35, 11, 'Blue Wool')
- self:add(35, 12, 'Brown Wool')
- self:add(35, 13, 'Green Wool')
- self:add(35, 14, 'Red Wool')
- self:add(35, 15, 'Black Wool')
- self:add(37, 0, 'Dandelion')
- self:add(38, 0, 'Poppy')
- self:add(38, 1, 'Blue Orchid')
- self:add(38, 2, 'Allium')
- self:add(38, 3, 'Azure Bluet')
- self:add(38, 4, 'Red Tulip')
- self:add(38, 5, 'Orange Tulip')
- self:add(38, 6, 'White Tulip')
- self:add(38, 7, 'Pink Tulip')
- self:add(38, 8, 'Oxeye Daisy')
- self:add(43, 0, 'Double Stone Slab')
- self:add(43, 1, 'Double Sandstone Slab')
- self:add(43, 2, 'Double Wooden Slab')
- self:add(43, 3, 'Double Cobblestone Slab')
- self:add(43, 4, 'Double Brick Slab')
- self:add(43, 5, 'Double Stone Brick Slab')
- self:add(43, 6, 'Double Nether Brick Slab')
- self:add(43, 7, 'Double Quartz Slab')
- self:add(51, 0, 'Fire')
- self:add(55, 0, 'Redstone Wire')
- self:add(62, 0, 'Burning Furnace')
- self:add(63, 0, 'Sign Post')
- self:add(64, 0, 'Wooden Door Block')
- self:add(68, 0, 'Wall Sign')
- self:add(71, 0, 'Iron Door Block')
- self:add(75, 0, 'Redstone Torch')
- self:add(76, 0, 'Redstone Torch (on)')
- self:add(83, 0, 'Sugar Cane')
- self:add(95, 0, 'White Stained Glass')
- self:add(95, 1, 'Orange Stained Glass')
- self:add(95, 2, 'Magenta Stained Glass')
- self:add(95, 3, 'Light Blue Stained Glass')
- self:add(95, 4, 'Yellow Stained Glass')
- self:add(95, 5, 'Lime Stained Glass')
- self:add(95, 6, 'Pink Stained Glass')
- self:add(95, 7, 'Gray Stained Glass')
- self:add(95, 8, 'Light Gray Stained Glass')
- self:add(95, 9, 'Cyan Stained Glass')
- self:add(95, 10, 'Purple Stained Glass')
- self:add(95, 11, 'Blue Stained Glass')
- self:add(95, 12, 'Brown Stained Glass')
- self:add(95, 13, 'Green Stained Glass')
- self:add(95, 14, 'Red Stained Glass')
- self:add(95, 15, 'Black Stained Glass')
- self:add(96, 0, 'Trapdoor')
- self:add(117, 0, 'Brewing Stand')
- self:add(118, 0, 'Cauldron')
- self:add(124, 0, 'Redstone Lamp (active)')
- self:add(125, 0, 'Double Oak Wood Slab')
- self:add(125, 1, 'Double Spruce Wood Slab')
- self:add(125, 2, 'Double Birch Wood Slab')
- self:add(125, 3, 'Double Jungle Wood Slab')
- self:add(125, 4, 'Double Acacia Wood Slab')
- self:add(125, 5, 'Double Dark Oak Wood Slab')
- self:add(126, 4, 'Acacia Wood Slab')
- self:add(126, 5, 'Dark Oak Wood Slab')
- self:add(130, 0, 'Ender Chest')
- self:add(140, 0, 'Flower Pot')
- self:add(144, 0, 'Mob Head')
- self:add(160, 0, 'White Stained Glass Pane')
- self:add(160, 1, 'Orange Stained Glass Pane')
- self:add(160, 2, 'Magenta Stained Glass Pane')
- self:add(160, 3, 'Light Blue Stained Glass Pane')
- self:add(160, 4, 'Yellow Stained Glass Pane')
- self:add(160, 5, 'Lime Stained Glass Pane')
- self:add(160, 6, 'Pink Stained Glass Pane')
- self:add(160, 7, 'Gray Stained Glass Pane')
- self:add(160, 8, 'Light Gray Stained Glass Pane')
- self:add(160, 9, 'Cyan Stained Glass Pane')
- self:add(160, 10, 'Purple Stained Glass Pane')
- self:add(160, 11, 'Blue Stained Glass Pane')
- self:add(160, 12, 'Brown Stained Glass Pane')
- self:add(160, 13, 'Green Stained Glass Pane')
- self:add(160, 14, 'Red Stained Glass Pane')
- self:add(160, 15, 'Black Stained Glass Pane')
- self:add(161, 0, 'Acacia Leaves')
- self:add(161, 1, 'Dark Oak Leaves')
- self:add(162, 0, 'Acacia Wood')
- self:add(162, 1, 'Dark Oak Wood')
- self:add(163, 0, 'Acacia Wood Stairs')
- self:add(164, 0, 'Dark Oak Wood Stairs')
- self:add(165, 0, 'Slime Block')
- self:add(167, 0, 'Iron Trapdoor')
- self:add(170, 0, 'Hay Bale')
- self:add(171, 0, 'White Carpet')
- self:add(171, 1, 'Orange Carpet')
- self:add(171, 2, 'Magenta Carpet')
- self:add(171, 3, 'Light Blue Carpet')
- self:add(171, 4, 'Yellow Carpet')
- self:add(171, 5, 'Lime Carpet')
- self:add(171, 6, 'Pink Carpet')
- self:add(171, 7, 'Gray Carpet')
- self:add(171, 8, 'Light Gray Carpet')
- self:add(171, 9, 'Cyan Carpet')
- self:add(171, 10, 'Purple Carpet')
- self:add(171, 11, 'Blue Carpet')
- self:add(171, 12, 'Brown Carpet')
- self:add(171, 13, 'Green Carpet')
- self:add(171, 14, 'Red Carpet')
- self:add(171, 15, 'Black Carpet')
- self:add(175, 0, 'Sunflower')
- self:add(175, 1, 'Lilac')
- self:add(175, 2, 'Double Tallgrass')
- self:add(175, 3, 'Large Fern')
- self:add(175, 4, 'Rose Bush')
- self:add(175, 5, 'Peony')
- self.dirty = true
- self:flush()
- end
- function blockDB:lookup(id, dmg)
- if not id or not dmg then error('blockDB:lookup: nil passed', 2) end
- local key = id .. ':' .. dmg
- return self.data[key]
- end
- function blockDB:lookupName(id, dmg)
- if not id or not dmg then error('blockDB:lookupName: nil passed', 2) end
- local key = id .. ':' .. dmg
- local block = self.data[key]
- if block then
- return block.name
- end
- end
- function blockDB:add(id, dmg, name)
- local key = id .. ':' .. dmg
- TableDB.add(self, key, {
- id = id,
- dmg = dmg,
- key = key,
- name = name
- })
- end
- --[[-- SubDBClass --]]--
- SubDBClass = class.class(TableDB)
- function SubDBClass:lookup(id, dmg)
- if not id or not dmg then error('SubDBClass:lookup: nil passed', 2) end
- local key = id .. ':' .. dmg
- return self.data[key]
- end
- function SubDBClass:remove(id, dmg)
- local key = id .. ':' .. dmg
- self.data[key] = nil
- self.dirty = true
- end
- function SubDBClass:lookupReference(refid, refdmg)
- for k,v in pairs(self.data) do
- if v.refid == refid and v.refdmg == refdmg then
- return v
- end
- end
- end
- function SubDBClass:lookupBlocksForSub(sid, sdmg)
- local t = { }
- for k,v in pairs(self.data) do
- if v.sid == sid and v.sdmg == sdmg then
- t[k] = v
- end
- end
- return t
- end
- function SubDBClass:lookupSubsForBlock(refid, refdmg)
- local t = { }
- for k,v in pairs(self.data) do
- if v.refid == refid and v.refdmg == refdmg then
- t[k] = v
- end
- end
- return t
- end
- function SubDBClass:getRealBlock(id, dmg)
- local sub = self:lookup(id, dmg)
- if sub then
- return { id = sub.sid, dmg = sub.sdmg, direction = sub.direction }
- end
- local b = blockDB:lookup(id, dmg)
- if b then
- return b
- end
- return { id = id, dmg = dmg }
- end
- function SubDBClass:addSubsForBlockType(id, dmg, bt)
- for _,sub in pairs(bt) do
- local odmg = sub.odmg
- if type(sub.odmg) == 'string' then
- odmg = dmg + tonumber(string.match(odmg, '+(%d+)'))
- end
- self:add(
- id,
- odmg,
- sub.sid or id,
- sub.sdmg or dmg,
- id,
- dmg,
- sub.dir)
- end
- end
- function SubDBClass:add(id, dmg, sid, sdmg, refid, refdmg, direction)
- if not id or not dmg then error('SubDBClass:add: nil passed', 2) end
- local key = id .. ':' .. dmg
- if direction and #direction == 0 then
- direction = nil
- end
- self.data[key] = {
- id = id,
- dmg = dmg,
- key = key,
- sid = sid,
- sdmg = sdmg,
- skey = sid .. ':' .. sdmg,
- refid = refid,
- refdmg = refdmg,
- direction = direction
- }
- self.dirty = true
- end
- --[[-- SubDB --]]--
- subDB = SubDBClass({
- fileName = '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 = 'key', type = 'string', length = 8 },
- { name = 'sid', type = 'number', length = 5 },
- { name = 'sdmg', type = 'number', length = 2 },
- { name = 'skey', type = 'string', length = 8 },
- { name = 'refid', type = 'number', length = 5 },
- { name = 'refdmg', type = 'number', length = 2 },
- { name = 'direction', type = 'string', length = 20 },
- }
- }
- })
- function subDB:load(sbDB, btDB)
- if fs.exists(self.fileName) then
- SubDBClass.load(self)
- else
- self:seedDB(sbDB, btDB)
- end
- end
- function subDB:seedDB(sbDB, btDB)
- for k,blockType in pairs(sbDB.data) do
- local bt = btDB.data[blockType]
- if not bt then
- error('missing block type: ' .. blockType)
- end
- local id, dmg = string.match(k, '(%d+):*(%d+)')
- self:addSubsForBlockType(tonumber(id), tonumber(dmg), bt)
- end
- self.dirty = true
- self:flush()
- end
- --[[-- StandardBlockDB --]]--
- standardBlockDB = TableDB({
- fileName = 'standard.db',
- tabledef = {
- autokeys = false,
- type = 'simple',
- columns = {
- { label = 'Key', type = 'key', length = 8 },
- { label = 'Block Type', type = 'string', length = 20 }
- }
- }
- })
- function standardBlockDB:load()
- if fs.exists(self.fileName) then
- TableDB.load(self)
- else
- self:seedDB()
- end
- end
- function standardBlockDB:seedDB()
- self.data = {
- [ '6:0' ] = 'sapling',
- [ '6:1' ] = 'sapling',
- [ '6:2' ] = 'sapling',
- [ '6:3' ] = 'sapling',
- [ '6:4' ] = 'sapling',
- [ '6:5' ] = 'sapling',
- [ '8:0' ] = 'truncate',
- [ '9:0' ] = 'truncate',
- [ '17:0' ] = 'wood',
- [ '17:1' ] = 'wood',
- [ '17:2' ] = 'wood',
- [ '17:3' ] = 'wood',
- [ '18:0' ] = 'leaves',
- [ '18:1' ] = 'leaves',
- [ '18:2' ] = 'leaves',
- [ '18:3' ] = 'leaves',
- [ '23:0' ] = 'dispenser',
- [ '26:0' ] = 'bed',
- [ '29:0' ] = 'piston',
- [ '33:0' ] = 'piston',
- [ '34:0' ] = 'air',
- [ '36:0' ] = 'air',
- [ '44:0' ] = 'slab',
- [ '44:1' ] = 'slab',
- [ '44:2' ] = 'slab',
- [ '44:3' ] = 'slab',
- [ '44:4' ] = 'slab',
- [ '44:5' ] = 'slab',
- [ '44:6' ] = 'slab',
- [ '44:7' ] = 'slab',
- [ '50:0' ] = 'torch',
- [ '51:0' ] = 'flatten',
- [ '53:0' ] = 'stairs',
- [ '54:0' ] = 'chest-furnace',
- [ '55:0' ] = 'flatten',
- [ '61:0' ] = 'chest-furnace',
- [ '62:0' ] = 'chest-furnace',
- [ '63:0' ] = 'signpost',
- [ '64:0' ] = 'door',
- [ '65:0' ] = 'wallsign-ladder',
- [ '66:0' ] = 'rail',
- [ '67:0' ] = 'stairs',
- [ '68:0' ] = 'wallsign-ladder',
- [ '69:0' ] = 'lever',
- [ '71:0' ] = 'door',
- [ '75:0' ] = 'torch',
- [ '76:0' ] = 'torch',
- [ '77:0' ] = 'button',
- [ '78:0' ] = 'flatten',
- [ '81:0' ] = 'flatten',
- [ '83:0' ] = 'flatten',
- [ '93:0' ] = 'repeater',
- [ '94:0' ] = 'repeater',
- [ '96:0' ] = 'trapdoor',
- [ '99:0' ] = 'flatten',
- [ '100:0' ] = 'flatten',
- [ '106:0' ] = 'vine',
- [ '107:0' ] = 'gate',
- [ '108:0' ] = 'stairs',
- [ '109:0' ] = 'stairs',
- [ '114:0' ] = 'stairs',
- [ '118:0' ] = 'cauldron',
- [ '126:0' ] = 'slab',
- [ '126:1' ] = 'slab',
- [ '126:2' ] = 'slab',
- [ '126:3' ] = 'slab',
- [ '126:4' ] = 'slab',
- [ '126:5' ] = 'slab',
- [ '128:0' ] = 'stairs',
- [ '130:0' ] = 'chest-furnace',
- [ '131:0' ] = 'tripwire',
- [ '134:0' ] = 'stairs',
- [ '135:0' ] = 'stairs',
- [ '136:0' ] = 'stairs',
- [ '140:0' ] = 'flatten',
- [ '141:0' ] = 'flatten',
- [ '142:0' ] = 'flatten',
- [ '143:0' ] = 'button',
- [ '144:0' ] = 'mobhead',
- [ '145:0' ] = 'anvil',
- [ '146:0' ] = 'chest-furnace',
- [ '151:0' ] = 'flatten',
- [ '154:0' ] = 'hopper',
- [ '155:2' ] = 'quartz-pillar',
- [ '156:0' ] = 'stairs',
- [ '158:0' ] = 'hopper',
- [ '161:0' ] = 'leaves',
- [ '161:1' ] = 'leaves',
- [ '162:0' ] = 'wood',
- [ '162:1' ] = 'wood',
- [ '163:0' ] = 'stairs',
- [ '164:0' ] = 'stairs',
- [ '167:0' ] = 'trapdoor',
- [ '170:0' ] = 'flatten',
- [ '175:0' ] = 'largeplant',
- [ '175:1' ] = 'largeplant',
- [ '175:2' ] = 'largeplant',
- [ '175:3' ] = 'largeplant',
- [ '175:4' ] = 'largeplant',
- [ '175:5' ] = 'largeplant',
- }
- self.dirty = true
- self:flush()
- end
- --[[-- BlockTypeDB --]]--
- blockTypeDB = TableDB({
- fileName = 'blocktype.db',
- tabledef = {
- autokeys = true,
- columns = {
- { name = 'odmg', type = 'number', length = 2 },
- { name = 'sid', type = 'number', length = 5 },
- { name = 'sdmg', type = 'number', length = 2 },
- { name = 'dir', type = 'string', length = 20 },
- }
- }
- })
- function blockTypeDB:load()
- if fs.exists(self.fileName) then
- TableDB.load(self)
- else
- self:seedDB()
- end
- end
- function blockTypeDB:addTemp(blockType, subs)
- local bt = self.data[blockType]
- if not bt then
- bt = { }
- self.data[blockType] = bt
- end
- for _,sub in pairs(subs) do
- table.insert(bt, {
- odmg = sub[1],
- sid = sub[2],
- sdmg = sub[3],
- dir = sub[4]
- })
- end
- self.dirty = true
- end
- function blockTypeDB:seedDB()
- blockTypeDB:addTemp('stairs', {
- { 0, nil, 0, 'east-up' },
- { 1, nil, 0, 'west-up' },
- { 2, nil, 0, 'south-up' },
- { 3, nil, 0, 'north-up' },
- { 4, nil, 0, 'east-down' },
- { 5, nil, 0, 'west-down' },
- { 6, nil, 0, 'south-down' },
- { 7, nil, 0, 'north-down' },
- })
- blockTypeDB:addTemp('gate', {
- { 0, nil, 0, 'north' },
- { 1, nil, 0, 'east' },
- { 2, nil, 0, 'north' },
- { 3, nil, 0, 'east' },
- { 4, nil, 0, 'north' },
- { 5, nil, 0, 'east' },
- { 6, nil, 0, 'north' },
- { 7, nil, 0, 'east' },
- })
- blockTypeDB:addTemp('anvil', {
- { 0, nil, 0, 'south' },
- { 1, nil, 0, 'east' },
- { 2, nil, 0 },
- { 3, nil, 0 },
- { 4, nil, 0 },
- { 5, nil, 0 },
- { 6, nil, 0 },
- { 7, nil, 0 },
- { 8, nil, 0 },
- { 9, nil, 0 },
- { 10, nil, 0 },
- { 11, nil, 0 },
- { 12, nil, 0 },
- { 13, nil, 0 },
- { 14, nil, 0 },
- { 15, nil, 0 },
- })
- blockTypeDB:addTemp('bed', {
- { 0, nil, 0, 'south' },
- { 1, nil, 0, 'west' },
- { 2, nil, 0, 'north' },
- { 3, nil, 0, 'east' },
- { 4, nil, 0, 'south' },
- { 5, nil, 0, 'west' },
- { 6, nil, 0, 'north' },
- { 7, nil, 0, 'east' },
- { 8, -1, 0 },
- { 9, -1, 0 },
- { 10, -1, 0 },
- { 11, -1, 0 },
- { 12, -1, 0 },
- { 13, -1, 0 },
- { 14, -1, 0 },
- { 15, -1, 0 },
- })
- blockTypeDB:addTemp('quartz-pillar', {
- { 2, nil, 2 },
- { 3, nil, 2, 'north-south-block' },
- { 4, nil, 2, 'east-west-block' }, -- should be east-west-block
- })
- blockTypeDB:addTemp('button', {
- { 1, nil, 0, 'west-block' },
- { 2, nil, 0, 'east-block' },
- { 3, nil, 0, 'north-block' },
- { 4, nil, 0, 'south-block' },
- })
- blockTypeDB:addTemp('cauldron', {
- { 0, nil, 0 },
- { 1, nil, 0 },
- { 2, nil, 0 },
- { 3, nil, 0 },
- })
- blockTypeDB:addTemp('dispenser', {
- { 0, nil, 0 },
- { 1, nil, 0 },
- { 2, nil, 0, 'south' },
- { 3, nil, 0, 'north' },
- { 4, nil, 0, 'east' },
- { 5, nil, 0, 'west' },
- { 9, nil, 0 },
- })
- blockTypeDB:addTemp('hopper', {
- { 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' },
- { 9, nil, 0 },
- { 10, nil, 0 },
- { 11, nil, 0, 'south-block' },
- { 12, nil, 0, 'north-block' },
- { 13, nil, 0, 'east-block' },
- { 14, nil, 0, 'west-block' },
- })
- blockTypeDB:addTemp('mobhead', {
- { 0, nil, 0 },
- { 1, nil, 0 },
- { 2, nil, 0, 'south-block' },
- { 3, nil, 0, 'north-block' },
- { 4, nil, 0, 'west-block' },
- { 5, nil, 0, 'east-block' },
- })
- blockTypeDB:addTemp('rail', {
- { 0, nil, 0, 'south' },
- { 1, nil, 0, 'east' },
- { 2, nil, 0, 'east' },
- { 3, nil, 0, 'east' },
- { 4, nil, 0, 'south' },
- { 5, nil, 0, 'south' },
- { 6, nil, 0, 'east' },
- { 7, nil, 0, 'south' },
- { 8, nil, 0, 'east' },
- { 9, nil, 0, 'south' },
- })
- blockTypeDB:addTemp('signpost', {
- { 0, nil, 0, 'south' },
- { 1, nil, 0, 'south' },
- { 2, nil, 0, 'south' },
- { 3, nil, 0, 'south' },
- { 4, nil, 0, 'west' },
- { 5, nil, 0, 'west' },
- { 6, nil, 0, 'west' },
- { 7, nil, 0, 'west' },
- { 8, nil, 0, 'north' },
- { 9, nil, 0, 'north' },
- { 10, nil, 0, 'north' },
- { 11, nil, 0, 'north' },
- { 12, nil, 0, 'east' },
- { 13, nil, 0, 'east' },
- { 14, nil, 0, 'east' },
- { 15, nil, 0, 'east' },
- })
- blockTypeDB:addTemp('vine', {
- { 0, nil, 0 },
- { 1, nil, 0, 'south-block' },
- { 2, nil, 0, 'west-block' },
- { 3, nil, 0, 'south-block' },
- { 4, nil, 0, 'north-block' },
- { 5, nil, 0, 'south-block' },
- { 6, nil, 0, 'north-block' },
- { 7, nil, 0, 'south-block' },
- { 8, nil, 0, 'east-block' },
- { 9, nil, 0, 'south-block' },
- { 10, nil, 0, 'east-block' },
- { 11, nil, 0, 'east-block' },
- { 12, nil, 0, 'east-block' },
- { 13, nil, 0, 'east-block' },
- { 14, nil, 0, 'east-block' },
- { 15, nil, 0, 'east-block' },
- })
- blockTypeDB:addTemp('torch', {
- { 0, nil, 0 },
- { 1, nil, 0, 'west-block' },
- { 2, nil, 0, 'east-block' },
- { 3, nil, 0, 'north-block' },
- { 4, nil, 0, 'south-block' },
- { 5, nil, 0 },
- })
- blockTypeDB:addTemp('tripwire', {
- { 0, nil, 0, 'north-block' },
- { 1, nil, 0, 'east-block' },
- { 2, nil, 0, 'south-block' },
- { 3, nil, 0, 'west-block' },
- })
- blockTypeDB:addTemp('trapdoor', {
- { 0, nil, 0, 'south-block' },
- { 1, nil, 0, 'north-block' },
- { 2, nil, 0, 'east-block' },
- { 3, nil, 0, 'west-block' },
- { 4, nil, 0, 'south-block' },
- { 5, nil, 0, 'north-block' },
- { 6, nil, 0, 'east-block' },
- { 7, nil, 0, 'west-block' },
- { 8, nil, 0, 'south-block' },
- { 9, nil, 0, 'north-block' },
- { 10, nil, 0, 'east-block' },
- { 11, nil, 0, 'west-block' },
- { 12, nil, 0, 'south-block' },
- { 13, nil, 0, 'north-block' },
- { 14, nil, 0, 'east-block' },
- { 15, nil, 0, 'west-block' },
- })
- blockTypeDB:addTemp('piston', {
- { 0, nil, 0, 'down' },
- { 1, nil, 0, 'up' },
- { 2, nil, 0, 'south' },
- { 3, nil, 0, 'north' },
- { 4, nil, 0, 'east' },
- { 5, nil, 0, 'west' },
- { 8, nil, 0, 'down' },
- { 9, nil, 0, 'up' },
- { 10, nil, 0, 'south' },
- { 11, nil, 0, 'north' },
- { 12, nil, 0, 'east' },
- { 13, nil, 0, 'west' },
- })
- blockTypeDB:addTemp('lever', {
- { 0, nil, 0, 'up' },
- { 1, nil, 0, 'west-block' },
- { 2, nil, 0, 'east-block' },
- { 3, nil, 0, 'north-block' },
- { 4, nil, 0, 'south-block' },
- { 5, nil, 0, 'north' },
- { 6, nil, 0, 'west' },
- { 7, nil, 0, 'up' },
- { 8, nil, 0, 'up' },
- { 9, nil, 0, 'west-block' },
- { 10, nil, 0, 'east-block' },
- { 11, nil, 0, 'north-block' },
- { 12, nil, 0, 'south-block' },
- { 13, nil, 0, 'north' },
- { 14, nil, 0, 'west' },
- { 15, nil, 0, 'up' },
- })
- blockTypeDB:addTemp('wallsign-ladder', {
- { 0, nil, 0 },
- { 2, nil, 0, 'south-block' },
- { 3, nil, 0, 'north-block' },
- { 4, nil, 0, 'east-block' },
- { 5, nil, 0, 'west-block' },
- })
- blockTypeDB:addTemp('chest-furnace', {
- { 0, nil, 0 },
- { 2, nil, 0, 'south' },
- { 3, nil, 0, 'north' },
- { 4, nil, 0, 'east' },
- { 5, nil, 0, 'west' },
- })
- blockTypeDB:addTemp('repeater', {
- { 0, nil, 0, 'north' },
- { 1, nil, 0, 'east' },
- { 2, nil, 0, 'south' },
- { 3, nil, 0, 'west' },
- { 4, nil, 0, 'north' },
- { 5, nil, 0, 'east' },
- { 6, nil, 0, 'south' },
- { 7, nil, 0, 'west' },
- { 8, nil, 0, 'north' },
- { 9, nil, 0, 'east' },
- { 10, nil, 0, 'south' },
- { 11, nil, 0, 'west' },
- { 12, nil, 0, 'north' },
- { 13, nil, 0, 'east' },
- { 14, nil, 0, 'south' },
- { 15, nil, 0, 'west' },
- })
- blockTypeDB:addTemp('flatten', {
- { 0, nil, 0 },
- { 1, nil, 0 },
- { 2, nil, 0 },
- { 3, nil, 0 },
- { 4, nil, 0 },
- { 5, nil, 0 },
- { 6, nil, 0 },
- { 7, nil, 0 },
- { 8, nil, 0 },
- { 9, nil, 0 },
- { 10, nil, 0 },
- { 11, nil, 0 },
- { 12, nil, 0 },
- { 13, nil, 0 },
- { 14, nil, 0 },
- { 15, nil, 0 },
- })
- blockTypeDB:addTemp('sapling', {
- { '+0', nil, nil },
- { '+8', nil, nil },
- })
- blockTypeDB:addTemp('leaves', {
- { '+0', nil, nil },
- { '+4', nil, nil },
- { '+8', nil, nil },
- { '+12', nil, nil },
- })
- blockTypeDB:addTemp('air', {
- { 0, -1, 0 },
- { 1, -1, 0 },
- { 2, -1, 0 },
- { 3, -1, 0 },
- { 4, -1, 0 },
- { 5, -1, 0 },
- { 6, -1, 0 },
- { 7, -1, 0 },
- { 8, -1, 0 },
- { 9, -1, 0 },
- { 10, -1, 0 },
- { 11, -1, 0 },
- { 12, -1, 0 },
- { 13, -1, 0 },
- { 14, -1, 0 },
- { 15, -1, 0 },
- })
- blockTypeDB:addTemp('truncate', {
- { 0, nil, 0 },
- { 1, -1, 0 },
- { 2, -1, 0 },
- { 3, -1, 0 },
- { 4, -1, 0 },
- { 5, -1, 0 },
- { 6, -1, 0 },
- { 7, -1, 0 },
- { 8, -1, 0 },
- { 9, -1, 0 },
- { 10, -1, 0 },
- { 11, -1, 0 },
- { 12, -1, 0 },
- { 13, -1, 0 },
- { 14, -1, 0 },
- { 15, -1, 0 },
- })
- blockTypeDB:addTemp('slab', {
- { '+0', nil, nil, 'bottom' },
- { '+8', nil, nil, 'top' },
- })
- blockTypeDB:addTemp('largeplant', {
- { '+0', nil, nil },
- { '+8', -1, 0 },
- })
- blockTypeDB:addTemp('wood', {
- { '+0', nil, nil },
- { '+4', nil, nil, 'east-west-block' },
- { '+8', nil, nil, 'north-south-block' },
- { '+12', nil, nil },
- })
- blockTypeDB:addTemp('door', {
- { 0, nil, 0, 'north-door' },
- { 1, nil, 0, 'west-door' },
- { 2, nil, 0, 'south-door' },
- { 3, nil, 0, 'east-door' },
- { 4, nil, 0, 'north-door' },
- { 5, nil, 0, 'west-door' },
- { 6, nil, 0, 'south-door' },
- { 7, nil, 0, 'east-door' },
- { 8, -1, 0 },
- { 9, -1, 0 },
- { 10, -1, 0 },
- { 11, -1, 0 },
- { 12, -1, 0 },
- { 13, -1, 0 },
- { 14, -1, 0 },
- { 15, -1, 0 },
- })
- self.dirty = true
- self:flush()
- end
- --[[-- maxStackDB --]]--
- maxStackDB = TableDB({
- fileName = 'maxstack.db',
- tabledef = {
- autokeys = false,
- type = 'simple',
- columns = {
- { label = 'Key', type = 'key', length = 8 },
- { label = 'Quantity', type = 'number', length = 2 }
- }
- }
- })
- function maxStackDB:get(id, dmg)
- return self.data[id .. ':' .. dmg] or 64
- end
- --[[-- Builder --]]--
- function Builder:getBlockCounts()
- local blocks = { }
- for k,b in pairs(schematic.blocks) do
- if k >= self.index then
- if b.id >= 0 then
- local key = tostring(b.id) .. ':' .. b.dmg
- local block = blocks[key]
- if not block then
- block ={
- id = b.id,
- dmg = b.dmg,
- need = 0,
- key = key,
- qty = 0
- }
- blocks[key] = block
- end
- blocks[key].need = blocks[key].need + 1
- end
- end
- end
- return blocks
- end
- function Builder:selectItem(id, dmg)
- for k,s in ipairs(self.slots) do
- if s.qty > 0 and s.id == id and s.dmg == dmg then
- -- check to see if someone pulled items from inventory
- -- or we passed over a hopper
- if turtle.getItemCount(s.index) > 0 then
- table.remove(self.slots, k)
- table.insert(self.slots, 1, s)
- turtle.select(s.index)
- return s
- end
- end
- end
- end
- function Builder:getSupplyList()
- for i = 1, self.resourceSlots do
- self.slots[i] = {
- qty = 0,
- need = 0,
- index = i
- }
- end
- local function getSlot(id, dmg)
- -- find matching slot
- local maxStack = maxStackDB:get(id, dmg)
- for _, s in ipairs(self.slots) do
- if s.id == id and s.dmg == dmg and s.need < maxStack then
- return s
- end
- end
- -- return first available slot
- for _, s in ipairs(self.slots) do
- if not s.id then
- s.key = id .. ':' .. dmg
- s.id = id
- s.dmg = dmg
- return s
- end
- end
- end
- for k = self.index, #schematic.blocks do
- local b = schematic.blocks[k]
- if b.id > 0 then
- local slot = getSlot(b.id, b.dmg)
- if not slot then
- break
- end
- slot.need = slot.need + 1
- end
- end
- for _,s in pairs(self.slots) do
- if s.id then
- s.name = blockDB:lookupName(s.id, s.dmg)
- end
- end
- end
- function Builder:substituteBlocks()
- local spinner = UI.Spinner({
- spinSymbols = { '' }
- })
- for _,b in pairs(schematic.blocks) do
- -- replace schematic block type with substitution
- if b.id ~= 0 then
- local sub = subDB:getRealBlock(b.id, b.dmg)
- b.id = sub.id
- b.dmg = sub.dmg
- b.direction = sub.direction
- end
- spinner:spin()
- end
- end
- function Builder:dumpInventory()
- for i = 1, self.resourceSlots do
- Builder.slots[i] = { id = 0, dmg = 0, qty = 0, index = i }
- local qty = turtle.getItemCount(i)
- if qty > 0 then
- self.itemProvider:insert(i, qty)
- end
- end
- turtle.select(1)
- end
- function Builder:autocraft(supplies)
- local t = { }
- for i,s in pairs(supplies) do
- local key = s.id .. ':' .. s.dmg
- local item = t[key]
- if not item then
- item = {
- id = s.id,
- dmg = s.dmg,
- qty = 0
- }
- t[key] = item
- end
- item.qty = item.qty + (s.need-s.qty)
- end
- for _,item in pairs(t) do
- Builder.itemProvider:craft(item.id, item.dmg, item.qty)
- end
- end
- function Builder:getSupplies()
- Builder.itemProvider:refresh()
- local t = { }
- for k,s in ipairs(self.slots) do
- if s.need > 0 then
- local item = Builder.itemProvider:getItemInfo(s.id, s.dmg)
- if item then
- if item.name then
- s.name = item.name
- end
- if s.qty ~= turtle.getItemCount(s.index) then
- print('wrong!')
- --s.qty = turtle.getItemCount(s.index)
- --Util.print(s)
- --read()
- --self:dumpInventory()
- TL2.reconcileSlots(self.slots, function(qty, slot)
- self.itemProvider:insert(slot.index, qty)
- end)
- else
- local qty = math.min(s.need-s.qty, item.qty)
- if qty + s.qty > item.maxSize then
- maxStackDB:add({ s.id, s.dmg }, item.maxSize)
- maxStackDB:flush()
- --[[
- Util.print(s)
- print(qty)
- print(item.maxSize)
- read()
- --]]
- qty = item.maxSize
- s.need = qty
- end
- if qty > 0 then
- turtle.select(s.index)
- local openSlot = TL2.selectOpenSlot()
- Logger.debug('requesting ' .. qty .. ' for slot ' .. s.index)
- self.itemProvider:provide(item, qty)
- if openSlot and openSlot ~= s.index then
- Logger.debug('transferring to ' .. s.index)
- turtle.transferTo(s.index)
- end
- s.qty = turtle.getItemCount(s.index)
- end
- end
- end
- end
- if s.qty < s.need then
- table.insert(t, s)
- local name = s.name or s.id .. ':' .. s.dmg
- Logger.log('builder', 'Need %d %s', s.need - s.qty, name)
- end
- end
- return t
- end
- Event.addHandler('build', function()
- Builder:build()
- end)
- function Builder:refuel()
- if turtle.getFuelLevel() < 4000 and self.fuelItem then
- Logger.log('builder', 'Refueling')
- turtle.select(1)
- self.itemProvider:provide(self.fuelItem, 64)
- turtle.refuel(64)
- end
- end
- function Builder:resupply()
- Logger.log('builder', 'Resupplying')
- TL2.gotoZlast(TL2.getLocation('supplies'))
- self:dumpInventory()
- self:refuel()
- self:getSupplyList()
- local supplies = self:getSupplies()
- if #supplies == 0 then
- os.queueEvent('build')
- else
- self:autocraft(supplies)
- Logger.log('builder', 'Waiting for supplies')
- supplyPage.grid:setTable(supplies)
- UI.pager:setPage('supply')
- end
- end
- function Builder:placeDown(slot)
- return TL2.placeDown(slot.index)
- end
- function Builder:place(slot)
- return TL2.place(slot.index)
- end
- function Builder:collectPiston(slot, tp)
- -- 1.6
- if self.ccVersion == 1.6 then
- return
- end
- if self.piston then
- if tp + 1 ~= self.piston.z then
- Logger.log('builder', 'Collecting piston')
- TL2.select(16)
- TL2.gotoZ(self.piston.z)
- self:goto(self.piston.x, self.piston.y)
- TL2.select(slot.index)
- self.piston = nil
- end
- end
- end
- function Builder:placePiston(b)
- self:goto(b.x-1, b.z)
- TL2.headTowardsX(b.x)
- TL2.place(16)
- os.sleep(.1)
- turtle.select(15)
- turtle.place()
- os.sleep(.1)
- turtle.place()
- TL2.up()
- self:goto(b.x, b.z)
- rs.setOutput('bottom', true)
- os.sleep(.25)
- rs.setOutput('bottom', false)
- turtle.select(16)
- turtle.digDown()
- end
- function Builder:movePistonTo(b)
- if self.ccVersion == 1.6 then
- self:placePiston(b)
- return true
- end
- if not self.piston or self.piston.z ~= TL2.getState().pt.z then
- self.piston = nil
- if turtle.getItemCount(16) > 1 then
- print('Make this piston point down')
- TL2.place(16)
- else
- print('Place piston beside me pointing down')
- end
- repeat
- Logger.log('builder', 'Waiting for piston')
- print('Waiting for piston')
- print('Press enter to continue')
- read()
- for i = 1, 4 do
- if turtle.detect() then
- local hi = TL2.getHeadingInfo()
- self.piston = {
- x = TL2.getState().pt.x + hi.xd,
- y = TL2.getState().pt.y + hi.yd,
- z = TL2.getState().pt.z,
- }
- break
- end
- TL2.turnRight()
- end
- until self.piston
- end
- while turtle.getItemCount(16) == 0 do
- Logger.log('builder', 'Waiting for a piston in inventory')
- print('Put a piston in slot 16')
- print('Press enter to continue')
- read()
- end
- TL2.up()
- if b.x ~= self.piston.x then
- local inc = 1
- if b.x > self.piston.x then
- inc = -1
- end
- self:goto(self.piston.x + inc, self.piston.y)
- TL2.headTowardsX(self.piston.x + inc + inc)
- rs.setOutput('bottom', true)
- while math.abs(TL2.getState().pt.x - b.x) > 1 do
- TL2.placeDown(16)
- turtle.digDown()
- TL2.goback()
- end
- if b.z ~= self.piston.y then
- rs.setOutput('bottom', false)
- end
- TL2.goback()
- rs.setOutput('bottom', false)
- self.piston.x = TL2.getState().pt.x
- end
- if b.z ~= self.piston.y then
- local inc = 1
- if b.z > self.piston.y then
- inc = -1
- end
- self:goto(self.piston.x, self.piston.y + inc)
- TL2.headTowardsY(self.piston.y + inc + inc)
- rs.setOutput('bottom', true)
- while math.abs(TL2.getState().pt.y - b.z) > 1 do
- TL2.placeDown(16)
- turtle.digDown()
- TL2.goback()
- end
- TL2.goback()
- self.piston.y = TL2.getState().pt.y
- end
- rs.setOutput('bottom', true)
- self:goto(self.piston.x, self.piston.y)
- rs.setOutput('bottom', false)
- while not turtle.detectDown() do
- print('Place piston below me pointing down')
- Logger.log('builder', 'piston missing')
- print('Press enter to continue')
- read()
- rs.setOutput('bottom', true)
- os.sleep(.25)
- rs.setOutput('bottom', false)
- end
- return true
- end
- function Builder:goto(x, z, y, heading)
- if not TL2.goto(x, z, y, heading) then
- Logger.log('builder', 'stuck')
- print('stuck')
- print('Press enter to continue')
- read()
- end
- end
- function Builder:placeDirectionalBlock(b, slot)
- local d = b.direction
- local directions = {
- [ 'north' ] = 'north',
- [ 'south' ] = 'south',
- [ 'east' ] = 'east',
- [ 'west' ] = 'west',
- }
- if directions[d] then
- self:goto(b.x, b.z, b.y, TL2.namedHeadings[directions[d]].heading)
- b.placed = self:placeDown(slot)
- b.warnOnly = true
- end
- if d == 'top' then
- self:goto(b.x, b.z, b.y+1)
- if self:placeDown(slot) then
- b.placed = self:movePistonTo(b)
- end
- end
- local stairDirections = {
- [ 'north-down' ] = 'north',
- [ 'south-down' ] = 'south',
- [ 'east-down' ] = 'east',
- [ 'west-down' ] = 'west'
- }
- if stairDirections[d] then
- self:goto(b.x, b.z, b.y+1, TL2.namedHeadings[stairDirections[d]].heading)
- if self:placeDown(slot) then
- b.placed = self:movePistonTo(b)
- end
- end
- local pistonDirections = {
- [ 'east-west-block' ] = 'east',
- [ 'north-south-block' ] = 'south'
- }
- if pistonDirections[d] then
- local hi = TL2.getHeadingInfo(pistonDirections[d])
- self:goto(b.x - hi.xd, b.z - hi.yd, b.y, hi.heading)
- self:place(slot)
- if turtle.detectUp() then
- TL2.goback()
- end
- TL2.up()
- b.placed = self:movePistonTo(b)
- end
- local doorDirections = {
- [ 'east-door' ] = 'south',
- [ 'south-door' ] = 'west',
- [ 'west-door' ] = 'north',
- [ 'north-door' ] = 'east',
- }
- if doorDirections[d] then
- self:goto(b.x, b.z, b.y, TL2.namedHeadings[doorDirections[d]].heading)
- if TL2.goback() then
- if not turtle.detectDown() then
- if TL2.down() then
- if not turtle.detectDown() then
- if TL2.down() then
- b.placed = self:place(slot)
- TL2.up()
- end
- end
- TL2.up()
- end
- end
- end
- end
- local blockDirections = {
- [ 'north-block' ] = 'north',
- [ 'south-block' ] = 'south',
- [ 'east-block' ] = 'east',
- [ 'west-block' ] = 'west',
- }
- if blockDirections[d] then
- local hi = TL2.getHeadingInfo(blockDirections[d])
- self:goto(b.x - hi.xd, b.z - hi.yd, b.y-1, hi.heading)
- b.placed = self:place(slot)
- end
- return b.placed
- end
- function Builder:reloadSchematic()
- schematic:reload()
- self:substituteBlocks()
- end
- function Builder:logBlock(index, b)
- local bdir = ''
- if b.direction then
- bdir = b.direction
- end
- local logText = string.format('Block %d %d:%d (x:%d,z:%d:y:%d) %s',
- index, b.id, b.dmg, b.x, b.z, b.y, bdir)
- print(logText)
- Logger.log('builder', logText)
- if b.info then
- Logger.debug(b.info)
- end
- end
- function Builder:build()
- local direction = 1
- local last = #schematic.blocks
- local travelPlane = 0
- if self.mode == 'destroy' then
- direction = -1
- last = 1
- end
- UI.pager:setPage('blank')
- if self.mode == 'dryRun' then
- if self.index >= #schematic.blocks then
- UI.pager:setPage('start')
- return
- end
- self:resupply()
- for _,s in pairs(Builder.slots) do
- self.index = self.index + s.qty
- end
- return
- end
- for i = self.index, last, direction do
- self.index = i
- local b = schematic.blocks[i]
- if b.id > 0 then
- if self.mode == 'destroy' then
- self:logBlock(self.index, b)
- if b.y ~= TL2.getState().pt.z then
- TL2.gotoZ(b.y)
- end
- if not TL2.goto(b.x, b.z, b.y) then
- print('stuck')
- print('Press enter to continue')
- read()
- end
- turtle.digDown()
- if turtle.getItemCount(self.resourceSlots) > 0 then
- Logger.log('builder', 'Dropping off inventory')
- TL2.gotoLocation('supplies')
- Builder:dumpInventory()
- end
- else
- local slot = Builder:selectItem(b.id, b.dmg)
- if not slot then
- if travelPlane > TL2.getState().pt.z then
- TL2.gotoZ(travelPlane)
- end
- self:resupply()
- return
- end
- if b.y > travelPlane then
- travelPlane = b.y
- self:collectPiston(slot, travelPlane)
- end
- if travelPlane > TL2.getState().pt.z then
- TL2.gotoZ(travelPlane)
- end
- self:logBlock(self.index, b)
- if b.direction then
- self:placeDirectionalBlock(b, slot)
- else
- self:goto(b.x, b.z, b.y)
- b.placed = self:placeDown(slot)
- b.warnOnly = true
- end
- if b.misplaced then
- Logger.log('builder', 'Misplaced block - ' .. b.misplaced)
- print('Misplaced block - ' .. b.misplaced)
- --sleep(3)
- end
- if b.placed then
- slot.qty = slot.qty - 1
- else
- Logger.log('builder', 'failed to place block')
- print('failed to place block')
- if not b.warnOnly then
- print('Hit enter to continue')
- --read()
- end
- end
- end
- end
- Util.writeTable('/' .. schematic.filename .. '.progress', { index = self.index+1 })
- end
- TL2.gotoLocation('supplies')
- Builder:dumpInventory()
- for i = 1, 4 do
- TL2.turnRight()
- end
- Event.exitPullEvents()
- UI.term:reset()
- fs.delete(schematic.filename .. '.progress')
- Logger.log('builder', 'Finished')
- print('Finished')
- end
- --[[-- MEProvider --]]--
- MEProvider = class.class()
- function MEProvider:init(args)
- self.items = {}
- self.name = 'ME'
- self.canCraft = true
- end
- function MEProvider:isValid()
- local mep = peripheral.wrap('bottom')
- return mep and mep.getAvailableItems and mep.getAvailableItems()
- end
- function MEProvider:refresh()
- local mep = peripheral.wrap('bottom')
- if mep then
- self.items = mep.getAvailableItems()
- end
- return self.items
- end
- function MEProvider:getItemInfo(id, dmg)
- for key,item in pairs(self.items) do
- if item.id == id and item.dmg == dmg then
- return item
- end
- end
- end
- function MEProvider:craft(id, dmg, qty)
- local mep = peripheral.wrap('bottom')
- if mep then
- Logger.log('builder', 'requested crafting for: ' .. id .. ':' .. dmg .. ' qty: ' .. qty)
- mep.requestCrafting({
- id = id,
- dmg = dmg,
- qty = qty
- })
- end
- end
- function MEProvider:provide(item, qty)
- local mep = peripheral.wrap('bottom')
- if mep then
- local extractedQty = mep.extractItem({
- id = item.id,
- dmg = item.dmg,
- qty = qty
- }, 'up')
- if item.qty then
- item.qty = item.qty - extractedQty
- end
- end
- end
- function MEProvider:insert(slot, qty)
- local mep = peripheral.wrap('bottom')
- if mep then
- mep.insertItem(slot, qty, 'up')
- end
- end
- --[[-- ChestProvider --]]--
- ChestProvider = class.class()
- function ChestProvider:init(args)
- self.stacks = {}
- self.name = 'chest'
- self.canCraft = false
- end
- function ChestProvider:isValid()
- local chest = peripheral.wrap('bottom')
- return chest and chest.getAllStacks
- end
- function ChestProvider:refresh()
- local chest = peripheral.wrap('bottom')
- if chest then
- chest.condenseItems()
- self.stacks = chest.getAllStacks()
- local t = { }
- for _,s in ipairs(self.stacks) do
- local key = s.id .. ':' .. s.dmg
- if t[key] and t[key].qty < 64 then
- t[key].maxSize = t[key].qty
- else
- t[key] = {
- qty = s.qty
- }
- end
- end
- for _,s in ipairs(self.stacks) do
- local key = s.id .. ':' .. s.dmg
- if t[key].maxSize then
- s.maxSize = t[key].qty
- else
- s.maxSize = 64
- end
- end
- end
- return self.stacks
- end
- function ChestProvider:getItemInfo(id, dmg)
- local item = { id = id, dmg = dmg, qty = 0, maxSize = 64 }
- for _,stack in pairs(self.stacks) do
- if stack.id == id and stack.dmg == dmg then
- item.name = stack.name
- item.qty = item.qty + stack.qty
- item.maxSize = stack.maxSize
- end
- end
- return item
- end
- function ChestProvider:craft(id, dmg, qty)
- end
- function ChestProvider:provide(item, qty)
- local chest = peripheral.wrap('bottom')
- if chest then
- self.stacks = chest.getAllStacks()
- for key,stack in pairs(self.stacks) do
- if stack.id == item.id and stack.dmg == item.dmg then
- local amount = math.min(qty, stack.qty)
- chest.pushItem('up', key, amount)
- qty = qty - amount
- if qty <= 0 then
- break
- end
- end
- end
- end
- end
- function ChestProvider:insert(slot, qty)
- local chest = peripheral.wrap('bottom')
- if chest then
- turtle.select(slot)
- turtle.dropDown(qty)
- end
- end
- --[[-- blankPage --]]--
- blankPage = UI.Page()
- function blankPage:draw()
- self:reset()
- end
- --[[-- selectSubstitutionPage --]]--
- selectSubstitutionPage = UI.Page({
- titleBar = UI.TitleBar({
- title = 'Select a substitution',
- previousPage = 'listing'
- }),
- grid = UI.ScrollingGrid({
- columns = {
- { 'OID', 'okey', 8 },
- { 'Orig', 'oname', 10 },
- },
- sortColumn = 'odmg',
- height = UI.term.height-1,
- autospace = true,
- y = 2,
- }),
- })
- function selectSubstitutionPage:enable()
- self.grid:adjustWidth()
- self.grid:setIndex(1)
- end
- function selectSubstitutionPage:eventHandler(event)
- if event.type == 'grid_select' then
- substitutionPage.origId = event.selected.id
- substitutionPage.origDmg = event.selected.dmg
- UI.pager:setPage(substitutionPage)
- elseif event.type == 'key' and event.key == 'q' then
- UI.pager:setPreviousPage()
- else
- return UI.Page.eventHandler(self, event)
- end
- return true
- end
- --[[-- substitutionPage --]]--
- substitutionPage = UI.Page({
- backgroundColor = colors.gray,
- titleBar = UI.TitleBar({
- previousPage = true,
- title = 'Substitute a block'
- }),
- menuBar = UI.MenuBar({
- y = 2,
- buttons = {
- { text = 'Accept', event = 'accept', help = 'Accept' },
- { text = 'Revert', event = 'revert', help = 'Restore to original' },
- { text = 'Air', event = 'air', help = 'Air' },
- },
- }),
- inName = UI.Text({ y = 4, width = UI.term.width }),
- outName = UI.Text({ y = 5, width = UI.term.width }),
- grid = UI.ScrollingGrid({
- columns = {
- { 'Name', 'name', UI.term.width-18 },
- },
- sortColumn = 'name',
- autospace = true,
- height = UI.term.height-7,
- y = 7,
- }),
- statusBar = UI.StatusBar()
- })
- substitutionPage.menuBar:add({
- filterLabel = UI.Text({
- value = 'Search',
- x = UI.term.width-14,
- textColor = colors.black,
- }),
- filter = UI.TextEntry({
- x = UI.term.width-7,
- width = 7,
- })
- })
- function substitutionPage:draw()
- local inName = blockDB:lookupName(self.origId, self.origDmg) or 'Unknown'
- self.inName.value = ' Replace ' .. inName
- local outName = ''
- for _,sub in pairs(self.subdb.data) do
- if sub.sid >= 0 then
- outName = blockDB:lookupName(sub.sid, sub.sdmg) or 'Unknown'
- break
- end
- end
- self.outName.value = ' With ' .. outName
- self.grid:adjustWidth()
- UI.Page.draw(self)
- end
- function substitutionPage:enable()
- local id = self.origId
- local dmg = self.origDmg
- self.subdb = SubDBClass()
- local subs = subDB:lookupSubsForBlock(id, dmg)
- for _,sub in pairs(subs) do
- self.subdb:add(sub.id, sub.dmg, sub.sid, sub.sdmg, sub.refid, sub.refdmg, sub.direction)
- end
- self.allItems = Builder.itemProvider:refresh()
- self.grid.t = self.allItems
- for _,item in pairs(self.grid.t) do
- item.key = item.id .. ':' .. item.dmg
- item.lname = string.lower(item.name)
- end
- self.menuBar.filter.value = ''
- self.menuBar.filter.pos = 1
- end
- function substitutionPage:applySubstitute(id, dmg)
- self.newId = id
- self.newDmg = dmg
- if Util.empty(self.subdb.data) then
- self.subdb:add(self.origId, self.origDmg, id, dmg, self.origId, self.origDmg)
- else
- for _,sub in pairs(self.subdb.data) do
- if sub.sid >= 0 then
- sub.sid = id
- sub.sdmg = dmg
- sub.skey = id .. ':' .. dmg
- end
- end
- end
- end
- function substitutionPage:eventHandler(event)
- if event.type == 'grid_focus_row' then
- local s = string.format('ID: %d:%d Quantity: %d',
- event.selected.id,
- event.selected.dmg,
- event.selected.qty)
- self.statusBar:setStatus(s)
- elseif event.type == 'grid_select' then
- if not blockDB:lookupName(event.selected.id, event.selected.dmg) then
- blockDB:add(event.selected.id, event.selected.dmg, event.selected.name)
- blockDB:flush()
- end
- self:applySubstitute(event.selected.id, event.selected.dmg)
- self:draw()
- elseif event.type == 'text_change' then
- local text = event.text
- if #text == 0 then
- self.grid.t = self.allItems
- else
- self.grid.t = { }
- for _,item in pairs(self.allItems) do
- if string.find(item.lname, text) then
- table.insert(self.grid.t, item)
- end
- end
- end
- self.grid:adjustWidth()
- self.grid:setIndex(1)
- self.grid:draw()
- elseif event.type == 'accept' then
- self.statusBar:setStatus('Saving changes...')
- self.statusBar:draw()
- if Util.empty(self.subdb.data) then
- subDB:remove(self.origId, self.origDmg)
- else
- for _,sub in pairs(self.subdb.data) do
- subDB:add(sub.id, sub.dmg, sub.sid, sub.sdmg, sub.refid, sub.refdmg, sub.direction)
- end
- end
- subDB:flush()
- Builder:reloadSchematic()
- UI.pager:setPage('listing')
- elseif event.type == 'air' then
- if not blockDB:lookupName(0, 0) then
- blockDB:add(0, 0, 'Air')
- blockDB:flush()
- end
- self:applySubstitute(0, 0)
- self:draw()
- elseif event.type == 'revert' then
- self.newId = self.origId
- self.newDmg = self.origDmg
- Util.clear(self.subdb.data)
- local st = standardBlockDB:get({ self.origId, self.origDmg })
- if st then
- local bt = blockTypeDB:get(st)
- self.subdb:addSubsForBlockType(self.origId, self.origDmg, bt)
- end
- self:draw()
- elseif event.type == 'cancel' then
- UI.pager:setPreviousPage()
- end
- return UI.Page.eventHandler(self, event)
- end
- --[[-- SupplyPage --]]--
- supplyPage = UI.Page({
- titleBar = UI.TitleBar({
- title = 'Waiting for supplies',
- previousPage = 'start'
- }),
- menuBar = UI.MenuBar({
- y = 2,
- buttons = {
- --{ text = 'Refresh', event = 'refresh', help = 'Refresh inventory' },
- { text = 'Continue', event = 'build', help = 'Continue building' },
- { text = 'Menu', event = 'menu', help = 'Return to main menu' },
- { text = 'Force Craft', event = 'craft', help = 'Request crafting (again)' },
- }
- }),
- grid = UI.Grid({
- columns = {
- { 'Slot', 'index', 4 },
- { 'ID', 'key', 7 },
- { 'Name', 'name', UI.term.width-20 },
- { 'Need', 'need', 4 },
- --{ 'Have', 'have', 4 },
- },
- sortColumn = 'index',
- y = 3,
- width = UI.term.width,
- height = UI.term.height - 3
- }),
- statusBar = UI.StatusBar({
- columns = {
- { 'Help', 'help', UI.term.width - 25 },
- { 'Block', 'block', 12 },
- { 'Fuel', 'fuel', 11 }
- }
- }),
- accelerators = {
- c = 'craft',
- r = 'refresh',
- b = 'build',
- m = 'menu',
- },
- })
- function supplyPage:eventHandler(event)
- if event.type == 'craft' then
- if Builder.itemProvider.canCraft then
- local s = self.grid:getSelected()
- Builder.itemProvider:craft(s.id, s.dmg, s.need-s.qty)
- local name = s.name or ''
- self.statusBar:timedStatus('Requested ' .. s.need-s.qty .. ' ' .. name, 3)
- else
- self.statusBar:timedStatus('Unable to craft')
- end
- elseif event.type == 'refresh' then
- self:refresh()
- elseif event.type == 'build' then
- Builder:build()
- elseif event.type == 'menu' then
- Builder:dumpInventory()
- --Builder.status = 'idle'
- UI.pager:setPage('start')
- elseif event.type == 'focus_change' then
- self.statusBar:timedStatus(event.focused.help, 3)
- end
- return UI.Page.eventHandler(self, event)
- end
- function supplyPage:enable()
- self.grid.index = 1
- self.statusBar:setValue('fuel',
- string.format('Fuel: %dk', math.floor(turtle.getFuelLevel() / 1024)))
- self.statusBar:setValue('block',
- string.format('Block: %d', Builder.index))
- Event.addNamedTimer('supplyRefresh', 12, true, function()
- if self.enabled then
- self:refresh()
- self.statusBar:timedStatus('Refreshed ', 2)
- end
- end)
- end
- function supplyPage:disable()
- Event.cancelNamedTimer('supplyRefresh')
- end
- function supplyPage:refresh()
- self.statusBar:timedStatus('Refreshed ', 3)
- local t = Builder:getSupplies()
- if #t == 0 then
- Builder:build()
- else
- self.grid:setTable(t)
- self.grid:draw()
- end
- end
- --[[-- ListingPage --]]--
- listingPage = UI.Page({
- titleBar = UI.TitleBar({
- title = 'Supply List',
- previousPage = 'start'
- }),
- menuBar = UI.MenuBar({
- y = 2,
- buttons = {
- { text = 'Craft', event = 'craft', help = 'Request crafting' },
- { text = 'Refresh', event = 'refresh', help = 'Refresh inventory' },
- { text = 'Toggle', event = 'toggle', help = 'Toggles needed blocks' },
- { text = 'Substitute', event = 'edit', help = 'Substitute a block' }
- }
- }),
- grid = UI.ScrollingGrid({
- columns = {
- { 'ID', 'key', 7 },
- { 'Name', 'name', UI.term.width - 20 },
- { 'Need', 'need', 4 },
- { 'Have', 'qty', 4 },
- },
- sortColumn = 'key',
- y = 3,
- height = UI.term.height-3,
- help = 'Set a block type or pick a substitute block'
- }),
- accelerators = {
- q = 'menu',
- c = 'craft',
- r = 'refresh',
- t = 'toggle',
- },
- statusBar = UI.StatusBar(),
- fullList = true
- })
- function listingPage:enable()
- listingPage:refresh()
- end
- function listingPage:eventHandler(event)
- if event.type == 'craft' then
- if Builder.itemProvider.canCraft then
- local s = self.grid:getSelected()
- Builder.itemProvider:craft(s.id, s.dmg, s.need)
- local name = s.name
- if not name then
- name = s.key
- end
- self.statusBar:timedStatus('Requested ' .. s.need .. ' ' .. name, 3)
- else
- self.statusBar:timedStatus('Unable to craft')
- end
- elseif event.type == 'refresh' then
- self:refresh()
- self:draw()
- self.statusBar:timedStatus('Refreshed ', 3)
- elseif event.type == 'toggle' then
- self.fullList = not self.fullList
- self:refresh()
- self:draw()
- elseif event.type == 'menu' then
- UI.pager:setPage('start')
- elseif event.type == 'edit' or event.type == 'grid_select' then
- self:manageBlock(self.grid:getSelected())
- elseif event.type == 'focus_change' then
- if event.focused.help then
- self.statusBar:timedStatus(event.focused.help, 3)
- end
- end
- return UI.Page.eventHandler(self, event)
- end
- function listingPage:refresh()
- local supplyList = Builder:getBlockCounts()
- Builder.itemProvider:refresh()
- for _,b in pairs(supplyList) do
- if b.need > 0 then
- local item = Builder.itemProvider:getItemInfo(b.id, b.dmg)
- if item then
- local block = blockDB:lookup(b.id, b.dmg)
- if not block then
- blockDB:add(b.id, b.dmg, item.name)
- elseif not block.name and item.name then
- blockDB:add(b.id, b.dmg, item.name)
- end
- b.qty = item.qty
- end
- end
- end
- blockDB:flush()
- local t = {}
- for _,b in pairs(supplyList) do
- --if b.id > 0 then
- local block = blockDB:lookup(b.id, b.dmg)
- if block then
- b.name = block.name
- end
- if self.fullList or b.qty < b.need then
- table.insert(t, b)
- end
- --end
- end
- self.grid:setTable(t)
- end
- function listingPage:manageBlock(selected)
- local sid = selected.id
- local sdmg = selected.dmg
- local t = { }
- local substitutes = subDB:lookupBlocksForSub(sid, sdmg)
- for _,sub in pairs(substitutes) do
- sub = subDB:lookup(sub.refid, sub.refdmg)
- local key = sub.refid .. ':' .. sub.refdmg
- if not t[key] and sub.sid >= 0 then
- t[sub.refid .. ':' .. sub.refdmg] = {
- okey = sub.key,
- oname = blockDB:lookupName(sub.refid, sub.refdmg) or 'Unknown',
- skey = sub.sid .. ':' .. sub.sdmg,
- sname = blockDB:lookupName(sub.sid, sub.sdmg),
- rkey = sub.refid .. ':' .. sub.refdmg,
- id = sub.refid,
- dmg = sub.refdmg
- }
- end
- end
- if Util.empty(t) then
- substitutionPage.origId = selected.id
- substitutionPage.origDmg = selected.dmg
- UI.pager:setPage(substitutionPage)
- elseif Util.size(t) == 1 then
- local _,sub = next(t)
- substitutionPage.origId = sub.id
- substitutionPage.origDmg = sub.dmg
- UI.pager:setPage(substitutionPage)
- else
- selectSubstitutionPage.selected = selected
- selectSubstitutionPage.grid.t = t
- UI.pager:setPage(selectSubstitutionPage)
- end
- end
- --[[-- startPage --]]--
- startPage = UI.Page({
- titleBar = UI.TitleBar({ title = 'Builder v' .. Builder.version }),
- window = UI.Window({
- x = UI.term.width-15,
- y = 3,
- width = 15,
- height = UI.term.height-3,
- backgroundColor = colors.gray,
- grid = UI.Grid({
- columns = {
- --[[
- { 'Blocks', 'blocks', 6 },
- { 'Mode', 'mode', 7 },
- { 'Start', 'block', 6 },
- { 'Fuel', 'fuel', 5 },
- --]]
- { 'Name', 'name', 6 },
- { 'Value', 'value', 7 },
- },
- disableHeader = true,
- --y = UI.term.height-1,
- x = 1,
- y = 2,
- width = 15,
- height = 9,
- --autospace = true,
- selectable = false,
- backgroundColor = colors.gray
- }),
- }),
- menu = UI.Menu({
- x = 2,
- y = 5,
- menuItems = {
- { prompt = 'Set starting level', event = 'startLevel' },
- { prompt = 'Set starting block', event = 'startBlock' },
- { prompt = 'Supply list', event = 'assignBlocks' },
- { prompt = 'Toggle mode', event = 'toggleMode' },
- { prompt = 'Begin', event = 'begin' },
- { prompt = 'Quit', event = 'quit' }
- }
- }),
- accelerators = {
- x = 'test',
- q = 'quit'
- }
- })
- function startPage:draw()
- local fuel = turtle.getFuelLevel()
- if fuel > 9999 then
- fuel = string.format('%dk', math.floor(fuel/1024))
- end
- local t = {
- { name = 'mode', value = Builder.mode },
- { name = 'start', value = Builder.index },
- { name = 'blocks', value = #schematic.blocks },
- { name = 'fuel', value = fuel },
- { name = '' },
- { name = 'length', value = schematic.length },
- { name = 'width', value = schematic.width },
- { name = 'height', value = schematic.height },
- }
- self.window.grid:setTable(t)
- UI.Page.draw(self)
- end
- function startPage:eventHandler(event)
- if event.type == 'startLevel' then
- local dialog = UI.Dialog({
- text = UI.Text({ x = 5, y = 3, value = '0 - ' .. schematic.height }),
- textEntry = UI.TextEntry({ x = 15, y = 3, '0 - 11' })
- })
- dialog.eventHandler = function(self, event)
- if event.type == 'accept' then
- local l = tonumber(self.textEntry.value)
- if l and l < schematic.height and l >= 0 then
- for k,v in pairs(schematic.blocks) do
- if v.y >= l then
- Builder.index = k
- Util.writeTable('/' .. schematic.filename .. '.progress',
- { index = Builder.index })
- UI.pager:setPreviousPage()
- break
- end
- end
- else
- self.statusBar:timedStatus('Invalid Level', 3)
- end
- return true
- end
- return UI.Dialog.eventHandler(self, event)
- end
- dialog.titleBar.title = 'Enter Starting Level'
- dialog:setFocus(dialog.textEntry)
- UI.pager:setPage(dialog)
- elseif event.type == 'startBlock' then
- local dialog = UI.Dialog({
- text = UI.Text({ x = 5, y = 3, value = '1 - ' .. #schematic.blocks }),
- textEntry = UI.TextEntry({ x = 15, y = 3, value = tostring(Builder.index) })
- })
- dialog.eventHandler = function(self, event)
- if event.type == 'accept' then
- local bn = tonumber(self.textEntry.value)
- if bn and bn < #schematic.blocks and bn >= 0 then
- Builder.index = bn
- Util.writeTable('/' .. schematic.filename .. '.progress',
- { index = Builder.index })
- UI.pager:setPreviousPage()
- else
- self.statusBar:timedStatus('Invalid Block', 3)
- end
- return true
- end
- return UI.Dialog.eventHandler(self, event)
- end
- dialog.titleBar.title = 'Enter Block Number'
- dialog:setFocus(dialog.textEntry)
- UI.pager:setPage(dialog)
- elseif event.type == 'assignBlocks' then
- Builder:dumpInventory()
- UI.pager:setPage('listing')
- elseif event.type == 'toggleMode' then
- if Builder.mode == 'build' then
- if Builder.index == 1 then
- Builder.index = #schematic.blocks
- end
- Builder.mode = 'destroy'
- elseif Builder.mode == 'destroy' then
- if Builder.index == #schematic.blocks then
- Builder.index = 1
- end
- Builder.mode = 'dryRun'
- else
- Builder.mode = 'build'
- end
- self:draw()
- elseif event.type == 'begin' then
- UI.pager:setPage('blank')
- --Builder.status = 'building'
- print('Reloading schematic')
- Builder:reloadSchematic()
- if Builder.mode ~= 'dryRun' then
- print('Determining block placement')
- schematic:determineBlockPlacement()
- print('Optimizing route (' .. #schematic.blocks .. ' blocks)')
- schematic:optimizeRoute()
- print('Adjusting route')
- schematic:setPlacementOrder()
- end
- Builder:dumpInventory()
- if Builder.mode == 'destroy' then
- print('Beginning destruction')
- else
- print('Starting build')
- end
- Builder:build()
- Profile.display()
- elseif event.type == 'quit' then
- Event.exitPullEvents()
- UI.term:reset()
- end
- return UI.Page.eventHandler(self, event)
- end
- --[[-- startup logic --]]--
- args = {...}
- if #args < 1 then
- error('supply file name')
- end
- --if #args > 1 then
- Profile.enable()
- --end
- if os.version() == 'TurtleOS 1.5' then
- Builder.ccVersion = 1.5
- Builder.resourceSlots = 15
- elseif os.version() == 'CraftOS 1.6' then
- Builder.ccVersion = 1.6
- Builder.resourceSlots = 14
- else
- error('Unsupported ComputerCraft version')
- end
- Builder.itemProvider = ChestProvider()
- if not Builder.itemProvider:isValid() then
- Builder.itemProvider = MEProvider()
- if not Builder.itemProvider:isValid() then
- error('No provider below turtle')
- end
- end
- blockDB:load()
- standardBlockDB:load()
- blockTypeDB:load()
- maxStackDB:load()
- subDB:load(standardBlockDB, blockTypeDB)
- print('Loading ' .. args[1])
- schematic:load(args[1])
- print('Substituting blocks')
- Builder:substituteBlocks()
- local progress = Util.readTable(schematic.filename .. '.progress')
- if progress then
- Builder.index = progress.index
- if Builder.index > #schematic.blocks then
- Builder.index = 1
- end
- end
- UI.pager:setPages({
- listing = listingPage,
- start = startPage,
- supply = supplyPage,
- blank = blankPage
- })
- UI.pager:setPage('start')
- TL2.setPolicy(TL2.policies.digAttack)
- TL2.getState().pt.x = -1
- TL2.getState().pt.y = -1
- TL2.saveLocation('supplies')
- Event.pullEvents()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement