Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local reactorCardId = 0
- local desiredTemp = 7995
- local allowedTempDifference = 5
- local baseReactorIO = 1500000
- local reactorHeatUpSpeedMultipler = 2
- local maxReactorFuelTotal = 10368
- local shieldDesiredPower = 0.10
- local shieldMaxInputMultipler = 50
- local fuelShutdownLevel = 0.9
- local reactor = nil
- local variableStore = nil
- local outputFlowGate = nil
- local outputFlow = 0
- local inputFlowGate = nil
- local inputFlow = 0
- local previousReactorInfo = nil
- local currentReactorInfo = nil
- local startingReactorOutput = 0
- local currentReactorFuelTotal = 0
- local temperatureDiff = 0
- local outputDiff = 0
- local lastOutputUpdateTicksAgo = 0
- local desiredTempMin = desiredTemp - allowedTempDifference
- local desiredTempMax = desiredTemp + allowedTempDifference
- local function CheckNumberBetween(min,max,val)
- return min < val and max > val
- end
- local reactorStates = {
- "Off",
- "Charging",
- "Running",
- "Stopping",
- "Cooling Down",
- "Exploding"
- }
- reactorStates[0] = reactorStates[1] --fix for not initalized reactor
- local function SetNewReactorOutput(value,forceNewValue)
- if value < 0 then
- value = 0
- end
- value = math.ceil(value)
- if forceNewValue ~= true then
- local gateNum = outputFlowGate.getSignalLowFlow()
- if outputFlow ~= gateNum then ---To allow manual number override
- value = gateNum
- end
- end
- lastOutputUpdateTicksAgo = 0
- outputFlow = value
- outputFlowGate.setSignalLowFlow(value)
- end
- local function SetNewReactorInput(value)
- if value < 0 or value ~= value then
- value = 0
- end
- value = math.ceil(value)
- inputFlow = value
- inputFlowGate.setSignalLowFlow(value)
- end
- local function ShieldTooLowFix()
- local shieldPercent = currentReactorInfo.shield_charge/currentReactorInfo.max_shield_charge
- return 1 + math.max(shieldMaxInputMultipler * ((shieldDesiredPower - shieldPercent)/shieldDesiredPower),0)
- end
- local function UpdateReactorInput()
- local newShield = currentReactorInfo.field_drain + (currentReactorInfo.field_drain * shieldDesiredPower)
- newShield = newShield * ShieldTooLowFix()
- SetNewReactorInput(newShield)
- end
- local function GetReactorData()
- return variableStore.read(reactorCardId).value.v
- end
- local function InitalizeReactorComponents()
- local sucessfulInitialization = true
- repeat
- if sucessfulInitialization == false then
- sleep(0.05)
- term.clear()
- term.setCursorPos(1,1)
- end
- sucessfulInitialization = true
- local deviceList = peripheral.getNames()
- local flowGates = {}
- for i = 1, #deviceList do
- local device = peripheral.getType(deviceList[i])
- if device == "draconic_reactor" then
- reactor = peripheral.wrap(deviceList[i])
- elseif device == "variableStore" then
- variableStore = peripheral.wrap(deviceList[i])
- elseif device == "flow_gate" then
- flowGates[#flowGates + 1] = peripheral.wrap(deviceList[i])
- end
- end
- if #flowGates ~= 2 then
- print("You need exactly 2 flow gates")
- sucessfulInitialization = false
- else
- for i = 1, #flowGates do
- local gate = flowGates[i]
- if gate.getSignalHighFlow() == 0 then
- inputFlowGate = gate
- elseif gate.getSignalHighFlow() == 1 then
- outputFlowGate = gate
- end
- end
- end
- if outputFlowGate == nil or inputFlowGate == nil then
- print("At Least one flow gate is missing configuration. Please set in \"Redstone Signal Hgh\":");
- print("0 : Input")
- print("1 : Output")
- sucessfulInitialization = false;
- end
- if reactor == nil then
- -- error("Reactor is missing");
- end
- if variableStore == nil then
- print("Variable Store is missing");
- sucessfulInitialization = false;
- end
- until (sucessfulInitialization)
- end
- local function ReactorRunning()
- lastOutputUpdateTicksAgo = lastOutputUpdateTicksAgo + 1
- if previousReactorInfo ~= nil then
- local newFlowDiff = math.ceil(outputDiff/2 * startingReactorOutput)
- local newOutputFlow = math.ceil(outputFlow+newFlowDiff)
- local maxAllowedTemp = desiredTemp + allowedTempDifference
- local mult = 1 - (math.sin((maxAllowedTemp - currentReactorInfo.temperature) / (allowedTempDifference * 2) * math.pi)^128)
- if CheckNumberBetween(desiredTempMin,desiredTempMax,currentReactorInfo.temperature) then
- if math.abs(temperatureDiff)>0.05 then
- return
- end
- if math.abs(desiredTemp - currentReactorInfo.temperature) < lastOutputUpdateTicksAgo then
- SetNewReactorOutput(outputFlow + (outputDiff*startingReactorOutput) * mult)
- end
- elseif ((currentReactorInfo.temperature < desiredTemp - allowedTempDifference and outputDiff*reactorHeatUpSpeedMultipler > temperatureDiff)
- or (currentReactorInfo.temperature > desiredTemp + allowedTempDifference)) and lastOutputUpdateTicksAgo > 10 then
- SetNewReactorOutput(newOutputFlow)
- end
- end
- end
- local function DisplayReactorStats()
- term.clear()
- term.setCursorPos(1,1)
- if previousReactorInfo ~= nil then
- print("Reactor state : ".. reactorStates[currentReactorInfo.reactor_state])
- print()
- print("Previous temperature : "..string.format("%.5f",(previousReactorInfo.temperature)))
- print("Current temperature : "..string.format("%.5f",currentReactorInfo.temperature))
- print()
- print("Temperature difference : "..string.format("%.6f",temperatureDiff))
- print()
- print("Reactor output : "..outputFlow)
- print()
- print()
- print("Previous containment field : ".. string.format("%.3f",previousReactorInfo.shield_charge).. " ".. string.format("%.2f",((previousReactorInfo.shield_charge)/previousReactorInfo.max_shield_charge)*100).."%")
- print("Current containment field : ".. string.format("%.3f",currentReactorInfo.shield_charge).. " ".. string.format("%.2f",((currentReactorInfo.shield_charge)/currentReactorInfo.max_shield_charge)*100).."%")
- print()
- print("Reactor input : "..inputFlow)
- print()
- print()
- print("Fuel : "..string.format("%.3f",currentReactorInfo.converted_fuel).." / "..currentReactorFuelTotal.." "..string.format("%.3f",currentReactorInfo.converted_fuel/currentReactorFuelTotal*100) .."%")
- print("Fuel conversion rate : "..string.format("%.3f",currentReactorInfo.fuel_use_rate * 1000).." nb/t")
- end
- end
- local function MainReactorLoop()
- previousReactorInfo = currentReactorInfo
- currentReactorInfo = GetReactorData()
- if next(currentReactorInfo) == nil then
- return
- end
- if previousReactorInfo ~= nil and previousReactorInfo.temperature == nil then
- return
- end
- if previousReactorInfo ~= nil then
- --print ("has Reactor info")
- temperatureDiff = currentReactorInfo.temperature - previousReactorInfo.temperature
- outputDiff = (1-(currentReactorInfo.temperature/desiredTemp))
- if previousReactorInfo.reactor_state ~= 2 and currentReactorInfo.reactor_state == 2 then
- -- this will happen only once
- --print ("started heating Up")
- currentReactorFuelTotal = math.floor((currentReactorInfo.reactable_fuel or 0) + (currentReactorInfo.converted_fuel or 0)+0.5)
- startingReactorOutput = currentReactorFuelTotal / maxReactorFuelTotal * baseReactorIO
- SetNewReactorOutput(0,true)
- SetNewReactorInput(10000000)
- elseif previousReactorInfo.reactor_state == 2 and currentReactorInfo.reactor_state == 2 then
- ---injecting 10M into reactor
- --- maybe try to start reactor
- ---reactor.activateReactor()
- elseif previousReactorInfo.reactor_state ~= 3 and currentReactorInfo.reactor_state == 3 then
- -- this will happen only once
- -- print ("Started Running")
- SetNewReactorOutput(0,true)
- UpdateReactorInput()
- elseif previousReactorInfo.reactor_state == 3 and currentReactorInfo.reactor_state == 3 then
- if currentReactorInfo.converted_fuel / currentReactorFuelTotal >= fuelShutdownLevel then
- --We are shutting reactor down
- SetNewReactorOutput(0)
- else
- ReactorRunning()
- end
- UpdateReactorInput()
- elseif currentReactorInfo.reactor_state >= 4 then
- UpdateReactorInput()
- end
- elseif previousReactorInfo == nil and currentReactorInfo.reactor_state ~= 1 then
- --we are starting program with reactor already running
- if currentReactorInfo.reactor_state <= 3 then
- currentReactorFuelTotal = math.floor((currentReactorInfo.reactable_fuel or 0) + (currentReactorInfo.converted_fuel or 0)+0.5)
- startingReactorOutput = currentReactorFuelTotal / maxReactorFuelTotal * baseReactorIO
- if currentReactorInfo.reactor_state == 2 then
- SetNewReactorInput(10000000)
- else
- UpdateReactorInput()
- end
- SetNewReactorOutput(outputFlowGate.getSignalLowFlow(value),true)
- end
- end
- DisplayReactorStats()
- end
- InitalizeReactorComponents();
- repeat
- MainReactorLoop()
- sleep(0.05)
- until (false)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement