· 3 years ago · Nov 13, 2021, 09:10 PM
1filenames = {}
2filenames.configFolder = "config"
3filenames.tankContents = filenames.configFolder.."/tank_contents.json"
4filenames.potionTypes = filenames.configFolder.."/potion_types.json"
5
6materialNames = {
7 redstone = "minecraft:redstone",
8 glowstone = "minecraft:glowstone",
9 gunpowder = "minecraft:gunpowder"
10}
11
12term.clear()
13term.setCursorPos(1,1)
14term.setTextColor(colors.white)
15json = {}
16if not fs.exists("apis/json") then
17 print("Downloading json api...")
18 shell.run("pastebin","get","4nRg9CHU","apis/json")
19end
20if not fs.exists(filenames.potionTypes) then
21 print("Downloading potion types config...")
22 shell.run("pastebin","get","YBSC0sGp",filenames.potionTypes)
23end
24
25filenames = {
26 tankContents = "tank_contents.json"
27}
28UNKNOWN = "unknown"
29
30potionTypes = {}
31potionModifiers = {
32 normal="Normal",
33 splash="Splash",
34 extended="Extended",
35 levelTwo="Level II",
36 lingering="Lingering"
37}
38
39waterTank = nil
40storageTanks = {}
41basinName = nil
42inventory = nil
43monitors = {}
44
45string.startsWith = function(self,str)
46 return self:find("^"..str)
47end
48table.contains = function(self,value)
49 for _, v in ipairs(self) do
50 if v == value then
51 return true
52 end
53 end
54 return false
55end
56container={
57 contents={},
58 contentsMatch=function(self,value)
59 if self.contents == nil then
60 return value == nil
61 elseif value == nil then
62 return false
63 end
64 if self.contents.name ~= value.name then
65 return false
66 end
67 if self.contents.name == UNKNOWN then
68 return true
69 end
70 return self.contents.modifier == value.modifier
71 end
72}
73
74function clearMonitor(mon)
75 if mon ~= nil then
76 mon.clear()
77 mon.setCursorPos(1,1)
78 elseif #monitors > 0 then
79 for _,v in ipairs(monitors) do
80 v.clear()
81 v.setCursorPos(1,1)
82 end
83 end
84end
85function writeMonitor(text)
86 if #monitors > 0 then
87 for k,v in ipairs(monitors) do
88 clearMonitor(v)
89 v.setTextColor(colors.write)
90 v.write(text)
91 end
92 end
93end
94function writeMonitorError(text)
95 if #monitors > 0 then
96 for k,v in ipairs(monitors) do
97 clearMonitor(v)
98 v.setTextColor(colors.red)
99 v.write(text)
100 end
101 end
102end
103function clearTerm()
104 term.clear()
105 term.setCursorPos(1,1)
106end
107function printError(text)
108 term.setTextColor(colors.red)
109 print(text)
110 term.setTextColor(colors.white)
111end
112function printLine()
113 print()
114end
115function waitForKey()
116 return os.pullEvent("key")
117end
118
119function wrapPeripherals()
120 while true do
121 waterTank = nil
122 storageTanks = {}
123 basin = nil
124 inventory = nil
125 monitors = {}
126 for _,v in ipairs(peripheral.getNames()) do
127 if v:startsWith("create:fluid_tank") then
128 local t = peripheral.wrap(v)
129 local tanks = t.tanks()
130 if #tanks > 0 and tanks[1].name == "minecraft:water" then
131 waterTank = t
132 waterTank.name = v
133 else
134 t.name = v
135 if #tanks > 0 then
136 t.contents = {
137 name=UNKNOWN,
138 modifier=potionModifiers.normal
139 }
140 else
141 t.contents = nil
142 end
143 t.contentsMatch = container.contentsMatch
144 storageTanks:insert(t)
145 end
146 elseif v:startsWith("create:basin") then
147 basin = peripheral.wrap(v)
148 basin.name = v
149 elseif v:startsWith("monitor") then
150 monitors:insert(peripheral.wrap(v))
151 elseif inventory == nil then
152 local sideNames = {"top","front","left","right","back","bottom"}
153 if not table.contains(sideNames,v) then
154 local p = peripheral.wrap(v)
155 if p.pullItem ~= nil then
156 inventory = p
157 inventory.name = v
158 end
159 end
160 end
161 end
162 local messages = {}
163 if waterTank == nil then
164 messages:insert("No water tank found")
165 end
166 if #storageTanks == 0 then
167 messages:insert("No storage tanks found")
168 end
169 if basin == nil then
170 messages:insert("No basin found")
171 end
172 if inventory == nil then
173 messages:insert("No inventory found")
174 end
175 if #messages > 0 then
176 writeMonitorError("Could not find necessary peripherals")
177 clearTerm()
178 printError("Could not find necessary peripherals")
179 for _,msg in ipairs(messages) do
180 printError("- "..msg)
181 end
182 printLine()
183 print("Press X to quit. Press any other key to retry.")
184 local event, key = waitForKey()
185 if key == keys.x then
186 return false
187 end
188 else
189 return true
190 end
191 end
192end
193function initializePotionTypes()
194 potionTypes = {}
195 if not pcall(function()
196 potionTypes = json.decodeFromFile(filenames.potionTypes)
197 local kvs = pairs(potionTypes)
198 for typeName,typeData in kvs do
199 for _,displayName in ipairs(typeData.names) do
200 potionTypes[displayName] = typeName
201 end
202 end
203 end) then
204 --failed to decode file and load potion types
205 clearTerm()
206 printError("An error occurred while loading potion types")
207 waitForKey()
208 os.exit()
209 end
210end
211function getPotionTypeByName(name)
212 return potionTypes[potionTypes[name]]
213end
214function initializeTankContents()
215 if fs.exists(filenames.tankContents) then
216 local contents = nil
217 if not pcall(function()
218 contents = json.decodeFromFile(filenames.tankContents)
219 for _,tank in ipairs(storageTanks) do
220 if tank.contents ~= nil then
221 if contents[tank.name] ~= nil then
222 tank.contents = contents[tank.name]
223 end
224 end
225 end
226 end) then
227 --failed to decode file and set tank contents
228 clearTerm()
229 printError("An error occurred while reading previous tank contents")
230 waitForKey()
231 end
232 writeTankContents()
233 end
234end
235function writeTankContents()
236 local contents = {}
237 for _,tank in storageTanks do
238 if tank.contents ~= nil and tank.contents.name ~= UNKNOWN then
239 contents[tank.name] = tank.contents
240 end
241 end
242 if not pcall(function()
243 local h = fs.open(filenames.tankContents,"w")
244 h.write(json.encode(contents))
245 h.close()
246 end) then
247 printError("Error writing tank contents file")
248 waitForKey()
249 end
250end
251
252function findStorage(potionName,modifier)
253 --finds all storage tanks containing the specified fluid
254 --also adds an empty tank to the end of the table
255 local tanks = {}
256 local emptyTank = nil
257 local search = {
258 name=potionName,
259 modifier=modifier
260 }
261 for _,v in ipairs(storageTanks) do
262 if #v.tanks() ~= 0 then
263 if v:contentsMatch(search) then
264 tanks:insert(v)
265 end
266 elseif emptyTank == nil then
267 emptyTank = v
268 end
269 end
270 if emptyTank ~= nil then
271 tanks:insert(emptyTank)
272 end
273 return tanks
274end
275
276function refillWater()
277 basin.pullFluid(waterTank.name)
278end
279
280function run()
281 if not wrapPeripherals() then
282 os.exit()
283 end
284
285 clearMonitor()
286 clearTerm()
287
288 if not os.loadAPI("apis/json") then
289 writeMonitorError("Could not load json api")
290 printError("Could not load json api")
291 os.exit()
292 end
293
294 initializeTankContents()
295 initializePotionTypes()
296end
297
298run()