Here a short video of it:
[media]http://www.youtube.com/watch?v=7Ko7ryW6hjw&feature=youtu.be[/media] (Sorry for bad quality! :P/>/> )
I used Computercraft an the operator panel.
Next days i will show you more of it.
-- NBT API
-- by MysticT
local function readShort(file)
local r = file.read() * 256 + file.read()
if r >= 32768 then
r = r - 65536
end
return r
end
local function readInt(file)
local r = 0
for i = 1, 4 do
r = r * 256 + file.read()
end
if r >= 2147483648 then
r = r - 4294967296
end
return r
end
local function readLong(file)
local r = 0
for i = 1, 8 do
r = r * 256 + file.read()
end
if r >= 9223372036854775808 then
r = r - 18446744073709551616
end
return r
end
local function readFloat(file)
for i = 1, 4 do
file.read()
end
return 0
end
local function readDouble(file)
for i = 1, 4 do
file.read()
end
return 0
end
local function readByteArray(file)
local size = readInt(file)
local array = {}
for i = 1, size do
table.insert(array, file.read())
end
return array
end
local function readString(file)
local len = readShort(file)
local s = ""
for i = 1, len do
local c = file.read()
if not c then
break
end
s = s..string.char(c)
end
return s
end
local function readIntArray(file)
local size = readInt(file)
local array = {}
for i = 1, size do
table.insert(array, readInt(file))
end
return array
end
local function readTags(file)
local function readPayload(id)
if id == 1 then
-- TAG_Byte
return file.read()
elseif id == 2 then
-- TAG_Short
return readShort(file)
elseif id == 3 then
-- TAG_Int
return readInt(file)
elseif id == 4 then
-- TAG_Long
return readLong(file)
elseif id == 5 then
-- TAG_Float
return readFloat(file)
elseif id == 6 then
-- TAG_Double
return readDouble(file)
elseif id == 7 then
-- TAG_Byte_Array
return readByteArray(file)
elseif id == 8 then
-- TAG_String
return readString(file)
elseif id == 9 then
-- TAG_List
local list = {}
local id = file.read()
local size = readInt(file)
for i = 1, size do
table.insert(list, readPayload(id))
end
return list
elseif id == 10 then
-- TAG_Compound
return readTags(file)
elseif id == 11 then
-- TAG_Int_Array
return readIntArray(file)
end
end
local tags = {}
while true do
local tag = {}
tag.id = file.read()
if not tag.id then
break
end
if tag.id == 0 then
-- TAG_End
tag.name = ""
break
elseif tag.id > 11 then
return nil, "Unknown tag id: "..tostring(tag.id)
end
tag.name = readString(file)
tag.payload = readPayload(tag.id)
table.insert(tags, tag)
end
return tags
end
-- API functions
function readNBTFile(sPath)
local file = fs.open(sPath, "rb")
if file then
local tags, err = readTags(file)
file.close()
return tags, err
end
return nil, "Error opening file "..sPath
end
-- Schematic API
-- by MysticT
function load(sPath)
local tags, err = nbt.readNBTFile(sPath)
if tags == nil then
return nil, err
end
if tags[1].name ~= "Schematic" then
return nil, "Not an schematic file"
end
return tags[1].payload
end
function getBlocks(schem)
local blocks, data
for _,tag in ipairs(schem) do
if tag.name == "Blocks" then
blocks = tag.payload
elseif tag.name == "Data" then
data = tag.payload
end
end
return blocks, data
end
function getSize(schem)
local width, height, length
for _,tag in ipairs(schem) do
if tag.name == "Width" then
width = tag.payload
elseif tag.name == "Height" then
height = tag.payload
elseif tag.name == "Length" then
length = tag.payload
end
end
return width, height, length
end
function getMaterials(schem)
for _,tag in ipairs(schem) do
if tag.name == "Materials" then
return tag.payload
end
end
end
-- VirtualBox API
-- by MysticT
local controller
local nX, nY, nZ
local nWidth, nHeight, nLength
local defaultBlock, defaultMeta
local pX, pY, pZ
local function yield()
os.queueEvent("vb_yield")
os.pullEvent("vb_yield")
end
function init()
for _,s in ipairs(rs.getSides()) do
if peripheral.isPresent(s) and peripheral.getType(s) == "controller" then
controller = peripheral.wrap(s)
return true
end
end
return false
end
function setPos(x, y, z)
nX, nY, nZ = x, y, z
end
function setSize(w, h, l)
nWidth, nHeight, nLength = w, h, l
end
function setDefaultBlock(id, meta)
defaultBlock = id
defaultMeta = meta or 0
end
function getPos()
return nX, nY, nZ
end
function getSize()
return nWidth, nHeight, nLength
end
function getDefaultBlock()
return defaultBlock, defaultMeta
end
-- Blocks
function set(x, y, z, blockID, meta)
if x < 0 or x >= nWidth or y < 0 or y >= nHeight or z < 0 or z >= nLength then
return false
end
if meta then
return pcall(controller.placeBlockAtPos, nX + x, nY + y, nZ + z, blockID, meta)
else
return pcall(controller.placeBlockAtPos, nX + x, nY + y, nZ + z, blockID)
end
end
function setChance(chance, x, y, z, blockID, meta)
if math.random() <= chance then
set(x, y, z, blockID, meta)
end
end
function get(x, y, z)
if x < 0 or x >= nWidth or y < 0 or y >= nHeight or z < 0 or z >= nLength then
return nil, nil
end
return controller.getBlockIDAtPos(nX + x, nY + y, nZ + z), controller.getBlockDataAtPos(nX + x, nY + y, nZ + z)
end
function delete(x, y, z)
if x < 0 or x >= nWidth or y < 0 or y >= nHeight or z < 0 or z >= nLength then
return false
end
return controller.deleteBlockAtPos(nX + x, nY + y, nZ + z)
end
function isBlock(x, y, z)
return controller.getBlockIDAtPos(nX + x, nY + y, nZ + z) ~= 0
end
function replace(x, y, z, block, meta)
if isBlock(x, y, z) then
delete(x, y, z)
end
return set(x, y, z, block, meta)
end
function replaceBlocks(x, y, z, w, h, l, fromId, toId, fromMeta, toMeta)
for i = 0, w - 1 do
for j = 0, h - 1 do
for k = 0, l - 1 do
local _x, _y, _z = x + i, y + j, z + k
local id, meta = get(_x, _y, _z)
if id == fromId and (fromMeta == nil or meta == fromMeta) then
replace(_x, _y, _z, toId, toMeta)
end
end
end
end
end
function clear(x, y, z, w, h, l)
for i = 0, w - 1 do
for j = 0, h - 1 do
for k = 0, l - 1 do
delete(x + i, y + j, z + k)
end
end
end
end
function column(x, y, z, h, blockID, meta)
for i = 0, h - 1 do
set(x, y + i, z, blockID, meta)
end
end
function wall(x, y, z, w, h, dir, blockID, meta)
if dir < 1 or dir > 2 then
return false
end
for i = 0, w - 1 do
for j = 0, h - 1 do
local _x, _z
if dir == 1 then
_x = x + i
_z = z
elseif dir == 2 then
_x = x
_z = z + i
end
set(_x, y + j, _z, blockID, meta)
end
end
return true
end
function floor(x, y, z, w, l, blockID, meta)
for i = 0, w - 1 do
for j = 0, l - 1 do
set(x + i, y, z + j, blockID, meta)
end
end
return true
end
function box(x, y, z, w, h, l, blockID, meta)
wall(x, y, z, w, h, 1, blockID, meta)
wall(x, y, z + l - 1, w, h, 1, blockID, meta)
wall(x, y, z, w, h, 2, blockID, meta)
wall(x + w - 1, y, z, w, h, 2, blockID, meta)
floor(x, y, z, w, l, blockID, meta)
floor(x, y + h - 1, z, w, l, blockID, meta)
return true
end
function clearAll()
clear(1, 1, 1, nWidth - 2, nHeight - 2, nLength - 2)
box(0, 0, 0, nWidth, nHeight, nLength, defaultBlock, defaultMeta)
end
-- Creatures
function spawnCreature(x, y, z, name)
if x < 0 or x >= nWidth or y < 0 or y >= nHeight or z < 0 or z >= nLength then
return false
end
return controller.spawnCreatureAtPos(nX + x, nY + y, nZ + z, name)
end
-- Items
function spawnItem(x, y, z, itemID, damage, amount)
if x < 0 or x >= nWidth or y < 0 or y >= nHeight or z < 0 or z >= nLength then
return false
end
if damage and amount then
return controller.spawnItemAtPos(nX + x, nY + y, nZ + z, itemID, damage, amount)
elseif damage then
return controller.spawnItemAtPos(nX + x, nY + y, nZ + z, itemID, damage)
else
return controller.spawnItemAtPos(nX + x, nY + y, nZ + z, itemID)
end
end
-- Player
function isPlayerInside()
local x, y, z = controller.getPlayerPos()
x = x - nX
y = y - nY
z = z - nZ
return x >= 0 and x < nWidth and y > 0 and y < nHeight and z > 0 and z < nLength
end
function getPlayerPos()
local x, y, z = controller.getPlayerPos()
return x - nX, y - nY, z - nZ
end
function teleportPlayer(x, y, z)
if x < 0 or x >= nWidth or y < 0 or y >= nHeight or z < 0 or z >= nLength then
return false
end
return controller.teleportPlayerToPos(nX + x, nY + y, nZ + z)
end
function sendMessage(msg)
controller.sendMessageToPlayer(msg)
end
function savePlayerPos()
pX, pY, pZ = controller.getPlayerPos()
end
function restorePlayerPos()
return controller.teleportPlayerToPos(pX, pY, pZ)
end
-- Schematic
function buildSchematic(sPath, x, y, z)
local schem, err = schematic.load(sPath)
if not schem then
return false, err
end
local _w, _h, _l = schematic.getSize(schem)
if not x or not y or not z then
-- Center
x = math.floor(nWidth / 2) - math.floor(_w / 2)
y = 1
z = math.floor(nLength / 2) - math.floor(_l / 2)
end
if x + _w > nWidth then
w = nWidth - x
else
w = _w
end
if y + _h > nHeight then
h = nHeight - y
else
h = _h
end
if z + _l > nLength then
l = nLength - z
else
l = _l
end
local blocks, data = schematic.getBlocks(schem)
if not blocks then
return false, "Not blocks to build"
end
for _y = 0, h - 1 do
for _z = 0, l - 1 do
for _x = 0, w - 1 do
local n = _y * _w * _l + _z * _w + _x + 1
set(x + _x, y + _y, z + _z, blocks[n], data and data[n])
end
end
yield()
end
return true
end
local nX, nY, nZ = 0, 0, 0 -- box location
local nWidth, nHeight, nLength = 30, 20, 30 -- box size
local defaultBlock, defaultMeta = 1, 0 -- default block id and metadata
if not nbt then
os.loadAPI("nbt")
if not nbt then
error("Error loading nbt api")
end
end
if not schematic then
os.loadAPI("schematic")
if not schematic then
error("Error loading schematic api")
end
end
if not vb then
os.loadAPI("vb")
if not vb then
error("Error loading vb api")
end
end
if not vb.init() then
print("Operator Panel not found.")
return
end
vb.setPos(nX, nY, nZ)
vb.setSize(nWidth, nHeight, nLength)
vb.setDefaultBlock(defaultBlock, defaultMeta)
-- Init
vb.savePlayerPos() -- save the current player position
vb.clearAll() -- clear the box (also adds the walls)
vb.teleportPlayer(nWidth / 2, 1, nLength / 2) -- teleport the player inside
local ok, err = vb.buildSchematic("someSchematicFile") -- build from an shematic file
if not ok then
print("Error: ", err)
end
sleep(30) -- wait some time
-- End
vb.restorePlayerPos() -- return the player to his position
vb.clearAll() -- clear the box
I named the apis "nbt", "schematic" and "vb" (to make function calls shorter :)/>/>).what the heck is it? superfast turtles placing blocks or?????
It's on the peripheral library. Check it out.I used Computercraft an the operator panel.
Read the op again. It uses the operator panel, a peripheral that lets you place blocks and more.Whhat the …. How can the computer program, api make that scematic? Is it turtles?
a peripheral called operator panelOh My God…how does this even work?