· 5 years ago · Mar 11, 2021, 05:02 AM
1
2package.loaded.warpdriveCommons = nil
3local w = require("warpdriveCommons")
4
5local data
6
7----------- Reactor support
8
9-- 0000000001111111111222222222233333333334444444444
10-- 1234567890123456789012345678901234567890123456789
11-- [Reactor stability % Laser level k ]
12-- [ 99.9 99.9 99.9 99.9 56 123456 123456 123456 ]
13-- [ 99.9 99.9 99.9 99.9 123.4 123.4 123.4 123.4 ]
14-- [ 99.9 99.9 99.9 99.9 4.5 x 456 123456 123456 ]
15-- [ 99.9 99.9 99.9 99.9 123456 123456 123456 123456 ]
16
17local reactor
18local reactorlasers = {}
19
20local reactor_outputMode = "off"
21local reactor_outputThreshold = 100
22local reactor_targetStability = 50
23local reactor_laserAmount = 10000
24
25local reactor_output = 0
26
27function reactor_read(parData)
28 data = parData
29end
30
31function reactor_boot()
32 if reactor ~= nil then
33 w.writeLn("Booting Reactor...")
34 reactor_outputMode, reactor_outputThreshold = reactor.outputMode()
35 reactor_targetStability = 100.0 - reactor.instabilityTarget()
36 reactor_laserAmount = reactor.stabilizerEnergy()
37 end
38end
39
40function reactor_cycleOutputMode()
41 if reactor_outputMode == "off" then
42 reactor_outputMode = "unlimited"
43 elseif reactor_outputMode == "unlimited" then
44 reactor_outputMode = "above"
45 elseif reactor_outputMode == "above" then
46 reactor_outputMode = "at_rate"
47 else
48 reactor_outputMode = "off"
49 end
50end
51
52function reactor_key(character, keycode)
53 if character == 's' or character == 'S' then -- S
54 reactor_start()
55 return true
56 elseif character == 'p' or character == 'P' then -- P
57 reactor_stop()
58 return true
59 elseif character == 'l' or character == 'L' then -- L
60 reactor_laser()
61 return true
62 elseif character == 'o' or character == 'O' then -- O
63 reactor_cycleOutputMode()
64 reactor_setMode()
65 return true
66 elseif character == 'g' or character == 'G' then -- G
67 reactor_outputThreshold = reactor_outputThreshold - 1000
68 reactor_setMode()
69 return true
70 elseif character == 't' or character == 'T' then -- T
71 reactor_outputThreshold = reactor_outputThreshold + 1000
72 reactor_setMode()
73 return true
74 elseif character == 'j' or character == 'J' then -- J
75 reactor_laserAmount = reactor_laserAmount - 500
76 reactor_setLaser()
77 return true
78 elseif character == 'u' or character == 'U' then -- U
79 reactor_laserAmount = reactor_laserAmount + 500
80 reactor_setLaser()
81 return true
82 elseif character == '-' then -- -
83 reactor_targetStability = reactor_targetStability - 1
84 reactor_setTargetStability()
85 return true
86 elseif character == '+' then -- +
87 reactor_targetStability = reactor_targetStability + 1
88 reactor_setTargetStability()
89 return true
90 elseif character == 'c' or character == 'C' then -- C
91 reactor_config()
92 return true
93 end
94 return false
95end
96
97function reactor_page()
98 w.page_begin(w.data_getName() .. " - Reactor status")
99
100 w.setCursorPos(1, 2)
101 if reactor == nil or reactor.isInterfaced() == nil then
102 w.setColorDisabled()
103 w.write("Reactor not detected")
104 else
105 w.setColorNormal()
106 w.write("Reactor stability (%)")
107 local instabilities = { reactor.getInstabilities() }
108 for key, instability in pairs(instabilities) do
109 local y = (key - 1) % 4
110 local x = (key - 1 - y) / 4
111 w.setCursorPos(2 + 6 * x, 3 + y)
112 local stability = math.floor((100.0 - instability) * 10) / 10.0
113 if stability >= reactor_targetStability then
114 w.setColorSuccess()
115 else
116 w.setColorWarning()
117 end
118 w.write(w.format_float(stability, 5))
119 end
120
121 w.setColorNormal()
122 local energyStored, energyMax, energyUnits, _, energyOutputRate = reactor.getEnergyStatus()
123 w.setCursorPos(1, 7)
124 w.write("Energy : ")
125 w.write(w.format_integer(energyStored, 10) .. " / " .. w.format_integer(energyMax, 10) .. " " .. energyUnits .. " +" .. w.format_integer(reactor_output, 6) .. " " .. energyUnits .. "/t")
126 w.setCursorPos(1, 8)
127 w.write("Outputing: ")
128 w.write(w.format_integer(energyOutputRate, 6) .. " " .. energyUnits .. "/t")
129
130 w.setCursorPos(1, 9)
131 w.setColorNormal()
132 w.write("Activated: ")
133 local isEnabled = reactor.enable()
134 if isEnabled then w.setColorSuccess() else w.setColorNormal() end
135 w.write(w.format_boolean(isEnabled, "YES", "no"))
136 end
137
138 w.setCursorPos(28, 2)
139 if #reactorlasers == 0 then
140 w.setColorDisabled()
141 w.write("Lasers not detected")
142 else
143 w.setColorNormal()
144 w.write("Lasers charge (k)")
145
146 for _, reactorlaser in pairs(reactorlasers) do
147 if reactorlaser.wrap ~= nil and reactorlaser.side ~= nil then
148 local y = reactorlaser.side % 4
149 local x = (reactorlaser.side - y) / 4
150 w.setCursorPos(28 + 6 * x, 3 + y)
151 local energyStored, _, _ = reactorlaser.wrap.getEnergyStatus()
152 if energyStored == nil then
153 energyStored = -1
154 end
155 local energy_k = math.floor(energyStored / 100) / 10.0
156 if not reactorlaser.wrap.getAssemblyStatus() then
157 w.setColorDisabled()
158 elseif energyStored > 3 * reactor_laserAmount then
159 w.setColorSuccess()
160 else
161 w.setColorWarning()
162 end
163 w.write(w.format_integer(energy_k, 5))
164 end
165 end
166 end
167
168 w.setCursorPos(1, 10)
169 w.setColorNormal()
170 w.write(" -----------------------------------------------")
171 w.setCursorPos(1, 11)
172 w.write("Output mode : ")
173 if reactor_outputMode == "off" then
174 w.setColorDisabled()
175 w.write("hold")
176 elseif reactor_outputMode == "unlimited" then
177 w.write("manual/unlimited")
178 elseif reactor_outputMode == "above" then
179 w.write("surplus above " .. reactor_outputThreshold .. " RF")
180 else
181 w.write("rated at " .. reactor_outputThreshold .. " RF")
182 end
183 w.setCursorPos( 1, 12)
184 w.setColorNormal()
185 w.write("Target stability: " .. reactor_targetStability .. "%")
186 w.setCursorPos(30, 12)
187 w.write("Laser amount: " .. w.format_integer(reactor_laserAmount))
188
189 w.setCursorPos(1, 18)
190 w.setColorControl()
191 w.writeFullLine(" Start/stoP reactor (S/P), Use lasers (L)")
192 w.writeFullLine(" Output mode (O), Configuration (C)")
193 w.writeFullLine(" Target stability (+/-), Laser amount (U/J)")
194 w.writeFullLine(" Output rate/threshold (T/G)")
195end
196
197function reactor_setMode()
198 if reactor_outputThreshold < 1 then
199 reactor_outputThreshold = 1
200 elseif reactor_outputThreshold > 100000 then
201 reactor_outputThreshold = 100000
202 end
203 if reactor ~= nil then
204 reactor.outputMode(reactor_outputMode, reactor_outputThreshold)
205 end
206end
207
208function reactor_setLaser()
209 if reactor_laserAmount < 1 then
210 reactor_laserAmount = 1
211 elseif reactor_laserAmount > 100000 then
212 reactor_laserAmount = 100000
213 end
214 if reactor ~= nil then
215 reactor_laserAmount = reactor.stabilizerEnergy(reactor_laserAmount)
216 end
217end
218
219function reactor_setTargetStability()
220 if reactor_targetStability < 1.0 then
221 reactor_targetStability = 1.0
222 elseif reactor_targetStability > 100.0 then
223 reactor_targetStability = 100.0
224 end
225 if reactor ~= nil then
226 reactor_targetStability = 100.0 - reactor.instabilityTarget(100.0 - reactor_targetStability)
227 end
228end
229
230function reactor_start()
231 if reactor ~= nil then
232 reactor_setMode()
233 reactor.enable(true)
234 end
235end
236
237function reactor_stop()
238 if reactor ~= nil then
239 reactor.enable(false)
240 end
241end
242
243function reactor_laser(side)
244 for key, reactorlaser in pairs(reactorlasers) do
245 if (side == nil) or (reactorlaser.side == side) then
246 reactorlaser.wrap.stabilize(reactor_laserAmount)
247 end
248 end
249end
250
251local reactor_configPageLoaded = false
252local reactor_pulseStep = 0
253function reactor_pulse(output)
254 reactor_output = output
255 if reactor == nil or reactor.isInterfaced() == nil then
256 w.reboot()
257 end
258 local instabilities = { reactor.getInstabilities() }
259 reactor_pulseStep = (reactor_pulseStep + 1) % 16
260 if w.page_getCallbackDisplay() == reactor_page and (not reactor_configPageLoaded) then
261 for key, instability in pairs(instabilities) do
262 local y = (key - 1) % 4
263 local x = (key - 1 - y) / 4
264 w.setCursorPos(2 + 6 * x, 3 + y)
265 local stability = math.floor((100.0 - instability) * 10) / 10
266 if stability >= reactor_targetStability then
267 w.setColorSuccess()
268 else
269 w.setColorWarning()
270 end
271 w.write(w.format_float(stability, 5))
272 end
273
274 if reactor_pulseStep % 6 == 1 then
275 local energyStored, _, _, _, energyOutputRate = reactor.getEnergyStatus()
276 w.setCursorPos(12, 7)
277 w.setColorNormal()
278 w.write(w.format_integer(energyStored, 10))
279 w.setCursorPos(40, 7)
280 w.write(w.format_integer(reactor_output, 6))
281 w.setCursorPos(12, 8)
282 w.write(w.format_integer(energyOutputRate, 6))
283 end
284
285 if #reactorlasers ~= 0 then
286 for _, reactorlaser in pairs(reactorlasers) do
287 if reactorlaser.wrap ~= nil and reactorlaser.side ~= nil and reactor_pulseStep == key then
288 local y = reactorlaser.side % 4
289 local x = (reactorlaser.side - y) / 4
290 w.setCursorPos(28 + 6 * x, 3 + y)
291 local energyStored, _, _ = reactorlaser.wrap.getEnergyStatus()
292 if energyStored == nil then
293 energyStored = -1
294 end
295 local energy_k = math.floor(energyStored / 100) / 10.0
296local component = require("component") --require component in order to use the component API
297local sides = require("sides")
298local redstone = component.redstone -- create the variable "redstone" (which is shorter than typing out component.redstone) if not reactorlaser.wrap.getAssemblyStatus() then
299 w.setColorDisabled()
300 elseif energyStored > 3 * reactor_laserAmount then
301 w.setColorSuccess()
302redstone.setOutput(sides.bottom, 0)
303 else
304 w.setColorWarning()
305redstone.setOutput(sides.bottom, 15)
306 end
307 w.write(w.format_integer(energy_k, 5))
308 end
309 end
310 end
311 end
312end
313
314function reactor_config()
315 reactor_configPageLoaded = true
316 w.page_begin(w.data_getName() .. " - Reactor configuration")
317
318 w.setCursorPos(1, 2)
319 if reactor == nil or reactor.isInterfaced() == nil then
320 w.setColorDisabled()
321 w.write("Reactor not detected")
322 else
323 -- reactor output rate
324 w.setCursorPos(1, 6)
325 w.setColorHelp()
326 w.writeFullLine(" Enter a positive number.")
327
328 w.setCursorPos(1, 4)
329 w.setColorNormal()
330 w.write("Reactor output rate (" .. w.format_integer(reactor_outputThreshold) .. " RF): ")
331 reactor_outputThreshold = w.input_readInteger(reactor_outputThreshold)
332 reactor_setMode()
333 w.setCursorPos(1, 5)
334 w.write("Reactor output rate set")
335 w.setCursorPos(1, 6)
336 w.writeFullLine(" ")
337
338 -- laser amount
339 w.setCursorPos(1, 9)
340 w.setColorHelp()
341 w.writeFullLine(" Enter a positive number.")
342
343 w.setCursorPos(1, 7)
344 w.setColorNormal()
345 w.write("Laser energy level (" .. w.format_integer(reactor_laserAmount) .. "): ")
346 reactor_laserAmount = w.input_readInteger(reactor_laserAmount)
347 reactor_setLaser()
348 w.setCursorPos(1, 8)
349 w.write("Laser energy level set")
350 w.setCursorPos(1, 9)
351 w.writeFullLine(" ")
352
353 -- target stability
354 w.setCursorPos(1, 12)
355 w.setColorHelp()
356 w.writeFullLine(" Enter a positive number.")
357
358 w.setCursorPos(1, 10)
359 w.setColorNormal()
360 w.write("Reactor target stability (" .. w.format_integer(reactor_targetStability) .. "%): ")
361 reactor_targetStability = w.input_readInteger(reactor_targetStability)
362 reactor_setTargetStability()
363 w.setCursorPos(1, 11)
364 w.write("Reactor target stability set")
365 w.setCursorPos(1, 12)
366 w.writeFullLine(" ")
367 end
368 reactor_configPageLoaded = false
369end
370
371function reactor_register()
372 w.device_register("warpdriveEnanReactorCore",
373 function(deviceType, address, wrap) reactor = wrap end,
374 function() end)
375 w.device_register("warpdriveEnanReactorLaser",
376 function(deviceType, address, wrap) table.insert(reactorlasers, { side = wrap.side(), wrap = wrap }) end,
377 function() end)
378 w.event_register("reactorPulse" , function(eventName, param) reactor_pulse(param) return false end )
379 w.event_register("reactorDeactivation", function( ) w.status_showWarning("Reactor deactivated") return false end )
380 w.event_register("reactorActivation" , function( ) w.status_showWarning("Reactor activated") return false end )
381 w.data_register("reactor", reactor_read, nil, nil)
382end
383
384----------- connections status
385
386function connections_page(isBooting)
387 w.page_begin(w.data_getName() .. " - Connections")
388
389 w.writeLn("")
390
391 if reactor == nil or reactor.isInterfaced() == nil then
392 w.setColorDisabled()
393 w.writeLn("No Enantiomorphic reactor detected")
394 else
395 w.setColorSuccess()
396 w.writeLn("Enantiomorphic reactor detected")
397 if isBooting then
398 reactor_boot()
399 end
400 end
401
402 if #reactorlasers == 0 then
403 w.setColorDisabled()
404 w.writeLn("No reactor stabilisation laser detected")
405 elseif #reactorlasers == 1 then
406 w.setColorSuccess()
407 w.writeLn("1 reactor stabilisation laser detected")
408 else
409 w.setColorSuccess()
410 w.writeLn(#reactorlasers .. " reactor stabilisation lasers detected")
411 end
412
413 w.writeLn("")
414 w.setColorNormal()
415 w.writeLn("This is a keyboard controlled user interface.")
416 w.write("Key controls are written like so: ")
417 w.setColorControl()
418 w.write("Action (key)")
419 w.setColorNormal()
420 w.writeLn(".")
421 w.write("For example, typing ")
422 w.setColorControl()
423 w.write(" 1 ")
424 w.setColorNormal()
425 w.writeLn(" will open Reactor controls.")
426end
427
428----------- Boot sequence
429
430w.page_setEndText(" Home (0), Reactor controls (1)")
431w.page_register('0', connections_page, nil)
432w.page_register('1', reactor_page, reactor_key)
433reactor_register()
434
435w.boot()
436local success, message = pcall(w.run)
437if not success then
438 print("failed with message")
439 print(message)
440 w.sleep(3.0)
441 print("rebooting...")
442 w.reboot()
443else
444 w.close()
445end