diff --git a/machines/nuclear_reactor.lua b/machines/nuclear_reactor.lua
index 5f9e583..e4affdf 100644
--- a/machines/nuclear_reactor.lua
+++ b/machines/nuclear_reactor.lua
@@ -15,10 +15,72 @@
-- along with this program. If not, see .
local S=minetest.get_translator("industrialtest")
-local reactor={}
-local reactorChamber={}
+industrialtest.Reactor=table.copy(industrialtest.ActivatedElectricMachine)
+industrialtest.internal.unpackTableInto(industrialtest.Reactor,{
+ name="industrialtest:nuclear_reactor",
+ description=S("Nuclear Reactor"),
+ tiles={
+ "industrialtest_machine_block.png^industrialtest_nuclear_reactor_top.png",
+ "industrialtest_machine_block.png",
+ "industrialtest_machine_block.png",
+ "industrialtest_machine_block.png",
+ "industrialtest_machine_block.png",
+ "industrialtest_machine_block.png^industrialtest_nuclear_reactor_front.png"
+ },
+ sounds="metal",
+ requiresWrench=true,
+ facedir=true,
+ storageLists={
+ "charged",
+ "fuel"
+ },
+ powerLists={
+ {
+ list="charged",
+ direction="o"
+ }
+ },
+ active={
+ tiles={
+ "industrialtest_machine_block.png^industrialtest_nuclear_reactor_top.png",
+ "industrialtest_machine_block.png",
+ "industrialtest_machine_block.png",
+ "industrialtest_machine_block.png",
+ "industrialtest_machine_block.png",
+ "industrialtest_machine_block.png^industrialtest_nuclear_reactor_front_active.png"
+ },
+ lightSource=2
+ },
+ capacity=industrialtest.api.evPowerFlow,
+ flow=industrialtest.api.evPowerFlow,
+ hasPowerOutput=true,
+ ioConfig="oooooo"
+})
-reactor.getFormspec=function(pos)
+function industrialtest.Reactor.onConstruct(self,pos)
+ local meta=minetest.get_meta(pos)
+ local inv=meta:get_inventory()
+ inv:set_size("fuel",4)
+ inv:set_size("charged",1)
+ meta:set_int("heat",0)
+ meta:set_int("size",6)
+ meta:set_int("enabled",0)
+ meta:set_int("stateChanged",0)
+ industrialtest.ActivatedElectricMachine.onConstruct(self,pos)
+end
+
+function industrialtest.Reactor.onDestruct(self,pos)
+ local meta=minetest.get_meta(pos)
+ local chambers=minetest.deserialize(meta:get_string("chambers")) or {}
+ for _,chamber in ipairs(chambers) do
+ minetest.remove_node(chamber)
+ minetest.add_item(chamber,"industrialtest:nuclear_reactor_chamber")
+ end
+ industrialtest.ActivatedElectricMachine.onDestruct(self,pos)
+end
+
+function industrialtest.Reactor.getFormspec(self,pos)
+ local parentFormspec=industrialtest.ActivatedElectricMachine.getFormspec(self,pos)
local meta=minetest.get_meta(pos)
local charged=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")
local size=math.floor(meta:get_int("size")/3)
@@ -29,32 +91,158 @@ reactor.getFormspec=function(pos)
"list[context;charged;7,2.8;1,1]",
industrialtest.internal.getItemSlotBg(7.7,2.8,1,1),
"button[7.7,1;1,0.8;toggle;"..minetest.formspec_escape(switchText).."]",
- "box[9,1;0.3,4.8;#202020]",
- (charged>0 and "box[9,"..(1+4.8-(charged*4.8))..";0.3,"..(charged*4.8)..";#FF1010]" or ""),
+ self.createPowerIndicatorWidget(charged,9,1),
"listring[context;fuel]"
}
- return table.concat(formspec,"")
+ return parentFormspec..table.concat(formspec,"")
end
-reactor.onConstruct=function(pos,meta,inv)
- inv:set_size("fuel",4)
- inv:set_size("charged",1)
- meta:set_int("heat",0)
- meta:set_int("size",6)
- meta:set_int("enabled",0)
- meta:set_int("stateChanged",0)
-end
-
-reactor.onDestruct=function(pos)
+function industrialtest.Reactor.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
local meta=minetest.get_meta(pos)
- local chambers=minetest.deserialize(meta:get_string("chambers")) or {}
- for _,chamber in ipairs(chambers) do
- minetest.remove_node(chamber)
- minetest.add_item(chamber,"industrialtest:nuclear_reactor_chamber")
+ local inv=meta:get_inventory()
+ local movedItemStack=inv:get_stack(fromList,fromIndex)
+ local def=movedItemStack:get_definition()
+ if toList=="fuel" and (not def or not def.groups._industrialtest_placedInNuclearReactor) then
+ return 0
end
+ return industrialtest.ActivatedElectricMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
end
-local function hasFuel(fuelList)
+function industrialtest.Reactor.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
+ local def=stack:get_definition()
+ if listname=="fuel" and (not def or not def.groups._industrialtest_placedInNuclearReactor) then
+ return 0
+ end
+ return industrialtest.ActivatedElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
+end
+
+function industrialtest.Reactor.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
+ industrialtest.ActivatedElectricMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)
+ self.synchronizeChambers(pos)
+end
+
+function industrialtest.Reactor.onMetadataInventoryPut(self,pos,listname,index,stack,player)
+ industrialtest.ActivatedElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack,player)
+ self.synchronizeChambers(pos)
+end
+
+function industrialtest.Reactor.onMetadataInventoryTake(self,pos,listname,index,stack)
+ industrialtest.ActivatedElectricMachine.onMetadataInventoryTake(self,pos,listname,index,stack)
+ self.synchronizeChambers(pos)
+end
+
+function industrialtest.Reactor.onReceiveFields(self,pos,formname,fields)
+ if not fields.toggle then
+ return
+ end
+ local meta=minetest.get_meta(pos)
+ if not self.hasFuel(pos) and meta:get_int("enabled")==0 then
+ return
+ end
+ if meta:get_int("enabled")==0 then
+ meta:set_int("enabled",1)
+ else
+ meta:set_int("enabled",0)
+ self:updateFormspec(pos)
+ self.synchronizeChambers(pos)
+ end
+ meta:set_int("stateChanged",1)
+ self:triggerIfNeeded(pos)
+end
+
+function industrialtest.Reactor.shouldActivate(self,pos)
+ local meta=minetest.get_meta(pos)
+
+ if meta:get_int("stateChanged")==0 then
+ return false
+ end
+
+ return meta:get_int("enabled")>0 and self.hasFuel(pos)
+end
+
+function industrialtest.Reactor.shouldDeactivate(self,pos)
+ local meta=minetest.get_meta(pos)
+ return meta:get_int("enabled")==0 or not self.hasFuel(pos)
+end
+
+function industrialtest.Reactor.afterActivation(self,pos)
+ local meta=minetest.get_meta(pos)
+ meta:set_int("stateChanged",0)
+ self.synchronizeChambers(pos)
+end
+
+function industrialtest.Reactor.afterDeactivation(self,pos)
+ local meta=minetest.get_meta(pos)
+ meta:set_int("enabled",0)
+ self:updateFormspec(pos)
+ self.synchronizeChambers(pos)
+end
+
+function industrialtest.Reactor.activeUpdate(self,pos,elapsed,meta,inv)
+ local size=math.floor(meta:get_int("size")/3)
+ local fuelList=inv:get_list("fuel")
+ local shouldRerunTimer=meta:get_int("enabled")>0
+ local shouldUpdateFormspec=false
+
+ local maxCluster=self.findMaxFuelCluster(size,fuelList)
+ for _,stack in ipairs(maxCluster) do
+ local index=stack.y*size+stack.x
+ local usedStack,_=self.useFuel(fuelList[index],5)
+ inv:set_stack("fuel",index,usedStack)
+ end
+ local generatedPowerAmount=math.pow(3,#maxCluster)
+ if industrialtest.api.addPower(meta,generatedPowerAmount)>0 then
+ shouldUpdateFormspec=true
+ end
+
+ local heat=meta:get_int("heat")+#maxCluster
+ local coolant=self.findCoolant(fuelList)
+ if coolant>0 then
+ local coolantStack,used=self.useFuel(fuelList[coolant],#maxCluster*50)
+ heat=math.max(0,heat-used)
+ inv:set_stack("fuel",coolant,coolantStack)
+ end
+ if heat>200 then
+ minetest.remove_node(pos)
+ industrialtest.internal.explode(pos,#maxCluster*4)
+ return false
+ end
+ meta:set_int("heat",heat)
+
+ self.synchronizeChambers(pos)
+
+ return shouldUpdateFormspec
+end
+
+function industrialtest.Reactor.changeSize(self,pos,diff)
+ local meta=minetest.get_meta(pos)
+ local inv=meta:get_inventory()
+ local size=meta:get_int("size")+diff
+ local actualSize=math.floor(size/3)
+ meta:set_int("size",size)
+ inv:set_size("fuel",actualSize*actualSize)
+ self:updateFormspec(pos)
+end
+
+function industrialtest.Reactor.synchronizeToChamber(self,pos)
+ local meta=minetest.get_meta(pos)
+ local inv=meta:get_inventory()
+ local fuelList=inv:get_list("fuel")
+ local chargedList=inv:get_list("charged")
+
+ local reactorPos=minetest.deserialize(meta:get_string("reactor"))
+ local reactorMeta=minetest.get_meta(reactorPos)
+ local reactorInv=reactorMeta:get_inventory()
+ reactorInv:set_list("fuel",fuelList)
+ reactorInv:set_list("charged",chargedList)
+
+ self.synchronizeChambers(reactorPos)
+end
+
+function industrialtest.Reactor.hasFuel(pos)
+ local meta=minetest.get_meta(pos)
+ local inv=meta:get_inventory()
+ local fuelList=inv:get_list("fuel")
for _,stack in ipairs(fuelList) do
if stack:get_name()=="industrialtest:uranium_cell" then
return true
@@ -63,7 +251,7 @@ local function hasFuel(fuelList)
return false
end
-local function findMaxFuelCluster(size,fuelList)
+function industrialtest.Reactor.findMaxFuelCluster(size,fuelList)
local maxCluster={}
for y=1,size do
for x=1,size do
@@ -137,7 +325,7 @@ local function findMaxFuelCluster(size,fuelList)
return maxCluster
end
-local function findCoolant(fuelList)
+function industrialtest.Reactor.findCoolant(fuelList)
for i=1,#fuelList do
local stack=fuelList[i]
local def=minetest.registered_tools[stack:get_name()]
@@ -148,7 +336,7 @@ local function findCoolant(fuelList)
return 0
end
-local function useFuel(stack,use)
+function industrialtest.Reactor.useFuel(stack,use)
local used=math.min(65535-stack:get_wear(),use)
if used