package management

This commit is contained in:
kepler155c
2018-11-03 18:14:11 -04:00
parent aa66b1c663
commit 1f7ef4a483
124 changed files with 1274 additions and 9 deletions

View File

@@ -0,0 +1,549 @@
local class = require('class')
local Util = require('util')
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
--[[-- blockDB --]]--
local blockDB = TableDB()
function blockDB:load()
local blocks = JSON.decodeFromFile('usr/etc/names/minecraft.json')
if not blocks then
error('Unable to read blocks.json')
end
for strId, block in pairs(blocks) do
strId = 'minecraft:' .. strId
if type(block.name) == 'string' then
self:add(block.id, 0, block.name, strId, block.place)
else
for nid,name in pairs(block.name) do
self:add(block.id, nid - 1, name, strId, block.place)
end
end
end
end
function blockDB:lookup(id, dmg)
if not id then
return
end
return self.data[id .. ':' .. dmg]
end
function blockDB:add(id, dmg, name, strId, place)
local key = id .. ':' .. dmg
TableDB.add(self, key, {
id = id,
dmg = dmg,
name = name,
strId = strId,
place = place,
})
end
--[[-- placementDB --]]--
-- in memory table that expands the standardBlock and blockType tables for each item/dmg/placement combination
local placementDB = TableDB()
function placementDB:load(sbDB, btDB)
for k,v in pairs(sbDB.data) do
if v.place then
local bt = btDB.data[v.place]
if not bt then
error('missing block type: ' .. v.place)
end
local id, dmg = string.match(k, '(%d+):*(%d+)')
self:addSubsForBlockType(tonumber(id), tonumber(dmg), bt)
end
end
-- special case for quartz pillars
self:addSubsForBlockType(155, 2, btDB.data['quartz-pillar'])
end
function placementDB: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
local b = blockDB:lookup(id, dmg)
local strId = tostring(id)
if b then
strId = b.strId
end
self:add(
id,
odmg,
sub.sid or strId,
sub.sdmg or dmg,
sub.dir,
sub.extra)
end
end
function placementDB:add(id, dmg, sid, sdmg, direction, extra)
if direction and #direction == 0 then
direction = nil
end
local entry = {
oid = id, -- numeric ID
odmg = dmg, -- dmg with placement info
id = sid, -- string ID
dmg = sdmg, -- dmg without placement info
direction = direction,
}
if extra then
Util.merge(entry, extra)
end
self.data[id .. ':' .. dmg] = entry
end
--[[-- BlockTypeDB --]]--
local blockTypeDB = TableDB()
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],
extra = sub[5]
})
end
self.dirty = true
end
function blockTypeDB:load()
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, 'south' },
{ 3, nil, 0, 'west' },
{ 4, nil, 0, 'north' },
{ 5, nil, 0, 'east' },
{ 6, nil, 0, 'south' },
{ 7, nil, 0, 'west' },
})
blockTypeDB:addTemp('pumpkin', {
{ 0, nil, 0, 'north-block' },
{ 1, nil, 0, 'east-block' },
{ 2, nil, 0, 'south-block' },
{ 3, nil, 0, 'west-block' },
{ 4, nil, 0, 'north-block' },
{ 5, nil, 0, 'east-block' },
{ 6, nil, 0, 'south-block' },
{ 7, nil, 0, 'west-block' },
})
blockTypeDB:addTemp('anvil', {
{ 0, nil, 0, 'south' },
{ 1, nil, 0, 'east' },
{ 2, nil, 0, 'south'},
{ 3, nil, 0, 'east' },
{ 4, nil, 0, 'south' },
{ 5, nil, 0, 'east' },
{ 6, nil, 0, 'east' },
{ 7, nil, 0, 'south' },
{ 8, nil, 0, 'south' },
{ 9, nil, 0, 'east' },
{ 10, nil, 0, 'east' },
{ 11, nil, 0, 'south' },
{ 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, 'minecraft:air', 0 },
{ 9, 'minecraft:air', 0 },
{ 10, 'minecraft:air', 0 },
{ 11, 'minecraft:air', 0 },
{ 12, 'minecraft:air', 0 },
{ 13, 'minecraft:air', 0 },
{ 14, 'minecraft:air', 0 },
{ 15, 'minecraft:air', 0 },
})
blockTypeDB:addTemp('comparator', {
{ 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, nil, 0, 'south' },
{ 9, nil, 0, 'west' },
{ 10, nil, 0, 'north' },
{ 11, nil, 0, 'east' },
{ 12, nil, 0, 'south' },
{ 13, nil, 0, 'west' },
{ 14, nil, 0, 'north' },
{ 15, nil, 0, 'east' },
})
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('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', {
{ 1, nil, 0, 'west-block' },
{ 2, nil, 0, 'east-block' },
{ 3, nil, 0, 'north-block' },
{ 4, nil, 0, 'south-block' },
{ 5, nil, 0 }, -- block top
})
blockTypeDB:addTemp('cauldron', {
{ 0, nil, 0 },
{ 1, nil, 0 },
{ 2, nil, 0 },
{ 3, nil, 0 },
})
blockTypeDB:addTemp('dispenser', {
{ 0, nil, 0, 'wrench-down' },
{ 1, nil, 0, 'wrench-up' },
{ 2, nil, 0, 'south' },
{ 3, nil, 0, 'north' },
{ 4, nil, 0, 'east' },
{ 5, nil, 0, 'west' },
{ 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', {
{ 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' },
{ 8, nil, 0 },
{ 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('adp-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' },
{ 8, nil, 0, 'south' },
{ 9, nil, 0, 'east' },
{ 10, nil, 0, 'east' },
{ 11, nil, 0, 'east' },
{ 12, nil, 0, 'south' },
{ 13, nil, 0, 'south' },
})
blockTypeDB:addTemp('signpost', {
{ 0, nil, 0, 'north' },
{ 1, nil, 0, 'north', { facing = 1 } },
{ 2, nil, 0, 'north', { facing = 2 } },
{ 3, nil, 0, 'north', { facing = 3 } },
{ 4, nil, 0, 'east' },
{ 5, nil, 0, 'east', { facing = 1 } },
{ 6, nil, 0, 'east', { facing = 2 } },
{ 7, nil, 0, 'east', { facing = 3 } },
{ 8, nil, 0, 'south' },
{ 9, nil, 0, 'south', { facing = 1 } },
{ 10, nil, 0, 'south', { facing = 2 } },
{ 11, nil, 0, 'south', { facing = 3 } },
{ 12, nil, 0, 'west' },
{ 13, nil, 0, 'west', { facing = 1 } },
{ 14, nil, 0, 'west', { facing = 2 } },
{ 15, nil, 0, 'west', { facing = 3 } },
})
blockTypeDB:addTemp('vine', {
{ 0, nil, 0 },
{ 1, nil, 0, 'south-block-vine' },
{ 2, nil, 0, 'west-block-vine' },
{ 3, nil, 0, 'south-block-vine' },
{ 4, nil, 0, 'north-block-vine' },
{ 5, nil, 0, 'south-block-vine' },
{ 6, nil, 0, 'north-block-vine' },
{ 7, nil, 0, 'south-block-vine' },
{ 8, nil, 0, 'east-block-vine' },
{ 9, nil, 0, 'south-block-vine' },
{ 10, nil, 0, 'east-block-vine' },
{ 11, nil, 0, 'east-block-vine' },
{ 12, nil, 0, 'east-block-vine' },
{ 13, nil, 0, 'east-block-vine' },
{ 14, nil, 0, 'east-block-vine' },
{ 15, nil, 0, 'east-block-vine' },
})
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' },
{ 9, nil, 0, 'north' },
{ 10, nil, 0, 'east' },
{ 11, nil, 0, 'west' },
{ 12, nil, 0, 'south' },
{ 13, nil, 0, 'north' },
{ 14, nil, 0, 'east' },
{ 15, nil, 0, 'west' },
})
blockTypeDB:addTemp('piston', {
{ 0, nil, 0, 'piston-down' },
{ 1, nil, 0, 'piston-up' },
{ 2, nil, 0, 'piston-north' },
{ 3, nil, 0, 'piston-south' },
{ 4, nil, 0, 'piston-west' },
{ 5, nil, 0, 'piston-east' },
{ 8, nil, 0, 'piston-down' },
{ 9, nil, 0, 'piston-up' },
{ 10, nil, 0, 'piston-north' },
{ 11, nil, 0, 'piston-south' },
{ 12, nil, 0, 'piston-west' },
{ 13, nil, 0, 'piston-east' },
})
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 },
{ 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('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('slab', {
{ '+0', nil, nil, 'bottom' },
{ '+8', nil, nil, 'top' },
})
blockTypeDB:addTemp('largeplant', {
{ '+0', nil, nil, 'east-door', { twoHigh = true } }, -- should use a generic double tall keyword
{ '+8', 'minecraft:air', 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, 'east-door', { twoHigh = true } },
{ 1, nil, 0, 'south-door', { twoHigh = true } },
{ 2, nil, 0, 'west-door', { twoHigh = true } },
{ 3, nil, 0, 'north-door', { twoHigh = true } },
{ 4, nil, 0, 'east-door', { twoHigh = true } },
{ 5, nil, 0, 'south-door', { twoHigh = true } },
{ 6, nil, 0, 'west-door', { twoHigh = true } },
{ 7, nil, 0, 'north-door', { twoHigh = true } },
{ 8,'minecraft:air', 0 },
{ 9,'minecraft:air', 0 },
{ 10,'minecraft:air', 0 },
{ 11,'minecraft:air', 0 },
{ 12,'minecraft:air', 0 },
{ 13,'minecraft:air', 0 },
{ 14,'minecraft:air', 0 },
{ 15,'minecraft:air', 0 },
})
blockTypeDB:addTemp('cocoa', {
{ 0, nil, 0, 'south-block' },
{ 1, nil, 0, 'west-block' },
{ 2, nil, 0, 'north-block' },
{ 3, nil, 0, 'east-block' },
{ 4, nil, 0, 'south-block' },
{ 5, nil, 0, 'west-block' },
{ 6, nil, 0, 'north-block' },
{ 7, nil, 0, 'east-block' },
{ 8, nil, 0, 'south-block' },
{ 9, nil, 0, 'west-block' },
{ 10, nil, 0, 'north-block' },
{ 11, nil, 0, 'east-block' },
})
end
local Blocks = class()
function Blocks:init(args)
Util.merge(self, args)
self.blockDB = blockDB
blockDB:load()
blockTypeDB:load()
placementDB:load(blockDB, blockTypeDB)
end
-- for an ID / dmg (with placement info)
-- return the correct block (without the placment info embedded in the dmg)
function Blocks:getPlaceableBlock(id, dmg)
local p = placementDB:get({id, dmg})
if p then
return Util.shallowCopy(p)
end
local b = blockDB:get({id, dmg})
if b then
return { id = b.strId, dmg = b.dmg }
end
b = blockDB:get({id, 0})
if b then
return { id = b.strId, dmg = b.dmg }
end
return { id = id, dmg = dmg }
end
return Blocks

View File

@@ -0,0 +1,101 @@
local Blocks = require('builder.blocks')
local class = require('class')
local Message = require('message')
local Util = require('util')
local device = _G.device
local fs = _G.fs
local turtle = _G.turtle
local Builder = class()
Util.merge(Builder, {
isCommandComputer = not turtle,
loc = { },
index = 1,
mode = 'build',
})
local BUILDER_DIR = 'usr/builder'
local blockInfo = Blocks()
function Builder:getBlockCounts()
local blocks = { }
for k = self.index, #self.schematic.blocks do
local b = self.schematic.blocks[k]
local key = tostring(b.id) .. ':' .. b.dmg
local block = blocks[key]
if not block then
block = Util.shallowCopy(b)
block.qty = 0
block.need = 0
blocks[key] = block
end
block.need = block.need + 1
end
return blocks
end
function Builder:substituteBlocks(throttle)
for _,b in pairs(self.schematic.blocks) do
-- replace schematic block type with substitution
local pb = blockInfo:getPlaceableBlock(b.id, b.dmg)
Util.merge(b, pb)
b.odmg = pb.odmg or pb.dmg
local sub = self.subDB:get({ b.id, b.dmg })
if sub then
b.id, b.dmg = self.subDB:extract(sub)
end
throttle()
end
end
function Builder:reloadSchematic(throttle)
self.schematic:reload(throttle)
self:substituteBlocks(throttle)
end
function Builder:log(...)
Util.print(...)
end
function Builder:dumpInventory()
end
function Builder:logBlock(index, b)
local bdir = b.direction or ''
local logText = string.format('%d %s:%d (x:%d,z:%d:y:%d) %s',
index, b.id, b.dmg, b.x, b.z, b.y, bdir)
self:log(logText)
-- self:log(b.index) -- unique identifier of block
if device.wireless_modem then
Message.broadcast('builder', { x = b.x, y = b.y, z = b.z, heading = b.heading })
end
end
function Builder:saveProgress(index)
Util.writeTable(
fs.combine(BUILDER_DIR, self.schematic.filename .. '.progress'),
{ index = index, loc = self.loc }
)
end
function Builder:loadProgress(filename)
local progress = Util.readTable(fs.combine(BUILDER_DIR, filename))
if progress then
self.index = progress.index
if self.index > #self.schematic.blocks then
self.index = 1
end
self.loc = progress.loc or { }
end
end
return Builder

View File

@@ -0,0 +1,84 @@
local Builder = require('builder.builder')
local Event = require('event')
local Util = require('util')
local commands = _G.commands
local fs = _G.fs
local os = _G.os
local read = _G.read
function Builder:begin()
local direction = 1
local last = #self.schematic.blocks
local throttle = Util.throttle()
local cx, cy, cz = commands.getBlockPosition()
if self.loc.x then
cx, cy, cz = self.loc.rx, self.loc.ry, self.loc.rz
end
if self.mode == 'destroy' then
direction = -1
last = 1
end
for i = self.index, last, direction do
self.index = i
local b = self.schematic:getComputedBlock(i)
if b.id ~= 'minecraft:air' then
self:logBlock(self.index, b)
local id = b.id
if self.mode == 'destroy' then
id = 'minecraft:air'
end
local function placeBlock(bid, dmg, x, y, z)
local command = table.concat({
"setblock",
cx + x + 1,
cy + y,
cz + z + 1,
bid,
dmg,
}, ' ')
commands.execAsync(command)
local result = { os.pullEvent("task_complete") }
if not result[4] then
Util.print(result[5])
if self.mode ~= 'destroy' then
read()
end
end
end
placeBlock(id, b.odmg, b.x, b.y, b.z)
if b.twoHigh then
local _, topBlock = self.schematic:findIndexAt(b.x, b.z, b.y + 1, true)
if topBlock then
placeBlock(id, topBlock.odmg, b.x, b.y + 1, b.z)
end
end
if self.mode == 'destroy' then
self:saveProgress(math.max(self.index, 1))
else
self:saveProgress(self.index + 1)
end
else
throttle() -- sleep in case there are a large # of skipped blocks
end
end
fs.delete(self.schematic.filename .. '.progress')
print('Finished')
Event.exitPullEvents()
end
return Builder

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff