SHOW:
|
|
- or go back to the newest paste.
1 | --[[ | |
2 | Optimised Adaptive Turbine Controller with Feedback Rods | |
3 | -------------------------------------------------------- | |
4 | * Layout, colours, button coordinates, labels and overall behaviour are **identical** to the original program supplied in your first message. | |
5 | * The **only** changes are internal optimisations (no blocking sleeps inside the main loop, nil‑safety, double‑buffered drawing) so the UI feels instantaneous. | |
6 | ||
7 | Version: 2025‑06‑14 | |
8 | ]]-- | |
9 | ||
10 | --------------------------------------------------------------------- | |
11 | -- 1. CONFIGURATION -------------------------------------------------- | |
12 | --------------------------------------------------------------------- | |
13 | ||
14 | local reactorName = "BigReactors-Reactor_0" | |
15 | local turbineName = "BigReactors-Turbine_0" | |
16 | local monitorName = "monitor_0" | |
17 | local FLOW_PERSIST_FILE = "nominal_flow.txt" | |
18 | ||
19 | - | RPM_TARGET, RPM_TOLERANCE = 1800, 5 |
19 | + | local RPM_TARGET, RPM_TOLERANCE = 1800, 5 |
20 | - | local COIL_ON_RPM = RPM_TARGET -- engage inductor when at or above |
20 | + | local COIL_ON_RPM = RPM_TARGET -- engage inductor when at or above |
21 | - | local COIL_OFF_RPM = RPM_TARGET - RPM_TOLERANCE -- disengage when below |
21 | + | local COIL_OFF_RPM = RPM_TARGET -- RPM_TOLERANCE -- disengage when below |
22 | ||
23 | local FLOW_TUNE_LOWER, FLOW_TUNE_UPPER = 100, 2000 -- hard bounds | |
24 | local MAX_TUNE_ITER = 7 -- binary-search passes | |
25 | ||
26 | -- Fuel/control bar geometry (unchanged) | |
27 | - | local CTRLBAR_X, CTRLBAR_Y, CTRLBAR_WD, CTRLBAR_HT, CTRLBAR_SPC = 76, 6, 3, 29, 3 |
27 | + | local CTRLBAR_X, CTRLBAR_Y, CTRLBAR_WD, CTRLBAR_HT, CTRLBAR_SPC = 76, 6, 3, 30, 3 |
28 | - | local TURBAR_X, TURBAR_Y, TURBAR_WD, TURBAR_HT, TURBAR_SPC = 88, 6, 3, 29, 3 |
28 | + | local TURBAR_X, TURBAR_Y, TURBAR_WD, TURBAR_HT, TURBAR_SPC = 88, 6, 3, 30, 3 |
29 | ||
30 | -- RPM progress bar geometry | |
31 | - | local RPMBAR_X, RPMBAR_Y, RPMBAR_H, RPMBAR_W = 3, 21, 2, 70 |
31 | + | local RPMBAR_X, RPMBAR_Y, RPMBAR_H, RPMBAR_W = 3, 21, 3, 70 |
32 | ||
33 | -- Dynamics | |
34 | local FLOW_BUFFER = 0.10 -- % extra flow when we are too slow | |
35 | local DECEL_FRACTION = 0.25 -- fraction of flow to keep when too fast | |
36 | local FLOW_LEARN_STEP = 2 -- learning granularity (mB/t per loop) | |
37 | ||
38 | -- UI refresh cadence (seconds). 0.25 s ⇒ 4 FPS; change if needed. | |
39 | local UPDATE_PERIOD = 0.25 | |
40 | ||
41 | --------------------------------------------------------------------- | |
42 | -- 2. UTILITY HELPERS ------------------------------------------------ | |
43 | --------------------------------------------------------------------- | |
44 | ||
45 | --- Return numeric `v` or fallback `d` if v is nil. | |
46 | local function num(v, d) if v == nil then return d end; return v end | |
47 | ||
48 | --- Pad a string on the right so residual characters are overwritten. | |
49 | local function pad(str, width) | |
50 | if #str < width then str = str .. string.rep(" ", width-#str) end | |
51 | return str | |
52 | end | |
53 | ||
54 | --------------------------------------------------------------------- | |
55 | -- 3. UI PRIMITIVES (unchanged API) --------------------------------- | |
56 | --------------------------------------------------------------------- | |
57 | ||
58 | UI = {} | |
59 | ||
60 | function UI.rectangle(wd,x,y,w,h,color) | |
61 | local win = window.create(wd,x,y,w,h,true) | |
62 | win.setBackgroundColor(color); win.clear(); return win | |
63 | end | |
64 | ||
65 | function UI.bar(wd,x,y,w,h,bg,segments,max) | |
66 | local bar = UI.rectangle(wd,x,y,w,h,bg) | |
67 | local total = max or 100 | |
68 | if h < w then -- horizontal | |
69 | local px = 1 | |
70 | for _,s in ipairs(segments) do | |
71 | local segW = math.floor((s.p/total)*w + 0.5) | |
72 | UI.rectangle(bar,px,1,segW,h,s.color); px = px+segW | |
73 | end | |
74 | else -- vertical (bottom‑up fill) | |
75 | local py = h | |
76 | for _,s in ipairs(segments) do | |
77 | local segH = math.floor((s.p/total)*h + 0.5) | |
78 | UI.rectangle(bar,1,py-segH+1,w,segH,s.color); py = py-segH | |
79 | end | |
80 | end | |
81 | end | |
82 | ||
83 | function UI.progress_bar(wd,x,y,w,h,p,bg,fg) | |
84 | UI.bar(wd,x,y,w,h,bg,{{p=p,color=fg}},100) | |
85 | end | |
86 | ||
87 | function UI.drawRect(wd,x,y,w,h,color) | |
88 | wd.setTextColor(color or colors.white) | |
89 | wd.setCursorPos(x,y); wd.write("+" .. string.rep("-",w-2) .. "+") | |
90 | for i=1,h-2 do wd.setCursorPos(x,y+i); wd.write("|" .. string.rep(" ",w-2) .. "|") end | |
91 | wd.setCursorPos(x,y+h-1); wd.write("+" .. string.rep("-",w-2) .. "+") | |
92 | end | |
93 | ||
94 | function UI.drawTable(wd,x,y,cols,rows,cellW,cellH,color) | |
95 | wd.setTextColor(color or colors.white) | |
96 | local tW,tH=cols*cellW+1,rows*cellH+1 | |
97 | for dy=0,tH-1 do | |
98 | for dx=0,tW-1 do | |
99 | local cx,cy=x+dx,y+dy | |
100 | local rowLine=(dy%cellH==0); local colLine=(dx%cellW==0) | |
101 | local ch = (rowLine and colLine) and "+" or rowLine and "-" or colLine and "|" or " " | |
102 | wd.setCursorPos(cx,cy); wd.write(ch) | |
103 | end | |
104 | end | |
105 | end | |
106 | ||
107 | local function UIHeader(wd,x,y,w,h,text,bg,fg) | |
108 | local hdr=UI.rectangle(wd,x,y,w,h,bg) | |
109 | wd.setTextColor(fg) | |
110 | wd.setCursorPos(x+math.floor(w/2-#text/2),y+math.floor(h/2)) | |
111 | wd.write(text) | |
112 | end | |
113 | ||
114 | --------------------------------------------------------------------- | |
115 | -- 4. PERIPHERAL SET‑UP --------------------------------------------- | |
116 | --------------------------------------------------------------------- | |
117 | ||
118 | local reactor = peripheral.wrap(reactorName) or error("Reactor not found") | |
119 | local turbine = peripheral.wrap(turbineName) or error("Turbine not found") | |
120 | local monitor = peripheral.wrap(monitorName) or peripheral.find("monitor") or error("Monitor not found") | |
121 | ||
122 | monitor.setTextScale(0.5) | |
123 | monitor.setBackgroundColor(colors.black) | |
124 | monitor.setTextColor(colors.white) | |
125 | monitor.clear() | |
126 | ||
127 | --------------------------------------------------------------------- | |
128 | -- 5. FLOW AUTOTUNE (runs once) ------------------------------------- | |
129 | --------------------------------------------------------------------- | |
130 | ||
131 | - | local function setRPMTarget(val) |
131 | + | |
132 | - | RPM_TARGET = val |
132 | + | |
133 | - | COIL_ON_RPM = RPM_TARGET |
133 | + | |
134 | - | COIL_OFF_RPM = RPM_TARGET - RPM_TOLERANCE |
134 | + | |
135 | end | |
136 | end | |
137 | ||
138 | local function writeFlow(v) | |
139 | local file=fs.open(FLOW_PERSIST_FILE,"w"); file.write(tostring(v)); file.close() | |
140 | end | |
141 | ||
142 | local function tuneFlow() | |
143 | local best, bestDelta=nil, math.huge | |
144 | local lo,hi=FLOW_TUNE_LOWER,FLOW_TUNE_UPPER | |
145 | for _=1,MAX_TUNE_ITER do | |
146 | local tf=math.floor((lo+hi)/2) | |
147 | turbine.setFluidFlowRateMax(tf) | |
148 | os.sleep(1) | |
149 | local r1=turbine.getRotorSpeed(); os.sleep(2); local r2=turbine.getRotorSpeed() | |
150 | local d=math.abs(r2-r1) | |
151 | if r2>RPM_TARGET+RPM_TOLERANCE then hi=tf-1 | |
152 | elseif r2<RPM_TARGET-RPM_TOLERANCE then lo=tf+1 | |
153 | else if d<bestDelta then best,bestDelta=tf,d end; if d<=1 then break end end | |
154 | end | |
155 | best = best or FLOW_TUNE_UPPER; writeFlow(best); return best | |
156 | end | |
157 | ||
158 | --------------------------------------------------------------------- | |
159 | -- 6. FAST, NON‑BLOCKING CONTROL RODS ------------------------------- | |
160 | --------------------------------------------------------------------- | |
161 | ||
162 | local function adjustRodsForSteam(targetSteam, margin) | |
163 | local produced = num(reactor.getHotFluidProducedLastTick(),0) | |
164 | local diff=targetSteam-produced; if math.abs(diff)<=margin then return end | |
165 | local lvl=num(reactor.getControlRodLevel(0),0) | |
166 | if diff>0 then lvl=math.max(0,lvl-2) else lvl=math.min(100,lvl+2) end | |
167 | reactor.setAllControlRodLevels(lvl) | |
168 | end | |
169 | ||
170 | --------------------------------------------------------------------- | |
171 | -- 7. BUTTONS & INTERACTION ----------------------------------------- | |
172 | --------------------------------------------------------------------- | |
173 | ||
174 | local TBL_X,TBL_Y=42,26 -- status LED table origin | |
175 | local ADJ_BTN_X_LEFT,ADJ_BTN_Y,ADJ_BTN_W,ADJ_BTN_H=24,27,7,3 | |
176 | local ADJ_BTN_X_RIGHT=ADJ_BTN_X_LEFT+ADJ_BTN_W+1 | |
177 | local ADJ_ROW_SPACING=1 | |
178 | local ADJ_OFFSETS={-10,10,-2,2,-1,1} | |
179 | local ADJ_LABELS={"-10","+10","-2","+2","-1","+1"} | |
180 | - | local TBL_X,TBL_Y=42,24 -- status LED table origin |
180 | + | |
181 | - | local ADJ_BTN_X_LEFT,ADJ_BTN_Y,ADJ_BTN_W,ADJ_BTN_H=24,25,7,3 |
181 | + | |
182 | learnedFlow = readFlow() or tuneFlow() -- forward declaration | |
183 | ||
184 | local function drawAdjButtons() | |
185 | for row=0,2 do | |
186 | local y=ADJ_BTN_Y+row*(ADJ_BTN_H+ADJ_ROW_SPACING) | |
187 | UI.rectangle(monitor,ADJ_BTN_X_LEFT ,y,ADJ_BTN_W,ADJ_BTN_H,ADJ_CLR) | |
188 | UI.rectangle(monitor,ADJ_BTN_X_RIGHT,y,ADJ_BTN_W,ADJ_BTN_H,ADJ_CLR) | |
189 | - | -- Horizontal buttons (row of 4) |
189 | + | |
190 | - | local H_BTN_X1 = 3 |
190 | + | |
191 | - | local H_BTN_Y = 40 |
191 | + | |
192 | - | local H_BTN_H = 7 |
192 | + | |
193 | - | local H_BTN_W = 16 |
193 | + | |
194 | - | local H_BTN_SPAC = 2 |
194 | + | |
195 | - | local H_BTN_LABELS = { |
195 | + | |
196 | - | "REACTOR ON/OFF", |
196 | + | |
197 | - | "TURBINE ON/OFF", |
197 | + | |
198 | - | "EJECT WASTE", |
198 | + | |
199 | - | "EJECT FUEL" |
199 | + | |
200 | - | } |
200 | + | |
201 | if x>=ADJ_BTN_X_LEFT and x<ADJ_BTN_X_LEFT+ADJ_BTN_W then | |
202 | - | -- compute even X-Distribution |
202 | + | |
203 | - | local H_BTN_X = {} |
203 | + | |
204 | - | do |
204 | + | |
205 | - | local startX = H_BTN_X1 |
205 | + | |
206 | - | for i = 1, #H_BTN_LABELS do |
206 | + | |
207 | - | H_BTN_X[i] = startX + (i - 1) * (H_BTN_W + H_BTN_SPAC) |
207 | + | |
208 | end | |
209 | end | |
210 | end | |
211 | - | -- Vertical RPM target buttons (stack of 2) |
211 | + | |
212 | - | local V_BTN_X = H_BTN_X[#H_BTN_X] + H_BTN_W + H_BTN_SPAC |
212 | + | |
213 | - | local V_BTN_Y = H_BTN_Y -- align top with the horizontal row |
213 | + | |
214 | - | local V_BTN_H = 3 |
214 | + | |
215 | - | local V_BTN_W = H_BTN_W |
215 | + | |
216 | - | local V_BTN_LABELS = { "900", "1800" } |
216 | + | |
217 | local function drawFuelRod() | |
218 | - | -- Draw Toggle and Speed Selector buttons |
218 | + | |
219 | - | local function drawControlButtons() |
219 | + | |
220 | - | -- Horizontal |
220 | + | |
221 | - | for i, label in ipairs(H_BTN_LABELS) do |
221 | + | |
222 | - | local x = H_BTN_X[i] |
222 | + | |
223 | - | UI.rectangle(monitor, x, H_BTN_Y, H_BTN_W, H_BTN_H, colors.gray) |
223 | + | |
224 | - | monitor.setTextColor(colors.white) |
224 | + | |
225 | - | local tx = x + math.floor((H_BTN_W - #label) / 2) |
225 | + | |
226 | - | local ty = H_BTN_Y + math.floor(H_BTN_H / 2) |
226 | + | |
227 | - | monitor.setCursorPos(tx, ty) |
227 | + | |
228 | - | monitor.write(label) |
228 | + | |
229 | UI.rectangle(monitor,CTRLBAR_X+CTRLBAR_SPC+CTRLBAR_WD+1,CTRLBAR_Y+1+CTRLBAR_HT-fht,CTRLBAR_WD,fht,colors.orange) | |
230 | - | -- Vertical |
230 | + | |
231 | - | for i, label in ipairs(V_BTN_LABELS) do |
231 | + | |
232 | - | local y = V_BTN_Y + (i - 1) * V_BTN_H |
232 | + | |
233 | - | UI.rectangle(monitor, V_BTN_X, y + (i - 1), V_BTN_W, V_BTN_H, colors.gray) |
233 | + | |
234 | - | monitor.setTextColor(colors.white) |
234 | + | |
235 | - | local tx = V_BTN_X + math.floor((V_BTN_W - #label) / 2) |
235 | + | |
236 | - | local ty = y + math.floor(V_BTN_H / 2) + (i-1) |
236 | + | |
237 | - | monitor.setCursorPos(tx, ty) |
237 | + | |
238 | - | monitor.write(label) |
238 | + | |
239 | local clntPercent=clntAmt/clntMax; | |
240 | local clntht=math.floor(clntPercent*TURBAR_HT+0.5) | |
241 | ||
242 | - | -- Handle touches on those buttons |
242 | + | |
243 | - | local function handleControlTouch(x, y) |
243 | + | |
244 | - | -- Horizontal row |
244 | + | |
245 | - | if y >= H_BTN_Y and y < H_BTN_Y + H_BTN_H then |
245 | + | |
246 | - | for i = 1, #H_BTN_X do |
246 | + | |
247 | - | local x0 = H_BTN_X[i] |
247 | + | |
248 | - | if x >= x0 and x < x0 + H_BTN_W then |
248 | + | |
249 | - | if i == 1 then reactor.setActive(not reactor.getActive()) |
249 | + | |
250 | - | elseif i == 2 then turbine.setActive(not turbine.getActive()) |
250 | + | |
251 | - | elseif i == 3 then reactor.doEjectWaste() |
251 | + | |
252 | - | elseif i == 4 then reactor.doEjectFuel() |
252 | + | |
253 | - | end |
253 | + | |
254 | - | return |
254 | + | |
255 | local function drawRPMgraph(rpm) | |
256 | local percent=math.min(1,rpm/(RPM_TARGET+200))*100 | |
257 | UI.drawRect(monitor,RPMBAR_X-1,RPMBAR_Y-1,72,RPMBAR_H+2,colors.orange) | |
258 | monitor.setTextColor(colors.orange) | |
259 | - | -- Vertical RPM presets |
259 | + | |
260 | - | if x >= V_BTN_X and x < V_BTN_X + V_BTN_W then |
260 | + | |
261 | - | for i = 1, #V_BTN_LABELS do |
261 | + | |
262 | - | local y0 = V_BTN_Y + (i - 1) * V_BTN_H |
262 | + | |
263 | - | if y >= y0 and y < y0 + V_BTN_H then |
263 | + | |
264 | - | if i == 1 then RPM_TARGET = 900 |
264 | + | |
265 | - | setRPMTarget(900) |
265 | + | |
266 | - | elseif i == 2 then RPM_TARGET = 1800 |
266 | + | |
267 | - | setRPMTarget(1800) |
267 | + | |
268 | - | end |
268 | + | |
269 | - | return |
269 | + | |
270 | } | |
271 | local s=labels[state] or labels[0] | |
272 | UI.drawRect(monitor,2,26,19,13,colors.orange) -- outline already static but redraw to clear old label | |
273 | UI.drawRect(monitor,2,29,19,7,colors.orange) | |
274 | UIHeader(monitor,3,30,17,5,s[1],s[2],s[3]) | |
275 | monitor.setTextColor(colors.white) | |
276 | end | |
277 | ||
278 | --------------------------------------------------------------------- | |
279 | -- 9. STATIC CHROME (draw once) ------------------------------------- | |
280 | --------------------------------------------------------------------- | |
281 | ||
282 | local function drawChrome() | |
283 | UIHeader(monitor,1,1,164,3,"MAIN SYSTEMS INFORMATION PANEL - BLOCK A",colors.lightBlue,colors.orange) | |
284 | -- static frames | |
285 | UI.drawRect(monitor,2,26,19,13,colors.orange) | |
286 | UI.drawRect(monitor,2,29,19,7,colors.orange) | |
287 | UI.drawRect(monitor,ADJ_BTN_X_LEFT-1,ADJ_BTN_Y-1,17,13,colors.orange) | |
288 | UI.drawTable(monitor,TBL_X,TBL_Y,1,4,17,3,colors.orange) | |
289 | UI.drawTable(monitor,TBL_X+17,TBL_Y,2,4,7,3,colors.orange) | |
290 | UI.drawTable(monitor,2,6,1,4,31,3,colors.orange) -- fluid info frame | |
291 | UI.drawTable(monitor,42,6,1,4,31,3,colors.orange) -- fuel info frame | |
292 | UI.drawTable(monitor,101,6,1,10,31,3,colors.orange) -- general info frame | |
293 | UI.drawTable(monitor,135,6,2,5,13,6,colors.orange) -- general info LED | |
294 | ||
295 | drawAdjButtons() | |
296 | end | |
297 | ||
298 | --------------------------------------------------------------------- | |
299 | -- 10. INITIALISATION ------------------------------------------------ | |
300 | --------------------------------------------------------------------- | |
301 | ||
302 | learnedFlow = readFlow() or tuneFlow() | |
303 | local lastRPM=num(turbine.getRotorSpeed(),0) | |
304 | local coilEngaged=turbine.getInductorEngaged() | |
305 | local stableTicks=0 | |
306 | local RPMSTATUS=0 -- 0 low, 1 high, 2 nominal | |
307 | ||
308 | monitor.clear(); drawChrome() | |
309 | ||
310 | --------------------------------------------------------------------- | |
311 | -- 11. MAIN LOOP ----------------------------------------------------- | |
312 | --------------------------------------------------------------------- | |
313 | while true do | |
314 | ------------------------------------------------------------------- | |
315 | -- schedule next UI tick | |
316 | local timer=os.startTimer(UPDATE_PERIOD) | |
317 | ||
318 | ------------------------------------------------------------------- | |
319 | -- SENSOR READ ----------------------------------------------------- | |
320 | local rpm=num(turbine.getRotorSpeed(),0) | |
321 | local drift=rpm-lastRPM; lastRPM=rpm | |
322 | ||
323 | ------------------------------------------------------------------- | |
324 | -- INDUCTOR COIL LOGIC -------------------------------------------- | |
325 | if not coilEngaged and rpm>=COIL_ON_RPM then coilEngaged=true end | |
326 | if coilEngaged and rpm<=COIL_OFF_RPM then coilEngaged=false end | |
327 | ||
328 | ------------------------------------------------------------------- | |
329 | -- ADAPTIVE FLOW LOGIC -------------------------------------------- | |
330 | local flow; local ventMsg | |
331 | if rpm<RPM_TARGET-RPM_TOLERANCE then | |
332 | flow=math.floor(learnedFlow*(1+FLOW_BUFFER)); ventMsg="OVERFLOW"; RPMSTATUS=0; turbine.setVentOverflow() | |
333 | learnedFlow=math.min(FLOW_TUNE_UPPER,learnedFlow+FLOW_LEARN_STEP); writeFlow(learnedFlow); stableTicks=0 | |
334 | elseif rpm>RPM_TARGET+RPM_TOLERANCE then | |
335 | flow=math.max(1,math.floor(learnedFlow*DECEL_FRACTION)); ventMsg="ALL"; RPMSTATUS=1; turbine.setVentAll() | |
336 | learnedFlow=math.max(FLOW_TUNE_LOWER,learnedFlow-FLOW_LEARN_STEP); writeFlow(learnedFlow); stableTicks=0 | |
337 | else | |
338 | flow=learnedFlow; ventMsg="OVERFLOW"; RPMSTATUS=2; turbine.setVentOverflow(); stableTicks=stableTicks+1 | |
339 | if stableTicks>=4 then | |
340 | if rpm<RPM_TARGET then learnedFlow=math.min(FLOW_TUNE_UPPER,learnedFlow+1) | |
341 | else learnedFlow=math.max(FLOW_TUNE_LOWER,learnedFlow-1) end | |
342 | writeFlow(learnedFlow); stableTicks=0 | |
343 | end | |
344 | end | |
345 | ||
346 | ------------------------------------------------------------------- | |
347 | -- APPLY CONTROLS -------------------------------------------------- | |
348 | - | local percent=math.min(1,rpm/(2000))*100 |
348 | + | |
349 | turbine.setInductorEngaged(coilEngaged) | |
350 | adjustRodsForSteam(math.floor(flow*1.03),2) | |
351 | ||
352 | ------------------------------------------------------------------- | |
353 | -- DYNAMIC UI UPDATE ---------------------------------------------- | |
354 | drawRPMgraph(rpm) | |
355 | drawFuelRod() | |
356 | -- drawFluidAmount() | |
357 | drawRPMStatus(RPMSTATUS) | |
358 | ||
359 | local function w(x,y,str) monitor.setCursorPos(x,y); monitor.write(pad(str,28)) end | |
360 | -- high‑frequency numeric/status strings | |
361 | w(102,10,"Inductors: " .. (coilEngaged and "ENGAGED" or "DISENGAGED")) | |
362 | w(102,13,"Vent Mode: " .. ventMsg) | |
363 | ||
364 | - | UI.drawRect(monitor,2,ADJ_BTN_Y-1,19,13,colors.orange) -- outline already static but redraw to clear old label |
364 | + | |
365 | - | UI.drawRect(monitor,2,ADJ_BTN_Y+2,19,7,colors.orange) |
365 | + | |
366 | - | UIHeader(monitor,3,ADJ_BTN_Y+3,17,5,s[1],s[2],s[3]) |
366 | + | |
367 | monitor.setCursorPos(102,31); monitor.write(pad(string.format("Fuel Temp : %6.1f °C",num(reactor.getFuelTemperature(),0)),28)) | |
368 | monitor.setCursorPos(102,34); monitor.write(pad(string.format("Fuel Consumed : %6.1f mB/t",num(reactor.getFuelConsumedLastTick(),0)),28)) | |
369 | ||
370 | monitor.setCursorPos(3,36); monitor.write(pad(string.format("RPM : %.1f rpm", rpm), 17)) | |
371 | monitor.setCursorPos(3,37); monitor.write(pad(string.format("Drift: %.1f rpm", drift), 17)) | |
372 | ||
373 | -- fuel & fluid info (these rarely change but we update each tick for safety) | |
374 | monitor.setCursorPos(4,10); monitor.write(pad("Target Flow: " .. learnedFlow .. " mB/t",28)) | |
375 | monitor.setCursorPos(4,13); monitor.write(pad("Current Flow: " .. flow .. " mB/t",28)) | |
376 | monitor.setCursorPos(4,16); monitor.write(pad("Fluid/t : " .. num(reactor.getHotFluidProducedLastTick(),0) .. " mB/t",28)) | |
377 | - | -- UI.drawRect(monitor,2,26,19,13,colors.orange) |
377 | + | |
378 | - | -- UI.drawRect(monitor,2,27,19,7,colors.orange) |
378 | + | |
379 | monitor.setCursorPos(44,13); monitor.write(pad("Available Fuel(mB) : " .. num(reactor.getFuelAmount(),0),28)) | |
380 | - | UI.drawRect(monitor,H_BTN_X1-1,H_BTN_Y-1, 2 + 5 * H_BTN_W + 4 * H_BTN_SPAC ,H_BTN_H + 2,colors.orange) |
380 | + | |
381 | ||
382 | -- ON/OFF LEDs ----------------------------------------------------- | |
383 | local function led(state,onX,offX,y) | |
384 | if state then | |
385 | UI.rectangle(monitor,onX ,y,4,2,colors.green) | |
386 | UI.rectangle(monitor,offX,y,4,2,colors.black) | |
387 | else | |
388 | UI.rectangle(monitor,onX ,y,4,2,colors.black) | |
389 | - | drawControlButtons() |
389 | + | |
390 | end | |
391 | end | |
392 | led(reactor.getActive(), TBL_X+26,TBL_X+19,TBL_Y+4) | |
393 | led(turbine.getActive(), TBL_X+26,TBL_X+19,TBL_Y+7) | |
394 | led(turbine.getInductorEngaged(),TBL_X+26,TBL_X+19,TBL_Y+10) | |
395 | ||
396 | -- LED Table ----------------------------------------------------- | |
397 | ||
398 | ||
399 | -- static labels (do once, but cheap to overwrite) | |
400 | monitor.setCursorPos(10,27); monitor.write("RPM") | |
401 | monitor.setCursorPos(8,28); monitor.write("Status:") | |
402 | monitor.setCursorPos(TBL_X+20,TBL_Y+1); monitor.write("OFF") | |
403 | monitor.setCursorPos(TBL_X+27,TBL_Y+1); monitor.write("ON") | |
404 | monitor.setCursorPos(TBL_X+1,TBL_Y+4); monitor.write("REACTOR:") | |
405 | monitor.setCursorPos(TBL_X+1,TBL_Y+7); monitor.write("TURBINE:") | |
406 | monitor.setCursorPos(TBL_X+1,TBL_Y+10); monitor.write("INDUCTORS:") | |
407 | monitor.setBackgroundColor(colors.lightGray) | |
408 | monitor.setTextColor(colors.black) | |
409 | monitor.setCursorPos(77,6); monitor.write("ROD") | |
410 | monitor.setCursorPos(83,6); monitor.write("FUL") | |
411 | ||
412 | local fpercent=math.floor(num(reactor.getFuelAmount(),0)/num(reactor.getFuelAmountMax(),1)*100+0.5) | |
413 | local fldpercent=math.floor(num(turbine.getInputAmount(),0)/num(turbine.getFluidAmountMax(),1)*100+0.5) | |
414 | local cntpercent=math.floor(num(reactor.getCoolantAmount(),0)/num(reactor.getCoolantAmountMax(),1)*100+0.5) | |
415 | local wpercent=math.floor(num(reactor.getWasteAmount(),0)/num(reactor.getFuelAmountMax(),1)*100+0.5) | |
416 | ||
417 | monitor.setCursorPos(77,37); monitor.write(string.format("%3d",num(reactor.getControlRodLevel(0),0))) | |
418 | monitor.setCursorPos(83,37); monitor.write(string.format("%3d",fpercent)) | |
419 | monitor.setCursorPos(89,6); monitor.write("FLD") | |
420 | monitor.setCursorPos(95,6); monitor.write("CNT") | |
421 | monitor.setCursorPos(89,37); monitor.write(string.format("%3d",fldpercent)) | |
422 | monitor.setCursorPos(95,37); monitor.write(pad(string.format("%d", num((100/reactor.getCoolantAmountMax()*reactor.getCoolantAmount()),0)),4)) | |
423 | monitor.setBackgroundColor(colors.black) | |
424 | monitor.setTextColor(colors.white) | |
425 | UI.rectangle(monitor, 3, 7, 30, 2, colors.blue) -- FLUID INFORMATION | |
426 | UI.rectangle(monitor, 43, 7, 30, 2, colors.blue) -- FUEL INFORMATION | |
427 | UI.rectangle(monitor, 102, 7, 30, 2, colors.blue) -- TURBINE STATUS | |
428 | UI.rectangle(monitor, 102, 16, 30, 2, colors.blue) -- ENERGY STATS | |
429 | UI.rectangle(monitor, 102, 25, 30, 2, colors.blue) -- CORE STATUS | |
430 | monitor.setBackgroundColor(colors.blue) | |
431 | monitor.setTextColor(colors.white) | |
432 | monitor.setCursorPos(3,7); monitor.write(" FLUID INFORMATION ") | |
433 | monitor.setCursorPos(43,7); monitor.write(" FUEL INFORMATION ") | |
434 | monitor.setCursorPos(102,7); monitor.write(" TURBINE STATUS ") | |
435 | monitor.setCursorPos(102,16); monitor.write(" ENERGY STATS ") | |
436 | monitor.setCursorPos(102,25); monitor.write(" CORE STATUS ") | |
437 | monitor.setBackgroundColor(colors.black) | |
438 | ||
439 | local colorOK = colors.lightBlue | |
440 | local colorER = colors.orange | |
441 | ||
442 | if reactor.getActive() then | |
443 | UIHeader(monitor, 136, 7, 12, 5, "REACTOR", colorOK , colorOK ) | |
444 | else | |
445 | UIHeader(monitor, 136, 7, 12, 5, "REACTORREAC OFF", colorER , colorER ) | |
446 | end | |
447 | ||
448 | if turbine.getActive() then | |
449 | UIHeader(monitor, 149, 7, 12, 5, "TURBINE", colorOK , colorOK ) | |
450 | else | |
451 | UIHeader(monitor, 149, 7, 12, 5, "TURBINE", colorER , colorER ) | |
452 | end | |
453 | ||
454 | if cntpercent > 10 then | |
455 | UIHeader(monitor, 136, 13, 12, 5, "COOLANT", colorOK , colorOK ) | |
456 | else | |
457 | UIHeader(monitor, 136, 13, 12, 5, "COOLANT", colorER , colorER ) | |
458 | end | |
459 | ||
460 | if fldpercent > 10 then | |
461 | UIHeader(monitor, 149, 13, 12, 5, "STEAM", colorOK , colorOK ) | |
462 | else | |
463 | UIHeader(monitor, 149, 13, 12, 5, "STEAM", colorER , colorER ) | |
464 | - | monitor.setCursorPos(3,34); monitor.write(pad(string.format("RPM : %.1f rpm", rpm), 17)) |
464 | + | |
465 | - | monitor.setCursorPos(3,35); monitor.write(pad(string.format("Drift: %.1f rpm", drift), 17)) |
465 | + | |
466 | if fpercent > 10 then | |
467 | UIHeader(monitor, 136, 19, 12, 5, "FUEL", colorOK , colorOK ) | |
468 | else | |
469 | UIHeader(monitor, 136, 19, 12, 5, "FUEL", colorER , colorER ) | |
470 | end | |
471 | ||
472 | if wpercent < 10 then | |
473 | UIHeader(monitor, 149, 19, 12, 5, "WASTE", colorOK , colorOK ) | |
474 | else | |
475 | UIHeader(monitor, 149, 19, 12, 5, "WASTE", colorER , colorER ) | |
476 | end | |
477 | ||
478 | if turbine.getEnergyStored() > 100 then | |
479 | UIHeader(monitor, 136, 25, 12, 5, "BATTERY", colorOK , colorOK ) | |
480 | else | |
481 | UIHeader(monitor, 136, 25, 12, 5, "BATTERY", colorER , colorER ) | |
482 | end | |
483 | ||
484 | if turbine.getEnergyProducedLastTick() > 15000 then | |
485 | UIHeader(monitor, 149, 25, 12, 5, "GENERATOR", colorOK , colorOK ) | |
486 | else | |
487 | UIHeader(monitor, 149, 25, 12, 5, "GENERATOR", colorER , colorER ) | |
488 | end | |
489 | ||
490 | if turbine.getFluidFlowRate() > 250 then | |
491 | UIHeader(monitor, 136, 31, 12, 5, "FLOW", colorOK , colorOK ) | |
492 | else | |
493 | UIHeader(monitor, 136, 31, 12, 5, "FLOW", colorER , colorER ) | |
494 | - | monitor.setCursorPos(10,25); monitor.write("RPM") |
494 | + | |
495 | - | monitor.setCursorPos(8,26); monitor.write("Status:") |
495 | + | |
496 | if reactor.getHotFluidProducedLastTick() > 250 then | |
497 | UIHeader(monitor, 149, 31, 12, 5, "FLUID", colorOK , colorOK ) | |
498 | else | |
499 | UIHeader(monitor, 149, 31, 12, 5, "FLUID", colorER , colorER ) | |
500 | end | |
501 | ||
502 | ------------------------------------------------------------------- | |
503 | -- EVENT HANDLING -------------------------------------------------- | |
504 | repeat | |
505 | local ev={os.pullEvent()} | |
506 | if ev[1]=="monitor_touch" then handleTouch(ev[3],ev[4]) end | |
507 | until ev[1]=="timer" and ev[2]==timer | |
508 | end | |
509 | - | monitor.setCursorPos(77,36); monitor.write(string.format("%3d",num(reactor.getControlRodLevel(0),0))) |
509 | + |