Implement industrialtest.api.createNetworkMap
This commit is contained in:
parent
71480f6a62
commit
7a6dacb614
173
api.lua
173
api.lua
@ -216,91 +216,141 @@ industrialtest.api.transferPowerFromItem=function(srcItemstack,meta,amount)
|
||||
industrialtest.api.addPowerToItem(srcItemstack,-actualFlow)
|
||||
return actualFlow
|
||||
end
|
||||
|
||||
-- \brief Transfers power from source node to all neighbouring nodes
|
||||
-- \param pos Vector with position of source node
|
||||
-- \returns two values: true if any neighbouring node has room for more power, false otherwise
|
||||
-- true if any power was transferred, false otherwise
|
||||
industrialtest.api.powerFlow=function(pos)
|
||||
local meta=minetest.get_meta(pos)
|
||||
if not industrialtest.api.hasPowerStorage(meta) then
|
||||
return false
|
||||
-- if machine doesn't have network map then it's not capable of transferring power
|
||||
if not meta:contains("industrialtest.network") then
|
||||
return false,false
|
||||
end
|
||||
local neighbourPositions={
|
||||
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 neighbours={}
|
||||
for key,value in ipairs(neighbourPositions) do
|
||||
neighbours[key]=minetest.get_meta(value)
|
||||
end
|
||||
local neighboursContainingPower=0
|
||||
for key,value in ipairs(neighbours) do
|
||||
local side=industrialtest.api.getOppositeSide(key)
|
||||
if industrialtest.api.hasPowerStorage(value) and industrialtest.api.isPowerInput(value,side) and not industrialtest.api.isFullyCharged(value) then
|
||||
neighboursContainingPower=neighboursContainingPower+1
|
||||
else
|
||||
neighbourPositions[key]=0
|
||||
neighbours[key]=0
|
||||
end
|
||||
end
|
||||
if neighboursContainingPower==0 then
|
||||
return false
|
||||
local network=minetest.deserialize(meta:get_string("industrialtest.network"))
|
||||
if #network==0 then
|
||||
return false,false
|
||||
end
|
||||
local powerFlow=meta:get_int("industrialtest.powerFlow")
|
||||
local powerDistribution=math.floor(powerFlow/neighboursContainingPower)
|
||||
-- TODO: if supplying machine power flow is too large for receiving machine to handle then that machine should explode
|
||||
local roomAvailable=false
|
||||
local powerDistribution=math.floor(powerFlow/#network)
|
||||
local transferred=false
|
||||
for key,value in ipairs(neighbours) do
|
||||
if value~=0 then
|
||||
local normalizedKey=industrialtest.api.normalizeSide(pos,key)
|
||||
if industrialtest.api.isPowerOutput(meta,normalizedKey) then
|
||||
if industrialtest.api.transferPower(meta,value,powerDistribution)>0 then
|
||||
local roomAvailable=false
|
||||
for _,endpoint in ipairs(network) do
|
||||
local endpointMeta=minetest.get_meta(endpoint.position)
|
||||
-- TODO: if supplying machine power flow is too large for receiving machine to handle then that machine should explode
|
||||
local transferredToEndpoint=false
|
||||
if industrialtest.api.transferPower(meta,endpointMeta,powerDistribution)>0 then
|
||||
transferred=true
|
||||
transferredToEndpoint=true
|
||||
end
|
||||
local def=minetest.registered_nodes[minetest.get_node(neighbourPositions[key]).name]
|
||||
local def=minetest.registered_nodes[minetest.get_node(endpoint.position).name]
|
||||
if def then
|
||||
local updateFormspec=def._industrialtest_updateFormspec
|
||||
if updateFormspec then
|
||||
updateFormspec(neighbourPositions[key])
|
||||
updateFormspec(endpoint.position)
|
||||
end
|
||||
local onPowerFlow=def._industrialtest_onPowerFlow
|
||||
if onPowerFlow and transferred then
|
||||
onPowerFlow(neighbourPositions[key],industrialtest.api.getOppositeSide(key))
|
||||
if onPowerFlow and transferredToEndpoint then
|
||||
onPowerFlow(endpoint.position,industrialtest.api.getOppositeSide(1))
|
||||
end
|
||||
end
|
||||
minetest.get_node_timer(neighbourPositions[key]):start(industrialtest.updateDelay)
|
||||
if not industrialtest.api.isFullyCharged(value) then
|
||||
minetest.get_node_timer(endpoint.position):start(industrialtest.updateDelay)
|
||||
if not industrialtest.api.isFullyCharged(endpointMeta) then
|
||||
roomAvailable=true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return roomAvailable,transferred
|
||||
end
|
||||
|
||||
local function addNodeToNetwork(pos,networkMasterPos)
|
||||
local meta=minetest.get_meta(pos)
|
||||
local networks={}
|
||||
if meta:contains("industrialtest.networks") then
|
||||
networks=minetest.deserialize(meta:get_string("industrialtest.networks"))
|
||||
end
|
||||
for _,network in ipairs(networks) do
|
||||
if network==networkMasterPos then
|
||||
return
|
||||
end
|
||||
end
|
||||
table.insert(networks,networkMasterPos)
|
||||
meta:set_string("industrialtest.networks",minetest.serialize(networks))
|
||||
end
|
||||
|
||||
-- \brief Creates network map starting from node at pos
|
||||
-- \param pos vector
|
||||
-- \returns table with network map
|
||||
industrialtest.api.createNetworkMap=function(pos)
|
||||
local workers={}
|
||||
local map={}
|
||||
local connections=industrialtest.api.getConnections(pos)
|
||||
if #connections==0 then
|
||||
return map
|
||||
end
|
||||
local serializedSourcePos=pos.x..","..pos.y..","..pos.z
|
||||
local visitedNodes={[serializedSourcePos]=true}
|
||||
for _,value in ipairs(connections) do
|
||||
visitedNodes[value.x..","..value.y..","..value.z]=true
|
||||
table.insert(workers,{
|
||||
position=value,
|
||||
distance=1,
|
||||
})
|
||||
end
|
||||
while #workers>0 do
|
||||
for _,worker in ipairs(workers) do
|
||||
local connections=industrialtest.api.getConnections(worker.position)
|
||||
if #connections==0 then
|
||||
table.remove(workers,i)
|
||||
break
|
||||
else
|
||||
local directionAssigned=false
|
||||
local foundNewNode=false
|
||||
for _,conn in ipairs(connections) do
|
||||
local serializedPos=conn.x..","..conn.y..","..conn.z
|
||||
if not visitedNodes[serializedPos] then
|
||||
local def=minetest.registered_nodes[minetest.get_node(conn).name]
|
||||
visitedNodes[serializedPos]=true
|
||||
foundNewNode=true
|
||||
addNodeToNetwork(conn,serializedSourcePos)
|
||||
if def.groups._industrialtest_cable then
|
||||
if directionAssigned then
|
||||
table.insert(workers,{
|
||||
position=conn,
|
||||
distance=worker.distance+1
|
||||
})
|
||||
else
|
||||
worker.position=conn
|
||||
worker.distance=worker.distance+1
|
||||
directionAssigned=true
|
||||
end
|
||||
else
|
||||
table.insert(map,{
|
||||
position=conn,
|
||||
distance=worker.distance
|
||||
})
|
||||
if #connections==1 then
|
||||
table.remove(workers,i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if not foundNewNode then
|
||||
table.remove(workers,i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return map
|
||||
end
|
||||
-- \brief Starts node timer of neighbouring nodes with center node
|
||||
-- \param pos Vector with position of center node
|
||||
-- \returns nil
|
||||
industrialtest.api.triggerNeighbours=function(pos)
|
||||
local neighbourPositions={
|
||||
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)
|
||||
}
|
||||
for key,value in ipairs(neighbourPositions) do
|
||||
local meta=minetest.get_meta(value)
|
||||
local side=industrialtest.api.getOppositeSide(key)
|
||||
if industrialtest.api.hasPowerStorage(meta) and industrialtest.api.isPowerOutput(meta,side) then
|
||||
for _,value in ipairs(industrialtest.api.getConnections(pos)) do
|
||||
minetest.get_node_timer(value):start(industrialtest.updateDelay)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- \brief Returns opposite side of provided one
|
||||
-- \param side Side number. See industrialtest.api.addPowerStorage for order
|
||||
@ -321,12 +371,17 @@ industrialtest.api.getConnections=function(pos)
|
||||
vector.offset(pos,0,0,-1),
|
||||
vector.offset(pos,0,0,1)
|
||||
}
|
||||
local index=1
|
||||
local sourceMeta=minetest.get_meta(pos)
|
||||
for key,value in ipairs(neighbourPositions) do
|
||||
local def=minetest.registered_nodes[minetest.get_node(value).name]
|
||||
if def.groups._industrialtest_cable then
|
||||
table.insert(result,value)
|
||||
else
|
||||
local meta=minetest.get_meta(value)
|
||||
if industrialtest.api.hasPowerStorage(meta) then
|
||||
result[index]=key
|
||||
index=index+1
|
||||
local side=industrialtest.api.getOppositeSide(key)
|
||||
if def.groups._industrialtest_hasPowerInput and industrialtest.api.isPowerOutput(sourceMeta,key) and industrialtest.api.isPowerInput(meta,side) then
|
||||
table.insert(result,value)
|
||||
end
|
||||
end
|
||||
end
|
||||
return result
|
||||
|
@ -142,6 +142,7 @@ local function registerCable(name,displayName,size,flow,registerInsulated)
|
||||
definition.sound=mcl_sounds.node_sound_metal_defaults()
|
||||
end
|
||||
definition.groups._industrialtest_hasPowerInput=1
|
||||
definition.groups._industrialtest_cable=1
|
||||
minetest.register_node("industrialtest:"..name.."_cable",definition)
|
||||
if registerInsulated then
|
||||
definition=table.copy(definition)
|
||||
|
Loading…
Reference in New Issue
Block a user