-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstartup
243 lines (210 loc) · 7.7 KB
/
startup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
-- BigReactors API can be found here: https://ftbwiki.org/Reactor_Computer_Port
-- ESSENTIAL ARRAY(s)
controlRodsArray = {}
--
print("Automated Reactor Control System v0.01-Alpha")
function loadConfigurationSettings()
configuration = {}
-- Check if a disk drive is present.
if not fs.isDir("disk/") then
configurationName = "arcs.config"
else
configurationName = "disk/arcs.config"
end
if not fs.exists(configurationName) then
print('[INFO] Creating configuration file: ',configurationName)
configurationIO = io.open(configurationName,"w")
io.output(configurationIO)
writeConfiguration = [[
# The amount in RF that the reactor's buffer is allowed to deviate
# from half-full before adjustments are made. The drift comes from
# inaccuracies in power adjustment.
#
# Default: 0
reactorBufferAllowedDrift = 0
# The threshold in RF that must be exceeded before any adjustments
# take place. Adjust this accordingly for your reactor.
#
# Default: 1
adjustmentThreshold = 1
# The amount from 1-99 that the reactors control rods are
# raised/lowered by each time an adjustment is made. A higher
# value will adjust the control rods faster albeit at the cost
# of accuracy.
#
# Default: 1
controlRodAdjustmentAmount = 1
# Emit redstone when the factor of the maximum capacity of fuel
# divided by the current amount of fuel is greater-than or equal
# to the specified value. Eq. getFuelAmountMax() / getFuelAmount()
#
# Default: 2
emitRedstoneWhenLowOnFuel = 2
# Emit redstone from the specified side. Redstone signal is
# emitted when the reactor is low on fuel.
#
# Default: none
emitRedstoneFromSide = none
]]
io.write(writeConfiguration)
io.close()
writeConfiguration = nil
end
print('[INFO] Loading configuration from file: ', configurationName)
configurationIO = io.open(configurationName,"r")
io.input(configurationIO)
for line in configurationIO:lines() do
for value in string.gmatch(line,"= (.*)") do
for varname in string.gmatch(line,"(.*) =") do
if varname == "emitRedstoneFromSide" then
if value == "front" or value == "back" or value == "left" or value == "right" or value == "top" or value == "bottom" or value == "none" then
table.insert(configuration,value)
else
print('[ERROR] arcs.config: emitRedstoneFromSide invalid side: ',value)
error()
end
else
table.insert(configuration,tonumber(value))
end
end
end
end
io.close()
end
loadConfigurationSettings()
function modifyControlRodIndex()
-- Make the array for indexing reactor control rods
print('[INFO] Indexing control rods')
if table.getn(controlRodsArray) == 0 then
for intControlRod=0,reactor.getNumberOfControlRods()-1,1 do
controlRodsArray[intControlRod+1] = intControlRod
reactor.setControlRodLevel(intControlRod,reactor.getControlRodLevel(0))
end
else
-- If current number of control rods are greater than the amount in the array, add however many control rods we're missing.
if reactor.getNumberOfControlRods() > table.getn(controlRodsArray) then
for intControlRod=1,reactor.getNumberOfControlRods() - table.getn(controlRodsArray),1 do
table.insert(controlRodsArray,table.getn(controlRodsArray))
reactor.setControlRodLevel(intControlRod,reactor.getControlRodLevel(0))
end
-- If current number of control rods are less than the amount in the array, remove control rods from the array starting at the end.
elseif reactor.getNumberOfControlRods() < table.getn(controlRodsArray) then
for intControlRod=1,table.getn(controlRodsArray) - reactor.getNumberOfControlRods(),1 do
table.remove(controlRodsArray)
end
end
end
end
function isReactorStructureValid()
-- The below will throw an error if the reactor does not have any control rods
if reactor.getNumberOfControlRods() == 0 then
error("Invalid Reactor")
end
end
-- Search for peripherals
function attachToReactor()
for _,side in pairs(peripheral.getNames()) do
if(peripheral.getType(side) == 'BigReactors-Reactor') then
reactor = peripheral.wrap(side)
if pcall(isReactorStructureValid) then
print('[INFO] Wrapping to reactor on ',side,' side.')
reactorSide = side
if not reactor.getActive() then
reactor.setActive(true)
end
print('[INFO] Reactor structure is valid.')
else
reactor = nil
end
end
end
end
attachToReactor()
function calculateFluctuation(rfGeneration,previousInternalBufferValue)
-- Set the sleep statement equal to 1 tick.
sleep(0.050)
return reactor.getEnergyStored() - previousInternalBufferValue
end
if not reactor then
print('[WARN] No reactor found or reactor structure invalid. Waiting for valid reactor structure...')
searchForReactorInterval = os.startTimer(5)
else
reactorAdjustmentInterval = os.startTimer(1)
end
while true do
local event,data1 = os.pullEventRaw()
if event == "terminate" then
print('Caught terminate event')
reactor = nil
reactorSide = nil
return
elseif event == "peripheral_detach" then
if data1 == reactorSide then
print('[WARN] Reactor computer port detached.')
reactor = nil
searchForReactorInterval = os.startTimer(5)
end
elseif event == "timer" and not reactor then
if data1 == searchForReactorInterval then
attachToReactor()
if not reactor then
searchForReactorInterval = os.startTimer(5)
else
reactorAdjustmentInterval = os.startTimer(1)
end
end
elseif event == "timer" and reactor then
if data1 == reactorAdjustmentInterval then
function adjustReactorOutput()
fluctuation = calculateFluctuation(reactor.getEnergyProducedLastTick(),reactor.getEnergyStored())
-- If current energy level is greater than half + Threshold,
-- reduce power output.
if reactor.getEnergyStored() > 5000000 + configuration[1] then
-- Repeat until fluctuation is less-than negative configuration[2].
if fluctuation > configuration[2]-(configuration[2]*2) then
for _,controlRod in pairs(controlRodsArray) do
if reactor.getControlRodLevel(controlRod) + configuration[3] <= 100 then
reactor.setControlRodLevel(controlRod,reactor.getControlRodLevel(controlRod) + configuration[3])
end
end
end
-- If current energy level is less than half - Threshold,
-- increase power output.
elseif reactor.getEnergyStored() < 5000000 - configuration[1] then
if fluctuation < configuration[2] then
for _,controlRod in pairs(controlRodsArray) do
if reactor.getControlRodLevel(controlRod) - configuration[3] >= 0 then
reactor.setControlRodLevel(controlRod,reactor.getControlRodLevel(controlRod) - configuration[3])
end
end
end
end
end
if reactor.getNumberOfControlRods() == table.getn(controlRodsArray) then
pcall(adjustReactorOutput)
if reactor.getFuelAmountMax() / reactor.getFuelAmount() >= configuration[4] and configuration[5] ~= "none" then
if not redstone.getOutput(configuration[5]) then
print('[WARN] Reactor is low on fuel. Emitting redstone signal on ', configuration[5], ' side.')
redstone.setOutput(configuration[5],true)
end
elseif configuration[5] ~= "none" then
if redstone.getOutput(configuration[5]) then
print('[INFO] Fuel level in reactor is above threshold. Disabling redstone signal.')
redstone.setOutput(configuration[5],false)
end
end
reactorAdjustmentInterval = os.startTimer(1)
else
if pcall(isReactorStructureValid) then
pcall(modifyControlRodIndex)
print('[INFO] Adjusted control rod index for current reactor configuration.')
reactorAdjustmentInterval = os.startTimer(1)
else
print('[WARN] No reactor found or reactor structure invalid. Waiting for valid reactor structure...')
reactor = nil
searchForReactorInterval = os.startTimer(5)
end
end
end
end
end