· 6 years ago · Aug 29, 2019, 02:46 PM
1--/ Storinator / Reactified /--
2if not turtle then
3 printError("This is a turtle program.")
4 return
5end
6local file = "/data"
7--/ System Variables /--
8local initRun = false
9local api = {}
10local data = {}
11local depth = 0
12--/ System Functions /--
13local function loadData()
14 if fs.exists(file) then
15 f = fs.open(file,"r")
16 data = textutils.unserialise(f.readAll())
17 f.close()
18 else
19 initRun = true
20 data = {
21 chests = {},
22 recipes = {},
23 aliases = {},
24 }
25 end
26end
27local function saveData()
28 f = fs.open(file,"w")
29 f.writeLine(textutils.serialise(data))
30 f.close()
31end
32local function gotoDepth(target)
33 while depth > target do
34 if not turtle.up() then return false end
35 depth = depth - 1
36 end
37 while depth < target do
38 if not turtle.down() then return false end
39 depth = depth + 1
40 end
41 return true
42end
43--/ Initialize System /--
44if not initRun then while turtle.up() do end end
45loadData()
46turtle.select(1)
47--/ Primary Functions /--
48function store(noReturn)
49 local err = false
50 local item = turtle.getItemDetail()
51 item = {count = item.count,name = item.name..tostring(item.damage)}
52 if not item then return false,"No item in selected slot." end
53 if not data.aliases[item.name] then
54 local shortname = item.name
55 shortname = string.sub(shortname,string.find(shortname,":")+1,#shortname)
56 local alias = ""
57 local caps = true
58 for i=1,#shortname do
59 local char = string.sub(shortname,i,i)
60 if char == "_" then
61 caps = true
62 char = " "
63 end
64 if caps and char ~= " " then
65 alias = alias .. string.upper(char)
66 caps = false
67 else
68 alias = alias .. char
69 end
70 end
71 data.aliases[item.name] = alias
72 end
73 chest = data.chests[item.name]
74 local cDepth = 1
75 if chest then
76 cDepth = chest.depth
77 else
78 for i,v in pairs(data.chests) do
79 cDepth = cDepth + 1
80 end
81 end
82 if gotoDepth(cDepth) then
83 local count = turtle.getItemCount()
84 turtle.drop()
85 local deposited = count - turtle.getItemCount()
86 if data.chests[item.name] then
87 prevCount = data.chests[item.name].count
88 else
89 prevCount = 0
90 end
91 data.chests[item.name] = {
92 count = prevCount + deposited,
93 depth = cDepth,
94 }
95 else
96 err = "Out of chests."
97 end
98 if not noReturn then gotoDepth(0) end
99 if turtle.getItemCount() > 0 and not err then
100 gotoDepth(0)
101 turtle.drop()
102 err = "Target chest is full."
103 end
104 saveData()
105 if err then
106 return false,err
107 else
108 return true
109 end
110end
111function fetch(item,quantity,noReturn)
112 local err = false
113 if data.chests[item] then
114 local chest = data.chests[item]
115 if turtle.getItemCount() > 0 then
116 return false,"Active slot not empty."
117 end
118 if not gotoDepth(chest.depth) then
119 if not noReturn then gotoDepth(0) end
120 return false,"Chest inaccessible."
121 end
122 turtle.suck(quantity or 1)
123 if turtle.getItemCount() < (quantity or 1) then
124 turtle.drop()
125 if not noReturn then gotoDepth(0) end
126 return false,"Not enough items."
127 end
128 data.chests[item] = {
129 depth = chest.depth,
130 count = chest.count - turtle.getItemCount(),
131 }
132 saveData()
133 if not noReturn then gotoDepth(0) end
134 else
135 return false,"Item not in system."
136 end
137 return true
138end
139--/ Startup Warning /--
140if initRun then
141 term.setBackgroundColor(colors.white)
142 term.clear()
143 term.setCursorPos(2,2)
144 term.setTextColor(colors.gray)
145 term.write("Storinator ")
146 term.setTextColor(colors.lightGray)
147 term.write("by Reactified")
148 term.setCursorPos(1,4)
149 term.setTextColor(colors.black)
150 print(" ! Important !")
151 print(" If the turtle does not have a block")
152 print(" above it's home, it will fly away.")
153 print(" If the target chest is full, the")
154 print(" turtle will dump excess items into")
155 print(" the overflow container (top chest)")
156 print(" Any free block in the turtle's")
157 print(" downwards shaft needs a chest")
158 term.setTextColor(colors.lightGray)
159 print(" Press enter to continue")
160 term.setTextColor(colors.white)
161 read()
162end
163--/ User Interface /--
164function prompt(name,options)
165 local cursor = 1
166 while true do
167 term.setBackgroundColor(colors.white)
168 term.setTextColor(colors.black)
169 term.clear()
170 term.setCursorPos(2,2)
171 write("Storinator ")
172 term.setTextColor(colors.lightGray)
173 write("| ")
174 term.setTextColor(colors.gray)
175 write(name)
176 for i,v in pairs(options) do
177 term.setCursorPos(2,3+i)
178 if cursor == i then
179 term.setBackgroundColor(colors.lightGray)
180 term.setTextColor(colors.black)
181 else
182 term.setBackgroundColor(colors.white)
183 term.setTextColor(colors.gray)
184 end
185 write(" "..v.." ")
186 end
187 local e,k = os.pullEvent("key")
188 if k == keys.down then
189 if cursor < #options then
190 cursor = cursor + 1
191 end
192 elseif k == keys.enter then
193 return cursor
194 elseif k == keys.up then
195 if cursor > 1 then
196 cursor = cursor - 1
197 end
198 end
199 end
200end
201local curX = 1
202local curY = 0
203local search = ""
204while true do
205 term.setBackgroundColor(colors.white)
206 term.clear()
207 term.setCursorPos(1,1)
208 if curX == 1 and curY == 0 then
209 term.setBackgroundColor(colors.gray)
210 term.setTextColor(colors.white)
211 else
212 term.setBackgroundColor(colors.lightGray)
213 term.setTextColor(colors.gray)
214 end
215 write(" Deposit ")
216 if curX == 2 and curY == 0 then
217 term.setBackgroundColor(colors.gray)
218 term.setTextColor(colors.white)
219 else
220 term.setBackgroundColor(colors.lightGray)
221 term.setTextColor(colors.gray)
222 end
223 write(" Craft ")
224 if curX == 3 and curY == 0 then
225 term.setBackgroundColor(colors.gray)
226 term.setTextColor(colors.white)
227 else
228 term.setBackgroundColor(colors.lightGray)
229 term.setTextColor(colors.gray)
230 end
231 local searchX = term.getCursorPos()
232 searchX = searchX + 1
233 write(" ")
234 term.setCursorPos(searchX,1)
235 if search == "" then
236 write("Search")
237 else
238 write(string.sub(search,1,21))
239 end
240 local items = {}
241 for i,v in pairs(data.chests) do
242 local alias = data.aliases[i]
243 if not alias then alias = string.upper(i) end
244 if string.find(string.lower(alias),search) then
245 items[#items+1] = {
246 id = i,
247 name = alias,
248 count = v.count,
249 }
250 end
251 end
252 for i=1,12 do
253 if i==curY then
254 term.setBackgroundColor(colors.gray)
255 term.setTextColor(colors.white)
256 else
257 term.setBackgroundColor(colors.white)
258 term.setTextColor(colors.black)
259 end
260 term.setCursorPos(1,i+1)
261 term.clearLine()
262 term.setCursorPos(2,i+1)
263 if items[i] then
264 write(items[i]["name"])
265 term.setCursorPos(38-#tostring(items[i]["count"]),i+1)
266 term.write("x"..tostring(items[i]["count"]))
267 end
268 end
269 local evt,key = os.pullEvent("key")
270 if evt == "key" then
271 if key == keys.right and curX < 3 then
272 curX = curX + 1
273 elseif key == keys.left and curX > 1 then
274 curX = curX - 1
275 elseif key == keys.up and curY > 0 then
276 curY = curY - 1
277 elseif key == keys.down and curY < #items then
278 curY = curY + 1
279 elseif key == keys.x and curY > 0 and items[curY] then
280 term.setBackgroundColor(colors.white)
281 term.clear()
282 term.setCursorPos(2,2)
283 term.setTextColor(colors.black)
284 write("Storinator ")
285 term.setTextColor(colors.lightGray)
286 write("| ")
287 term.setTextColor(colors.gray)
288 write("Set Alias")
289 term.setCursorPos(2,4)
290 write(items[curY].name)
291 term.setTextColor(colors.lightGray)
292 write(" -> ")
293 term.setTextColor(colors.black)
294 local newAlias = read()
295 if newAlias and newAlias ~= "" then
296 data.aliases[items[curY].id] = newAlias
297 end
298 elseif key == keys.enter then
299 if curY > 0 and items[curY] then
300 -- Fetch
301 fetch(items[curY].id)
302 end
303 if curX == 3 and curY == 0 then
304 -- Search
305 term.setCursorPos(searchX,1)
306 term.setBackgroundColor(colors.gray)
307 term.setTextColor(colors.white)
308 term.write(" ")
309 term.setCursorPos(searchX,1)
310 search = read()
311 elseif curX == 2 and curY == 0 then
312 -- Craft
313 elseif curX == 1 and curY == 0 then
314 -- Deposit
315 term.setBackgroundColor(colors.white)
316 term.clear()
317 term.setCursorPos(2,2)
318 term.setTextColor(colors.black)
319 term.write("Storinator ")
320 term.setTextColor(colors.lightGray)
321 term.write("| ")
322 term.setTextColor(colors.gray)
323 term.write("Storing")
324 term.setCursorPos(1,4)
325 term.setTextColor(colors.black)
326 local mission = 0
327 local errorWarn = false
328 if turtle.getFuelLevel() < 256 then
329 print(" Refuel soon, fuel: "..tostring(turtle.getFuelLevel()))
330 errorWarn = true
331 end
332 local emptyInv = true
333 for i=1,16 do
334 turtle.select(i)
335 if turtle.getItemCount() > 0 then
336 emptyInv = false
337 local ok,err = store(true)
338 mission = mission + 1
339 write(" #"..tostring(mission).." ")
340 if ok then
341 print("Completed")
342 else
343 print(err)
344 errorWarn = true
345 end
346 end
347 end
348 if emptyInv then
349 print(" No items in inventory.")
350 end
351 turtle.select(1)
352 gotoDepth(0)
353 if errorWarn or emptyInv then
354 os.pullEvent("key")
355 end
356 end
357 end
358 end
359end