View difference between Paste ID: ZzakiEaf and tBV3kxjh
SHOW: | | - or go back to the newest paste.
1
--[[
2
The specified software is distributed under the CC0 license
3
No Rights Reserved
4
]] --
5
6
local ore_dict = {
7
    {
8
        'Железная руда',
9
        'Железный слиток',
10
2,
11
        take = {name='minecraft:iron_ore', damage=0},
12
        give = {name='minecraft:iron_ingot', damage=0},
13
        rate = {take = 1, give = 2}  -- добавлена запятая
14
    },
15
    {
16
        'Золотая руда',
17
        'Золотой слиток',
18
2,
19
        take = {name='minecraft:gold_ore', damage=0},
20
        give = {name='minecraft:gold_ingot', damage=0},
21
        rate = {take = 1, give = 2}  -- добавлена запятая
22
    },
23
    {
24
        'Никилевая руда',
25
        'Никелевый слиток',
26
2,
27
        take = {name='ThermalFoundation:Ore', damage=4},
28
        give = {name='ThermalFoundation:material', damage=68},
29
        rate = {take = 1, give = 2}  -- добавлена запятая
30
    },
31
    {
32
        'Мифриловая руда',
33
        'Мифриловый слиток',
34
2,
35
        take = {name='ThermalFoundation:Ore', damage=6},
36
        give = {name='ThermalFoundation:material', damage=70},
37
        rate = {take = 1, give = 2}  -- добавлена запятая
38
    },
39
    {
40
        'Платиновая руда',
41
        'Платиновый слиток',
42
2,
43
        take = {name='ThermalFoundation:Ore', damage=5},
44
        give = {name='ThermalFoundation:material', damage=69.0},
45
        rate = {take = 1, give = 2}  -- добавлена запятая
46
    },
47
    {
48
        'Свинцовая руда',
49
        'Свинцовый слиток',
50
2,
51
        take = {name='IC2:blockOreLead', damage=0},
52
        give = {name='IC2:itemIngot', damage=5},
53
        rate = {take = 1, give = 2}  -- добавлена запятая
54
    },
55
    {
56
        'Серебрянная руда',
57
        'Серебрянный слиток',
58
2,
59
        take = {name='ThermalFoundation:Ore', damage=2},
60
        give = {name='IC2:itemIngot', damage=6},
61
        rate = {take = 1, give = 2}  -- добавлена запятая
62
    },
63
    {
64
        'Медная руда',
65
        'Медный слиток',
66
2,
67
        take = {name='IC2:blockOreCopper', damage=0},
68
        give = {name='IC2:itemIngot', damage=0},
69
        rate = {take = 1, give = 2}  -- добавлена запятая
70
    },
71
    {
72
        'Оловянная руда',
73
        'Оловянный слиток',
74
2,
75
        take = {name='IC2:blockOreTin', damage=0},
76
        give = {name='IC2:itemIngot', damage=1},
77
        rate = {take = 1, give = 2}  -- добавлена запятая
78
    },
79
    {
80
        '(АД)Медная Руда',
81
        'Медный слиток',
82
4,
83
        take = {name='NetherOres:tile.netherores.ore.0', damage=6},
84
        give = {name='IC2:itemIngot', damage=0},
85
        rate = {take = 1, give = 4}  -- добавлена запятая
86
    },
87
    {
88
        '(АД)Оловянная руда',
89
        'Оловянный слиток',
90
4,
91
        take = {name='NetherOres:tile.netherores.ore.0', damage=7},
92
        give = {name='IC2:itemIngot', damage=1},
93
        rate = {take = 1, give = 4}  -- добавлена запятая
94
    },
95
    {
96
        'Кварцевая руда',
97
        'Кварц',
98
3,
99
        take = {name='minecraft:quartz_ore', damage=0},  -- исправлено 'damege' на 'damage'
100
        give = {name='minecraft:quartz', damage=0},  -- исправлено 'damege' на 'damage'
101
        rate = {take = 1, give = 3}  -- добавлена запятая
102
    },
103
}
104
105
local unicode = require("unicode")
106
local computer = require("computer")
107
local com = require("component")
108
local event = require("event")
109
local me = com.isAvailable("me_interface") and com.me_interface or error("нет ме интерфейса")
110
local pim = com.isAvailable("pim") and com.pim or error("нет пима")
111
112
local gpu = com.gpu
113
local w, h = 80, 50
114
local defBG, defFG = gpu.getBackground(), gpu.getForeground()
115
gpu.setResolution(w, h)
116
117
local function center(height, text, color)
118
    gpu.setForeground(color)
119
    gpu.set(math.floor(w / 2 - unicode.len(text) / 2), height, text)
120
end
121
122
local function populateQty()
123
    local totalOre = 0
124
    for i, ore in pairs(ore_dict) do
125
    	local fingerprint = {id = ore.give.name, damage = ore.give.damage}
126
        local item = me.getItemDetail(fingerprint).basic()
127
        if item == nil then
128
            return 0
129
        else
130
            ore.sizeOfStack = item.max_size
131
            ore.qty = item.qty
132
            totalOre = totalOre + item.qty
133
        end
134
    end
135
    return totalOre
136
end
137
138
local function displayOres()
139
    local line = 2
140
    for i, ore in pairs(ore_dict) do
141
        local print_row = line + (i)
142
143
        gpu.setForeground(0x00ff00)
144
        gpu.set(5, print_row, ore[1])
145
        gpu.set(42, print_row, ore[2])
146
147
        gpu.setForeground(0xFF00FF)
148
        gpu.set(28, print_row, "1")
149
		gpu.set(34, print_row, " " .. ore.rate.give)
150
        gpu.set(73, print_row, tostring(ore.qty))
151
152
        gpu.setForeground(0xFFFF00)
153
        gpu.set(30, print_row, " ->")
154
        gpu.set(63, print_row, "Доступно:")
155
        gpu.setForeground(0x202020)
156
        gpu.set(2, print_row + 1, string.rep("═", w - 2))
157
        line = line + 1
158
    end
159
end
160
161
local function updateOres()
162
    local totalOre = populateQty()
163
    gpu.fill(1, 1, w, h - 16, " ")
164
    if totalOre == 0 then
165
        gpu.fill(1, 1, w, h - 15, " ")
166
        center(h - 15, "Нет соединения с МЭ", 0xff0000)
167
    else
168
        displayOres()
169
    end
170
end
171
172
local function giveItemFromMe(item, dmg, amount)
173
    local fingerprint = {id = item, dmg = dmg}
174
    local err, res = pcall(me.exportItem, fingerprint, "UP", amount)
175
    if err == true then
176
    	return res.size
177
    end
178
end
179
180
local function giveIngot(toGive, ore)
181
    local totalGive = 0
182
    local givePreIteration = 0
183
    while totalGive < toGive do
184
        if toGive - totalGive > 64 then
185
            givePreIteration = ore.sizeOfStack
186
        else
187
            givePreIteration = toGive - totalGive
188
        end
189
190
        local gived = giveItemFromMe(ore.give.name, ore.give.damage, givePreIteration)
191
192
        totalGive = totalGive + gived
193
        if gived == 0 then
194
            gpu.fill(1, h - 15, w, 2, " ")
195
            center(h - 15, "Oсвободите место в инвентаре", 0xff0000)
196
            center(h - 14, "Ожидаю выдать " .. tostring(toGive - totalGive) .. " " .. ore[2], 0xFFFFFF)
197
            os.sleep(1)
198
        end
199
        gpu.fill(1, h - 15, 2, h, " ")
200
    end
201
end
202
203
local function logExchange(playerName, oreName, amountTaken, ingotName, amountGiven)
204
    local logFile = io.open("exchange_log.txt", "a") -- открыть файл для добавления
205
    if logFile then
206
        local logEntry = string.format("[%s] %s обменял(а) %d %s на %d %s\n", 
207
                                        os.date("%Y-%m-%d %H:%M:%S"), 
208
                                        playerName, 
209
                                        amountTaken, 
210
                                        oreName, 
211
                                        amountGiven, 
212
                                        ingotName)
213
        logFile:write(logEntry) -- записать запись в файл
214
        logFile:close() -- закрыть файл
215
    else
216
        print("Не удалось открыть лог файл!")
217
    end
218
end
219
220
local function exchangeOre(slot, ore)
221
    local curSlot = pim.getStackInSlot(slot)
222
    if curSlot == nil then
223
        center(h - 14, "Вы сошли с PIM, обмен прерван. (Не удалось прочесть слот)", 0xff0000)
224
        os.sleep(0.5)
225
        return
226
    end
227
    local userOreQty = curSlot.qty
228
    local takeQty = userOreQty - (userOreQty % ore.rate.take)
229
    local giveQty = userOreQty * ore.rate.give
230
    if ore.qty < giveQty then
231
        gpu.fill(1, h - 14, w, 1, " ")
232
        center(h - 14, "Недостаточно слитков для обмена <" .. ore[1] .. ">", 0xff0000)
233
        os.sleep(0.5)
234
        return
235
    end
236
    -- Количетсво могло измениться..
237
    local takedOre = pim.pushItem("DOWN", slot, takeQty)
238
239
    if takedOre == nil then
240
        gpu.fill(1, h - 14, w, 1, " ")
241
        center(h - 14, "Вы сошли с PIM, обмен прерван. (Не удалось извлечь руду)", 0xff0000)
242
        os.sleep(0.5)
243
    elseif takedOre == 0 then
244
        gpu.fill(1, h - 14, w, 1, " ")
245
        center(h - 14, "В выбраном слоте руды нет.. А была.. Хмм...", 0x505050)
246
    else
247
        local giveQty = (takedOre // ore.rate.take) * ore.rate.give
248
        gpu.fill(1, h - 15, w, 2, " ")
249
        center(h - 14, "Меняю  " .. takedOre .. "  " .. ore[1] .. "  на  " .. giveQty .. "  " .. ore[2], 0xffffff)
250
        giveIngot(giveQty, ore)
251
        
252
        -- Логируем обмен
253
        logExchange("Игрок", ore[1], takedOre, ore[2], giveQty) -- замените "Игрок" на имя игрока, если оно доступно
254
    end
255
end
256
257
local function checkInventory()
258
    local size = pim.getInventorySize()
259
    local data = pim.getAllStacks(0)
260
261
    for slot = 1, size do
262
        if data[slot] then
263
            for i, ore in pairs(ore_dict) do
264
                if data[slot].id == ore.take.name and data[slot].dmg == ore.take.damage then
265
                    exchangeOre(slot, ore)
266
                end
267
            end
268
        end
269
    end
270
271
    updateOres()
272
273
    if pim.getInventoryName() ~= "pim" then
274
        gpu.fill(1, h - 15, w, 2, " ")
275
        center(h - 15, "Обмен окончен! Приходите ещё!", 0xffffff)
276
277
        checkInventory()
278
    else
279
        -- Может быть, мы не поймали событие когда юзер ушел
280
        event.push("player_off")
281
    end
282
end
283
284
function handleEvent(eventID, ...)
285
    local args = {...}
286
    if eventID == "interrupted" then
287
        gpu.setBackground(defBG)
288
        gpu.setForeground(defFG)
289
        gpu.fill(1, 1, w, h, " ")
290
        os.exit()
291
        return true
292
    elseif eventID == "player_on" then
293
        gpu.fill(1, h - 15, w, 1, " ")
294
        center(h - 15, "Приветствую, " .. args[1] .. "! Начинаю обмен", 0xffffff)
295
        updateOres()
296
        checkInventory()
297
    elseif eventID == "player_off" then
298
        gpu.fill(1, h - 15, w, 1, " ")
299
        center(h - 15, "Для обмена встаньте на PIM и не сходите до окончания обмена", 0xffffff)
300
        updateOres()
301
    end
302
end
303
304
function drawStat()
305
    gpu.setForeground(0x444444)
306
    gpu.set(
307
        2,
308
        h - 1,
309
        string.format(
310
            "RAM: %.1fkB / %.1fkB",
311
            (computer.totalMemory() - computer.freeMemory()) / 1024,
312
            computer.totalMemory() / 1024
313
        )
314
    )
315
end
316
317
local oreTimeFn = function()
318
    updateOres()
319
    -- Каджый 10 такт обновляем экран
320
    for i = 1, 10 do
321
        coroutine.yield()
322
    end
323
end
324
local oreTimer = coroutine.create(oreTimeFn)
325
326
function draw_img(img, x, y, fore, back)
327
    fore = fore or 0xffffff
328
    back = back or 0x0
329
    oldFG = gpu.getForeground()
330
    gpu.setForeground(fore)
331
    local i = 0
332
    for line in img:gmatch("([^\n]*)\n?") do
333
        gpu.set(x, y + i, line)
334
        i = i + 1
335
    end
336
    gpu.setForeground(oldFG)
337
end
338
local img =
339
    [[
340
    ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
341
    ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡐⢆⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
342
    ⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠠⡐⣄⢢⡐⢄⢢⡐⣄⠂⡄⠀⠀⢄⢢⢰⣀⢦⡐⣄⢢⡐⠄⣂⠆⠀⠀⢀⡐⢦⠹⠌⠀⢀⡰⢠⠀⠐⣠⠀⠀⠀⠀⠀⠀⠀⠀⠄⡐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
343
    ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢡⠂⡄⠀⠀⠀⠀⠌⡤⠃⠀⢳⡌⠃⠘⠈⠂⠑⠈⠑⠀⠀⡜⡢⠍⠂⠑⠈⠑⠈⠃⠀⠐⣌⠎⢀⡐⠦⣜⠂⠁⠀⠀⠀⡜⡡⠂⠘⠤⡁⠀⠀⠀⠀⠀⠀⠀⢂⠱⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
344
    ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢢⠑⡌⢢⠀⠤⣉⡜⣰⠁⠀⡣⢝⠀⠀⠀⠀⠀⠀⠀⠀⢀⠳⣹⢌⡱⢢⡱⢌⢲⢰⡀⠀⢎⠺⣤⣙⠳⣀⠀⠀⠀⠀⠠⣙⠦⠁⢨⣑⠂⠀⠀⠀⠀⠀⠀⠀⢌⠳⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
345
    ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢢⡑⠈⠒⡭⠒⠌⠸⣡⠃⠀⣙⠮⡄⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠈⠁⠁⠉⣈⠞⡢⠄⠈⢎⡳⠂⠉⠳⢆⡆⣀⠀⠀⠐⡌⠦⠁⠠⣃⠎⠀⠀⠀⠀⠀⠀⠀⠌⢒⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
346
    ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠒⡄⠁⠀⠀⠁⠀⠰⣡⠂⠀⠈⠸⣑⢋⢆⢳⡘⣔⠣⢆⢠⠱⣊⡕⣎⢖⡱⢎⠞⠁⠀⠈⣎⠱⠀⠀⠀⠈⠲⣡⠢⠄⠀⡜⡡⠂⠐⡥⢊⡴⢡⠎⡤⢁⠆⠀⠘⡀⠎⡐⢂⠰⠀⠆⡀⠀⠀⠀⠀⠀
347
    ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⢌⡁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
348
    ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
349
    ]]
350
351
function copyleft()
352
    local text = {
353
        {"Авторы: ", 0x444444, w - 35},
354
        {"Rijen, Intro2255", 0x64fff2, w - 28}
355
    }
356
    local startPos = w - 32
357
    for i, str in pairs(text) do
358
        gpu.setForeground(str[2])
359
        gpu.set(str[3], h - 1, str[1])
360
    end
361
362
    gpu.setBackground(defBG)
363
    gpu.setForeground(defFG)
364
end
365
366
gpu.fill(1, 1, w, h, " ")
367
center(h - 15, "Для обмена встаньте на PIM и не сходите до окончания обмена", 0xffffff)
368
draw_img(img, 1, h - 13, 0x00a400)
369
copyleft()
370
371
while true do
372
    drawStat()
373
374
    handleEvent(event.pull(1))
375
376
    if coroutine.status(oreTimer) == "dead" then
377
        oreTimer = coroutine.create(oreTimeFn)
378
    else
379
        coroutine.resume(oreTimer)
380
    end
381
end
382