-- 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