2019-05-01 13:20:09 +02:00
|
|
|
local me = microexpansion
|
|
|
|
me.networks = {}
|
|
|
|
local networks = me.networks
|
|
|
|
local path = microexpansion.get_module_path("network")
|
|
|
|
|
2020-03-03 17:16:35 +01:00
|
|
|
local function split_stack_values(stack)
|
2020-03-01 08:23:39 +01:00
|
|
|
local stack_name
|
|
|
|
local stack_count
|
|
|
|
if type(stack) == "string" then
|
|
|
|
local split_string = stack:split(" ")
|
|
|
|
stack_name = split_string[1]
|
|
|
|
if (#split_string > 1) then
|
|
|
|
stack_count = tonumber(split_string[2])
|
|
|
|
else
|
|
|
|
stack_count = 1
|
|
|
|
end
|
|
|
|
else
|
|
|
|
stack_name = stack:get_name()
|
|
|
|
stack_count = stack:get_count()
|
|
|
|
end
|
2020-03-03 17:16:35 +01:00
|
|
|
return stack_name, stack_count
|
|
|
|
end
|
|
|
|
|
|
|
|
function me.insert_item(stack, inv, listname)
|
|
|
|
if me.settings.huge_stacks == false then
|
|
|
|
return inv:add_item(listname, stack)
|
|
|
|
end
|
|
|
|
local stack_name,stack_count = split_stack_values(stack)
|
2020-03-01 08:23:39 +01:00
|
|
|
local found = false
|
|
|
|
for i = 0, inv:get_size(listname) do
|
|
|
|
local inside = inv:get_stack(listname, i)
|
|
|
|
if inside:get_name() == stack_name then
|
|
|
|
local total_count = inside:get_count() + stack_count
|
|
|
|
-- bigger item count is not possible we only have unsigned 16 bit
|
|
|
|
if total_count <= math.pow(2,16) then
|
|
|
|
if not inside:set_count(total_count) then
|
|
|
|
minetest.log("error"," adding items to stack in microexpansion network failed")
|
|
|
|
print("stack is now " .. inside:to_string())
|
|
|
|
end
|
|
|
|
inv:set_stack(listname, i, inside)
|
|
|
|
found = true
|
|
|
|
break;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if not found then
|
2020-03-03 17:16:35 +01:00
|
|
|
return inv:add_item(listname, stack)
|
2020-03-01 08:23:39 +01:00
|
|
|
end
|
|
|
|
end
|
2019-05-01 13:20:09 +02:00
|
|
|
|
|
|
|
dofile(path.."/network.lua") -- Network Management
|
|
|
|
|
|
|
|
-- generate iterator to find all connected nodes
|
2020-03-01 08:23:39 +01:00
|
|
|
function me.connected_nodes(start_pos,include_ctrl)
|
2019-05-01 13:20:09 +02:00
|
|
|
-- nodes to be checked
|
2020-03-01 08:23:39 +01:00
|
|
|
local open_list = {{pos = start_pos}}
|
2019-05-01 13:20:09 +02:00
|
|
|
-- nodes that were checked
|
|
|
|
local closed_set = {}
|
|
|
|
-- local connected nodes function to reduce table lookups
|
|
|
|
local adjacent_connected_nodes = me.network.adjacent_connected_nodes
|
|
|
|
-- return the generated iterator
|
|
|
|
return function ()
|
|
|
|
-- start looking for next pos
|
2019-05-04 13:53:49 +02:00
|
|
|
local open = false
|
2019-05-01 13:20:09 +02:00
|
|
|
-- pos to be checked
|
2020-03-01 08:23:39 +01:00
|
|
|
local current
|
2019-05-01 13:20:09 +02:00
|
|
|
-- find next unclosed
|
2019-05-04 13:53:49 +02:00
|
|
|
while not open do
|
2019-05-01 13:20:09 +02:00
|
|
|
-- get unchecked pos
|
2020-03-01 08:23:39 +01:00
|
|
|
current = table.remove(open_list)
|
2019-05-01 13:20:09 +02:00
|
|
|
-- none are left
|
2020-03-01 08:23:39 +01:00
|
|
|
if current == nil then return end
|
2019-05-04 13:53:49 +02:00
|
|
|
-- assume it's open
|
|
|
|
open = true
|
2019-05-01 13:20:09 +02:00
|
|
|
-- check the closed positions
|
|
|
|
for _,closed in pairs(closed_set) do
|
|
|
|
-- if current is unclosed
|
2020-03-01 08:23:39 +01:00
|
|
|
if vector.equals(closed,current.pos) then
|
2019-05-04 13:53:49 +02:00
|
|
|
--found one was closed
|
|
|
|
open = false
|
2019-05-01 13:20:09 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
-- get all connected nodes
|
2020-03-01 08:23:39 +01:00
|
|
|
local nodes = adjacent_connected_nodes(current.pos,include_ctrl)
|
2019-05-01 13:20:09 +02:00
|
|
|
-- iterate through them
|
2020-03-01 08:23:39 +01:00
|
|
|
for _,n in pairs(nodes) do
|
2019-05-01 13:20:09 +02:00
|
|
|
-- mark position to be checked
|
2020-03-01 08:23:39 +01:00
|
|
|
table.insert(open_list,n)
|
2019-05-01 13:20:09 +02:00
|
|
|
end
|
|
|
|
-- add this one to the closed set
|
2020-03-01 08:23:39 +01:00
|
|
|
table.insert(closed_set,current.pos)
|
2019-05-01 13:20:09 +02:00
|
|
|
-- return the one to be checked
|
2020-03-01 08:23:39 +01:00
|
|
|
return current.pos,current.name
|
2019-05-01 13:20:09 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- get network connected to position
|
2019-05-04 13:53:49 +02:00
|
|
|
function me.get_connected_network(start_pos)
|
2020-03-01 08:23:39 +01:00
|
|
|
for npos,nn in me.connected_nodes(start_pos,true) do
|
|
|
|
if nn == "microexpansion:ctrl" then
|
2019-05-04 13:53:49 +02:00
|
|
|
local network = me.get_network(npos)
|
|
|
|
if network then
|
2019-05-07 17:49:26 +02:00
|
|
|
return network,npos
|
2019-05-01 13:20:09 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-03-07 18:02:14 +01:00
|
|
|
function me.update_connected_machines(start_pos,event,include_start)
|
|
|
|
minetest.log("action","updating connected machines")
|
|
|
|
local ev = event or {type = "n/a"}
|
|
|
|
local sn = microexpansion.get_node(start_pos)
|
|
|
|
local sd = minetest.registered_nodes[sn.name]
|
|
|
|
local sm = sd.machine or {}
|
|
|
|
ev.origin = {
|
|
|
|
pos = start_pos,
|
|
|
|
name = sn.name,
|
|
|
|
type = sm.type
|
|
|
|
}
|
|
|
|
--print(dump2(ev,"event"))
|
|
|
|
for npos in me.connected_nodes(start_pos) do
|
|
|
|
if include_start or not vector.equals(npos,start_pos) then
|
|
|
|
me.update_node(npos,ev)
|
|
|
|
end
|
2019-05-04 13:53:49 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-03-07 18:02:14 +01:00
|
|
|
function me.send_event(spos,type,data)
|
|
|
|
local d = data or {}
|
|
|
|
local event = {
|
|
|
|
type = type,
|
|
|
|
net = d.net,
|
|
|
|
payload = d.payload
|
|
|
|
}
|
|
|
|
me.update_connected_machines(spos,event,false)
|
|
|
|
end
|
|
|
|
|
2019-05-04 13:53:49 +02:00
|
|
|
function me.get_network(pos)
|
|
|
|
for i,net in pairs(networks) do
|
|
|
|
if net.controller_pos then
|
|
|
|
if vector.equals(pos, net.controller_pos) then
|
|
|
|
return net,i
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
dofile(path.."/ctrl.lua") -- Controller/wires
|
|
|
|
|
2019-05-01 13:20:09 +02:00
|
|
|
-- load networks
|
|
|
|
function me.load()
|
2020-03-01 08:23:39 +01:00
|
|
|
local f = io.open(me.worldpath.."/microexpansion_networks", "r")
|
|
|
|
if f then
|
|
|
|
local res = minetest.deserialize(f:read("*all"))
|
|
|
|
f:close()
|
2019-05-01 13:20:09 +02:00
|
|
|
if type(res) == "table" then
|
2020-03-01 08:23:39 +01:00
|
|
|
for _,n in pairs(res) do
|
|
|
|
local net = me.network.new(n)
|
|
|
|
net:load()
|
|
|
|
table.insert(me.networks,net)
|
2019-05-01 13:20:09 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- load now
|
|
|
|
me.load()
|
|
|
|
|
|
|
|
-- save networks
|
|
|
|
function me.save()
|
2020-03-01 08:23:39 +01:00
|
|
|
local data = {}
|
|
|
|
for _,v in pairs(me.networks) do
|
|
|
|
table.insert(data,v:serialize())
|
|
|
|
end
|
|
|
|
local f = io.open(me.worldpath.."/microexpansion_networks", "w")
|
|
|
|
f:write(minetest.serialize(data))
|
|
|
|
f:close()
|
2019-05-01 13:20:09 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
-- save on server shutdown
|
|
|
|
minetest.register_on_shutdown(me.save)
|