Guest User

Draconic Reactor(1.12.2)

a guest
Jan 20th, 2024
431
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.02 KB | Software | 0 0
  1. print("reactor control")
  2.  
  3. function setupPeripherals()
  4. print("Setup peripherals...")
  5. reactor = peripheral.wrap(sideReactor)
  6. gateIn = periphSearch("flux_gate")
  7. gateOut = peripheral.wrap(sideGateOut)
  8.  
  9. if reactor == null then
  10. error("No valid reactor was found!")
  11. end
  12. if gateIn == null then
  13. error("No valid input fluxgate was found!")
  14. end
  15. if gateOut == null then
  16. error("No valid output fluxgate was found!")
  17. end
  18.  
  19. local modem = "right"
  20. local reactor = "top"
  21. local fuel = {
  22. type = 'block',
  23. amt = 8
  24. }
  25.  
  26. local coEff = 18
  27. local shieldSafety = {
  28. stopping = 0.98,
  29. online = 0.5 --lower this margin to get more energy should be safe
  30. }
  31.  
  32.  
  33. ---DEFUALTS END
  34. local reactorData = {}
  35. local reactorShadow = {
  36. __index = function(t, k) return reactorShadow[k](t) end,
  37. canStart = function(self)
  38. return
  39. self.temperature >= 2000 and
  40. self.fieldStrength >= floor(self.maxFieldStrength / 2) and
  41. self.energySaturation >= floor(self.maxEnergySaturation / 2)
  42. --self.convertedFuel + this.reactorFuel + self.conversionUnit >= 144
  43. end,
  44. canCharge = function(self)
  45. return self.status ~= "online"
  46. end,
  47. canStop = function(self)
  48. return self.status ~= "offline"
  49. end
  50. }
  51.  
  52. for k,v in pairs(gates) do
  53. gates[k] = peripheral.wrap(v)
  54. gates[k].setOverrideEnabled(true)
  55. gates[k].setFlowOverride(0)
  56. gates[k].set = gates[k].setFlowOverride
  57. gates[k].get = gates[k].getFlow
  58. gates[k].name = v
  59. end
  60.  
  61. modem = peripheral.wrap(modem)
  62. modem.open(0)
  63.  
  64. reactor = peripheral.wrap(reactor)
  65. local run = true
  66. local floor = math.floor
  67. local commands = {
  68. exit = function()
  69. run = false
  70. return true
  71. end,
  72. fetch = function()
  73. local data = reactorData
  74. data.gates = {}
  75. for k,v in pairs(gates) do
  76. data.gates[k] = v.get()
  77. end
  78. return data
  79. end,
  80. start = function()
  81. local result = reactor.activateReactor()
  82. --print("STARTING", result)
  83. return result
  84. end,
  85. stop = function()
  86. local result = reactor.stopReactor()
  87. --print("STOPPING", result)
  88. return result
  89. end,
  90. charge = function()
  91. local result = reactor.chargeReactor()
  92. --print("CHARGING")
  93. return result
  94. end
  95. }
  96.  
  97. local function convertFuel(fuel)
  98. if fuel.type == 'nugget' then return fuel.amt * 16 end
  99. if fuel.type == 'ingot' then return fuel.amt * 144 end
  100. if fuel.type == 'block' then return fuel.amt * 1296 end
  101. return 0
  102. end
  103.  
  104. fuel = convertFuel(fuel)
  105. fuel = fuel - convertFuel({type = 'nugget', amt = 1})
  106.  
  107. local function tick(amt)
  108. if amt ~= nil then
  109. os.sleep(amt/20)
  110. else
  111. os.sleep(1/20)
  112. end
  113. end
  114.  
  115. local function ShieldRF(reactorData)
  116. local saturation = (reactorData.energySaturation / reactorData.maxEnergySaturation)
  117. local baseMaxRFt = floor((reactorData.maxEnergySaturation / 1000.0) * 1.5)
  118.  
  119. local tempDrainFactor = 0
  120. if reactorData.temperature > 8000 then
  121. tempDrainFactor = 1 + ((reactorData.temperature - 8000) * (reactorData.temperature - 8000) * 0.0000025)
  122. elseif reactorData.temperature > 2000 then
  123. tempDrainFactor = 1
  124. elseif reactorData.temperature > 1000 then
  125. tempDrainFactor = (reactorData.temperature - 1000) / 1000
  126. else
  127. tempDrainFactor = 0
  128. end
  129.  
  130. --Field Drain Calculation
  131. local fieldDrain = floor(math.min(tempDrainFactor * (1.0 - saturation) * (baseMaxRFt / 10.923556), math.pow(2,127)))
  132. local fieldNegPercent = 1.0 - (reactorData.fieldStrength / reactorData.maxFieldStrength)
  133. local fieldInputRate = fieldDrain / fieldNegPercent
  134.  
  135. local shieldMod = reactorData.fieldStrength / reactorData.maxFieldStrength * 100;
  136. if shieldMod < 50 then --we're ~1 tick behind so idle around 50% charge
  137. fieldInputRate = fieldInputRate * 1.001
  138. else
  139. fieldInputRate = fieldInputRate * 0.995
  140. end
  141.  
  142. return fieldInputRate
  143. end
  144.  
  145. local function DrainRF(reactorData)
  146. return math.min(reactorData.energySaturation, reactorData.maxEnergySaturation / 100) / coEff
  147. end
  148.  
  149. local function ChargeRF(reactorData)
  150. if reactorData.fieldStrength < floor(reactorData.maxFieldStrength / 2) then
  151. return floor(reactorData.maxFieldStrength / 2)+1;
  152. elseif reactorData.energySaturation < floor(reactorData.maxEnergySaturation / 2) then
  153. return floor(reactorData.maxEnergySaturation / 2)+1;
  154. elseif reactorData.temperature-1 < 2000 then
  155. return 10 * (2000 - reactorData.temperature+1) * (fuel + 100) * 20;
  156. end
  157. return 0
  158. end
  159.  
  160. local function fetchStatus(target)
  161. local data = reactor.getReactorInfo()
  162. if type(data) ~= "table" then
  163. data = {
  164. fuelConversaionRate = 0,
  165. temperature = 0,
  166. fieldStrength = 0,
  167. fieldDrainRate = 0,
  168. generationRate = 0,
  169. status = "invalid",
  170. energySaturation = 0,
  171. maxFuelConversion = 0,
  172. fuelConversion = 0,
  173. maxFieldStrength = 0,
  174. maxEnergySaturation = 0,
  175. shieldRF = 0,
  176. drainRF = 0,
  177. chargeRF = 0
  178. }
  179. end
  180. setmetatable(data, reactorShadow)
  181. data.lastUpdate = os.clock()
  182. data.shieldRF = ShieldRF(data)
  183. data.drainRF = DrainRF(data)
  184. data.chargeRF = ChargeRF(data)
  185. return data
  186. end
  187.  
  188. reactorData = fetchStatus()
  189.  
  190. local states = {}
  191.  
  192. local function handleOffline()
  193. --do nothing
  194. end
  195. states.offline = handleOffline
  196.  
  197. local function handleCharge()
  198. gates.charge.set(reactorData.chargeRF)
  199. gates.shield.set(0)
  200. gates.drain.set(0)
  201. end
  202. states.charging = handleCharge
  203.  
  204. local function handleCharged()
  205. gates.charge.set(0)
  206. gates.shield.set(0)
  207. gates.drain.set(0)
  208. end
  209. states.charged = handleCharged
  210.  
  211. local function handleOnline()
  212. local gen = reactorData.generationRate
  213. gen = gen - reactorData.shieldRF
  214. if gen > 0 then
  215. gates.charge.set(0)
  216. gates.shield.set(reactorData.shieldRF)
  217. --local r = math.ceil
  218. local trueDrain = reactorData.drainRF - (reactorData.shieldRF) -- drainRF - (reactorData.generationRate - shieldRF)
  219. --print("gR ", r(reactorData.generationRate), " tD ", r(trueDrain), " sRF " , r(shieldRF), " dR " , r(drainRF))
  220. if trueDrain > 0 then
  221. gates.drain.set(trueDrain)
  222. else
  223. --should not happen...
  224. --print("trueDrain ", trueDrain, " generationRate ", reactorData.generationRate, " shieldRF " , shieldRF, " t+s ", trueDrain+shieldRF)
  225. gates.drain.set(gen)
  226. end
  227. else
  228. gates.shield.set(reactorData.shieldRF * shieldSafety.online) --10% safety
  229. gates.drain.set(0)
  230. gates.charge.set(gen * -1.1)
  231. end
  232. end
  233. states.online = handleOnline
  234.  
  235. local function handleStopping()
  236. local gen = reactorData.generationRate;
  237. gen = gen - reactorData.shieldRF
  238. if gen > 0 then
  239. gates.drain.set(gen * shieldSafety.stopping) --safety margin
  240. gates.shield.set(reactorData.shieldRF)
  241. gates.charge.set(0)
  242. else
  243. --redirect full energy to shield
  244. gates.drain.set(0)
  245. gates.shield.set(reactorData.generationRate)
  246. --use remaining energy from buffer
  247. gates.charge.set(-gen)
  248. end
  249. end
  250. states.stopping = handleStopping
  251.  
  252. states.invalid = function()
  253. --print("SOMETHING WENT WRONG")
  254. error("SOMETHING WENT WRONG")
  255. end
  256.  
  257. function control()
  258. print("control up")
  259. while run do
  260. local tmpReactorData = fetchStatus()
  261. if tmpReactorData.status ~= reactorData.status then
  262. print(reactorData.status, "->", tmpReactorData.status)
  263. end
  264. reactorData = tmpReactorData
  265. local state = states[reactorData.status]
  266. if state ~= nil then
  267. local ok, error = pcall(state)
  268. if not ok then
  269. print(error)
  270. end
  271. end
  272. tick()
  273. end
  274. end
  275.  
  276. function input()
  277. print("input up")
  278. while run do
  279. local msg = read()
  280. local cmd = string.lower(msg)
  281. if commands[cmd] ~= nil then
  282. print("->", msg)
  283. local result = commands[cmd]()
  284. print("<-", result)
  285. if type(result) == 'table' then
  286. for i,v in pairs(result) do
  287. print(i, " ", v)
  288. end
  289. end
  290. else
  291. print("unkown command ", msg)
  292. end
  293. end
  294. end
  295.  
  296. function server()
  297. print("server up")
  298. while run do
  299. local event = {os.pullEvent("modem_message")}
  300. local cmd = string.lower(event[5])
  301. if commands[cmd] ~= nil then
  302. modem.transmit(0,0, textutils.serialize(commands[cmd]()))
  303. else
  304. modem.transmit(0,0, "error")
  305. end
  306. --print(textutils.serialize(event))
  307. end
  308. end
  309. parallel.waitForAny(control, input, server)
Advertisement
Add Comment
Please, Sign In to add comment