SHOW:
|
|
- or go back to the newest paste.
1 | -- Refined Storage autocraft | |
2 | -- | |
3 | -- Run the program with the pathname of the crafts' listing file | |
4 | -- Crafts file (a craft per line): [item_name] [count] | |
5 | -- File example: https://pastebin.com/zDrXzfSM | |
6 | -- | |
7 | -- Created by Nyhillius | |
8 | ||
9 | local event = require("event") | |
10 | local io = require("io") | |
11 | local sides = require("sides") | |
12 | local term = require("term") | |
13 | local component = require("component") | |
14 | local rs = component.block_refinedstorage_interface | |
15 | ||
16 | local args = { ... } | |
17 | local paths = {} | |
18 | ||
19 | -- Print contents of `tbl`, with indentation. | |
20 | -- `indent` sets the initial level of indentation. | |
21 | function tprint (tbl, indent) | |
22 | if not indent then indent = 0 end | |
23 | for k, v in pairs(tbl) do | |
24 | formatting = string.rep(" ", indent) .. k .. ": " | |
25 | if type(v) == "table" then | |
26 | print(formatting) | |
27 | tprint(v, indent+1) | |
28 | elseif type(v) == 'boolean' then | |
29 | print(formatting .. tostring(v)) | |
30 | else | |
31 | print(formatting .. v) | |
32 | end | |
33 | end | |
34 | end | |
35 | ||
36 | -- Check if the file exist | |
37 | local function file_exist(path) | |
38 | local file = io.open(path) | |
39 | ||
40 | if (not file) then | |
41 | print("[ERROR]: No such file: " .. path .. ".") | |
42 | return false | |
43 | end | |
44 | io.close(file) | |
45 | return true | |
46 | end | |
47 | ||
48 | -- Load and parse the file, return a table with all the item to craft. | |
49 | local function load_file(path) | |
50 | local crafts = {} | |
51 | ||
52 | - | local n, c, l, f = line:match "(%S+)%s+(%d+)" |
52 | + | |
53 | - | l = n:match "(%u%S+)" |
53 | + | local n, c, m = line:match "(%S+)%s+(%d+)%s*(%d*)" |
54 | - | f = n:match("(%l+:%l+)") |
54 | + | local l = n:match "(%u%S+)" |
55 | - | if (l) then |
55 | + | local f = n:match("(%l+:%l+)") |
56 | - | table.insert(crafts, { name = f, label = l, count = c, fullName = n }) |
56 | + | if m == "" then |
57 | m = nil | |
58 | - | table.insert(crafts, { name = f, count = c, fullName = n }) |
58 | + | end |
59 | ||
60 | table.insert(crafts, { name = f, label = l, count = c, fullName = n, damage = m }) | |
61 | end | |
62 | return crafts | |
63 | end | |
64 | ||
65 | -- Check if a task have missing items. | |
66 | local function is_missing_items(task) | |
67 | if (task.missing.n > 0) then | |
68 | return true | |
69 | end | |
70 | return false | |
71 | end | |
72 | ||
73 | -- Check if craft is already on the tasks' queue. | |
74 | local function craft_is_on_tasks(craft, tasks) | |
75 | for i, task in ipairs(tasks) do | |
76 | if craft.name == task.stack.name then | |
77 | local missing_items = rs.getMissingItems(task.stack, task.quantity) | |
78 | for j, item in ipairs(missing_items) do | |
79 | print("[WARNING]: Missing " .. item.size .. " " .. item.name) | |
80 | end | |
81 | return true | |
82 | end | |
83 | end | |
84 | return false | |
85 | end | |
86 | ||
87 | -- Craft an item | |
88 | function craft_item(craft, tasks) | |
89 | local toCraft = tonumber(craft.count) | |
90 | ||
91 | if (rs.hasPattern(craft)) then | |
92 | if (not craft_is_on_tasks(craft, tasks)) then | |
93 | local rsStack = rs.getItem(craft) | |
94 | ||
95 | if (rsStack) then | |
96 | toCraft = toCraft - rsStack.size | |
97 | end | |
98 | - | rs.craftItem(craft, toCraft) |
98 | + | |
99 | rs.scheduleTask(craft, toCraft) | |
100 | print("Crafting " .. toCraft .. "x of " .. craft.name) | |
101 | end | |
102 | end | |
103 | else | |
104 | print("[WARNING]: Missing pattern for: " .. craft.fullName .. ".") | |
105 | end | |
106 | end | |
107 | ||
108 | -- Destroy item | |
109 | function destroy_item(item) | |
110 | local rs_item = rs.getItem(item) | |
111 | local limit = tonumber(item.count) | |
112 | ||
113 | if (not rs_item) then | |
114 | return | |
115 | end | |
116 | while (rs_item.size > limit) do | |
117 | local dropped = rs.extractItem(rs_item, rs_item.size - limit, sides.down) | |
118 | ||
119 | rs_item.size = rs_item.size - dropped | |
120 | if (dropped < 1) then | |
121 | break | |
122 | end | |
123 | end | |
124 | end | |
125 | ||
126 | -- Check the args | |
127 | if (#args > 0) then | |
128 | paths[1] = os.getenv("PWD") .. "/" .. args[1] | |
129 | if not file_exist(paths[1]) then | |
130 | return | |
131 | end | |
132 | else | |
133 | print("[ERROR]: Filename is needed.") | |
134 | return | |
135 | end | |
136 | if (#args > 1) then | |
137 | paths[2] = os.getenv("PWD") .. "/" .. args[2] | |
138 | file_exist(paths[2]) | |
139 | end | |
140 | ||
141 | -- The main loop ("Ctrl + C" to interrup the program) | |
142 | term.clear() | |
143 | while (true) do | |
144 | local crafts = load_file(paths[1]) | |
145 | local tasks = rs.getTasks() | |
146 | local bin = nil | |
147 | ||
148 | -- Craft needed items | |
149 | for i, craft in ipairs(crafts) do | |
150 | craft_item(craft, tasks) | |
151 | end | |
152 | ||
153 | -- Destroy items | |
154 | if (paths[2]) then | |
155 | bin = load_file(paths[2]) | |
156 | for i, item in ipairs(bin) do | |
157 | destroy_item(item) | |
158 | end | |
159 | end | |
160 | ||
161 | -- Event handler | |
162 | local id = event.pull(5, "interrupted") | |
163 | if (id == "interrupted") then | |
164 | print("Program stopped.") | |
165 | break | |
166 | end | |
167 | end |