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