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)
Comments
0 B
|👍
/👎