diff --git a/machines/common.lua b/machines/common.lua index eec610c..23df385 100644 --- a/machines/common.lua +++ b/machines/common.lua @@ -95,9 +95,6 @@ machine.onConstruct=function(pos,config) local inv=meta:get_inventory() industrialtest.api.addPowerStorage(meta,config.capacity,config.flow,config.ioConfig) - if not config.withoutFormspec then - meta:set_string("formspec",machine.getFormspec(pos,config)) - end if config.groups then if config.groups._industrialtest_hasPowerInput then @@ -130,10 +127,14 @@ machine.onConstruct=function(pos,config) config.onConstruct(pos,meta,inv) end + if not config.withoutFormspec then + meta:set_string("formspec",machine.getFormspec(pos,config)) + end + minetest.get_node_timer(pos):start(industrialtest.updateDelay) end -machine.onDestruct=function(pos) +machine.onDestruct=function(pos,config) local meta=minetest.get_meta(pos) if industrialtest.api.isNetworkMaster(meta) then local network=industrialtest.api.createNetworkMap(pos,true) @@ -155,6 +156,9 @@ machine.onDestruct=function(pos) industrialtest.api.removeNodeFromNetwork(network,pos) end end + if config.onDestruct then + config.onDestruct(pos) + end end machine.onTimer=function(pos,elapsed,config) @@ -287,7 +291,9 @@ function industrialtest.internal.registerMachine(config) on_construct=function(pos) machine.onConstruct(pos,config) end, - on_destruct=machine.onDestruct, + on_destruct=function(pos) + machine.onDestruct(pos,config) + end, on_timer=function(pos,elapsed) local shouldRerunTimer,_=machine.onTimer(pos,elapsed,config) return shouldRerunTimer @@ -321,6 +327,12 @@ function industrialtest.internal.registerMachine(config) end, _industrialtest_updateFormspec=function(pos) machine.updateFormspec(pos,config) + end, + _industrialtest_getFormspec=function(pos) + if config.withoutFormspec then + return "" + end + return machine.getFormspec(pos,config) end } if industrialtest.mtgAvailable then diff --git a/machines/nuclear_reactor.lua b/machines/nuclear_reactor.lua index 277e964..f283537 100644 --- a/machines/nuclear_reactor.lua +++ b/machines/nuclear_reactor.lua @@ -16,15 +16,17 @@ local S=minetest.get_translator("industrialtest") local reactor={} +local reactorChamber={} reactor.getFormspec=function(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) local switchText=(meta:get_int("enabled")==0 and S("Start") or S("Stop")) local formspec if industrialtest.mtgAvailable then formspec={ - "list[context;fuel;1,1;5,4]", + "list[context;fuel;1,1;"..size..","..size.."]", "listring[context;fuel]", "list[context;charged;7.7,2.8;1,1]", "listring[context;charged]", @@ -34,8 +36,8 @@ reactor.getFormspec=function(pos) } elseif industrialtest.mclAvailable then formspec={ - "list[context;fuel;1,1;5,4]", - mcl_formspec.get_itemslot_bg(1,1,5,4), + "list[context;fuel;1,1;"..size..","..size.."]", + mcl_formspec.get_itemslot_bg(1,1,size,size), "listring[context;fuel]", "list[context;charged;7,2.8;1,1]", mcl_formspec.get_itemslot_bg(7.7,2.8,1,1), @@ -49,13 +51,23 @@ reactor.getFormspec=function(pos) end reactor.onConstruct=function(pos,meta,inv) - inv:set_size("fuel",20) + 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) + 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 +end + local function hasFuel(fuelList) for _,stack in ipairs(fuelList) do if stack:get_name()=="industrialtest:uranium_cell" then @@ -65,12 +77,12 @@ local function hasFuel(fuelList) return false end -local function findMaxFuelCluster(fuelList) +local function findMaxFuelCluster(size,fuelList) local maxCluster={} - for y=1,4 do - for x=1,5 do + for y=1,size do + for x=1,size do local iy=y-1 - local stack=fuelList[iy*5+x] + local stack=fuelList[iy*size+x] local def=minetest.registered_tools[stack:get_name()] if def and def.groups._industrialtest_nuclearReactorFuel then local cluster={ @@ -79,49 +91,49 @@ local function findMaxFuelCluster(fuelList) y=iy } } - if x>1 and fuelList[iy*5+x-1]:get_name()==stack:get_name() then + if x>1 and fuelList[iy*size+x-1]:get_name()==stack:get_name() then table.insert(cluster,{ x=x-1, y=iy }) end - if x<5 and fuelList[iy*5+x+1]:get_name()==stack:get_name() then + if x1 and fuelList[(iy-1)*5+x]:get_name()==stack:get_name() then + if y>1 and fuelList[(iy-1)*size+x]:get_name()==stack:get_name() then table.insert(cluster,{ x=x, y=iy-1 }) end - if y<4 and fuelList[(iy+1)*5+x]:get_name()==stack:get_name() then + if y1 and y>1 and fuelList[(iy-1)*5+x-1]:get_name()==stack:get_name() then + if x>1 and y>1 and fuelList[(iy-1)*size+x-1]:get_name()==stack:get_name() then table.insert(cluster,{ x=x-1, y=iy-1 }) end - if x<5 and y>1 and fuelList[(iy-1)*5+x+1]:get_name()==stack:get_name() then + if x1 and fuelList[(iy-1)*size+x+1]:get_name()==stack:get_name() then table.insert(cluster,{ x=x+1, y=iy-1 }) end - if x>1 and y<4 and fuelList[(iy+1)*5+x-1]:get_name()==stack:get_name() then + if x>1 and y0 then local coolantStack,used=useFuel(fuelList[coolant],#maxCluster*50) - heat=heat-used + heat=math.max(0,heat-used) inv:set_stack("fuel",coolant,coolantStack) end if heat>200 then @@ -247,6 +263,8 @@ reactor.activeOnTimer=function(pos,elapsed,meta,inv) end meta:set_int("heat",heat) + reactor.synchronizeChambers(pos) + return shouldRerunTimer,shouldUpdateFormspec end @@ -271,6 +289,7 @@ end reactor.metadataChange=function(pos) minetest.get_node_timer(pos):start(industrialtest.updateDelay) + reactor.synchronizeChambers(pos) end reactor.handleFormspecFields=function(pos,formname,fields) @@ -292,33 +311,121 @@ reactor.handleFormspecFields=function(pos,formname,fields) reactor.metadataChange(pos) end -local definition={ - description=S("Nuclear Reactor Chamber"), - tiles={"industrialtest_machine_block.png^industrialtest_nuclear_reactor_top.png"}, - drop="industrialtest:machine_block", - groups={ - _industrialtest_wrenchUnmountable=1 - } -} -if industrialtest.mtgAvailable then - definition.sounds=default.node_sound_metal_defaults() - definition.groups.cracky=1 - definition.groups.level=2 -elseif industrialtest.mclAvailable then - definition.sounds=mcl_sounds.node_sound_metal_defaults() - definition._mcl_blast_resistance=6 - definition._mcl_hardness=5 +reactor.synchronizeToChamber=function(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) + + reactor.synchronizeChambers(reactorPos) end -minetest.register_node("industrialtest:nuclear_reactor_chamber",definition) -minetest.register_craft({ - type="shaped", - output="industrialtest:nuclear_reactor_chamber", - recipe={ - {"","industrialtest:copper_plate",""}, - {"industrialtest:copper_plate","industrialtest:machine_block","industrialtest:copper_plate"}, - {"","industrialtest:copper_plate",""} + +reactor.synchronizeChambers=function(pos) + local meta=minetest.get_meta(pos) + local chambers=meta:contains("chambers") and minetest.deserialize(meta:get_string("chambers")) or {} + for _,chamber in ipairs(chambers) do + reactorChamber.synchronize(chamber,pos) + end +end + +reactor.changeSize=function(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) + + local def=minetest.registered_nodes[minetest.get_node(pos).name] + def._industrialtest_updateFormspec(pos) +end + +reactorChamber.synchronize=function(pos,reactor) + local meta=minetest.get_meta(pos) + local inv=meta:get_inventory() + local reactorDef=minetest.registered_nodes[minetest.get_node(reactor).name] + meta:set_string("formspec",reactorDef._industrialtest_getFormspec(reactor)) + + local reactorMeta=minetest.get_meta(reactor) + local reactorInv=reactorMeta:get_inventory() + local fuelList=reactorInv:get_list("fuel") + local chargedList=reactorInv:get_list("charged") + inv:set_size("fuel",#fuelList) + inv:set_size("charged",#chargedList) + inv:set_list("fuel",fuelList) + inv:set_list("charged",chargedList) +end + +reactorChamber.afterPlaceNode=function(pos) + local neighbours={ + vector.offset(pos,-1,0,0), + vector.offset(pos,1,0,0), + vector.offset(pos,0,-1,0), + vector.offset(pos,0,1,0), + vector.offset(pos,0,0,-1), + vector.offset(pos,0,0,1) } -}) + local reactorPos=nil + for _,neighbour in ipairs(neighbours) do + local node=minetest.get_node(neighbour) + if node.name=="industrialtest:nuclear_reactor" or node.name=="industrialtest:nuclear_reactor_active" then + reactorPos=neighbour + end + end + if not reactorPos then + minetest.remove_node(pos) + return true + end + + local meta=minetest.get_meta(pos) + meta:set_string("reactor",minetest.serialize(reactorPos)) + + reactor.changeSize(reactorPos,1) + reactor.synchronizeChambers(reactorPos) + + local reactorMeta=minetest.get_meta(reactorPos) + local chambers=reactorMeta:contains("chambers") and minetest.deserialize(reactorMeta:get_string("chambers")) or {} + table.insert(chambers,pos) + reactorMeta:set_string("chambers",minetest.serialize(chambers)) + + industrialtest.api.createNetworkMapForNode(reactorPos) + + reactorChamber.synchronize(pos,reactorPos) +end + +reactorChamber.onDestruct=function(pos) + local meta=minetest.get_meta(pos) + if not meta:contains("reactor") then + return + end + local reactorPos=minetest.deserialize(meta:get_string("reactor")) + local reactorMeta=minetest.get_meta(reactorPos) + if not reactorMeta or not reactorMeta:contains("chambers") then + return + end + local chambers=minetest.deserialize(reactorMeta:get_string("chambers")) + for i,chamber in ipairs(chambers) do + if chamber.x==pos.x and chamber.y==pos.y and chamber.z==pos.z then + table.remove(chambers,i) + break + end + end + reactorMeta:set_string("chambers",minetest.serialize(chambers)) + reactor.changeSize(reactorPos,-1) + reactor.synchronizeChambers(reactorPos) +end + +reactorChamber.handleFormspecFields=function(pos,formname,fields) + local meta=minetest.get_meta(pos) + local reactorPos=minetest.deserialize(meta:get_string("reactor")) + reactor.handleFormspecFields(reactorPos,formname,fields) +end industrialtest.internal.registerMachine({ name="nuclear_reactor", @@ -363,12 +470,14 @@ industrialtest.internal.registerMachine({ on_receive_fields=reactor.handleFormspecFields }, onConstruct=reactor.onConstruct, + onDestruct=reactor.onDestruct, onTimer=reactor.onTimer, activeOnTimer=reactor.activeOnTimer, allowMetadataInventoryMove=reactor.allowMetadataInventoryMove, allowMetadataInventoryPut=reactor.allowMetadataInventoryPut, onMetadataInventoryMove=reactor.metadataChange, - onMetadataInventoryPut=reactor.metadataChange + onMetadataInventoryPut=reactor.metadataChange, + onMetadataInventoryTake=reactor.metadataChange }) minetest.register_craft({ type="shaped", @@ -379,3 +488,42 @@ minetest.register_craft({ {"","industrialtest:generator",""} } }) + +local definition={ + description=S("Nuclear Reactor Chamber"), + tiles={"industrialtest_machine_block.png^industrialtest_nuclear_reactor_top.png"}, + drop="industrialtest:machine_block", + groups={ + _industrialtest_wrenchUnmountable=1, + _industrialtest_cable=1 + }, + on_destruct=reactorChamber.onDestruct, + after_place_node=reactorChamber.afterPlaceNode, + can_dig=minetest.registered_nodes["industrialtest:nuclear_reactor"].can_dig, + on_receive_fields=reactorChamber.handleFormspecFields, + allow_metadata_inventory_move=minetest.registered_nodes["industrialtest:nuclear_reactor"].allow_metadata_inventory_move, + allow_metadata_inventory_put=minetest.registered_nodes["industrialtest:nuclear_reactor"].allow_metadata_inventory_put, + on_metadata_inventory_move=reactor.synchronizeToChamber, + on_metadata_inventory_put=reactor.synchronizeToChamber, + on_metadata_inventory_take=reactor.synchronizeToChamber, + _industrialtest_cableFlow=industrialtest.api.evPowerFlow +} +if industrialtest.mtgAvailable then + definition.sounds=default.node_sound_metal_defaults() + definition.groups.cracky=1 + definition.groups.level=2 +elseif industrialtest.mclAvailable then + definition.sounds=mcl_sounds.node_sound_metal_defaults() + definition._mcl_blast_resistance=6 + definition._mcl_hardness=5 +end +minetest.register_node("industrialtest:nuclear_reactor_chamber",definition) +minetest.register_craft({ + type="shaped", + output="industrialtest:nuclear_reactor_chamber", + recipe={ + {"","industrialtest:copper_plate",""}, + {"industrialtest:copper_plate","industrialtest:machine_block","industrialtest:copper_plate"}, + {"","industrialtest:copper_plate",""} + } +})