Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- print("reactor control")
- local gates = {
- ['drain'] = "flux_gate_5",
- ['charge'] = "flux_gate_6",
- ['shield'] = "flux_gate_7"
- }
- local modem = "right"
- local reactor = "top"
- local fuel = {
- type = 'block',
- amt = 8
- }
- local coEff = 18
- local shieldSafety = {
- stopping = 0.98,
- online = 0.5 --lower this margin to get more energy should be safe
- }
- ---DEFUALTS END
- local reactorData = {}
- local reactorShadow = {
- __index = function(t, k) return reactorShadow[k](t) end,
- canStart = function(self)
- return
- self.temperature >= 2000 and
- self.fieldStrength >= floor(self.maxFieldStrength / 2) and
- self.energySaturation >= floor(self.maxEnergySaturation / 2)
- --self.convertedFuel + this.reactorFuel + self.conversionUnit >= 144
- end,
- canCharge = function(self)
- return self.status ~= "online"
- end,
- canStop = function(self)
- return self.status ~= "offline"
- end
- }
- for k,v in pairs(gates) do
- gates[k] = peripheral.wrap(v)
- gates[k].setOverrideEnabled(true)
- gates[k].setFlowOverride(0)
- gates[k].set = gates[k].setFlowOverride
- gates[k].get = gates[k].getFlow
- gates[k].name = v
- end
- modem = peripheral.wrap(modem)
- modem.open(0)
- reactor = peripheral.wrap(reactor)
- local run = true
- local floor = math.floor
- local commands = {
- exit = function()
- run = false
- return true
- end,
- fetch = function()
- local data = reactorData
- data.gates = {}
- for k,v in pairs(gates) do
- data.gates[k] = v.get()
- end
- return data
- end,
- start = function()
- local result = reactor.activateReactor()
- --print("STARTING", result)
- return result
- end,
- stop = function()
- local result = reactor.stopReactor()
- --print("STOPPING", result)
- return result
- end,
- charge = function()
- local result = reactor.chargeReactor()
- --print("CHARGING")
- return result
- end
- }
- local function convertFuel(fuel)
- if fuel.type == 'nugget' then return fuel.amt * 16 end
- if fuel.type == 'ingot' then return fuel.amt * 144 end
- if fuel.type == 'block' then return fuel.amt * 1296 end
- return 0
- end
- fuel = convertFuel(fuel)
- fuel = fuel - convertFuel({type = 'nugget', amt = 1})
- local function tick(amt)
- if amt ~= nil then
- os.sleep(amt/20)
- else
- os.sleep(1/20)
- end
- end
- local function ShieldRF(reactorData)
- local saturation = (reactorData.energySaturation / reactorData.maxEnergySaturation)
- local baseMaxRFt = floor((reactorData.maxEnergySaturation / 1000.0) * 1.5)
- local tempDrainFactor = 0
- if reactorData.temperature > 8000 then
- tempDrainFactor = 1 + ((reactorData.temperature - 8000) * (reactorData.temperature - 8000) * 0.0000025)
- elseif reactorData.temperature > 2000 then
- tempDrainFactor = 1
- elseif reactorData.temperature > 1000 then
- tempDrainFactor = (reactorData.temperature - 1000) / 1000
- else
- tempDrainFactor = 0
- end
- --Field Drain Calculation
- local fieldDrain = floor(math.min(tempDrainFactor * (1.0 - saturation) * (baseMaxRFt / 10.923556), math.pow(2,127)))
- local fieldNegPercent = 1.0 - (reactorData.fieldStrength / reactorData.maxFieldStrength)
- local fieldInputRate = fieldDrain / fieldNegPercent
- local shieldMod = reactorData.fieldStrength / reactorData.maxFieldStrength * 100;
- if shieldMod < 50 then --we're ~1 tick behind so idle around 50% charge
- fieldInputRate = fieldInputRate * 1.001
- else
- fieldInputRate = fieldInputRate * 0.995
- end
- return fieldInputRate
- end
- local function DrainRF(reactorData)
- return math.min(reactorData.energySaturation, reactorData.maxEnergySaturation / 100) / coEff
- end
- local function ChargeRF(reactorData)
- if reactorData.fieldStrength < floor(reactorData.maxFieldStrength / 2) then
- return floor(reactorData.maxFieldStrength / 2)+1;
- elseif reactorData.energySaturation < floor(reactorData.maxEnergySaturation / 2) then
- return floor(reactorData.maxEnergySaturation / 2)+1;
- elseif reactorData.temperature-1 < 2000 then
- return 10 * (2000 - reactorData.temperature+1) * (fuel + 100) * 20;
- end
- return 0
- end
- local function fetchStatus(target)
- local data = reactor.getReactorInfo()
- if type(data) ~= "table" then
- data = {
- fuelConversaionRate = 0,
- temperature = 0,
- fieldStrength = 0,
- fieldDrainRate = 0,
- generationRate = 0,
- status = "invalid",
- energySaturation = 0,
- maxFuelConversion = 0,
- fuelConversion = 0,
- maxFieldStrength = 0,
- maxEnergySaturation = 0,
- shieldRF = 0,
- drainRF = 0,
- chargeRF = 0
- }
- end
- setmetatable(data, reactorShadow)
- data.lastUpdate = os.clock()
- data.shieldRF = ShieldRF(data)
- data.drainRF = DrainRF(data)
- data.chargeRF = ChargeRF(data)
- return data
- end
- reactorData = fetchStatus()
- local states = {}
- local function handleOffline()
- --do nothing
- end
- states.offline = handleOffline
- local function handleCharge()
- gates.charge.set(reactorData.chargeRF)
- gates.shield.set(0)
- gates.drain.set(0)
- end
- states.charging = handleCharge
- local function handleCharged()
- gates.charge.set(0)
- gates.shield.set(0)
- gates.drain.set(0)
- end
- states.charged = handleCharged
- local function handleOnline()
- local gen = reactorData.generationRate
- gen = gen - reactorData.shieldRF
- if gen > 0 then
- gates.charge.set(0)
- gates.shield.set(reactorData.shieldRF)
- --local r = math.ceil
- local trueDrain = reactorData.drainRF - (reactorData.shieldRF) -- drainRF - (reactorData.generationRate - shieldRF)
- --print("gR ", r(reactorData.generationRate), " tD ", r(trueDrain), " sRF " , r(shieldRF), " dR " , r(drainRF))
- if trueDrain > 0 then
- gates.drain.set(trueDrain)
- else
- --should not happen...
- --print("trueDrain ", trueDrain, " generationRate ", reactorData.generationRate, " shieldRF " , shieldRF, " t+s ", trueDrain+shieldRF)
- gates.drain.set(gen)
- end
- else
- gates.shield.set(reactorData.shieldRF * shieldSafety.online) --10% safety
- gates.drain.set(0)
- gates.charge.set(gen * -1.1)
- end
- end
- states.online = handleOnline
- local function handleStopping()
- local gen = reactorData.generationRate;
- gen = gen - reactorData.shieldRF
- if gen > 0 then
- gates.drain.set(gen * shieldSafety.stopping) --safety margin
- gates.shield.set(reactorData.shieldRF)
- gates.charge.set(0)
- else
- --redirect full energy to shield
- gates.drain.set(0)
- gates.shield.set(reactorData.generationRate)
- --use remaining energy from buffer
- gates.charge.set(-gen)
- end
- end
- states.stopping = handleStopping
- states.invalid = function()
- --print("SOMETHING WENT WRONG")
- error("SOMETHING WENT WRONG")
- end
- function control()
- print("control up")
- while run do
- local tmpReactorData = fetchStatus()
- if tmpReactorData.status ~= reactorData.status then
- print(reactorData.status, "->", tmpReactorData.status)
- end
- reactorData = tmpReactorData
- local state = states[reactorData.status]
- if state ~= nil then
- local ok, error = pcall(state)
- if not ok then
- print(error)
- end
- end
- tick()
- end
- end
- function input()
- print("input up")
- while run do
- local msg = read()
- local cmd = string.lower(msg)
- if commands[cmd] ~= nil then
- print("->", msg)
- local result = commands[cmd]()
- print("<-", result)
- if type(result) == 'table' then
- for i,v in pairs(result) do
- print(i, " ", v)
- end
- end
- else
- print("unkown command ", msg)
- end
- end
- end
- function server()
- print("server up")
- while run do
- local event = {os.pullEvent("modem_message")}
- local cmd = string.lower(event[5])
- if commands[cmd] ~= nil then
- modem.transmit(0,0, textutils.serialize(commands[cmd]()))
- else
- modem.transmit(0,0, "error")
- end
- --print(textutils.serialize(event))
- end
- end
- parallel.waitForAny(control, input, server)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement