osmarks

Naive Reactor Controller

Jul 28th, 2019
286
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.12 KB | None | 0 0
  1. local storage
  2. local reactors = {}
  3. local reactor_count = 0
  4. for _, n in pairs(peripheral.getNames()) do
  5.     if n:match "^Induction Matrix" then
  6.         storage = peripheral.wrap(n)
  7.     end
  8.     if n:match "^Reactor Logic Adapter" then
  9.         reactors[n] = peripheral.wrap(n)
  10.         reactor_count = reactor_count + 1
  11.     end
  12. end
  13. local integrators = {
  14.     ["redstone_integrator_16"] = "north",
  15.     ["redstone_integrator_17"] = "south",
  16. }
  17. local min_rate = 2
  18. local max_rate = 98
  19. local energy_crit_threshold = 0.2
  20. local energy_scaling_range = 1 - energy_crit_threshold
  21. local range_rate = max_rate - min_rate
  22. local fuel_threshold = 900
  23. local power_per_injection_rate = 250000 * reactor_count -- in MJ (mekanism joules or something), not RF
  24.  
  25. local function rnd2(f)
  26.     return math.ceil(f / 2) * 2
  27. end
  28. local function log(...)
  29.     print(os.date "%H:%M:%S", ...)
  30. end
  31.  
  32. local function calc_injection_rate(target, reactor, name)
  33.     if reactor.getTritium() < fuel_threshold then
  34.         log(name, "tritium critical! Injection rate reduced to", min_rate)
  35.         return min_rate
  36.     elseif reactor.getDeuterium() < fuel_threshold then
  37.         log(name, "deuterium critical! Injection rate reduced to", min_rate)
  38.         return min_rate
  39.     end
  40.     return target
  41. end
  42.  
  43. while true do
  44.     local energy = storage.getEnergy() / storage.getMaxEnergy()
  45.     local output = storage.getOutput()
  46.     local input = storage.getInput()
  47.     local target_level = 1 - ((energy - energy_crit_threshold) / energy_scaling_range)
  48.     local target_1 = min_rate + math.floor(range_rate * math.min(1, math.max(0, target_level)))
  49.     local target_2 = math.ceil(math.min(max_rate, math.max(min_rate, output / power_per_injection_rate)))
  50.     log("Stored energy IR target:", target_1)
  51.     log("Current output IR target:", target_2)
  52.     local target = math.max(target_1, target_2)
  53.     for name, reactor in pairs(reactors) do
  54.         reactor.setInjectionRate(rnd2(calc_injection_rate(target, reactor, name)))
  55.     end
  56.     local d_t = energy < energy_crit_threshold or (target_2 >= 96 and input < output)
  57.     if d_t then
  58.         log("D-T injection activated.")
  59.     end
  60.     for periph, side in pairs(integrators) do
  61.         peripheral.call(periph, "setOutput", side, d_t)
  62.     end
  63.     sleep(1)
  64. end
Add Comment
Please, Sign In to add comment