--[[
The specified software is distributed under the CC0 license
No Rights Reserved
]] --
local ore_dict = {
{
"Железная руда",
"Железный слиток",
take = {name = "minecraft:iron_ore", damage = 0},
give = {name = "minecraft:iron_ingot", damage = 0},
rate = {take = 3, give = 7}
},
{
"Кварцевая руда",
"Кварц",
take = {name = "minecraft:quartz_ore", damage = 0},
give = {name = "minecraft:quartz", damage = 0},
rate = {take = 1, give = 4}
},
{
"Золотая руда",
"Золотой слиток",
take = {name = "minecraft:gold_ore", damage = 0},
give = {name = "minecraft:gold_ingot", damage = 0},
rate = {take = 3, give = 7}
},
{
"Лазуритовая руда",
"Лазурит",
take = {name = "minecraft:lapis_ore", damage = 0},
give = {name = "minecraft:dye", damage = 4},
rate = {take = 1, give = 9}
},
{
"Красная руда",
"Красная пыль",
take = {name = "minecraft:redstone_ore", damage = 0},
give = {name = "minecraft:redstone", damage = 0},
rate = {take = 1, give = 5}
},
{
"Медная руда",
"Медный слиток",
take = {name = "IC2:blockOreCopper", damage = 0},
give = {name = "IC2:itemIngot", damage = 0},
rate = {take = 3, give = 7}
},
{
"Оловянная руда",
"Оловянный слиток",
take = {name = "IC2:blockOreTin", damage = 0},
give = {name = "IC2:itemIngot", damage = 1},
rate = {take = 3, give = 7}
},
{
"Оловянная руда",
"Оловянный слиток",
take = {name = "NetherOres:tile.netherores.ore.0", damage = 7},
give = {name = "IC2:itemIngot", damage = 1},
rate = {take = 3, give = 7}
},
{
"Дракониевая руда",
"Дракониевый слиток",
take = {name = "DraconicEvolution:draconiumOre", damage = 0},
give = {name = "DraconicEvolution:draconiumIngot", damage = 0},
rate = {take = 1, give = 3}
}
}
local unicode = require("unicode")
local computer = require("computer")
local com = require("component")
local event = require("event")
local me = com.isAvailable("me_interface") and com.me_interface or error("нет ме интерфейса")
local pim = com.isAvailable("pim") and com.pim or error("нет пима")
local gpu = com.gpu
local w, h = 80, 50
local defBG, defFG = gpu.getBackground(), gpu.getForeground()
gpu.setResolution(w, h)
local function center(height, text, color)
gpu.setForeground(color)
gpu.set(math.floor(w / 2 - unicode.len(text) / 2), height, text)
end
local function populateQty()
local totalOre = 0
for i, ore in pairs(ore_dict) do
local fingerprint = {id = ore.give.name, damage = ore.give.damage}
local item = me.getItemDetail(fingerprint).basic()
if item == nil then
return 0
else
ore.sizeOfStack = item.max_size
ore.qty = item.qty
totalOre = totalOre + item.qty
end
end
return totalOre
end
local function displayOres()
local line = 2
for i, ore in pairs(ore_dict) do
local print_row = line + (i)
gpu.setForeground(0x00ff00)
gpu.set(5, print_row, ore[1])
gpu.set(42, print_row, ore[2])
gpu.setForeground(0xFF00FF)
gpu.set(28, print_row, tostring(ore.rate.take))
gpu.set(34, print_row, tostring(ore.rate.give))
gpu.set(73, print_row, tostring(ore.qty))
gpu.setForeground(0xFFFF00)
gpu.set(30, print_row, "-->")
gpu.set(63, print_row, "Доступно:")
gpu.setForeground(0x202020)
gpu.set(2, print_row + 1, string.rep("═", w - 2))
line = line + 1
end
end
local function updateOres()
local totalOre = populateQty()
gpu.fill(1, 1, w, h - 16, " ")
if totalOre == 0 then
gpu.fill(1, 1, w, h - 15, " ")
center(h - 15, "Нет соединения с МЭ", 0xff0000)
else
displayOres()
end
end
local function giveItemFromMe(item, dmg, amount)
local fingerprint = {id = item, dmg = dmg}
local err, res = pcall(me.exportItem, fingerprint, "UP", amount)
if err == true then
return res.size
end
end
local function giveIngot(toGive, ore)
local totalGive = 0
local givePreIteration = 0
while totalGive < toGive do
if toGive - totalGive > 64 then
givePreIteration = ore.sizeOfStack
else
givePreIteration = toGive - totalGive
end
local gived = giveItemFromMe(ore.give.name, ore.give.damage, givePreIteration)
totalGive = totalGive + gived
if gived == 0 then
gpu.fill(1, h - 15, w, 2, " ")
center(h - 15, "Oсвободите место в инвентаре", 0xff0000)
center(h - 14, "Ожидаю выдать " .. tostring(toGive - totalGive) .. " " .. ore[2], 0xFFFFFF)
os.sleep(1)
end
gpu.fill(1, h - 15, 2, h, " ")
end
end
local function exchangeOre(slot, ore)
local curSlot = pim.getStackInSlot(slot)
if curSlot == nil then
center(h - 14, "Вы сошли с PIM, обмен прерван. (Не удалось прочесть слот)", 0xff0000)
os.sleep(0.5)
return
end
local userOreQty = curSlot.qty
local takeQty = userOreQty - (userOreQty % ore.rate.take)
local giveQty = userOreQty * ore.rate.give
if ore.qty < giveQty then
gpu.fill(1, h - 14, w, 1, " ")
center(h - 14, "Недостаточно слитков для обмена <" .. ore[1] .. ">", 0xff0000)
os.sleep(0.5)
return
end
-- Количетсво могло измениться..
local takedOre = pim.pushItem("DOWN", slot, takeQty)
if takedOre == nil then
gpu.fill(1, h - 14, w, 1, " ")
center(h - 14, "Вы сошли с PIM, обмен прерван. (Не удалось извлечь руду)", 0xff0000)
os.sleep(0.5)
elseif takedOre == 0 then
gpu.fill(1, h - 14, w, 1, " ")
center(h - 14, "В выбраном слоте руды нет.. А была.. Хмм...", 0x505050)
else
local giveQty = (takedOre // ore.rate.take) * ore.rate.give
gpu.fill(1, h - 15, w, 2, " ")
center(h - 14, "Меняю " .. takedOre .. " " .. ore[1] .. " на " .. giveQty .. " " .. ore[2], 0xffffff)
giveIngot(giveQty, ore)
end
end
local function checkInventory()
local size = pim.getInventorySize()
local data = pim.getAllStacks(0)
for slot = 1, size do
if data[slot] then
for i, ore in pairs(ore_dict) do
if data[slot].id == ore.take.name and data[slot].dmg == ore.take.damage then
exchangeOre(slot, ore)
end
end
end
end
updateOres()
if pim.getInventoryName() ~= "pim" then
gpu.fill(1, h - 15, w, 2, " ")
center(h - 15, "Обмен окончен! Приходите ещё!", 0xffffff)
checkInventory()
else
-- Может быть, мы не поймали событие когда юзер ушел
event.push("player_off")
end
end
function handleEvent(eventID, ...)
local args = {...}
if eventID == "interrupted" then
gpu.setBackground(defBG)
gpu.setForeground(defFG)
gpu.fill(1, 1, w, h, " ")
os.exit()
return true
elseif eventID == "player_on" then
gpu.fill(1, h - 15, w, 1, " ")
center(h - 15, "Приветствую, " .. args[1] .. "! Начинаю обмен", 0xffffff)
updateOres()
checkInventory()
elseif eventID == "player_off" then
gpu.fill(1, h - 15, w, 1, " ")
center(h - 15, "Для обмена встаньте на PIM и не сходите до окончания обмена", 0xffffff)
updateOres()
end
end
function drawStat()
gpu.setForeground(0x444444)
gpu.set(
2,
h - 1,
string.format(
"RAM: %.1fkB / %.1fkB",
(computer.totalMemory() - computer.freeMemory()) / 1024,
computer.totalMemory() / 1024
)
)
end
local oreTimeFn = function()
updateOres()
-- Каджый 10 такт обновляем экран
for i = 1, 10 do
coroutine.yield()
end
end
local oreTimer = coroutine.create(oreTimeFn)
function draw_img(img, x, y, fore, back)
fore = fore or 0xffffff
back = back or 0x0
oldFG = gpu.getForeground()
gpu.setForeground(fore)
local i = 0
for line in img:gmatch("([^\n]*)\n?") do
gpu.set(x, y + i, line)
i = i + 1
end
gpu.setForeground(oldFG)
end
local img =
[[
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡐⢆⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠠⡐⣄⢢⡐⢄⢢⡐⣄⠂⡄⠀⠀⢄⢢⢰⣀⢦⡐⣄⢢⡐⠄⣂⠆⠀⠀⢀⡐⢦⠹⠌⠀⢀⡰⢠⠀⠐⣠⠀⠀⠀⠀⠀⠀⠀⠀⠄⡐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢡⠂⡄⠀⠀⠀⠀⠌⡤⠃⠀⢳⡌⠃⠘⠈⠂⠑⠈⠑⠀⠀⡜⡢⠍⠂⠑⠈⠑⠈⠃⠀⠐⣌⠎⢀⡐⠦⣜⠂⠁⠀⠀⠀⡜⡡⠂⠘⠤⡁⠀⠀⠀⠀⠀⠀⠀⢂⠱⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢢⠑⡌⢢⠀⠤⣉⡜⣰⠁⠀⡣⢝⠀⠀⠀⠀⠀⠀⠀⠀⢀⠳⣹⢌⡱⢢⡱⢌⢲⢰⡀⠀⢎⠺⣤⣙⠳⣀⠀⠀⠀⠀⠠⣙⠦⠁⢨⣑⠂⠀⠀⠀⠀⠀⠀⠀⢌⠳⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢢⡑⠈⠒⡭⠒⠌⠸⣡⠃⠀⣙⠮⡄⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠈⠁⠁⠉⣈⠞⡢⠄⠈⢎⡳⠂⠉⠳⢆⡆⣀⠀⠀⠐⡌⠦⠁⠠⣃⠎⠀⠀⠀⠀⠀⠀⠀⠌⢒⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠒⡄⠁⠀⠀⠁⠀⠰⣡⠂⠀⠈⠸⣑⢋⢆⢳⡘⣔⠣⢆⢠⠱⣊⡕⣎⢖⡱⢎⠞⠁⠀⠈⣎⠱⠀⠀⠀⠈⠲⣡⠢⠄⠀⡜⡡⠂⠐⡥⢊⡴⢡⠎⡤⢁⠆⠀⠘⡀⠎⡐⢂⠰⠀⠆⡀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⢌⡁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
]]
function copyleft()
local text = {
{"Авторы: ", 0x444444, w - 35},
{"Rijen, Furryonelove", 0x64fff2, w - 28}
}
local startPos = w - 32
for i, str in pairs(text) do
gpu.setForeground(str[2])
gpu.set(str[3], h - 1, str[1])
end
gpu.setBackground(defBG)
gpu.setForeground(defFG)
end
gpu.fill(1, 1, w, h, " ")
center(h - 15, "Для обмена встаньте на PIM и не сходите до окончания обмена", 0xffffff)
draw_img(img, 1, h - 13, 0x00a400)
copyleft()
while true do
drawStat()
handleEvent(event.pull(1))
if coroutine.status(oreTimer) == "dead" then
oreTimer = coroutine.create(oreTimeFn)
else
coroutine.resume(oreTimer)
end
end