Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local c = require "component"
- local e = require "event"
- local s = require "sides"
- local selector = c.transposer
- local gpu = c.gpu
- -------- Chests scheme -------- chest transposer
- -- C C C | C = chest | 1-3
- -- CTCTCTC | - = adapter | 4-7 1-3
- -- CTCTC | T = transposer | 8-10 4-5
- -- CTC-CTC |-----------------| 11-14 6-7
- -- CTCTC | 74 m3, 36 chs | 15-17 8-9
- -- CTCTCTC | | 18-21 10-12
- -- C C C | Usage sp 48.6% | 22-24
- -------------------------------
- ------ Used transposer API --------
- -- getAllStacks(side) |
- ------ Events format --------------
- -- "interrupted" ... |
- -- "touch" <address> <x> <y> ... |
- local cur_id, cur_addr
- local function attach_transposer(id)
- if id == cur_id then return cur_addr end
- if cur_id then
- selector.transferItem(s.down, s.north, 1, 1, cur_id)
- end
- if id then
- selector.transferItem(s.north, s.down, 1, id, 1)
- end
- cur_id = id
- local cname = "transposer" -- inventory_controller doesn't work
- cur_addr = ({e.pull(1, "component_added", nil, cname)})[2]
- return cur_addr
- end
- local function invoke_transposer(tid, ...)
- local addr = attach_transposer(tid)
- -- print("invoke", tid, ...)
- return c.invoke(addr, ...)
- end
- local N,E,W,S = s.north, s.east, s.west, s.south
- local chests = {
- ["2 1 0"] = {{N, 1}},
- ["4 1 0"] = {{N, 2}},
- ["6 1 0"] = {{N, 3}},
- ["1 2 0"] = {{W, 1}},
- ["3 2 0"] = {{W, 2}, {E, 1}, {N, 4}},
- ["5 2 0"] = {{W, 3}, {E, 2}, {N, 5}},
- ["7 2 0"] = {{E, 3}},
- ["2 3 0"] = {{S, 1}, {W, 4}, {N, 6}},
- ["4 3 0"] = {{S, 2}, {W, 5}, {E, 4}},
- ["6 3 0"] = {{S, 3}, {E, 5}, {N, 7}},
- ["1 4 0"] = {{W, 6}},
- ["3 4 0"] = {{S, 4}, {E, 6}, {N, 8}},
- ["5 4 0"] = {{S, 5}, {W, 7}, {N, 9}},
- ["7 4 0"] = {{E, 7}},
- ["2 5 0"] = {{S, 6}, {W, 8}, {N, 10}},
- ["4 5 0"] = {{W, 9}, {E, 8}, {N, 11}},
- ["6 5 0"] = {{S, 7}, {E, 9}, {N, 12}},
- ["1 6 0"] = {{W, 10}},
- ["3 6 0"] = {{S, 8}, {W, 11}, {E, 10}},
- ["5 6 0"] = {{S, 9}, {W, 12}, {E, 11}},
- ["7 6 0"] = {{E, 12}},
- ["2 7 0"] = {{S, 10}},
- ["4 7 0"] = {{S, 11}},
- ["6 7 0"] = {{S, 12}},
- }
- local filled = {
- [{0, 0}] = 0xFFFFFF,
- [{1, 7}] = 0xFFFF80,
- [{8, 64}] = 0xFF8080,
- [{65, 127}] = 0x808080,
- [{128, 191}] = 0x808000,
- [{192, 255}] = 0x800000,
- [{256, 1e9}] = 0x00FF00
- }
- local displayed_items = {}
- local cx, cy, selected_item
- local function draw_active_chest(x, y, color)
- gpu.setBackground(color or 0xFF0000)
- gpu.set(x * 2 + 2, y + 2, ' ')
- gpu.setBackground(0)
- end
- local items_buf = {}
- local function update_chest_info(key, position)
- local items = invoke_transposer(position[1][2], "getAllStacks", position[1][1]).getAll()
- local items_count = 0
- for i = 0, #items do
- items_count = items_count + (items[i].size or 0)
- end
- items_buf[key] = items
- items_buf[key].total_count = items_count
- for range, color in pairs(filled) do
- if items_count >= range[1] and items_count <= range[2] then
- draw_active_chest(tonumber(key:sub(1, 1)), tonumber(key:sub(3, 3)), color)
- break
- end
- end
- end
- local function draw_chest_info(s, items)
- for h = 3, 25 do gpu.set(20, h, (' '):rep(60)) end
- gpu.set(20, 3, 'Chest at `' .. s .. '`')
- if not items then return end
- displayed_items = {}
- selected_item = nil
- local h = 4
- for i = 0, #items do
- if items[i].name then
- local desc = items[i].name .. ' - ' .. (items[i].label or '') .. ' - ' .. tostring(math.floor(items[i].size))
- gpu.set(20, h, desc)
- displayed_items[h] = {["slot"] = i, ["size"] = items[i].size, ["desc"] = desc}
- h = h + 1
- end
- end
- return displayed_items, selected_item
- end
- local chest_dirs = {}
- for k, transposers in pairs(chests) do
- chest_dirs[k] = {}
- for i, t in ipairs(transposers) do
- chest_dirs[k][t[1]] = t[2]
- end
- end
- local tcache = {}
- local function mtc(tostr_return)
- return {
- __tostring = function(self)
- return tostr_return
- end
- }
- end
- local function collapse(...) -- make {x,y,z} able to be used as table key
- local tkey = table.concat({...}, ' ')
- if not tcache[tkey] then tcache[tkey] = setmetatable({...}, mtc(tkey)) end
- return tcache[tkey]
- end
- local function distance(x1, y1, z1, x2, y2, z2)
- return math.abs(x1 - x2) + math.abs(y1 - y2) + math.abs(z1 - z2)
- end
- local function move_item(x1, y1, z1, x2, y2, z2, count, slot)
- if z1 ~= 0 or z2 ~= 0 then error('Moving items along Z is not supported') end
- local cd = distance(x1, y1, z1, x2, y2, z2)
- if cd == 0 then return end
- local stx, sty, stz = x1, y1, z1
- local st = tostring(collapse(x2, y2, z2))
- if not chests[st] then error('Chest at `' .. st .. '` not found') end
- local valid_targets = {}
- local visited = {}
- visited[collapse(x1, y1, z1)] = true
- while x1 ~= x2 or y1 ~= y2 or z1 ~= z2 do
- local s = tostring(collapse(x1, y1, z1))
- if not chests[s] then error('Chest at `' .. s .. '` not found') end
- draw_active_chest(x1, y1)
- valid_targets = {}
- valid_targets[collapse(x1 - 2, y1, z1, E, W)] = chest_dirs[s][E]
- valid_targets[collapse(x1 + 2, y1, z1, W, E)] = chest_dirs[s][W]
- valid_targets[collapse(x1, y1 - 2, z1, S, N)] = chest_dirs[s][S]
- valid_targets[collapse(x1, y1 + 2, z1, N, S)] = chest_dirs[s][N]
- valid_targets[collapse(x1 - 1, y1 - 1, z1, E, N)] = chest_dirs[s][E]
- valid_targets[collapse(x1 - 1, y1 + 1, z1, E, S)] = chest_dirs[s][E]
- valid_targets[collapse(x1 + 1, y1 + 1, z1, W, S)] = chest_dirs[s][W]
- valid_targets[collapse(x1 + 1, y1 - 1, z1, W, N)] = chest_dirs[s][W]
- valid_targets[collapse(x1 - 1, y1 - 1, z1, S, W)] = chest_dirs[s][S]
- valid_targets[collapse(x1 - 1, y1 + 1, z1, N, W)] = chest_dirs[s][N]
- valid_targets[collapse(x1 + 1, y1 + 1, z1, N, E)] = chest_dirs[s][N]
- valid_targets[collapse(x1 + 1, y1 - 1, z1, S, E)] = chest_dirs[s][S]
- local best_xyz, best_transposer, best_target_distance = {}, 0, 65535
- for xyz_uv, transposer in pairs(valid_targets) do
- local x, y, z, u, v = table.unpack(xyz_uv)
- local dist = distance(x2, y2, z2, x, y, z)
- if dist < best_target_distance and not visited[collapse(x, y, z)] then
- -- print('Valid transposer', transposer, 'with distance', dist)
- best_xyz = xyz_uv
- best_transposer = transposer
- best_target_distance = dist
- end
- end
- if best_transposer == 0 then
- error('No moves available from ' .. s)
- end
- os.sleep(0.3)
- draw_active_chest(x1, y1, 0xFFFF00)
- local start_slot = (x1 == stx and y1 == sty and z1 == stz) and slot or 96
- local s1, s2
- x1, y1, z1, s1, s2 = table.unpack(best_xyz)
- local invoke_result
- if x1 ~= x2 or y1 ~= y2 or z1 ~= z2 then
- invoke_result = invoke_transposer(best_transposer, "transferItem", s1, s2, count, start_slot, 96)
- else
- invoke_result = invoke_transposer(best_transposer, "transferItem", s1, s2, count, start_slot)
- end
- if invoke_result <= 0.5 then
- error('Item not moved from ' .. s)
- end
- local new_chest_s = tostring(collapse(x1, y1, z1))
- update_chest_info(s, {{s1, best_transposer}})
- update_chest_info(new_chest_s, {{s2, best_transposer}})
- displayed_items, selected_item = draw_chest_info(new_chest_s, items_buf[new_chest_s])
- -- print('Moved to', x1, y1, z1)
- visited[collapse(x1, y1, z1)] = true
- end
- draw_active_chest(x2, y2)
- end
- os.execute('cls')
- gpu.set(1, 1, 'Please, wait for a while.')
- selector.transferItem(s.down, s.north, 1) -- force detach MFU
- for k,v in pairs(chests) do
- update_chest_info(k, v)
- end
- gpu.set(1, 1, 'Click on the chest to get information about it.')
- while true do
- local evt = {e.pull()}
- if evt[1] == 'interrupted' then
- break
- elseif evt[1] == 'touch' then
- local x, y = evt[3], evt[4]
- local chest_x, chest_y = math.floor(x) // 2 - 1, math.floor(y) - 2
- local s = tostring(chest_x) .. ' ' .. tostring(chest_y) .. ' 0'
- local items = items_buf[s]
- if items and selected_item then
- move_item(cx, cy, 0, chest_x, chest_y, 0, selected_item.size, selected_item.slot + 1)
- cx, cy = chest_x, chest_y
- selected_item = nil
- elseif items then
- displayed_items, selected_item = draw_chest_info(s, items)
- cx, cy = chest_x, chest_y
- elseif x >= 20 and displayed_items[y] then
- selected_item = displayed_items[y]
- gpu.setForeground(0x00FFFF)
- gpu.set(20, y, selected_item.desc)
- gpu.setForeground(0xFFFFFF)
- end
- end
- ::continue::
- end
- attach_transposer(nil)
- os.execute('cls')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement