mirror of
https://github.com/theFox6/microexpansion.git
synced 2024-08-21 13:34:05 +02:00
fixed lots of bugs
fixed too far inventory accesses by detaching the networks inventory fixed vanishsing items with dynamic inventory size allocation
This commit is contained in:
parent
d0e2a070bd
commit
4c5b36fc88
39
api.lua
39
api.lua
@ -1,8 +1,6 @@
|
|||||||
-- microexpansion/api.lua
|
-- microexpansion/api.lua
|
||||||
local BASENAME = "microexpansion"
|
local BASENAME = "microexpansion"
|
||||||
|
|
||||||
--FIXME: this is very full of bad coding
|
|
||||||
|
|
||||||
-- [function] Register Recipe
|
-- [function] Register Recipe
|
||||||
function microexpansion.register_recipe(output, recipe)
|
function microexpansion.register_recipe(output, recipe)
|
||||||
-- Check if disabled
|
-- Check if disabled
|
||||||
@ -10,38 +8,13 @@ function microexpansion.register_recipe(output, recipe)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local function isint(n)
|
for _,r in ipairs(recipe) do
|
||||||
return n==math.floor(n)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_amount(_)
|
|
||||||
if isint(recipe[_][1]) then
|
|
||||||
return recipe[_][1]
|
|
||||||
else return 1 end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_type(_)
|
|
||||||
if type(recipe[_][2]) == "string" then
|
|
||||||
return recipe[_][2]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function register(_)
|
|
||||||
local def = {
|
local def = {
|
||||||
type = get_type(_),
|
type = type(r[2]) == "string" and r[2],
|
||||||
output = output.." "..tostring(get_amount(_)),
|
output = output.." "..(r[1] or 1),
|
||||||
recipe = recipe[_][3] or recipe[_][2]
|
recipe = r[3] or r[2]
|
||||||
}
|
}
|
||||||
minetest.register_craft(def)
|
minetest.register_craft(def)
|
||||||
end
|
|
||||||
|
|
||||||
-- Check if disabled
|
|
||||||
if recipe.disabled == true then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
for i in ipairs(recipe) do
|
|
||||||
register(i)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
2
init.lua
2
init.lua
@ -46,7 +46,7 @@ end
|
|||||||
|
|
||||||
-- [function] Load module (overrides modules.conf)
|
-- [function] Load module (overrides modules.conf)
|
||||||
function microexpansion.load_module(name)
|
function microexpansion.load_module(name)
|
||||||
if loaded_modules[name] ~= false then
|
if not loaded_modules[name] then
|
||||||
local module_path = microexpansion.get_module_path(name)
|
local module_path = microexpansion.get_module_path(name)
|
||||||
|
|
||||||
if module_path then
|
if module_path then
|
||||||
|
@ -3,59 +3,6 @@
|
|||||||
local me = microexpansion
|
local me = microexpansion
|
||||||
local network = me.network
|
local network = me.network
|
||||||
|
|
||||||
local function update_ctrl(pos)
|
|
||||||
local cnetwork = me.get_network(pos)
|
|
||||||
if cnetwork == nil then
|
|
||||||
minetest.log("error","no network for ctrl at pos "..minetest.pos_to_string(pos))
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local size = cnetwork:get_item_capacity()
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
inv:set_size("main", me.int_to_stacks(size))
|
|
||||||
end
|
|
||||||
|
|
||||||
function me.insert_item(stack, inv, listname)
|
|
||||||
if me.settings.huge_stacks == false then
|
|
||||||
inv:add_item(listname, stack)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
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
|
|
||||||
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
|
|
||||||
inv:add_item(listname, stack)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- [register node] Controller
|
-- [register node] Controller
|
||||||
me.register_node("ctrl", {
|
me.register_node("ctrl", {
|
||||||
description = "ME Controller",
|
description = "ME Controller",
|
||||||
@ -87,11 +34,18 @@ me.register_node("ctrl", {
|
|||||||
},
|
},
|
||||||
groups = { cracky = 1, me_connect = 1, },
|
groups = { cracky = 1, me_connect = 1, },
|
||||||
connect_sides = "nobottom",
|
connect_sides = "nobottom",
|
||||||
me_update = update_ctrl,
|
me_update = function(pos)
|
||||||
|
local cnet = me.get_network(pos)
|
||||||
|
if cnet == nil then
|
||||||
|
minetest.log("error","no network for ctrl at pos "..minetest.pos_to_string(pos))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
cnet:update()
|
||||||
|
end,
|
||||||
after_place_node = function(pos, player)
|
after_place_node = function(pos, player)
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
table.insert(me.networks,network:new({controller_pos = pos}))
|
table.insert(me.networks,network.new({controller_pos = pos}))
|
||||||
me.update_connected_machines(pos)
|
me.update_connected_machines(pos)
|
||||||
|
|
||||||
meta:set_string("infotext", "Network Controller (owned by "..name..")")
|
meta:set_string("infotext", "Network Controller (owned by "..name..")")
|
||||||
@ -100,48 +54,15 @@ me.register_node("ctrl", {
|
|||||||
on_destruct = function(pos)
|
on_destruct = function(pos)
|
||||||
local net,idx = me.get_network(pos)
|
local net,idx = me.get_network(pos)
|
||||||
if net then
|
if net then
|
||||||
net.controller_pos = nil
|
net:destruct()
|
||||||
end
|
end
|
||||||
if idx then
|
if idx then
|
||||||
table.remove(me.networks,idx)
|
table.remove(me.networks,idx)
|
||||||
end
|
end
|
||||||
end,
|
|
||||||
after_dig_node = function(pos)
|
|
||||||
me.update_connected_machines(pos)
|
me.update_connected_machines(pos)
|
||||||
end,
|
end,
|
||||||
allow_metadata_inventory_put = function(pos, listname, index, stack)
|
after_dig_node = function(pos)
|
||||||
local inv = minetest.get_meta(pos):get_inventory()
|
me.update_connected_machines(pos)
|
||||||
local inside_stack = inv:get_stack(listname, index)
|
|
||||||
local stack_name = stack:get_name()
|
|
||||||
-- improve performance by skipping unnessecary calls
|
|
||||||
if inside_stack:get_name() ~= stack_name or inside_stack:get_count() >= inside_stack:get_stack_max() then
|
|
||||||
if inv:get_stack(listname, index+1):get_name() ~= "" then
|
|
||||||
return stack:get_count()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local max_slots = inv:get_size(listname)
|
|
||||||
local max_items = math.floor(max_slots * 99)
|
|
||||||
|
|
||||||
local slots, items = 0, 0
|
|
||||||
-- Get amount of items in drive
|
|
||||||
for i = 1, max_slots do
|
|
||||||
local dstack = inv:get_stack("main", i)
|
|
||||||
if dstack:get_name() ~= "" then
|
|
||||||
slots = slots + 1
|
|
||||||
local num = dstack:get_count()
|
|
||||||
if num == 0 then num = 1 end
|
|
||||||
items = items + num
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return math.max(math.min(stack:get_count(),max_items-items),0)
|
|
||||||
end,
|
|
||||||
on_metadata_inventory_put = function(pos, listname, _, stack)
|
|
||||||
local inv = minetest.get_meta(pos):get_inventory()
|
|
||||||
inv:remove_item(listname, stack)
|
|
||||||
me.insert_item(stack, inv, listname)
|
|
||||||
end,
|
|
||||||
allow_metadata_inventory_take = function(_, _, _, stack)
|
|
||||||
return math.min(stack:get_count(),stack:get_stack_max())
|
|
||||||
end,
|
end,
|
||||||
machine = {
|
machine = {
|
||||||
type = "transporter",
|
type = "transporter",
|
||||||
@ -169,6 +90,14 @@ me.register_machine("cable", {
|
|||||||
groups = { crumbly = 1, },
|
groups = { crumbly = 1, },
|
||||||
after_place_node = me.update_connected_machines,
|
after_place_node = me.update_connected_machines,
|
||||||
after_dig_node = me.update_connected_machines,
|
after_dig_node = me.update_connected_machines,
|
||||||
|
me_update = function(pos)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if me.get_connected_network(pos) then
|
||||||
|
meta:set_string("infotext", "Network connected")
|
||||||
|
else
|
||||||
|
meta:set_string("infotext", "No Network")
|
||||||
|
end
|
||||||
|
end,
|
||||||
machine = {
|
machine = {
|
||||||
type = "transporter",
|
type = "transporter",
|
||||||
},
|
},
|
||||||
|
@ -3,14 +3,53 @@ me.networks = {}
|
|||||||
local networks = me.networks
|
local networks = me.networks
|
||||||
local path = microexpansion.get_module_path("network")
|
local path = microexpansion.get_module_path("network")
|
||||||
|
|
||||||
-- load Resources
|
function me.insert_item(stack, inv, listname)
|
||||||
|
if me.settings.huge_stacks == false then
|
||||||
|
inv:add_item(listname, stack)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
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
|
||||||
|
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
|
||||||
|
inv:add_item(listname, stack)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
dofile(path.."/network.lua") -- Network Management
|
dofile(path.."/network.lua") -- Network Management
|
||||||
|
|
||||||
-- generate iterator to find all connected nodes
|
-- generate iterator to find all connected nodes
|
||||||
function me.connected_nodes(start_pos)
|
function me.connected_nodes(start_pos,include_ctrl)
|
||||||
-- nodes to be checked
|
-- nodes to be checked
|
||||||
local open_list = {start_pos}
|
local open_list = {{pos = start_pos}}
|
||||||
-- nodes that were checked
|
-- nodes that were checked
|
||||||
local closed_set = {}
|
local closed_set = {}
|
||||||
-- local connected nodes function to reduce table lookups
|
-- local connected nodes function to reduce table lookups
|
||||||
@ -20,42 +59,42 @@ function me.connected_nodes(start_pos)
|
|||||||
-- start looking for next pos
|
-- start looking for next pos
|
||||||
local open = false
|
local open = false
|
||||||
-- pos to be checked
|
-- pos to be checked
|
||||||
local current_pos
|
local current
|
||||||
-- find next unclosed
|
-- find next unclosed
|
||||||
while not open do
|
while not open do
|
||||||
-- get unchecked pos
|
-- get unchecked pos
|
||||||
current_pos = table.remove(open_list)
|
current = table.remove(open_list)
|
||||||
-- none are left
|
-- none are left
|
||||||
if current_pos == nil then return end
|
if current == nil then return end
|
||||||
-- assume it's open
|
-- assume it's open
|
||||||
open = true
|
open = true
|
||||||
-- check the closed positions
|
-- check the closed positions
|
||||||
for _,closed in pairs(closed_set) do
|
for _,closed in pairs(closed_set) do
|
||||||
-- if current is unclosed
|
-- if current is unclosed
|
||||||
if vector.equals(closed,current_pos) then
|
if vector.equals(closed,current.pos) then
|
||||||
--found one was closed
|
--found one was closed
|
||||||
open = false
|
open = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- get all connected nodes
|
-- get all connected nodes
|
||||||
local next_pos = adjacent_connected_nodes(current_pos)
|
local nodes = adjacent_connected_nodes(current.pos,include_ctrl)
|
||||||
-- iterate through them
|
-- iterate through them
|
||||||
for _,p in pairs(next_pos) do
|
for _,n in pairs(nodes) do
|
||||||
-- mark position to be checked
|
-- mark position to be checked
|
||||||
table.insert(open_list,p)
|
table.insert(open_list,n)
|
||||||
end
|
end
|
||||||
-- add this one to the closed set
|
-- add this one to the closed set
|
||||||
table.insert(closed_set,current_pos)
|
table.insert(closed_set,current.pos)
|
||||||
-- return the one to be checked
|
-- return the one to be checked
|
||||||
return current_pos
|
return current.pos,current.name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- get network connected to position
|
-- get network connected to position
|
||||||
function me.get_connected_network(start_pos)
|
function me.get_connected_network(start_pos)
|
||||||
for npos in me.connected_nodes(start_pos) do
|
for npos,nn in me.connected_nodes(start_pos,true) do
|
||||||
if me.get_node(npos).name == "microexpansion:ctrl" then
|
if nn == "microexpansion:ctrl" then
|
||||||
local network = me.get_network(npos)
|
local network = me.get_network(npos)
|
||||||
if network then
|
if network then
|
||||||
return network,npos
|
return network,npos
|
||||||
@ -85,12 +124,15 @@ dofile(path.."/ctrl.lua") -- Controller/wires
|
|||||||
|
|
||||||
-- load networks
|
-- load networks
|
||||||
function me.load()
|
function me.load()
|
||||||
local res = io.open(me.worldpath.."/microexpansion.txt", "r")
|
local f = io.open(me.worldpath.."/microexpansion_networks", "r")
|
||||||
if res then
|
if f then
|
||||||
res = minetest.deserialize(res:read("*all"))
|
local res = minetest.deserialize(f:read("*all"))
|
||||||
|
f:close()
|
||||||
if type(res) == "table" then
|
if type(res) == "table" then
|
||||||
for _,n in pairs(res.networks) do
|
for _,n in pairs(res) do
|
||||||
table.insert(networks,me.network:new(n))
|
local net = me.network.new(n)
|
||||||
|
net:load()
|
||||||
|
table.insert(me.networks,net)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -101,11 +143,13 @@ me.load()
|
|||||||
|
|
||||||
-- save networks
|
-- save networks
|
||||||
function me.save()
|
function me.save()
|
||||||
local data = {
|
local data = {}
|
||||||
networks = networks,
|
for _,v in pairs(me.networks) do
|
||||||
}
|
table.insert(data,v:serialize())
|
||||||
|
end
|
||||||
io.open(me.worldpath.."/microexpansion.txt", "w"):write(minetest.serialize(data))
|
local f = io.open(me.worldpath.."/microexpansion_networks", "w")
|
||||||
|
f:write(minetest.serialize(data))
|
||||||
|
f:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- save on server shutdown
|
-- save on server shutdown
|
||||||
|
@ -13,17 +13,28 @@ microexpansion.network = network
|
|||||||
-- @function [parent=#network] new
|
-- @function [parent=#network] new
|
||||||
-- @param #table o the object to become a network or nil
|
-- @param #table o the object to become a network or nil
|
||||||
-- @return #table the new network object
|
-- @return #table the new network object
|
||||||
function network:new(o)
|
function network.new(o)
|
||||||
return setmetatable(o or {}, {__index = self})
|
return setmetatable(o or {}, {__index = network})
|
||||||
end
|
end
|
||||||
|
|
||||||
--- check if a node can be connected
|
--- check if a node can be connected
|
||||||
-- @function [parent=#network] can_connect
|
-- @function [parent=#network] can_connect
|
||||||
-- @param #table pos the position of the node to be checked
|
-- @param #table np the position of the node to be checked
|
||||||
|
-- the node itself or the name of the node
|
||||||
-- @return #boolean whether this node has the group me_connect
|
-- @return #boolean whether this node has the group me_connect
|
||||||
function network.can_connect(pos)
|
function network.can_connect(np)
|
||||||
local node = microexpansion.get_node(pos)
|
local nn
|
||||||
return minetest.get_item_group(node.name, "me_connect") > 0
|
if type(np)=="string" then
|
||||||
|
nn = np
|
||||||
|
else
|
||||||
|
if np.name then
|
||||||
|
nn = np.name
|
||||||
|
else
|
||||||
|
local node = microexpansion.get_node(np)
|
||||||
|
nn = node.name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return minetest.get_item_group(nn, "me_connect") > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
--- get all adjacent connected nodes
|
--- get all adjacent connected nodes
|
||||||
@ -44,15 +55,17 @@ function network.adjacent_connected_nodes(pos, include_ctrl)
|
|||||||
local nodes = {}
|
local nodes = {}
|
||||||
|
|
||||||
for _,apos in pairs(adjacent) do
|
for _,apos in pairs(adjacent) do
|
||||||
if network.can_connect(apos) then
|
local napos = microexpansion.get_node(apos)
|
||||||
if include_ctrl == false then
|
local nn = napos.name
|
||||||
if not microexpansion.get_node(apos).name == "microexpansion:ctrl" then
|
if network.can_connect(nn) then
|
||||||
table.insert(nodes, apos)
|
if include_ctrl == false then
|
||||||
end
|
if nn ~= "microexpansion:ctrl" then
|
||||||
else
|
table.insert(nodes,{pos = apos, name = nn})
|
||||||
table.insert(nodes, apos)
|
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
table.insert(nodes,{pos = apos, name = nn})
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return nodes
|
return nodes
|
||||||
@ -125,5 +138,148 @@ function network:get_item_capacity()
|
|||||||
cap = cap + get_drive_capacity(npos)
|
cap = cap + get_drive_capacity(npos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
self.capacity_cache = cap
|
||||||
return cap
|
return cap
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function network:add_storage_slots(count,listname)
|
||||||
|
local c = count or 1
|
||||||
|
local ln = listname or "main"
|
||||||
|
local inv = self:get_inventory()
|
||||||
|
local csize = inv:get_size(ln)
|
||||||
|
local space = 0
|
||||||
|
local inside = 0
|
||||||
|
local contents = inv:get_list(ln) or {}
|
||||||
|
for _,s in pairs(contents) do
|
||||||
|
if s:is_empty() then
|
||||||
|
space = space + 1
|
||||||
|
else
|
||||||
|
inside = inside + s:get_count()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local cap = self:get_item_capacity()
|
||||||
|
--the capacity is allocated outside of the condition because it updates the cached capacity
|
||||||
|
if count == true then
|
||||||
|
if inside < cap then
|
||||||
|
c = 1
|
||||||
|
else
|
||||||
|
c = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local needed = c - space
|
||||||
|
needed = needed + csize
|
||||||
|
--TODO allow list removal
|
||||||
|
if needed == 0 then
|
||||||
|
needed = 1
|
||||||
|
end
|
||||||
|
inv:set_size(ln, needed)
|
||||||
|
end
|
||||||
|
|
||||||
|
--FIXME: add size removal function because items are removed when size decreases
|
||||||
|
|
||||||
|
function network:update()
|
||||||
|
self:add_storage_slots(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function network:get_inventory_name()
|
||||||
|
local cp = self.controller_pos
|
||||||
|
assert(cp, "trying to get inventory name of a network without controller")
|
||||||
|
return "microexpansion_storage_"..cp.x.."_"..cp.y.."_"..cp.z
|
||||||
|
end
|
||||||
|
|
||||||
|
local function create_inventory(net)
|
||||||
|
local invname = net:get_inventory_name()
|
||||||
|
net.inv = minetest.create_detached_inventory(invname, {
|
||||||
|
allow_put = function(inv, listname, index, stack)
|
||||||
|
local inside_stack = inv:get_stack(listname, index)
|
||||||
|
local stack_name = stack:get_name()
|
||||||
|
-- improve performance by skipping unnessecary calls
|
||||||
|
if inside_stack:get_name() ~= stack_name or inside_stack:get_count() >= inside_stack:get_stack_max() then
|
||||||
|
if inv:get_stack(listname, index+1):get_name() ~= "" then
|
||||||
|
return stack:get_count()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local max_slots = inv:get_size(listname)
|
||||||
|
local max_items = net.capacity_cache
|
||||||
|
|
||||||
|
local slots, items = 0, 0
|
||||||
|
-- Get amount of items in drive
|
||||||
|
for i = 1, max_slots do
|
||||||
|
local dstack = inv:get_stack("main", i)
|
||||||
|
if dstack:get_name() ~= "" then
|
||||||
|
slots = slots + 1
|
||||||
|
local num = dstack:get_count()
|
||||||
|
if num == 0 then num = 1 end
|
||||||
|
items = items + num
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return math.max(math.min(stack:get_count(),max_items-items),0)
|
||||||
|
end,
|
||||||
|
on_put = function(inv, listname, _, stack)
|
||||||
|
inv:remove_item(listname, stack)
|
||||||
|
microexpansion.insert_item(stack, inv, listname)
|
||||||
|
net:add_storage_slots(true)
|
||||||
|
end,
|
||||||
|
allow_take = function(_, _, _, stack)
|
||||||
|
return math.min(stack:get_count(),stack:get_stack_max())
|
||||||
|
end,
|
||||||
|
on_take = function()
|
||||||
|
net:add_storage_slots(true)
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
function network:get_inventory()
|
||||||
|
if not self.inv then
|
||||||
|
create_inventory(self)
|
||||||
|
assert(self.inv,"no inventory created")
|
||||||
|
end
|
||||||
|
return self.inv
|
||||||
|
end
|
||||||
|
|
||||||
|
function network:load_inventory(lists)
|
||||||
|
local inv = self:get_inventory()
|
||||||
|
for listname,c in pairs(lists) do
|
||||||
|
inv:set_size(listname, #c)
|
||||||
|
for i,s in pairs(c) do
|
||||||
|
inv:set_stack(listname,i,s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function network:save_inventory()
|
||||||
|
local contents = {}
|
||||||
|
local lists = self.inv:get_lists()
|
||||||
|
for listname,c in pairs(lists or {}) do
|
||||||
|
local ct = {}
|
||||||
|
contents[listname] = ct
|
||||||
|
for i,stack in pairs(c) do
|
||||||
|
ct[i] = stack:to_string()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return contents
|
||||||
|
end
|
||||||
|
|
||||||
|
function network:load()
|
||||||
|
if self.strinv then
|
||||||
|
self:load_inventory(self.strinv)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function network:serialize()
|
||||||
|
local sert = {}
|
||||||
|
for i,v in pairs(self) do
|
||||||
|
if i == "inv" then
|
||||||
|
sert.strinv = self:save_inventory()
|
||||||
|
else
|
||||||
|
sert[i] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return sert
|
||||||
|
end
|
||||||
|
|
||||||
|
function network:destruct()
|
||||||
|
self.controller_pos = nil
|
||||||
|
self.inv = nil
|
||||||
|
minetest.remove_detached_inventory(self:get_inventory_name())
|
||||||
|
end
|
||||||
|
@ -9,6 +9,7 @@ end
|
|||||||
local function write_to_cell(cell, items, item_count)
|
local function write_to_cell(cell, items, item_count)
|
||||||
local size = microexpansion.get_cell_size(cell:get_name())
|
local size = microexpansion.get_cell_size(cell:get_name())
|
||||||
local item_meta = cell:get_meta()
|
local item_meta = cell:get_meta()
|
||||||
|
--print(dump2(items,"cell_items"))
|
||||||
item_meta:set_string("items", minetest.serialize(items))
|
item_meta:set_string("items", minetest.serialize(items))
|
||||||
local base_desc = minetest.registered_craftitems[cell:get_name()].microexpansion.base_desc
|
local base_desc = minetest.registered_craftitems[cell:get_name()].microexpansion.base_desc
|
||||||
-- Calculate Percentage
|
-- Calculate Percentage
|
||||||
@ -68,48 +69,44 @@ microexpansion.register_node("drive", {
|
|||||||
end,
|
end,
|
||||||
on_metadata_inventory_put = function(pos, _, _, stack)
|
on_metadata_inventory_put = function(pos, _, _, stack)
|
||||||
me.update_connected_machines(pos)
|
me.update_connected_machines(pos)
|
||||||
local network,cp = me.get_connected_network(pos)
|
local network = me.get_connected_network(pos)
|
||||||
if network == nil then
|
if network == nil then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local ctrl_meta = minetest.get_meta(cp)
|
local ctrl_inv = network:get_inventory()
|
||||||
local ctrl_inv = ctrl_meta:get_inventory()
|
|
||||||
local items = minetest.deserialize(stack:get_meta():get_string("items"))
|
local items = minetest.deserialize(stack:get_meta():get_string("items"))
|
||||||
if items == nil then
|
if items == nil then
|
||||||
print("no items")
|
print("no items")
|
||||||
me.update_connected_machines(pos)
|
me.update_connected_machines(pos)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
network:add_storage_slots(#items)
|
||||||
for _,s in pairs(items) do
|
for _,s in pairs(items) do
|
||||||
me.insert_item(s, ctrl_inv, "main")
|
me.insert_item(s, ctrl_inv, "main")
|
||||||
end
|
end
|
||||||
me.update_connected_machines(pos)
|
me.update_connected_machines(pos)
|
||||||
end,
|
end,
|
||||||
allow_metadata_inventory_take = function(pos,_,_,stack) --args: pos, listname, index, stack, player
|
allow_metadata_inventory_take = function(pos,_,_,stack) --args: pos, listname, index, stack, player
|
||||||
--FIXME sometimes items vanish if one cell is filled
|
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local own_inv = meta:get_inventory()
|
local own_inv = meta:get_inventory()
|
||||||
local network,cp = me.get_connected_network(pos)
|
local network = me.get_connected_network(pos)
|
||||||
if network == nil then
|
if network == nil then
|
||||||
return stack:get_count()
|
return stack:get_count()
|
||||||
end
|
end
|
||||||
local ctrl_meta = minetest.get_meta(cp)
|
local ctrl_inv = network:get_inventory()
|
||||||
local ctrl_inv = ctrl_meta:get_inventory()
|
|
||||||
local cells = {}
|
local cells = {}
|
||||||
for i = 1, own_inv:get_size("main") do
|
for i = 1, own_inv:get_size("main") do
|
||||||
local cell = own_inv:get_stack("main", i)
|
local cell = own_inv:get_stack("main", i)
|
||||||
local name = cell:get_name()
|
local name = cell:get_name()
|
||||||
if name ~= "" then
|
if name ~= "" then
|
||||||
table.insert(cells, i, cell)
|
cells[i] = cell
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local cell_idx = next(cells)
|
local cell_idx = next(cells)
|
||||||
|
local size = microexpansion.get_cell_size(cells[cell_idx]:get_name())
|
||||||
local items_in_cell_count = 0
|
local items_in_cell_count = 0
|
||||||
local cell_items = {}
|
local cell_items = {}
|
||||||
if cell_idx == nil then
|
assert(cell_idx,"cannot take a cell from an empty drive")
|
||||||
minetest.log("warning","too many items to store in drive")
|
|
||||||
return stack:get_count()
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, ctrl_inv:get_size("main") do
|
for i = 1, ctrl_inv:get_size("main") do
|
||||||
local stack_inside = ctrl_inv:get_stack("main", i)
|
local stack_inside = ctrl_inv:get_stack("main", i)
|
||||||
@ -117,18 +114,19 @@ microexpansion.register_node("drive", {
|
|||||||
if stack_name ~= "" then
|
if stack_name ~= "" then
|
||||||
local item_count = stack_inside:get_count()
|
local item_count = stack_inside:get_count()
|
||||||
while item_count ~= 0 and cell_idx ~= nil do
|
while item_count ~= 0 and cell_idx ~= nil do
|
||||||
local size = microexpansion.get_cell_size(cells[cell_idx]:get_name())
|
|
||||||
if size < items_in_cell_count + item_count then
|
if size < items_in_cell_count + item_count then
|
||||||
local rest = size - items_in_cell_count
|
local space = size - items_in_cell_count
|
||||||
item_count = item_count - rest
|
item_count = item_count - space
|
||||||
table.insert(cell_items,stack_name.." "..rest)
|
table.insert(cell_items,stack_name.." "..space)
|
||||||
items_in_cell_count = items_in_cell_count + rest
|
items_in_cell_count = items_in_cell_count + space
|
||||||
|
|
||||||
own_inv:set_stack("main", cell_idx, write_to_cell(cells[cell_idx],cell_items,items_in_cell_count))
|
own_inv:set_stack("main", cell_idx, write_to_cell(cells[cell_idx],cell_items,items_in_cell_count))
|
||||||
items_in_cell_count = 0
|
|
||||||
cell_items = {}
|
|
||||||
cell_idx = next(cells, cell_idx)
|
cell_idx = next(cells, cell_idx)
|
||||||
if cell_idx == nil then
|
size = microexpansion.get_cell_size(cells[cell_idx]:get_name())
|
||||||
|
items_in_cell_count = 0
|
||||||
|
cell_items = {}
|
||||||
|
if cell_idx == nil then
|
||||||
|
--there may be other drives within the network
|
||||||
minetest.log("info","too many items to store in drive")
|
minetest.log("info","too many items to store in drive")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -152,14 +150,14 @@ microexpansion.register_node("drive", {
|
|||||||
return stack:get_count()
|
return stack:get_count()
|
||||||
end,
|
end,
|
||||||
on_metadata_inventory_take = function(pos, _, _, stack)
|
on_metadata_inventory_take = function(pos, _, _, stack)
|
||||||
local network,cp = me.get_connected_network(pos)
|
local network = me.get_connected_network(pos)
|
||||||
if network == nil then
|
if network == nil then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local ctrl_meta = minetest.get_meta(cp)
|
local ctrl_inv = network:get_inventory()
|
||||||
local ctrl_inv = ctrl_meta:get_inventory()
|
|
||||||
local items = minetest.deserialize(stack:get_meta():get_string("items"))
|
local items = minetest.deserialize(stack:get_meta():get_string("items"))
|
||||||
if items == nil then
|
if items == nil then
|
||||||
|
network:update()
|
||||||
me.update_connected_machines(pos)
|
me.update_connected_machines(pos)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -169,6 +167,7 @@ microexpansion.register_node("drive", {
|
|||||||
end
|
end
|
||||||
print(stack:to_string())
|
print(stack:to_string())
|
||||||
|
|
||||||
|
network:update()
|
||||||
me.update_connected_machines(pos)
|
me.update_connected_machines(pos)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
@ -11,5 +11,5 @@ dofile(module_path.."/api.lua")
|
|||||||
dofile(module_path.."/storage.lua")
|
dofile(module_path.."/storage.lua")
|
||||||
|
|
||||||
-- Load machines
|
-- Load machines
|
||||||
dofile(module_path.."/chest.lua")
|
|
||||||
dofile(module_path.."/drive.lua")
|
dofile(module_path.."/drive.lua")
|
||||||
|
dofile(module_path.."/terminal.lua")
|
||||||
|
@ -12,15 +12,17 @@ local function chest_formspec(pos, start_id, listname, page_max, q)
|
|||||||
|
|
||||||
if cp then
|
if cp then
|
||||||
if listname and net:get_item_capacity() > 0 then
|
if listname and net:get_item_capacity() > 0 then
|
||||||
|
local ctrlinvname = net:get_inventory_name()
|
||||||
if listname == "main" then
|
if listname == "main" then
|
||||||
list = "list[nodemeta:"..cp.x..","..cp.y..","..cp.z..";" .. listname .. ";0,0.3;8,4;" .. (start_id - 1) .. "]"
|
list = "list[detached:"..ctrlinvname..";"
|
||||||
|
.. listname .. ";0,0.3;8,4;" .. (start_id - 1) .. "]"
|
||||||
else
|
else
|
||||||
list = "list[context;" .. listname .. ";0,0.3;8,4;" .. (start_id - 1) .. "]"
|
list = "list[context;" .. listname .. ";0,0.3;8,4;" .. (start_id - 1) .. "]"
|
||||||
end
|
end
|
||||||
list = list .. [[
|
list = list .. [[
|
||||||
list[current_player;main;0,5.5;8,1;]
|
list[current_player;main;0,5.5;8,1;]
|
||||||
list[current_player;main;0,6.73;8,3;8]
|
list[current_player;main;0,6.73;8,3;8]
|
||||||
listring[nodemeta:]]..cp.x..","..cp.y..","..cp.z..[[;main]
|
listring[detached:]]..ctrlinvname..[[;main]
|
||||||
listring[current_player;main]
|
listring[current_player;main]
|
||||||
]]
|
]]
|
||||||
buttons = [[
|
buttons = [[
|
||||||
@ -76,6 +78,9 @@ local function update_chest(pos)
|
|||||||
meta:set_string("formspec", chest_formspec(pos, 1, "main", page_max))
|
meta:set_string("formspec", chest_formspec(pos, 1, "main", page_max))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--FIXME: items inserted in a search inventory vanish
|
||||||
|
--TODO: add a main inv that transfers to the network
|
||||||
|
|
||||||
-- [me chest] Register node
|
-- [me chest] Register node
|
||||||
microexpansion.register_node("term", {
|
microexpansion.register_node("term", {
|
||||||
description = "ME Terminal",
|
description = "ME Terminal",
|
||||||
@ -105,26 +110,44 @@ microexpansion.register_node("term", {
|
|||||||
end,
|
end,
|
||||||
on_metadata_inventory_take = function(pos, listname, _, stack)
|
on_metadata_inventory_take = function(pos, listname, _, stack)
|
||||||
if listname == "search" then
|
if listname == "search" then
|
||||||
local _,cp = me.get_connected_network(pos)
|
local net = me.get_connected_network(pos)
|
||||||
local inv = minetest.get_meta(cp):get_inventory()
|
local inv = net:get_inventory()
|
||||||
inv:remove_item("main", stack)
|
inv:remove_item("main", stack)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
on_receive_fields = function(pos, _, fields, sender)
|
on_receive_fields = function(pos, _, fields, sender)
|
||||||
local _,cp = me.get_connected_network(pos)
|
local net,cp = me.get_connected_network(pos)
|
||||||
|
if net then
|
||||||
|
if cp then
|
||||||
|
minetest.log("none","network and ctrl_pos")
|
||||||
|
else
|
||||||
|
minetest.log("warning","network but no ctrl_pos")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if cp then
|
||||||
|
minetest.log("warning","no network but ctrl_pos")
|
||||||
|
else
|
||||||
|
minetest.log("info","no network and no ctrl_pos")
|
||||||
|
end
|
||||||
|
end
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local page = meta:get_int("page")
|
local page = meta:get_int("page")
|
||||||
local inv_name = meta:get_string("inv_name")
|
local inv_name = meta:get_string("inv_name")
|
||||||
local own_inv = meta:get_inventory()
|
local own_inv = meta:get_inventory()
|
||||||
local ctrl_inv
|
local ctrl_inv
|
||||||
if cp then
|
if cp then
|
||||||
ctrl_inv = minetest.get_meta(cp):get_inventory()
|
ctrl_inv = net:get_inventory()
|
||||||
|
else
|
||||||
|
minetest.log("warning","no network connected")
|
||||||
|
return
|
||||||
end
|
end
|
||||||
local inv
|
local inv
|
||||||
if inv_name == "main" then
|
if inv_name == "main" then
|
||||||
inv = ctrl_inv
|
inv = ctrl_inv
|
||||||
|
assert(inv,"no control inv")
|
||||||
else
|
else
|
||||||
inv = own_inv
|
inv = own_inv
|
||||||
|
assert(inv,"no own inv")
|
||||||
end
|
end
|
||||||
local page_max = math.floor(inv:get_size(inv_name) / 32) + 1
|
local page_max = math.floor(inv:get_size(inv_name) / 32) + 1
|
||||||
if inv_name == "none" then
|
if inv_name == "none" then
|
||||||
@ -168,7 +191,9 @@ microexpansion.register_node("term", {
|
|||||||
meta:set_string("formspec", chest_formspec(pos, 1, "main", page_max))
|
meta:set_string("formspec", chest_formspec(pos, 1, "main", page_max))
|
||||||
elseif fields.tochest then
|
elseif fields.tochest then
|
||||||
local pinv = minetest.get_inventory({type="player", name=sender:get_player_name()})
|
local pinv = minetest.get_inventory({type="player", name=sender:get_player_name()})
|
||||||
|
net:add_storage_slots(pinv:get_size("main"))
|
||||||
microexpansion.move_inv({ inv=pinv, name="main" }, { inv=ctrl_inv, name="main" })
|
microexpansion.move_inv({ inv=pinv, name="main" }, { inv=ctrl_inv, name="main" })
|
||||||
|
net:add_storage_slots(true)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user