diff --git a/api/api.lua b/api/api.lua index 7097bb1..19ae8f9 100644 --- a/api/api.lua +++ b/api/api.lua @@ -10,3 +10,4 @@ dofile(path.."/item_storage.lua") dofile(path.."/access_point.lua") dofile(path.."/lava_furnace.lua") dofile(path.."/lava_furnace_recipe.lua") +dofile(path.."/trashcan.lua") diff --git a/api/lava_furnace.lua b/api/lava_furnace.lua index 3789b77..4983ba1 100644 --- a/api/lava_furnace.lua +++ b/api/lava_furnace.lua @@ -226,7 +226,6 @@ local function lava_furnace_node_timer(pos, elapsed) return false end - local timeLeft = useLava(meta, config.lava, config.time, runningTime, elapsed, isNewItem) if timeLeft == nil then --not enough lava left reset_furnace(pos, meta) diff --git a/api/trashcan.lua b/api/trashcan.lua new file mode 100644 index 0000000..2a526bf --- /dev/null +++ b/api/trashcan.lua @@ -0,0 +1,114 @@ +local S = logistica.TRANSLATOR + +local INV_FILT = "filt" +local INV_MAIN = "main" +local INV_UNDO = "dst" + +local function get_trashcan_formspec() + return "formspec_version[4]" .. + "size[10.6,9.2]" .. + logistica.ui.background.. + "label[0.5,0.4;"..S("List of Items to delete, if they can't be put elsewhere in the Network.").."]".. + "label[0.5,0.8;"..S("If list is empty, it will delete all excess items.").."]".. + "list[context;"..INV_FILT..";0.5,1.1;8,1;0]".. + "label[3.0,2.6;"..S("Trash slot").."]" .. + "list[context;"..INV_MAIN..";3.0,2.8;1,1;0]".. + "label[6.75,2.6;"..S("Last deleted item").."]".. + "list[context;"..INV_UNDO..";6.75,2.8;1,1;0]".. + "list[current_player;main;0.5,4.2;8,4;0]".. + "listring[current_player;main]".. + "listring[context;"..INV_MAIN.."]" +end + +local function after_place_trashcan(pos, _, _) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size(INV_FILT, 8) + inv:set_size(INV_MAIN, 1) + inv:set_size(INV_UNDO, 1) + meta:set_string("formspec", get_trashcan_formspec()) + logistica.on_trashcan_change(pos) +end + +local function allow_trashcan_inv_put(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then return 0 end + if listname == INV_UNDO then return 0 end + if listname == INV_FILT then + local inv = minetest.get_meta(pos):get_inventory() + local copyStack = ItemStack(stack) ; copyStack:set_count(1) + inv:set_stack(listname, index, copyStack) + return 0 + end + return stack:get_count() +end + +local function allow_trashcan_inv_take(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then return 0 end + if listname == INV_FILT then + local inv = minetest.get_meta(pos):get_inventory() + inv:set_stack(listname, index, ItemStack("")) + return 0 + end + return stack:get_count() +end + +local function allow_trashcan_inv_move(_, _, _, _, _, _, _) + return 0 +end + +local function on_trashcan_inventory_put (pos, listname, index, _, _) + if listname == INV_MAIN then + local inv = minetest.get_meta(pos):get_inventory() + local stack = inv:get_stack(listname, index) + inv:set_stack(listname, index, ItemStack("")) + inv:set_stack(INV_UNDO, 1, stack) + end +end + +---------------------------------------------------------------- +-- Public Registration API +---------------------------------------------------------------- +-- `simpleName` is used for the description and for the name (can contain spaces) +function logistica.register_trashcan(desc, name, tiles) + local lname = string.lower(name:gsub(" ", "_")) + local trashcan_name = "logistica:"..lname + logistica.trashcans[trashcan_name] = true + local grps = {oddly_breakable_by_hand = 3, cracky = 3 } + grps[logistica.TIER_ALL] = 1 + local def = { + description = desc, + drawtype = "normal", + tiles = tiles, + paramtype = "none", + paramtype2 = "facedir", + is_ground_content = false, + groups = grps, + drop = trashcan_name, + sounds = logistica.node_sound_metallic(), + after_place_node = after_place_trashcan, + after_destruct = logistica.on_trashcan_change, + allow_metadata_inventory_put = allow_trashcan_inv_put, + allow_metadata_inventory_take = allow_trashcan_inv_take, + allow_metadata_inventory_move = allow_trashcan_inv_move, + on_metadata_inventory_put = on_trashcan_inventory_put, + logistica = { }, + } + + minetest.register_node(trashcan_name, def) + + local def_disabled = table.copy(def) + local tiles_disabled = {} + for k, v in pairs(def.tiles) do tiles_disabled[k] = v.."^logistica_disabled.png" end + + def_disabled.tiles = tiles_disabled + def_disabled.groups = { oddly_breakable_by_hand = 3, cracky = 3, choppy = 3, not_in_creative_inventory = 1 } + def_disabled.on_construct = nil + def_disabled.after_destruct = nil + def_disabled.on_punch = nil + def_disabled.on_rightclick = nil + def_disabled.on_timer = nil + def_disabled.logistica = nil + + minetest.register_node(trashcan_name.."_disabled", def_disabled) + +end diff --git a/logic/groups.lua b/logic/groups.lua index 5e72620..5c70d89 100644 --- a/logic/groups.lua +++ b/logic/groups.lua @@ -6,6 +6,7 @@ logistica.suppliers = {} logistica.mass_storage = {} logistica.item_storage = {} logistica.misc_machines = {} +logistica.trashcans = {} logistica.tiers = {} logistica.TIER_ALL = "logistica_all_tiers" logistica.GROUP_ALL = "group:" .. logistica.TIER_ALL @@ -57,6 +58,10 @@ function logistica.is_misc(name) return logistica.misc_machines[name] ~= nil end +function logistica.is_trashcan(name) + return logistica.trashcans[name] ~= nil +end + function logistica.get_item_tiers(name) local tiers = {} for tier,_ in pairs(logistica.tiers) do diff --git a/logic/logic.lua b/logic/logic.lua index a367663..ea9bad6 100644 --- a/logic/logic.lua +++ b/logic/logic.lua @@ -14,3 +14,4 @@ dofile(path.."/item_storage.lua") dofile(path.."/access_point.lua") dofile(path.."/access_point_formspec.lua") dofile(path.."/lava_furnace_guide_formspec.lua") +dofile(path.."/trashcan.lua") diff --git a/logic/network_logic.lua b/logic/network_logic.lua index 91d3692..e2bc1cf 100644 --- a/logic/network_logic.lua +++ b/logic/network_logic.lua @@ -22,6 +22,7 @@ local function has_machine(network, id) or network.item_storage[id] or network.injectors[id] or network.misc[id] + or network.trashcans[id] then return true else @@ -155,6 +156,9 @@ local function recursive_scan_for_nodes_for_controller(network, positionHashes, elseif logistica.is_misc(otherName) then network.misc[otherHash] = true valid = true + elseif logistica.is_trashcan(otherName) then + network.trashcans[otherHash] = true + valid = true end if valid then newToScan = newToScan + 1 @@ -190,6 +194,7 @@ local function create_network(controllerPosition, oldNetworkName) network.mass_storage = {} network.item_storage = {} network.misc = {} + network.trashcans = {} network.storage_cache = {} network.supplier_cache = {} network.requester_cache = {} @@ -322,6 +327,12 @@ local ACCESS_POINT_OPS = { update_cache_node_removed = function(_) end, } +local TRASHCAN_OPS = { + get_list = function(network) return network.trashcans end, + update_cache_node_added = function(_) end, + update_cache_node_removed = function(_) end, +} + local function cable_can_extend_network_from(pos) local node = minetest.get_node_or_nil(pos) if not node then return false end @@ -412,3 +423,7 @@ end function logistica.on_access_point_change(pos, oldNode) on_node_change(pos, oldNode, ACCESS_POINT_OPS) end + +function logistica.on_trashcan_change(pos, oldNode) + on_node_change(pos, oldNode, TRASHCAN_OPS) +end diff --git a/logic/network_storage.lua b/logic/network_storage.lua index 00f55a0..c23f464 100644 --- a/logic/network_storage.lua +++ b/logic/network_storage.lua @@ -211,5 +211,13 @@ function logistica.insert_item_in_network(itemstack, networkId, dryRun) workingStack = leftover end + local trashcans = network.trashcans or {} + for hash, _ in pairs(trashcans) do + local pos = minetest.get_position_from_hash(hash) + logistica.load_position(pos) + workingStack = logistica.trashcan_trash_item(pos, workingStack) + if workingStack:is_empty() then return 0 end + end + return workingStack:get_count() end \ No newline at end of file diff --git a/logic/trashcan.lua b/logic/trashcan.lua new file mode 100644 index 0000000..4c4c2cc --- /dev/null +++ b/logic/trashcan.lua @@ -0,0 +1,16 @@ + +local INV_FILT = "filt" + +-- Tries to trash the given itemstack for Trashcan at the given position +-- Returns either an empty ItemStack if successful, or the same itemStack if not +function logistica.trashcan_trash_item(pos, inputStack) + local itemStackName = inputStack:get_name() + local inv = minetest.get_meta(pos):get_inventory() + if inv:is_empty(INV_FILT) then return ItemStack("") end + for _, filterStack in ipairs(inv:get_list(INV_FILT) or {}) do + if filterStack:get_name() == itemStackName then + return ItemStack("") + end + end + return inputStack +end diff --git a/registration/machines_api_reg.lua b/registration/machines_api_reg.lua index 9425ed0..c9f5a58 100644 --- a/registration/machines_api_reg.lua +++ b/registration/machines_api_reg.lua @@ -94,6 +94,33 @@ logistica.register_item_storage("Tool Box\nStores Tools Only", "item_storage", { "logistica_tool_box_front.png", }) +-------------------------------- +-- Lava Furnace +-------------------------------- + +logistica.register_lava_furnace("Lava Furnace", "lava_furnace", 4, { + inactive = { + "logistica_lava_furnace_side.png", "logistica_lava_furnace_side.png", + "logistica_lava_furnace_side.png", "logistica_lava_furnace_side.png", + "logistica_lava_furnace_side.png", "logistica_lava_furnace_front_off.png" + }, + active = { + "logistica_lava_furnace_side.png", "logistica_lava_furnace_side.png", + "logistica_lava_furnace_side.png", "logistica_lava_furnace_side.png", + "logistica_lava_furnace_side.png", + { + image = "logistica_lava_furnace_front_on_anim.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.5 + }, + } + } +}) + -------------------------------- -- Mass Storage -------------------------------- @@ -134,28 +161,14 @@ logistica.register_supplier("Passive Supplier Chest", "passive_supplier", 16, { }) -------------------------------- --- Lava Furnace +-- Trashcan -------------------------------- -logistica.register_lava_furnace("Lava Furnace", "lava_furnace", 4, { - inactive = { - "logistica_lava_furnace_side.png", "logistica_lava_furnace_side.png", - "logistica_lava_furnace_side.png", "logistica_lava_furnace_side.png", - "logistica_lava_furnace_side.png", "logistica_lava_furnace_front_off.png" - }, - active = { - "logistica_lava_furnace_side.png", "logistica_lava_furnace_side.png", - "logistica_lava_furnace_side.png", "logistica_lava_furnace_side.png", - "logistica_lava_furnace_side.png", - { - image = "logistica_lava_furnace_front_on_anim.png", - backface_culling = false, - animation = { - type = "vertical_frames", - aspect_w = 16, - aspect_h = 16, - length = 1.5 - }, - } - } +logistica.register_trashcan("Trashcan", "trashcan", { + "logistica_trashcan_top.png", + "logistica_trashcan_bottom.png", + "logistica_trashcan_side.png", + "logistica_trashcan_side.png", + "logistica_trashcan_side.png", + "logistica_trashcan_side.png", }) diff --git a/textures/logistica_trashcan_bottom.png b/textures/logistica_trashcan_bottom.png new file mode 100644 index 0000000..20d09ce Binary files /dev/null and b/textures/logistica_trashcan_bottom.png differ diff --git a/textures/logistica_trashcan_side.png b/textures/logistica_trashcan_side.png new file mode 100644 index 0000000..482deeb Binary files /dev/null and b/textures/logistica_trashcan_side.png differ diff --git a/textures/logistica_trashcan_top.png b/textures/logistica_trashcan_top.png new file mode 100644 index 0000000..c388d69 Binary files /dev/null and b/textures/logistica_trashcan_top.png differ diff --git a/util/util.lua b/util/util.lua index 7388c62..fc613cd 100644 --- a/util/util.lua +++ b/util/util.lua @@ -13,10 +13,14 @@ dofile(path.."/inv_list_filtering.lua") d = {} d.ttos = logistica.ttos d.log = minetest.chat_send_all -function table.map(self, f) +function d.table_map(self, f) local t = {} for k,v in pairs(self) do t[k] = f(v) end return t +end +function d.ltos(list) + if not list then return "{NIL}" end + return d.ttos(d.table_map(list, function(st) return st:to_string() end)) end \ No newline at end of file