Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
C#
Python
SQL
Shell
Bash
Markdown
YAML
JSON
HTML
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
Arduino
TypeScript
Perl
Autohotkey
Lua
SQF
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
1. local component = require("component") 2. local event = require("event") 3. local term = require("term") 4. local gpu = component.gpu 5. 6. -- Safety Checks 7. 8. if not component.isAvailable("draconic_reactor") then 9. print("Reactor not connected. Please connect computer to reactor with an Adapter block.") 10. os.exit() 11. end 12. reactor = component.draconic_reactor 13. local flux_gates = {} 14. for x,y in pairs(component.list("flux_gate")) do 15. flux_gates[#flux_gates+1] = x 16. end 17. if #flux_gates < 2 then 18. print("Not enough flux gates connected; please connect inflow and outflow flux gates with Adapter blocks.") 19. os.exit() 20. end 21. flux_in = component.proxy(flux_gates[1]) 22. flux_out = component.proxy(flux_gates[2]) 23. if not flux_in or not flux_out then 24. print("Not enough flux gates connected; please connect inflow and outflow flux gates with Adapter blocks.") 25. os.exit() 26. end 27. 28. -- Functions 29. 30. function exit_msg(msg) 31. term.clear() 32. print(msg) 33. os.exit() 34. end 35. 36. function modify_temp(offset) 37. local new_temp = ideal_temp + offset 38. if new_temp > 8000 then 39. new_temp = 8000 40. elseif new_temp < 2500 then 41. new_temp = 2500 42. end 43. ideal_temp = new_temp 44. end 45. 46. function modify_field(offset) 47. local new_strength = ideal_strength + offset 48. if new_strength > 90 then 49. new_strength = 90 50. elseif new_strength < 1 then 51. new_strength = 1 52. end 53. ideal_strength = new_strength 54. end 55. 56. -- Buttons 57. 58. local adj_button_width = 19 59. local temp_adjust_x_offset = 68 60. local temp_adjust_y_offset = 2 61. local field_adjust_x_offset = temp_adjust_x_offset + adj_button_width + 2 62. local field_adjust_y_offset = 2 63. 64. local buttons = { 65. start={ 66. x=42, 67. y=2, 68. width=24, 69. height=7, 70. text="Start", 71. action=function() 72. if safe then 73. state = "Charging" 74. reactor.chargeReactor() 75. elseif shutting_down then 76. state = "Active" 77. reactor.activateReactor() 78. end 79. end, 80. condition=function() return safe or shutting_down end 81. }, 82. shutdown={ 83. x=42, 84. y=12, 85. width=24, 86. height=7, 87. text="Shutdown", 88. action=function() 89. state = "Manual Shutdown" 90. reactor.stopReactor() 91. end, 92. condition=function() return running end 93. }, 94. switch_gates={ 95. x=2, 96. y=20, 97. width=24, 98. height=3, 99. text="Swap flux gates", 100. action=function() 101. local old_addr = flux_in.address 102. flux_in = component.proxy(flux_out.address) 103. flux_out = component.proxy(old_addr) 104. end, 105. condition=function() return safe end 106. }, 107. exit={ 108. x=42, 109. y=12, 110. width=24, 111. height=7, 112. text="Exit", 113. action=function() 114. event_loop = false 115. end, 116. condition=function() return safe end 117. }, 118. temp_up_thousand={ 119. x=temp_adjust_x_offset, 120. y=temp_adjust_y_offset, 121. width=adj_button_width, 122. height=1, 123. text="+ 1000", 124. action=function() modify_temp(1000) end 125. }, 126. temp_up_hundred={ 127. x=temp_adjust_x_offset, 128. y=temp_adjust_y_offset+2, 129. width=adj_button_width, 130. height=1, 131. text="+ 100", 132. action=function() modify_temp(100) end 133. }, 134. temp_up_ten={ 135. x=temp_adjust_x_offset, 136. y=temp_adjust_y_offset+4, 137. width=adj_button_width, 138. height=1, 139. text="+ 10", 140. action=function() modify_temp(10) end 141. }, 142. temp_up_one={ 143. x=temp_adjust_x_offset, 144. y=temp_adjust_y_offset+6, 145. width=adj_button_width, 146. height=1, 147. text="+ 1", 148. action=function() modify_temp(1) end 149. }, 150. temp_down_thousand={ 151. x=temp_adjust_x_offset, 152. y=temp_adjust_y_offset+16, 153. width=adj_button_width, 154. height=1, 155. text="- 1000", 156. action=function() modify_temp(-1000) end 157. }, 158. temp_down_hundred={ 159. x=temp_adjust_x_offset, 160. y=temp_adjust_y_offset+14, 161. width=adj_button_width, 162. height=1, 163. text=" - 100", 164. action=function() modify_temp(-100) end 165. }, 166. temp_down_ten={ 167. x=temp_adjust_x_offset, 168. y=temp_adjust_y_offset+12, 169. width=adj_button_width, 170. height=1, 171. text="- 10", 172. action=function() modify_temp(-10) end 173. }, 174. temp_down_one={ 175. x=temp_adjust_x_offset, 176. y=temp_adjust_y_offset+10, 177. width=adj_button_width, 178. height=1, 179. text="- 1", 180. action=function() modify_temp(-1) end 181. }, 182. field_up_ten={ 183. x=field_adjust_x_offset, 184. y=field_adjust_y_offset+4, 185. width=adj_button_width, 186. height=1, 187. text="+ 10", 188. action=function() modify_field(10) end 189. }, 190. field_up_one={ 191. x=field_adjust_x_offset, 192. y=field_adjust_y_offset+6, 193. width=adj_button_width, 194. height=1, 195. text="+ 1", 196. action=function() modify_field(1) end 197. }, 198. field_down_ten={ 199. x=field_adjust_x_offset, 200. y=field_adjust_y_offset+12, 201. width=adj_button_width, 202. height=1, 203. text="- 10", 204. action=function() modify_field(-10) end 205. }, 206. field_down_one={ 207. x=field_adjust_x_offset, 208. y=field_adjust_y_offset+10, 209. width=adj_button_width, 210. height=1, 211. text="- 1", 212. action=function() modify_field(-1) end 213. } 214. } 215. 216. -- main code 217. 218. flux_in.setFlowOverride(0) 219. flux_out.setFlowOverride(0) 220. flux_in.setOverrideEnabled(true) 221. flux_out.setOverrideEnabled(true) 222. 223. local condition = reactor.getReactorInfo() 224. if not condition then 225. print("Reactor not initialized, please ensure the stabilizers are properly laid out.") 226. os.exit() 227. end 228. 229. ideal_strength = 50 230. 231. ideal_temp = 8000 232. cutoff_temp = 8100 233. 234. -- tweakable pid gains 235. 236. inflow_P_gain = 1 237. inflow_I_gain = 0.04 238. inflow_D_gain = 0.1 239. 240. outflow_P_gain = 500 241. outflow_I_gain = 0.5 242. outflow_II_gain = 0.0000003 243. outflow_D_gain = 60000 244. 245. -- initialize main loop 246. 247. inflow_I_sum = 0 248. inflow_D_last = 0 249. 250. outflow_I_sum = 0 251. outflow_II_sum = 0 252. outflow_D_last = 0 253. 254. state = "Standby" 255. shutting_down = false 256. 257. if condition.temperature > 25 then 258. state = "Cooling" 259. end 260. if condition.temperature > 2000 then 261. state = "Active" 262. end 263. 264. -- Possible states: 265. --Standby 266. --Charging 267. --Active 268. --Manual Shutdown 269. --Emergency Shutdown 270. --Cooling 271. 272. event_loop = true 273. while event_loop do 274. 275. if not component.isAvailable("draconic_reactor") then 276. exit_msg("Reactor disconnected, exiting") 277. end 278. 279. if not component.isAvailable("flux_gate") then 280. exit_msg("Flux gates disconnected, exiting") 281. end 282. 283. local info = reactor.getReactorInfo() 284. 285. local inflow = 0 286. local outflow = 0 287. 288. shutting_down = state == "Manual Shutdown" or state == "Emergency Shutdown" 289. running = state == "Charging" or state == "Active" 290. safe = state == "Standby" or state == "Cooling" 291. 292. if state == "Charging" then 293. inflow = 200000 294. 295. if info.temperature > 2000 then 296. reactor.activateReactor() 297. state = "Active" 298. end 299. elseif state == "Cooling" then 300. if info.temperature < 25 then 301. state = "Standby" 302. end 303. inflow = 10 304. outflow = 20 305. elseif state == "Standby" then 306. inflow = 10 307. outflow = 20 308. else 309. -- adjust inflow rate based on field strength 310. 311. local field_error = (info.maxFieldStrength * (ideal_strength / 100)) - info.fieldStrength 312. local proportional_field_error = field_error * inflow_P_gain 313. inflow_I_sum = inflow_I_sum + field_error 314. local integral_field_error = inflow_I_sum * inflow_I_gain 315. local derivative_field_error = (field_error - inflow_D_last) * inflow_D_gain 316. inflow_D_last = field_error 317. local inflow_correction = proportional_field_error + integral_field_error + derivative_field_error 318. if inflow_correction < 0 then 319. inflow_I_sum = inflow_I_sum - field_error 320. end 321. inflow = inflow_correction 322. 323. if not shutting_down then 324. 325. -- adjust outflow rate based on core temperature 326. 327. local temp_error = ideal_temp - info.temperature 328. local proportional_temp_error = temp_error * outflow_P_gain 329. outflow_I_sum = outflow_I_sum + temp_error 330. local integral_temp_error = outflow_I_sum * outflow_I_gain 331. if math.abs(temp_error) < 100 then 332. outflow_II_sum = outflow_II_sum + integral_temp_error 333. else 334. outflow_II_sum = 0 335. end 336. local second_integral_temp_error = outflow_II_sum * outflow_II_gain 337. local derivative_temp_error = (temp_error - outflow_D_last) * outflow_D_gain 338. outflow_D_last = temp_error 339. local outflow_correction = proportional_temp_error + integral_temp_error + second_integral_temp_error + derivative_temp_error 340. if outflow_correction < 0 then 341. outflow_I_sum = outflow_I_sum - temp_error 342. end 343. outflow = outflow_correction 344. 345. -- cut off reactor in case of emergency 346. 347. if info.temperature > cutoff_temp then 348. print("Reactor temperature greater than", cutoff_temp, ", failsafe activated, shutting down") 349. outflow = 0 350. state = "Emergency Shutdown" 351. reactor.stopReactor() 352. end 353. else 354. if info.temperature < 2000 then 355. state = "Cooling" 356. end 357. end 358. end 359. 360. if state ~= "Active" and not shutting_down then 361. inflow_I_sum = 0 362. inflow_D_last = 0 363. outflow_I_sum = 0 364. outflow_II_sum = 0 365. outflow_D_last = 0 366. end 367. 368. if inflow < 0 then 369. inflow = 0 370. end 371. if outflow < 0 then 372. outflow = 0 373. end 374. 375. inflow = math.floor(inflow) 376. outflow = math.floor(outflow) 377. 378. flux_in.setFlowOverride(inflow) 379. flux_out.setFlowOverride(outflow) 380. 381. -- Draw screen 382. 383. if term.isAvailable() then 384. 385. -- Draw Values 386. 387. local left_margin = 2 388. local spacing = 2 389. 390. local values = { 391. "Status: " .. state, 392. "Field Strength: " .. ((info.fieldStrength / info.maxFieldStrength) * 100) .. "%", 393. "Energy Saturation: " .. ((info.energySaturation / info.maxEnergySaturation) * 100) .. "%", 394. "Fuel Concentration: " .. ((1 - info.fuelConversion / info.maxFuelConversion) * 100) .. "%", 395. "Temperature: " .. info.temperature .. " F", 396. "Reactor Efficiency: " .. info.fuelConversionRate .. " nb/t", 397. "Energy Inflow Rate: " .. inflow .. " RF/t", 398. "Energy Outflow Rate: " .. outflow .. " RF/t" 399. } 400. 401. if safe then 402. values[#values+1] = "Click if flux gates need to be swapped" 403. end 404. 405. term.clear() 406. 407. for i, v in ipairs(values) do 408. term.setCursor(left_margin, i * spacing) 409. term.write(v) 410. end 411. 412. -- Draw button values 413. 414. term.setCursor(temp_adjust_x_offset, temp_adjust_y_offset+8) 415. term.write("Target Temp: " .. ideal_temp .. " F") 416. term.setCursor(field_adjust_x_offset, field_adjust_y_offset+8) 417. term.write("Target Strength: " .. ideal_strength .. "%") 418. 419. -- Draw Buttons 420. 421. gpu.setForeground(0x000000) 422. 423. for bname, button in pairs(buttons) do 424. if button.depressed then 425. 426. button.depressed = button.depressed - 1 427. if button.depressed == 0 then 428. button.depressed = nil 429. end 430. end 431. if button.condition == nil or button.condition() then 432. local center_color = 0xAAAAAA 433. local highlight_color = 0xCCCCCC 434. local lowlight_color = 0x808080 435. if button.depressed then 436. center_color = 0x999999 437. highlight_color = 0x707070 438. lowlight_color = 0xBBBBBB 439. end 440. gpu.setBackground(center_color) 441. gpu.fill(button.x, button.y, button.width, button.height, " ") 442. if button.width > 1 and button.height > 1 then 443. gpu.setBackground(lowlight_color) 444. gpu.fill(button.x+1, button.y+button.height-1, button.width-1, 1, " ") 445. gpu.fill(button.x+button.width-1, button.y, 1, button.height, " ") 446. gpu.setBackground(highlight_color) 447. gpu.fill(button.x, button.y, 1, button.height, " ") 448. gpu.fill(button.x, button.y, button.width, 1, " ") 449. end 450. gpu.setBackground(center_color) 451. term.setCursor(button.x + math.floor(button.width / 2 - #button.text / 2), button.y + math.floor(button.height / 2)) 452. term.write(button.text) 453. end 454. end 455. 456. gpu.setBackground(0x000000) 457. gpu.setForeground(0xFFFFFF) 458. end 459. 460. -- Wait for next tick, or manual shutdown 461. 462. local event, id, op1, op2 = event.pull(0.05) 463. if event == "interrupted" then 464. if safe then 465. break 466. end 467. elseif event == "touch" then 468. 469. -- Handle Button Presses 470. 471. local x = op1 472. local y = op2 473. 474. for bname, button in pairs(buttons) do 475. if (button.condition == nil or button.condition()) and x >= button.x and x <= button.x + button.width and y >= button.y and y <= button.y + button.height then 476. button.action() 477. button.depressed = 3 478. end 479. end 480. end 481. end 482. 483. term.clear()
Mark as private (unlisted)
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
everlasting (like CCCP)