diff --git a/README.md b/README.md index edf5751..fe69583 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # Storagetest +![](screenshot.png) A solution to your hoarding addiction. In [Minetest](http://minetest.net). +This mod adds devices into the game that allow you to build a mass storage system with ease. + This mod is an attempt at re-creating [Refined Storage](https://github.com/raoulvdberge/refinedstorage) in Minetest. I can't promise that this will ever be completed, but we'll see. Help is always welcome. diff --git a/network.lua b/network.lua index 9a00d01..4165bd4 100644 --- a/network.lua +++ b/network.lua @@ -447,9 +447,14 @@ function storagetest.network.take_item(network_id, stack) local storage_nodes = storagetest.network.get_storage_devices(network_id) for _,pos in pairs(storage_nodes) do - local success = storagetest.take_stack(pos, stack) - if success then - return success + local success, stacki = storagetest.take_stack(pos, stack) + if success and stacki then + if stacki:get_count() == stack:get_count() then + return success, stacki + else + stack:set_count(stack:get_count() - stacki:get_count()) + return storagetest.network.take_item(network_id, stack) + end end end diff --git a/nodes/bus.lua b/nodes/bus.lua index 4ae2c0c..fb8f777 100644 --- a/nodes/bus.lua +++ b/nodes/bus.lua @@ -1,5 +1,70 @@ -- Storagetest cabling +local function get_formspec(title, filter) + local fl = "Blacklist" + + if filter ~= nil then + if filter == 1 then + fl = "Whitelist" + end + else + fl = nil + end + + if fl then + fl = "button[0,2.5;2,1;filter;"..fl.."]" + else + fl = "" + end + + return "size[8,8.5]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "label[0,0;"..title.."]".. + "list[context;filter;0,1.5;8,1;]".. + "list[current_player;main;0,4.25;8,1;]".. + "list[current_player;main;0,5.5;8,3;8]".. + fl.. + "listring[context;filter]".. + "listring[current_player;main]".. + default.get_hotbar_bg(0, 4.25) +end + +local function inventory_ghost_put(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + + local inv = minetest.get_meta(pos):get_inventory() + stack:set_count(1) + inv:set_stack(listname, index, stack) + return 0 +end + +local function inventory_ghost_take(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + + local inv = minetest.get_meta(pos):get_inventory() + inv:set_stack(listname, index, ItemStack(nil)) + return 0 +end + +local function flip_filter(pos, form, fields, player) + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + local ndef = minetest.registered_nodes[node.name].description + if fields["filter"] then + local f = meta:get_int("filter") + if f == 0 then f = 1 else f = 0 end + meta:set_int("filter", f) + + meta:set_string("formspec", get_formspec(ndef, f)) + end +end + minetest.register_node("storagetest:import_bus", { description = "Import Bus", tiles = { @@ -16,11 +81,21 @@ minetest.register_node("storagetest:import_bus", { }, on_construct = function (pos) storagetest.network.clear_networks(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_formspec("Import Bus", 0)) + + local inv = meta:get_inventory() + inv:set_size("filter", 8) + + meta:set_int("filter", 0) end, on_destruct = storagetest.network.clear_networks, + on_receive_fields = flip_filter, storagetest_run = function (pos, _, controller) local network = minetest.hash_node_position(controller) local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() local front = storagetest.front(pos, node.param2) local front_node = minetest.get_node(front) @@ -30,23 +105,104 @@ minetest.register_node("storagetest:import_bus", { local front_def = minetest.registered_nodes[front_node.name] if front_inv:get_list("main") then local list = front_inv:get_list("main") + local filter_type = meta:get_int("filter") for index, stack in pairs(list) do if not stack:is_empty() then - local allow_count = 0 + local can_take = false local copystack = front_inv:get_stack("main", index) copystack:set_count(1) - local success, outst = storagetest.network.insert_item(network, copystack) - if success then - stack:set_count(stack:get_count() - 1) - front_inv:set_stack("main", index, stack) - break -- Don't take more than one per cycle + + if filter_type == 0 and inv:contains_item("filter", copystack) then + can_take = false + elseif filter_type == 1 and inv:contains_item("filter", copystack) then + can_take = true + else + can_take = true + end + + if can_take then + local success, outst = storagetest.network.insert_item(network, copystack) + if success then + stack:set_count(stack:get_count() - 1) + front_inv:set_stack("main", index, stack) + break -- Don't take more than one per cycle + end end end end front_inv:set_list("main", list) end end - end + end, + allow_metadata_inventory_take = inventory_ghost_take, + allow_metadata_inventory_put = inventory_ghost_put +}) + +minetest.register_node("storagetest:export_bus", { + description = "Export Bus", + tiles = { + "storagetest_machine_block.png", "storagetest_machine_block.png", "storagetest_machine_block.png", + "storagetest_machine_block.png", "storagetest_machine_block.png", "storagetest_export.png", + }, + paramtype2 = "facedir", + is_ground_content = false, + groups = { + storagetest_distributor = 1, + storagetest_device = 1, + cracky = 2, + oddly_breakable_by_hand = 2 + }, + on_construct = function (pos) + storagetest.network.clear_networks(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_formspec("Export Bus")) + + local inv = meta:get_inventory() + inv:set_size("filter", 8) + end, + on_destruct = storagetest.network.clear_networks, + storagetest_run = function (pos, _, controller) + local network = minetest.hash_node_position(controller) + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local front = storagetest.front(pos, node.param2) + + local front_node = minetest.get_node(front) + if front_node.name ~= "air" then + local front_meta = minetest.get_meta(front) + local front_inv = front_meta:get_inventory() + local front_def = minetest.registered_nodes[front_node.name] + if front_inv:get_list("main") then + local items = storagetest.network.get_storage_inventories(network) + for index, stack in pairs(items) do + if not stack:is_empty() then + local can_take = false + stack:set_count(1) + + if inv:contains_item("filter", stack) then + can_take = true + end + + if not front_inv:room_for_item("main", stack) then + can_take = false + end + + if can_take then + local success, gotten = storagetest.network.take_item(network, stack) + if success then + front_inv:add_item("main", gotten) + break -- Don't take more than one per cycle + end + end + end + end + end + end + end, + allow_metadata_inventory_take = inventory_ghost_take, + allow_metadata_inventory_put = inventory_ghost_put }) storagetest.devices["storagetest:import_bus"] = true +storagetest.devices["storagetest:export_bus"] = true diff --git a/nodes/disk_drive.lua b/nodes/disk_drive.lua index a5c7ee1..c41a891 100644 --- a/nodes/disk_drive.lua +++ b/nodes/disk_drive.lua @@ -114,6 +114,7 @@ function storagetest.take_stack(pos, stack) local invs = storagetest.get_all_inventories(pos) if not invs then return {} end local tabl = {} + local stack_ret local success = false for _,diskptr in pairs(invs) do @@ -121,9 +122,15 @@ function storagetest.take_stack(pos, stack) if invref then local list = invref:get_list("main") for i, stacki in pairs(list) do - if stacki:get_name() == stack:get_name() and stacki:get_count() == stack:get_count() and stacki:get_wear() == stack:get_wear() then + if stacki:get_name() == stack:get_name() and stacki:get_wear() == stack:get_wear() then success = true - stacki:clear() + if stack:get_count() >= stacki:get_count() then + stack:set_count(stacki:get_count()) + stacki:clear() + else + stacki:set_count(stacki:get_count() - stack:get_count()) + end + stack_ret = stack list[i] = stacki break end @@ -132,7 +139,7 @@ function storagetest.take_stack(pos, stack) end end - return success + return success, stack_ret end function storagetest.get_all_inventories(pos) diff --git a/nodes/grid.lua b/nodes/grid.lua index e9e53f0..2360a41 100644 --- a/nodes/grid.lua +++ b/nodes/grid.lua @@ -54,9 +54,9 @@ function storagetest.grid.get_formspec(scroll_lvl, pages, craft_inv) if craft_inv then title = "Crafting Grid" height = 3 - craft = "list[current_player;craft;1.5,4;3,3;]".. - "image[4.5,5;1,1;gui_furnace_arrow_bg.png^[transformR270]".. - "list[current_player;craftpreview;5.5,5;1,1;]" + craft = "list[current_player;craft;1.5,3.8;3,3;]".. + "image[4.5,4.8;1,1;gui_furnace_arrow_bg.png^[transformR270]".. + "list[current_player;craftpreview;5.5,4.8;1,1;]" end local scroll = "" diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..df26bd6 Binary files /dev/null and b/screenshot.png differ