From 74b3c5a25dff5e4cf306e7eb93e4ed831a4d29eb Mon Sep 17 00:00:00 2001 From: nxet Date: Thu, 8 Oct 2020 11:17:51 +0200 Subject: [PATCH 01/12] Mod rewrite and new models (#21) * Aliases moved to utils folder * Method to generate two different formspec layouts, big and small * Log Actions moved to separate module * Added method to generate a chest definition * Rewritten models * Add Fridge model * Add Toolbox models * "Mod loaded" message; Updated localization template * Add Italian localization * Fridge now has both normal and big (2 blocks) models * Fixed mixed indentation * Rewritten README; improved IT and FR (thanks to @louisroyer) localizations. --- README.md | 102 +++++++++++++++------- cobble.lua | 115 ------------------------- dropbox.lua | 113 ------------------------ init.lua | 16 ++-- locale/more_chests.fr.tr | 10 ++- locale/more_chests.it.tr | 17 ++++ locale/template.txt | 17 +++- models/cobble.lua | 26 ++++++ models/dropbox.lua | 45 ++++++++++ models/fridge.lua | 50 +++++++++++ models/secret.lua | 54 ++++++++++++ models/shared.lua | 72 ++++++++++++++++ models/toolbox.lua | 34 ++++++++ models/wifi.lua | 34 ++++++++ secret.lua | 132 ---------------------------- shared.lua | 138 ------------------------------ textures/fridge_front.png | Bin 0 -> 1586 bytes textures/fridge_side.png | Bin 0 -> 2066 bytes textures/toolbox_acacia_front.png | Bin 0 -> 2562 bytes textures/toolbox_acacia_top.png | Bin 0 -> 3226 bytes textures/toolbox_aspen_front.png | Bin 0 -> 2171 bytes textures/toolbox_aspen_top.png | Bin 0 -> 2857 bytes textures/toolbox_front.xcf | Bin 0 -> 17577 bytes textures/toolbox_jungle_front.png | Bin 0 -> 2397 bytes textures/toolbox_jungle_top.png | Bin 0 -> 2860 bytes textures/toolbox_pine_front.png | Bin 0 -> 2478 bytes textures/toolbox_pine_top.png | Bin 0 -> 3119 bytes textures/toolbox_steel_front.png | Bin 0 -> 2542 bytes textures/toolbox_steel_top.png | Bin 0 -> 3007 bytes textures/toolbox_top.xcf | Bin 0 -> 12314 bytes textures/toolbox_wood_front.png | Bin 0 -> 2413 bytes textures/toolbox_wood_top.png | Bin 0 -> 3088 bytes utils/actions.lua | 90 +++++++++++++++++++ aliases.lua => utils/aliases.lua | 0 utils/base.lua | 97 +++++++++++++++++++++ utils/formspec.lua | 38 ++++++++ wifi.lua | 54 ------------ 37 files changed, 659 insertions(+), 595 deletions(-) delete mode 100644 cobble.lua delete mode 100644 dropbox.lua create mode 100644 locale/more_chests.it.tr create mode 100644 models/cobble.lua create mode 100644 models/dropbox.lua create mode 100644 models/fridge.lua create mode 100644 models/secret.lua create mode 100644 models/shared.lua create mode 100644 models/toolbox.lua create mode 100644 models/wifi.lua delete mode 100644 secret.lua delete mode 100644 shared.lua create mode 100644 textures/fridge_front.png create mode 100644 textures/fridge_side.png create mode 100644 textures/toolbox_acacia_front.png create mode 100644 textures/toolbox_acacia_top.png create mode 100644 textures/toolbox_aspen_front.png create mode 100644 textures/toolbox_aspen_top.png create mode 100644 textures/toolbox_front.xcf create mode 100644 textures/toolbox_jungle_front.png create mode 100644 textures/toolbox_jungle_top.png create mode 100644 textures/toolbox_pine_front.png create mode 100644 textures/toolbox_pine_top.png create mode 100644 textures/toolbox_steel_front.png create mode 100644 textures/toolbox_steel_top.png create mode 100644 textures/toolbox_top.xcf create mode 100644 textures/toolbox_wood_front.png create mode 100644 textures/toolbox_wood_top.png create mode 100644 utils/actions.lua rename aliases.lua => utils/aliases.lua (100%) create mode 100644 utils/base.lua create mode 100644 utils/formspec.lua delete mode 100644 wifi.lua diff --git a/README.md b/README.md index d5dc1f1..494736d 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,85 @@ -more_chests -=========== + -More Chests +# more_chests +Originally a fork of 0gb.us's chests_0gb_us (https://forum.minetest.net/viewtopic.php?f=11&t=4366). +Megaf's more_chests fixes several bugs, uses new textures and adds compatibility with [VanessaE's Pipeworks] (https://github.com/VanessaE/pipeworks) mod. +nxet's rework introduces a new backend which allows for easier extension of the available models, including two new models showcasing the feature. -This mod is a fork of 0gb.us's chests_0gb_us https://forum.minetest.net/viewtopic.php?f=11&t=4366 -Megaf's more_chests fixes several bugs, uses new textures and adds compatibility with [VanessaE's Pipeworks] (https://github.com/VanessaE/pipeworks) mod. +### Available models +> NOTE: descriptions of the original models come from 0gb.us initial effort -The following text was writen by 0gb.us -``` -Cobble Chest: -{'default:wood','default:cobble','default:wood'}, -{'default:cobble','default:steel_ingot','default:cobble'}, -{'default:wood','default:cobble','default:wood'} +#### Cobble Chest +This locked chest looks like cobblestone, and has no info text. Great for hiding things in. However, unlike real cobblestone, this chest is breakable by hand. If you suspect there is one hiding, hold the left mouse button and run your hand along the walls. When cracks appear, you've found the chest. +1 | 2 | 3 +---|---|--- +default:wood | default:cobble | default:wood +default:cobble | default:steel_ingot | default:cobble +default:wood | default:cobble | default:wood -This locked chest looks like cobblestone, and has no info text. Great for hiding things in. However, unlike real cobblestone, this chest is breakable by hand. If you suspect there is one hiding, Hold the left mouse button, ant run your hand along the walls. When cracks appear, you've found the chest. - -Drop Box: -{'default:wood','','default:wood'}, -{'default:wood','default:steel_ingot','default:wood'}, -{'default:wood','default:wood','default:wood'} +#### Drop Box Anyone can put things in, but only the chest's placer can remove items. +1 | 2 | 3 +---|---|--- +default:wood | _empty_ | default:wood +default:wood | default:steel_ingot | default:wood +default:wood | default:wood | default:wood -Secret Chest: -{'default:wood','default:cobble','default:wood'}, -{'default:wood','default:steel_ingot','default:wood'}, -{'default:wood','default:wood','default:wood'} -As long as you remember to click “close” before you leave the chest, no one can see what the chest contains. Only the chest's owner can click “open” and “close” on the chest's formspec, revealing and hiding the chest's contents. +#### Secret Chest +As long as you remember to click "close" before you leave the chest, no one can see what the chest contains. Only the chest's owner can click "open" and "close" on the chest's formspec, revealing and hiding the chest's contents. +1 | 2 | 3 +---|---|--- +default:wood | default:cobble | default:wood +default:wood | default:steel_ingot | default:wood +default:wood | default:wood | default:wood -Shared Chest: -{'default:wood','default:leaves','default:wood'}, -{'default:wood','default:steel_ingot','default:wood'}, -{'default:wood','default:wood','default:wood'} +#### Shared Chest Exactly what it sounds like. The chest's placer can add people to the chest's shared list using the chest's formspec. Warning: anyone you add may empty the chest. When the chest is empty, it can be mined by anyone, just like a regular locked chest. +1 | 2 | 3 +---|---|--- +default:wood | default:leaves | default:wood +default:wood | default:steel_ingot | default:wood +default:wood | default:wood | default:wood -Wifi Chest - -{'default:wood','default:mese','default:wood'}, -{'default:wood','default:steel_ingot','default:wood'}, -{'default:wood','default:wood','default:wood'} +#### Wifi Chest A wacky chest that doesn't store it's items in the usual way, but instead, stores them remotely. For that reason, all wifi chests appear to have the same inventory. Due to not actually having an inventory, wifi chests can also be mined, even when they appear to have stuff in them. Lastly, as everyone gets their own wifi account, the items you see in the wifi chest are not the same items anyone else sees. This chest's properties make it nice for keeping secrets, as well as essentially almost doubling your inventory space, if you choose to carry one with you. -``` +1 | 2 | 3 +---|---|--- +default:wood | default:mese | default:wood +default:wood | default:steel_ingot | default:wood +default:wood | default:wood | default:wood + + +#### Fridge +A new model which comes in two forms, 1- and 2-block tall, which indeed have different sizes inventories. No fancy functionality here, I just wanted to know at a glance which one is the chest I'm storing food into. + +###### Fridge Recipe +1 | 2 | 3 +---|---|--- +_empty_ | default:steel_ingot | _empty_ +default:steel_ingot | default:ice | default:steel_ingot +_empty_ | default:steel_ingot | _empty_ + +###### Big Fridge Recipe +1 | 2 | 3 +---|---|--- +default:steel_ingot | default:steel_ingot | default:steel_ingot +default:steel_ingot | default:ice | default:steel_ingot +default:steel_ingot | default:steel_ingot | default:steel_ingot + + +#### Toolbox +This model has no particular functionality to offer other than giving your tools' chest a new look. As a bonus you can also craft the chest with different types of wood, which will give you different results. For the fanciest garage workshop you ever built on Minetest. +1 | 2 | 3 +---|---|--- +default:wood | default:wood | default:wood +default:wood | default:pickaxe | default:wood +default:wood | default:wood | default:wood +> Note: crafting also accepts Aspen, Acacia, Junglewood, Pine and Steel instead of wood diff --git a/cobble.lua b/cobble.lua deleted file mode 100644 index 6bb2c4c..0000000 --- a/cobble.lua +++ /dev/null @@ -1,115 +0,0 @@ --- Load support for translation. -local S = minetest.get_translator("more_chests") - -local function has_locked_chest_privilege(meta, player) - if player:get_player_name() ~= meta:get_string("owner") then - return false - end - return true -end - -minetest.register_node("more_chests:cobble", { - description = S("Cobble Chest"), - tiles = {"default_cobble.png", "default_cobble.png", "default_cobble.png", - "default_cobble.png", "default_cobble.png", "cobblechest_front.png"}, - paramtype2 = "facedir", - groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, --- First attempt to add a way to connect to pipeworks. - tube = { - insert_object = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:add_item("main", stack) - end, - can_insert = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:room_for_item("main", stack) - end, - input_inventory = "main", - connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} - }, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - after_place_node = function(pos, placer) - local meta = minetest.get_meta(pos) - meta:set_string("owner", placer:get_player_name() or "") - - end, - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec", - "size[8,9]".. - default.gui_bg .. - default.gui_bg_img .. - default.gui_slots .. - "list[current_name;main;0,0.3;8,4;]".. - "list[current_player;main;0,4.85;8,1;]" .. - "list[current_player;main;0,6.08;8,3;8]" .. - "listring[current_name;main]".. - "listring[current_player;main]" .. - default.get_hotbar_bg(0,4.85)) - meta:set_string("owner", "") - local inv = meta:get_inventory() - inv:set_size("main", 8*4) - end, - can_dig = function(pos,player) - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory() - return inv:is_empty("main") - end, - allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a locked chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return count - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a locked chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return stack:get_count() - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a locked chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return stack:get_count() - end, - on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in locked chest at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to locked chest at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from locked chest at "..minetest.pos_to_string(pos)) - end, -}) - -minetest.register_craft({ - output = 'more_chests:cobble', - recipe = { - {'default:wood','default:cobble','default:wood'}, - {'default:cobble','default:steel_ingot','default:cobble'}, - {'default:wood','default:cobble','default:wood'} - } -}) diff --git a/dropbox.lua b/dropbox.lua deleted file mode 100644 index a8f16de..0000000 --- a/dropbox.lua +++ /dev/null @@ -1,113 +0,0 @@ --- Load support for translation. -local S = minetest.get_translator("more_chests") -local DS = minetest.get_translator("default") - -local function has_locked_chest_privilege(meta, player) - if player:get_player_name() ~= meta:get_string("owner") then - return false - end - return true -end - -minetest.register_node("more_chests:dropbox", { - description = S("Dropbox"), - tiles = {"dropbox_top.png", "dropbox_top.png", "dropbox_side.png", - "dropbox_side.png", "dropbox_side.png", "dropbox_front.png"}, - paramtype2 = "facedir", - groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, --- Pipeworks - tube = { - insert_object = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:add_item("main", stack) - end, - can_insert = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:room_for_item("main", stack) - end, - input_inventory = "main", - connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} - }, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - after_place_node = function(pos, placer) - local meta = minetest.get_meta(pos) - meta:set_string("owner", placer:get_player_name() or "") - meta:set_string("infotext", S("@1 (owned by @2)", - S("Dropbox"), - meta:get_string("owner"))) - end, - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec", - "size[8,9]".. - default.gui_bg .. - default.gui_bg_img .. - default.gui_slots .. - "list[current_name;main;0,0.3;8,4;]".. - "list[current_player;main;0,4.85;8,1;]" .. - "list[current_player;main;0,6.08;8,3;8]" .. - "listring[current_name;main]" .. - "listring[current_player;main]" .. - default.get_hotbar_bg(0,4.85)) - meta:set_string("infotext", DS("Chest")) - local inv = meta:get_inventory() - inv:set_size("main", 8*4) - end, - can_dig = function(pos,player) - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory() - return inv:is_empty("main") - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a dropbox belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return stack:get_count() - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if has_locked_chest_privilege(meta, player) then - return stack:get_count() - end - local target = meta:get_inventory():get_list(listname)[index] - local target_name = target:get_name() - local stack_count = stack:get_count() - if target_name == stack:get_name() - and target:get_count() < stack_count then - return stack_count - end - if target_name ~= "" then - return 0 - end - return stack_count - end, - on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in dropbox at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to dropbox at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from dropbox at "..minetest.pos_to_string(pos)) - end, -}) - -minetest.register_craft({ - output = 'more_chests:dropbox', - recipe = { - {'default:wood','','default:wood'}, - {'default:wood','default:steel_ingot','default:wood'}, - {'default:wood','default:wood','default:wood'} - } -}) diff --git a/init.lua b/init.lua index 5b161ec..b1e85a0 100644 --- a/init.lua +++ b/init.lua @@ -1,7 +1,11 @@ -dofile(minetest.get_modpath("more_chests").."/cobble.lua") -dofile(minetest.get_modpath("more_chests").."/dropbox.lua") -dofile(minetest.get_modpath("more_chests").."/secret.lua") -dofile(minetest.get_modpath("more_chests").."/shared.lua") -dofile(minetest.get_modpath("more_chests").."/wifi.lua") -dofile(minetest.get_modpath("more_chests").."/aliases.lua") +dofile(minetest.get_modpath("more_chests").."/models/cobble.lua") +dofile(minetest.get_modpath("more_chests").."/models/dropbox.lua") +dofile(minetest.get_modpath("more_chests").."/models/fridge.lua") +dofile(minetest.get_modpath("more_chests").."/models/secret.lua") +dofile(minetest.get_modpath("more_chests").."/models/shared.lua") +dofile(minetest.get_modpath("more_chests").."/models/toolbox.lua") +dofile(minetest.get_modpath("more_chests").."/models/wifi.lua") +dofile(minetest.get_modpath("more_chests").."/utils/aliases.lua") + +print ("[MOD] more_chests loaded") diff --git a/locale/more_chests.fr.tr b/locale/more_chests.fr.tr index 1fe8fa1..002f8d9 100644 --- a/locale/more_chests.fr.tr +++ b/locale/more_chests.fr.tr @@ -1,11 +1,17 @@ # textdomain: more_chests Cobble Chest=Coffre en pierre taillée Dropbox=Boîte de dépôt +Fridge=Réfrigérateur +Big Fridge=Grand réfrigérateur Secret Chest=Coffre secret Shared Chest=Coffre partagé Wifi Chest=Coffre wifi - - +Wooden Toolbox=Boîte à outils en bois +Aspen Wood Toolbox=Boîte à outils en bois de tremble +Acacia Wood Toolbox=Boîte à outils en bois d’acacia +Junglewood Toolbox=Boîte à outils en bois de la jungle +Pine Wood Toolbox=Boîte à outils en bois de pin +Steel Toolbox=Boîte à outils en acier @1 (owned by @2)=@1 (appartient à @2) Shared with (separate names with spaces)=Partagé avec (séparez les noms avec des espaces) submit=valider diff --git a/locale/more_chests.it.tr b/locale/more_chests.it.tr new file mode 100644 index 0000000..740616e --- /dev/null +++ b/locale/more_chests.it.tr @@ -0,0 +1,17 @@ +# textdomain: more_chests +Cobble Chest=Baule in ciottoli +Dropbox=Baule Donazioni +Fridge=Frigorifero +Big Fridge=Frigorifero Grande +Secret Chest=Baule Segreto +Shared Chest=Baule Condiviso +Wifi Chest=Baule WiFi +Wooden Toolbox=Scatola degli attrezzi in legno +Aspen Wood Toolbox=Scatola degli attrezzi in legno di pioppo +Acacia Wood Toolbox=Scatola degli attrezzi in legno di acacia +Junglewood Toolbox=Scatola degli attrezzi in legno di jungla +Pine Wood Toolbox=Scatola degli attrezzi in legno di pino +Steel Toolbox=Scatola degli attrezzi in acciaio +@1 (owned by @2)=@1 (di proprietà di @2) +Shared with (separate names with spaces)=Condiviso con (separa i nomi con degli spazi) +submit=invia diff --git a/locale/template.txt b/locale/template.txt index d95f7b1..5784d43 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -1,6 +1,17 @@ # textdomain: more_chests -Secret Chest= -Wifi Chest= Cobble Chest= -Shared Chest= Dropbox= +Fridge= +Big Fridge= +Secret Chest= +Shared Chest= +Wifi Chest= +Wooden Toolbox= +Aspen Wood Toolbox= +Acacia Wood Toolbox= +Junglewood Toolbox= +Pine Wood Toolbox= +Steel Toolbox= +@1 (owned by @2)= +Shared with (separate names with spaces)= +submit= diff --git a/models/cobble.lua b/models/cobble.lua new file mode 100644 index 0000000..2a568fa --- /dev/null +++ b/models/cobble.lua @@ -0,0 +1,26 @@ +local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") +local S = minetest.get_translator("more_chests") + +local cobble = gen_def({ + description = S("Cobble Chest"), + type = "chest", + size = "small", + tiles = { + top = "default_cobble.png", + side = "default_cobble.png", + front = "cobblechest_front.png" + }, + pipeworks_enabled = true, + recipe = { + {"group:wood", "default:cobble", "group:wood"}, + {"default:cobble", "default:steel_ingot", "default:cobble"}, + {"group:wood", "default:cobble", "group:wood"} + }, +}) + + +minetest.register_node("more_chests:cobble", cobble) +minetest.register_craft({ + output = "more_chests:cobble", + recipe = cobble.recipe, +}) diff --git a/models/dropbox.lua b/models/dropbox.lua new file mode 100644 index 0000000..94da127 --- /dev/null +++ b/models/dropbox.lua @@ -0,0 +1,45 @@ +local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") +local actions = dofile(minetest.get_modpath("more_chests") .. "/utils/actions.lua") +local S = minetest.get_translator("more_chests") + +local dropbox = gen_def({ + description = S("Dropbox"), + type = "dropbox", + size = "small", + tiles = { + top = "dropbox_top.png", + side = "dropbox_side.png", + front = "dropbox_front.png" + }, + pipeworks_enabled = true, + recipe = { + {"group:wood", "", "group:wood"}, + {"group:wood", "default:steel_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"} + }, + allow_metadata_inventory_move = false, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if actions.has_locked_chest_privilege(meta, player) then + return stack:get_count() + end + local target = meta:get_inventory():get_list(listname)[index] + local target_name = target:get_name() + local stack_count = stack:get_count() + if target_name == stack:get_name() + and target:get_count() < stack_count then + return stack_count + end + if target_name ~= "" then + return 0 + end + return stack_count + end +}) + + +minetest.register_node("more_chests:dropbox", dropbox) +minetest.register_craft({ + output = "more_chests:dropbox", + recipe = dropbox.recipe, +}) diff --git a/models/fridge.lua b/models/fridge.lua new file mode 100644 index 0000000..4600d68 --- /dev/null +++ b/models/fridge.lua @@ -0,0 +1,50 @@ +local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") +local S = minetest.get_translator("more_chests") + +-- TODO model open + +local fridge = gen_def({ + description = S("Fridge"), + type = "fridge", + size = "small", + tiles = { + side = "fridge_side.png", + front = "fridge_front.png", + }, + recipe = { + {"", "default:steel_ingot", ""}, + {"default:steel_ingot", "default:ice", "default:steel_ingot"}, + {"", "default:steel_ingot", ""} + }, +}) + +minetest.register_node("more_chests:fridge", fridge) +minetest.register_craft({ + output = "more_chests:fridge", + recipe = fridge.recipe, +}) + + +local big_fridge = gen_def({ + description = S("Big Fridge"), + type = "fridge", + size = "big", + node_box = { + {-0.5, -0.5, -0.5, 0.5, 1.5, 0.5}, + }, + tiles = { + side = "fridge_side.png", + front = "fridge_front.png", + }, + recipe = { + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "default:ice", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} + }, +}) + +minetest.register_node("more_chests:big_fridge", big_fridge) +minetest.register_craft({ + output = "more_chests:big_fridge", + recipe = big_fridge.recipe, +}) diff --git a/models/secret.lua b/models/secret.lua new file mode 100644 index 0000000..2536694 --- /dev/null +++ b/models/secret.lua @@ -0,0 +1,54 @@ +local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") +local actions = dofile(minetest.get_modpath("more_chests") .. "/utils/actions.lua") +local S = minetest.get_translator("more_chests") + +local open = "size[8,10]".. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[current_name;main;0,0.3;8,4;]" .. + "list[current_player;main;0,4.85;8,1;]" .. + "list[current_player;main;0,6.08;8,3;8]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. + "button[3,9;2,1;open;close]" .. + default.get_hotbar_bg(0,4.85) + +local closed = "size[2,1]" .. + "button[0,0;2,1;open;open]" + +local secret = gen_def({ + description = S("Secret Chest"), + type = "secret chest", + size = "small", + tiles = { + top = "secret_top.png", + side = "secret_side.png", + front = "secret_front.png" + }, + formspec = open, + pipeworks_enabled = true, + recipe = { + {"group:wood", "default:cobble", "group:wood"}, + {"group:wood", "default:steel_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"} + }, +}) + +secret.on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + if actions.has_locked_chest_privilege(meta, sender) then + if fields.open == "open" then + meta:set_string("formspec", open) + else + meta:set_string("formspec", closed) + end + end +end + + +minetest.register_node("more_chests:secret", secret) +minetest.register_craft({ + output = "more_chests:secret", + recipe = secret.recipe, +}) diff --git a/models/shared.lua b/models/shared.lua new file mode 100644 index 0000000..b4272fa --- /dev/null +++ b/models/shared.lua @@ -0,0 +1,72 @@ +local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") +local actions = dofile(minetest.get_modpath("more_chests") .. "/utils/actions.lua") +local S = minetest.get_translator("more_chests") + +local function get_formspec(string) + return "size[8,10]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[current_name;main;0,0.3;8,4;]" .. + "list[current_player;main;0,4.85;8,1;]" .. + "list[current_player;main;0,6;8,3;8]" .. + "field[.25,9.5;8,1;shared;" .. + S("Shared with (separate names with spaces)") .. + ":;" .. string .. "]" .. + "button[6,9.2;2,1;submit;" .. + S("submit") .. "]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,4.85) +end + +local function check_privs(meta, player) + local name = player:get_player_name() + local shared = " " .. meta:get_string("shared") .. " " + if name == meta:get_string("owner") then + return true + elseif shared:find(" " .. name .. " ") then + return true + else + return false + end +end + +local shared = gen_def({ + description = S("Shared Chest"), + type = "shared chest", + size = "small", + tiles = { + top = "shared_top.png", + side = "shared_side.png", + front = "shared_front.png" + }, + formspec = get_formspec(""), + pipeworks_enabled = true, + sounds = default.node_sound_wood_defaults(), + recipe = { + {"group:wood", "default:leaves", "group:wood"}, + {"group:wood", "default:steel_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"} + }, + allow_metadata_inventory_move = actions.get_allow_metadata_inventory_move{"shared chest", check_privs=check_privs}, + allow_metadata_inventory_put = actions.get_allow_metadata_inventory_put{"shared chest", check_privs=check_privs}, + allow_metadata_inventory_take = actions.get_allow_metadata_inventory_take{"shared chest", check_privs=check_privs}, +}) + +shared.on_receive_fields = function(pos, formspec, fields, sender) + local meta = minetest.get_meta(pos); + if fields.shared then + if meta:get_string("owner") == sender:get_player_name() then + meta:set_string("shared", fields.shared) + meta:set_string("formspec", get_formspec(fields.shared)) + end + end +end + + +minetest.register_node("more_chests:shared", shared) +minetest.register_craft({ + output = "more_chests:shared", + recipe = shared.recipe, +}) diff --git a/models/toolbox.lua b/models/toolbox.lua new file mode 100644 index 0000000..3b72476 --- /dev/null +++ b/models/toolbox.lua @@ -0,0 +1,34 @@ +local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") +local S = minetest.get_translator("more_chests") + +local function register_toolbox(description, type, side_tile, recipe) + local def = gen_def({ + description = description, + type = "toolbox", + size = "big", + -- node_box = {-0.5, -0.5, -0.5, 1.5, 0.5, 0.5}, -- makes it two blocks wide + tiles = { + side = side_tile, + front = "toolbox_" .. type .. "_front.png", + top = "toolbox_" .. type .. "_top.png", + }, + recipe = recipe, + }) + minetest.register_node("more_chests:toolbox_" .. type, def) +end + +local function gen_recipe(craft_item) + return { + {craft_item, craft_item, craft_item}, + {craft_item, "group:pickaxe", craft_item}, + {craft_item, craft_item, craft_item} + } +end + +register_toolbox(S("Wooden Toolbox"), "wood", "default_wood.png", gen_recipe("default:wood")) +register_toolbox(S("Aspen Wood Toolbox"), "aspen", "default_aspen_wood.png", gen_recipe("default:aspen_wood")) +register_toolbox(S("Acacia Wood Toolbox"), "acacia", "default_acacia_wood.png", gen_recipe("default:acacia_wood")) +register_toolbox(S("Junglewood Toolbox"), "jungle", "default_junglewood.png", gen_recipe("default:junglewood")) +register_toolbox(S("Pine Wood Toolbox"), "pine", "default_pine_wood.png", gen_recipe("default:pine_wood")) + +register_toolbox(S("Steel Toolbox"), "steel", "default_steel_block.png", gen_recipe("default:steel_ingot")) diff --git a/models/wifi.lua b/models/wifi.lua new file mode 100644 index 0000000..f40d491 --- /dev/null +++ b/models/wifi.lua @@ -0,0 +1,34 @@ +local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") +local S = minetest.get_translator("more_chests") + +local wifi = gen_def({ + description = S("Wifi Chest"), + type = "wifi chest", + size = "small", + tiles = { + top = "wifi_top.png", + side = "wifi_side.png", + front = "wifi_front.png" + }, + recipe = { + {"group:wood", "default:mese", "group:wood"}, + {"group:wood", "default:steel_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"} + }, + allow_metadata_inventory_move = false, + allow_metadata_inventory_put = false, + allow_metadata_inventory_take = false, +}) + +wifi.can_dig = function(pos, player) return true end + +minetest.register_node("more_chests:wifi", wifi) +minetest.register_craft({ + output = "more_chests:wifi", + recipe = wifi.recipe, +}) + +minetest.register_on_joinplayer(function(player) + local inv = player:get_inventory() + inv:set_size("more_chests:wifi", 8*4) +end) diff --git a/secret.lua b/secret.lua deleted file mode 100644 index 71fe742..0000000 --- a/secret.lua +++ /dev/null @@ -1,132 +0,0 @@ --- Load support for translation. -local S = minetest.get_translator("more_chests") - -local function has_locked_chest_privilege(meta, player) - if player:get_player_name() ~= meta:get_string("owner") then - return false - end - return true -end - -local open = "size[8,10]".. - default.gui_bg .. - default.gui_bg_img .. - default.gui_slots .. - "list[current_name;main;0,0.3;8,4;]".. - "list[current_player;main;0,4.85;8,1;]" .. - "list[current_player;main;0,6.08;8,3;8]" .. - "listring[current_name;main]" .. - "listring[current_player;main]" .. - "button[3,9;2,1;open;close]" .. - default.get_hotbar_bg(0,4.85) -local closed = "size[2,1]".. - "button[0,0;2,1;open;open]" - -minetest.register_node("more_chests:secret", { - description = S("Secret Chest"), - tiles = {"secret_top.png", "secret_top.png", "secret_side.png", - "secret_side.png", "secret_side.png", "secret_front.png"}, - paramtype2 = "facedir", - groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, --- Pipeworks - tube = { - insert_object = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:add_item("main", stack) - end, - can_insert = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:room_for_item("main", stack) - end, - input_inventory = "main", - connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} - }, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - after_place_node = function(pos, placer) - local meta = minetest.get_meta(pos) - meta:set_string("owner", placer:get_player_name() or "") - meta:set_string("infotext", S("@1 (owned by @2)", - S("Secret Chest"), - meta:get_string("owner"))) - end, - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec", open) - meta:set_string("infotext", S("Secret Chest")) - meta:set_string("owner", "") - local inv = meta:get_inventory() - inv:set_size("main", 8*4) - end, - can_dig = function(pos,player) - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory() - return inv:is_empty("main") - end, - allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a secret chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return count - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a secret chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return stack:get_count() - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a secret chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return stack:get_count() - end, - on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in secret chest at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to secret chest at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from secret chest at "..minetest.pos_to_string(pos)) - end, - on_receive_fields = function(pos, formname, fields, sender) - local meta = minetest.get_meta(pos) - if has_locked_chest_privilege(meta, sender) then - if fields.open == "open" then - meta:set_string("formspec", open) - else - meta:set_string("formspec", closed) - end - end - end, -}) - -minetest.register_craft({ - output = 'more_chests:secret', - recipe = { - {'default:wood','default:cobble','default:wood'}, - {'default:wood','default:steel_ingot','default:wood'}, - {'default:wood','default:wood','default:wood'} - } -}) diff --git a/shared.lua b/shared.lua deleted file mode 100644 index e100a93..0000000 --- a/shared.lua +++ /dev/null @@ -1,138 +0,0 @@ --- Load support for translation. -local S = minetest.get_translator("more_chests") - -local function has_locked_chest_privilege(meta, player) - local name = player:get_player_name() - local shared = " "..meta:get_string("shared").." " - if name == meta:get_string("owner") then - return true - elseif shared:find(" "..name.." ") then - - return true - else - return false - end -end - -local function get_formspec(string) - return "size[8,10]".. - default.gui_bg .. - default.gui_bg_img .. - default.gui_slots .. - "list[current_name;main;0,0.3;8,4;]".. - "list[current_player;main;0,4.85;8,1;]" .. - "list[current_player;main;0,6;8,3;8]" .. - "field[.25,9.5;8,1;shared;"..S("Shared with (separate names with spaces)")..":;"..string.."]".. - "button[6,9.2;2,1;submit;"..S("submit").."]" .. - "listring[current_name;main]" .. - "listring[current_player;main]" .. - default.get_hotbar_bg(0,4.85) -end - -minetest.register_node("more_chests:shared", { - description = S("Shared Chest"), - tiles = {"shared_top.png", "shared_top.png", "shared_side.png", - "shared_side.png", "shared_side.png", "shared_front.png"}, - paramtype2 = "facedir", - groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, --- Pipeworks - tube = { - insert_object = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:add_item("main", stack) - end, - can_insert = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:room_for_item("main", stack) - end, - input_inventory = "main", - connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} - }, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - after_place_node = function(pos, placer) - local meta = minetest.get_meta(pos) - meta:set_string("owner", placer:get_player_name() or "") - meta:set_string("infotext", S("@1 (owned by @2)", - S("Shared Chest"), - meta:get_string("owner"))) - end, - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec", get_formspec("")) - meta:set_string("infotext", S("Shared Chest")) - meta:set_string("owner", "") - local inv = meta:get_inventory() - inv:set_size("main", 8*4) - end, - can_dig = function(pos,player) - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory() - return inv:is_empty("main") - end, - allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a shared chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return count - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a shared chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return stack:get_count() - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a shared chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return stack:get_count() - end, - on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in shared chest at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to shared chest at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from shared chest at "..minetest.pos_to_string(pos)) - end, - on_receive_fields = function(pos, formspec, fields, sender) - local meta = minetest.get_meta(pos); - if fields.shared then - if meta:get_string("owner") == sender:get_player_name() then - meta:set_string("shared", fields.shared); - meta:set_string("formspec", get_formspec(fields.shared)) - end - end - end, -}) - -minetest.register_craft({ - output = 'more_chests:shared', - recipe = { - {'default:wood','default:leaves','default:wood'}, - {'default:wood','default:steel_ingot','default:wood'}, - {'default:wood','default:wood','default:wood'} - } -}) diff --git a/textures/fridge_front.png b/textures/fridge_front.png new file mode 100644 index 0000000000000000000000000000000000000000..3818b7af4d0942b9fdce60ceedb7eae1e6f2cc87 GIT binary patch literal 1586 zcmV-22F>}2P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1Y?mg6W4{Ld-&2uR}dI2g=(dxJUt78po^lj-i+ z35mf%NTN!DsPosqRsDkxYu3tGA6#@!<71+UoG=Lb`dmF})1Tu-&%ujatqF!m(98Ae z&Y_H6Nq`mLfvod z{xSu4E(A>`7$dB>HT6#TCv6$3wWThR4ht*9#Vw~1Mq{o$p#?&y4oq#ww>R~aH~NWK z0fV-~9I(NpkITei>5*H~c^2qdZIr%BgM1kV013fRC<$a4W061J1msY%VvVxaI_qt) z(IzL(IP0AAuANcIi#OhS=e-X;`V=IXV1o-jgb+iD90f<1jV^i>LyR#cI888}usT5_ zrGpPS%wZ3A_#+(gNEzvqO}5!(pF@s06)sXx{>2rqN+_|UlTM`4X-<2()1TptXR64x zD%Dh5UG+88Skq!{u=>gxZOr|iH5#ln#!T1q57r>|ewv_moY=-07-K_V+&2c0(A+rF zfsEnCT;ohfMp0M>Yh)Wag&JdE(454!(&FyH+;4eP*8GS!{=}SW)cp8&Rzo4`*`Y7UlbzlA64W(aPI+`j7C8V2DUlGHunPPg^8-;dF>UcK6V-`DUM9(npa z;_%t+s^;A7*dY0zmA=!fFBI@+Wev;e=f3kT0o4D?phu!8^BEZT0H&T_z}Ud%@8EsQ zioI92Y?PDo8rFJSA+$%=Q~Yg-+;#W9n0*QUv5mRtc4hfqEHA8mj$!GFOwlTXT;^Pg z>c>1A{#gC@a8jK~Xl6P(H!abAB=j;+KdA#ZPmwnzq`ua5w?pV%C8{5WvW|||+P6r^ zAJ_Tr7uZfOV2k>p$9TNA;b`j{A*`rV{S(;RQ?spTlIAfn%w>92b=GCzH)|8?`;z7)%Wy@nFV?cVx>Hlt6NrfLC7Pz8EK6>;8=K7rtu>)<_I*!T zmIHY@odPhQ&xhJ`-y`q}{DS3j34n9%ZNX?T2&n7&S3%cxbX`XnhW{P>sNmc8du+E` zMC4b&CtR=Bw_4x#V+Ee1wf;D`UatW##t=mj0BM^3t>AfBYmK!QYb`}la5x-B+zBu^ z{|cW3fQXPJ$s1<^pp+UFwbp2@iQ{-k==F)un?*z<%QC6!TE2xbM!K$(34pbh$Kx?t zoaZ^m)doGs?ZQC-N z&DihvIOkAG(KHQto>Ns7Q521m2#TVRBuO}*&qKD>T7n=LKGf?y_;UvcPN$O?V}?U{ k#bU7-MH zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1b>(!(YU{Ld+R1cZ1VhliQz4SM`8AaLR@`KIkO zo*05bNV_ZHsOzskyZQqkqmxnAh3J#_8Xuc%G8vty*Jrh)?Yzqmy*qE?>O3$QVzj(| z`b*|#jJtb5urglW$5p6eCyJqMSq$>n*`Ooyq8MVc#z}swBO8#@O1S;qMt3Z=bF@DGe+ zoZM&ZCPEL^_Ren)U?Aw%&kJ_Fx7ho&qRZ9;DX%1`9m?!sVgZyqmw8+PUx$8}SHcw$ zVg+LjY!+NqQ6dAhJ6UR!sna#vN);|zbD4nFmH=6H1|z&ze*81H^NLqFh*GM<5Hgn|I2j@^**Faq~pN~ewm>fxG|U;cgzAI)CE&F z@tv1?(T#o~mcgK#Fh>NKby+5gqgz`%d1lOW+A6(LgF+JnfCzg#I718ukPqw#NfC?* zM8GkEpA63pTT{RQIcFNF4sMt|$cbj`jWvPhT;t3dMri>Njy+N(f}squtaZ>&un`){ zj-6G`Iq!mtF1hU4TkpL0!H*i10|y&i@F9d4Qpk~`jV}5aVvH%~WD=uG?ByzifHN_h5-aetjx1suhvn!6)U)w0=5b>E(yCu3 z91A&2qp0Iyv}94AXl|Y&A$`W6@}Sf$kBUaMoNFVB;vCD`yVWaxWb#;}cT3#v0X0X$ zH>YZtR#5PzW#i>h^LxmTR(*_VO|DP^%WQMa-66ScQaZWb7!|h><~%L5+oqKWb-d=t zh3ywmuIL!r?q#)cboCL0DH{r##RjEJvL{nty-Pe(DA7VW4xB?iiTR%{`sGB5dQEmn zYCFNkmb84mBC_o1*ltO5#j!4%cn1)tD$c#EjuhJ(jYgj1jVd05a+mGNKABnC$xwC^ zp&$ca6!pa;0H8nmtab-4TEaooK{QDzf!)h6bDk0DhHc+cG)K-NMOhiwNQDGJ;nq|0D492=`X4#*wio zg`e)^6RRhh_MP~2T=Xw4N)HZ6#%RX-QQr1_eN--8k7GN5liSAbIA+mOZ|?XndW$>3 z;Gnpb4ehAwa7(Re^=Og&E`d^}w3GrA>g}k=HS43%Rcg=NyJfR$Bp+nGKTMS*^X!35 zF`s%b%1^Q0XN1r1b!d3sMT9u9myZ<%e6a>IjlUJ5Bc8hem;?SfHdMMv^M@Kf>DitO z@}0!49AND@MW(a`igY`2^zYABW^+hFZ;Lyjin`C!bB5h2h+CcYNSJn~i4^gtb*9Mh zTXNHH5}?R)`k50GzcCA?v&7qm3?B4*w?W}|b;E_UM|Sp`jp;}}^-{nOFj}W?rPh7n zR_~y{D4^000SaNLh0L01FWS01FWTe`H^g00007bV*G`2jm3;4;3IJZ#6Ce z00JIKL_t(I%Y~E8ZrV^3guinE6aR@Cti&xyt=e_p{|)j2-87p@q^*F2`UjiX7~7`{ z6Q@xYJ*%sGXGU{pbfjs2s_GGABK|k0(}|+UNs>PV!GigG%6Mc}C^bz}aL9B3Pp4A= zJkJ~MvUCf$ROOM@cNv)oQB?&vH!($#<9pWtR8R+U^%3R~QLVYO1m&%Q67O zG=w3H%<9EKrx`FA&d=oScKasGwrPMdoo2m2oO}ad9()}H(sV<8Y6emmh5+pMdu&Jg zynMeGXj_M_n-1W|$DB!ThMQZer%zu{Z4mhYfa$C9(Qfz+#+>NXLd-CztuJJsJ z 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 M07*qoM6N<$f*72!!{EP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1b<(&Q!#{m&_K1Oy1gaagNzgB(9kfZfZt&1BN9 zHbQ_9dRnj<|NK48U-&uiqY0cO<`^x0A&2Y=2(kOOTe4xj*Uz0H^k4Yq9&liJw0?Kv zIP(km{8*5};n!EbN$tpyBZ%zF)?Rm3`plCf$h*y_(>M97E8*!l=kMAPdmZbo9}t0Au#Y|gn(Pa}3W4E2DF}S1u;*Zy zIdWp*%q995BF7k0)ErfkPa$!NDJ4lc74Z^;B}x*JEG4__k-|8~oJ^LSb1B%gKy<3sJ@~`Z^(U*8XeRWv9RW)2WnuabcrBMC#;wOF&7AkCq)1b?G!UB z6oOOa6f>KV`aL_KMy%j;QpA8@802`;jokyeZ*emmehWAE6>>(Q`#+E~3f)2OBW|Cd z*2}6WegULWs5Z5JBC*Yoi<9E2NEaofXm#3c>=c+d=fG{xVu!;jGuY?Z=4ILI@?cx3 z+A?y$k|JNW-nguPaC*fFo3>-^lkvIm#Af5q9nBERpX4Z>Ctx@zNb?7;aILH~% zR+@fv;;D`k5|V=&B}$paVlSV?J*4<8r4?{GICXZj79kH0OPlipivOR`Hm~ zgnUyW2y)c2S)dT}ws;Fk9E@RZo1h-7QvoBvHAgmFsBXOMndJkbuuQBtIxAu7=D^Ko zE@Kg&pvadKY>nVJV-0ni{g!4zggE#f3TBB~r?&3W(ouA;#+<#4zc*~7u zgAZrxd@baCn2Jyj$4#(Uhoi>Xb}{?bns)}gfDtq<^F=%@YWEJ)GJLP}w0zw*F-i=z zLz6!u%^!)FMXpFOCsYvYOKV&Ws4sgUzT+}ra6bhaouG}LzKYFT=*{?QrtyWgF421n zUrGa-SGT9sQS4H9@cf}?etqiqJ@d`rvKwWjkChb=TpF!j^Ms~V=iwnp=pYb=hPIP1 z?!8xzLYBeV_6gNVG@7>A?>UsWgGT)Wf@Ul)Z&9?H0}W4Qore*5dki)`oS|pM&_sOd0B39Zn+py(I0WKekan-y^&{Ku6ulWOC8pw-U=?!b~%d%rCI)gIDVtnk+eQN`R z@3rvL+GON^s*vW_Yhj41T;n>3`zT!*E1iUBf_$iDyL91nWuH#$PaYDtvDN3?xyMr4 zgFWOQ!`9>0oz1_2T6E@}->)(N000JJOGiWi{{a60|De66lK=n!32;bRa{vG?BLDy{ zBLR4&KXw2B00(qQO+^Rf1p*Qj7m+uSLjV8*1xZ9fR9M5!mpxD0Kp4k==VS=P!o0Nz zSlSQJuT<2L_jZU#I+T}zreY{40wzE~>@3VINJy+8Kk|-@r{OMF6_g7XTM5+bpX z^hN3Nr`VGL*5K=A8i3D>ac`$o6K7P)uFFCR$=j>@J}#}u5zzVvTo2IthN>qu&i%yn zGyof^l+(VlTmvE$eLA~FXYe&pYnf@?s4E&G-TeSO6f>rWhQa!3lKTJMJZ`oYd<5!q zW#zS<5>+)P3IJXX4YytSO7e@Gj-!J$LxPQ#Ip;4aDMe z0Hk+zpH-QCIpy!nBA=a;Baqi`rHMjbZ^~%3GWkC4@W>1HJBtUJVHBYJ7y;n^&rfr` zr_a74-0lFcVnsIi2)6 z!Qoe~9AN1Uz6NfuE*fI=e`2-pzpuYF>=S zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1bjF4eP7J{$S#)6qOnp8Yc~pN*LIxIfQM&pHbq)H#2uXWLt? zx95;xj3(HR$x&y|7w&nU!uxOd%eoWYBaC_T{)6q@(|t4E(|fbsWoMi}o5Ef3Oo(qb zI^$m6#`!shK1t+XCx3cj^>KnPwi~16G5XfdLWHHFJ4)TEtR5y7n3C7Bh%4bQ=%;ll zt_&3`5NklQ;Hu86Cs=#<;F~u;d|z$#6(R=el+Y4Y;x(2zky3^EJ%@SuL5Y={;|x?P zP-6_!Ba2_>>N>CbjFX$kO!C;wW5t)teK+|3T+c>hOxN}P%8#ue7fqjr7!$d9$1DKi z$FZp_`>xA<@SE!cunYucnK?s2yUO08h=2JOFPs_kQAaF&` z;-kM3QSu&k%)rMWIdPx@1iT0}?*_18jsPdqJR570Uvo)l4})3&gmB~pXp{|Lg&^>s z6f%6sge5o;iIOCXibakgN{lhZ$x)U#g(NAalycH!nRCdJV@^3|&8DOb3KNZ*oMu%u z!=Z+)4XX_^%nB7Qp-71(m0Yw~h5OV{rN)|Su3D{8qHYz!{JUiKDcG_)hK8P39Aa&0Yg0gckTpwq< zPs=_p4_CD^TLA~GUGk4DJF>O7=HlC01fk;^3iPMdejgm!7sT4P2R@rV13!tzVN2rT zb1vnrI(XG@bAUwldY-(pl>M=Fl4@%*LT;-AIJ<>V2eM4I0mQR$n;rs+AIHp6YqYfi zstE2|qIRj*S=%6aNKL(snkURaQ=|-d!R+^dV7tOd2Rgfkk{@fY2oJ3bHH7{$ScW%7 zE@gT`n3{DVh|+tXb1)Gu%=0HIa)=eb&-84l3BP-{hY0X zk9sXcTAgW@P@Tcigd}Z~7p?8(Ri$3rQ^_RsR1jbtk%G{aAy-fEcP(lSVN#ro+Q!}n z<3`#TOS*Zr9?P5$%kZ2(5KV}?s^dNtx>P8#By`LBn+-OD{Htx9Vme-7Ie&FWSZ!Jn zjS)g8%yBn~;E9=K9f%tZ`KBWgrFh*i)l8)$wg3TLyu&C`%xuMh_WG2*z^Oo41~SDEbOE86cm zT7l50x!h9H+~R&rkT2H$>?F7KLH;q`x?F|VFof)T zgWnRPG{Fr84{8>gRc)7rPNXd4-~6!BpPL*PG^L=TFm zhPvcLhC?}n8q-ib&Za?LA&L;^a354U9NXJI4TL?DUO|;H|4-u=<@9+EtzG7k9eW5WHE5b^nK_0A z00v@9M??UR0FVHE8B!@t00009a7bBm001r{001r{0eGc9b^rhX2XskIMF->s0umn} z%6{#K0008?Nkl1(_r7^Ua&s^1;89Hj0E8l4002PC`ce(aQK#Ingh2M${0FXN4hATnOn+=an;PL%&-Qy~o10*1F z*Mok0G(0*10C;rwDwiKUJ_GmOAtUgaE$& zEC2w~eR1TMa(n|CC+WVp8QY%2dQvUVj=LH)cJm2$y-~R<4kVKMT?M*(`aK`T^T|8r z|3uPqHe)U>SXNfJbxZS@@_BUW+C66OCQJ7xt-1@Gkk9jVEJh?|Pzs4Lgv1!M zvIecJfe1VG5fB-`Apy~K*e=tmih5Q3e;nYUUQ;d2ea}N=e6w zkFOut-U*o#nPW&zQKr4XYb}0070pF91L+zQ^>m zH#OjBAWgoOy$k5MJ2fD-9I)1Zv#(rH>M}CF=qYmB?rr!F_JIh(MPmNX00000NkvXX Hu0mjf(Z)It literal 0 HcmV?d00001 diff --git a/textures/toolbox_front.xcf b/textures/toolbox_front.xcf new file mode 100644 index 0000000000000000000000000000000000000000..380ecab2aa2a63ecafe20ec3c1584614afe74c3e GIT binary patch literal 17577 zcmds8eQZ=$cAt~W&1F1&Ode!-%o>|lCJqiHV6Z$Te3=g=3lu9Wrz=`TO8kNGdSeU% zXC0)yDpjgf^}kA){?5H` z-n^OjhNSyP*XxJQJ-_pD&pGct-+AY~8M=G+>~ml5-0l9TVdcsg4%Z{bKLgnyA`J6D zv$sISgyV70EYNDud=IlpTHmQM(AgH_Oy3*J+r5)zkOGGe>>DM_|PlsnqS}3 z>;9-~|AC&pee0L3T;8z6?dt2?yQ`UhK3a@zoDAHsWf5TisD-FGCvkr z{_g!fy9!Gmt3S|xu(!)aojtprs;b}J-MP1S?|!#lvuE~qceJ|=%Nz6&0dS@C@f4(?C{oYuSnRjst4DpK%W49Iuz)O5%5(;`Hs_3vW;(46nA zjihvESEQc(A8yMucVyCQW@Wy9X^oS~8&H*@HC2&G^39B9rNerSr35 zly~qq$h=BZ7#Hk@e+Rzl{PTaLxx5AZziY+|N_P1x9ld)yUtPYhubXYtYM*mKIR4Om z{ugF?VVvDoK;W)N!surIt>JofF*4zp?eBj&BYsN9=%@5Py#@Xj9mRN@PSSDl{zGl= z(N{D{H^o<=ak?%i=u4Uqky?5WQQ=FI>`galoUYNA@+M8_e3dNk!}lwAepX&apNdiBt)RyhJtMh}_w+fO1V4^7;1v2ag{EM>zEnbS<%*O}3WQhQ&eiO@C>!sft60tJ_#3}W7f>hftxqtgvW52#$A&Lve1MT_xhy^b zewdA~(=~ZTUv0CqE_*vGqz&vVuD{a0inMwA>i>Sfx{bf7Nvy|h+=s^L3x8)t>QNQ% ztx4=H_+y35J&Wh_J+hMJefZwSC(LcZ+}yJ!F_-UIl`KcOBJ3l?*7vM&@17N<<^9F+ zcz;dmdlvuw74BJ;ZO1XoyTj@I^*PRK+}mB1EQK9Zyk}j;x)pa;xxRc~@k;Z)D!*fy zeN}Gd`_d%-@=EVnW?xmd75A07M!XZF?^)6I!rsa0eZ|+9sq~%|W#irR1?ZYy#q-|2 zD%`W8Ert6M@2m6rp2f9ZF1cq#+4$P!&|w7cS-29oXGQ7*dyDV8mG)MI4UM7e5rHQQ z{d9XL-XF9>^NnpZ`~0aqF7qQn;FxzNAh^Ix-sAGT&wvYu3&4b9-tP>L#qhYi6pzcB zmf{iE06Z=)#p7~>;JX-*-^5eXoA9_i4MJpEJDSthtmdy5Sx$4_fU0J)sv-s7#en=G zo|<0t{Im$6pU@MtGGEsu@YHPpp3oC`LXQx97X$J&X*i{8@Ps}MLd>)$bn}Vw%D~>e zyT0ucI`6dqw~rQYTmPX?=sYiQEGWEfWS#4g_k_NnmX+S&f-~V*kTpCOlgH3+jKnXZ z_d0F`usTLBTb=S{(WyKRJVc$zV;GMqAF)J3f@l63G-Q`ZNk}vzh7j%NG?KVjCWSIM zs6!6%sD|V*8$>=woQue@pN{Gp0ul|WmmSpUbPAq^^ zE%ZXtNAb;6XVuF(QLj7>oTd8YW{jJak65Ct;CWj?S-V6+yez#SvWWIVqNN0fqC3bh zvplM-+-!r$=ZMjQ_)pVnoj)K^R@FJE(Ww_%g)DYUfpa#+F`>om7l6Aeojmymnq??7zqgX>cyci51lrD}YraK5tx)2;Be9r2W9Yu0AMcRP)E* zzXXn&;eg-*GkMKl&Bwrn!v$c%QS&c`>*jAgn!gv#`z2D;RMA)EO zysDsAlXNG3kM7tW$2+3WtWo)y7*!qzzDc9WNsN=qM=a4zIZ3}`j@dp=^0zH_#7#uL zMRyYS%A`3 zU}m`nHQh__n>S>}dyhN#hN(=Zd#O?JSv5$G;(a$(N9gRR1#_&BMsam_uzK2J1+cm& zb9lQs8OPhUq>th``VD;;KSv+R--r)Y07D+5b2M({z;h~qS;m_qjxhlmvr8nz9>ckg zDSkIRnYdjh1u~RobNDSFzOOJ`j>()2q9VszM!ZcLPof^_V;bWqsdHw8MQ62d7ZHu| z8KV|$!A#6A*PzDR3E1&oZk*0z91~?S-JXXv63FFvT%40*yq?0;GQrhbA&uf%C$Y-f zVg<0eEziz&(e@}L=K4~%HzPpbcEiu&Vrv+0n9QD3!ZxpG;Ehhh&haN z8CGZMS9CscsZ0uGarj-`J7U;yIV{iGAS&`p$Z~?-O`;CzV;WXN4r+CdK&vy^mx_pn z`RtHiTQCcA%QdL$QUZ2yp5CPs7>7lfOqWte#85Rz9+AVmX2Rq@#}!*4jpF*wV>U3%a&p;-7M-g#O#pkycmBNN7+lbF1LJQv=33v&3Ak%l@*(5?5+L5Xi z)zu(bE1P)zyvo==YlSp87tXl`tDtRGiKKSOdgN+~WA$jM6~L;V9<%1k$HZLaao`Ni zP1a+qS3Y8iGJW~>8RYum^Ao4llWRb(6I$c9R zqKtaXL7mQA!84G_&K42p#LG&YA1Z|nQJRR)B0>w_Yyw`mLiNbB3Z5Ae(oi-vS3Fh? zl5=H-*Uzhr{p+ld2Ir#lV->UwuMAO5LBi|8ITWWH+%5Rgcz zn1ebU5TP} z*gtNCG&mQXAFH5kR*9te{~Wj;5x7-&mfzRYH{;sFIXJ<7)2v zx?xR7{De|@9C(T*l6NuQRX$>grUcLXH_((_A|c)s-4|2pF8wRrPdq4-LKz&?K))AL zhRZ2=*9K9MKR}jSHfoR_qA7L5L5X7T!We(Bw!c!;dKk+ zlqi$wK?*;os|LvlImK%wbavE&YORn)adr2xg4$vQuzDab&_`A-smJ&Q`~dLn_&fBr zd`rBo0vPfLzlO0cfL~An%rd@$#(exx>?3^nT_Pdw2wuO9s0(z-%9Y?i^wLb}9DO84 zc$6dZf(^pg@&%qlmS5ua8S0Qe#+T`cmU_pGuprw!WHlUL{pa-0Juj&oVO~(;iW2a~ ztIhNDON=9;Os3pCtcO5+$K&E1IfB|u_RDz5_>om6s}YsMT0(1kJf4$>=^&kmpQIB> zAH@$-o7ExPM2GS?@Bnqt8`fd)!zzGTrUAiokAep55(zN}@G5OU9j2eqiNwh=DU`)Q z9du9(7%m6oVH-q6eiB)F>5U}nkUpjX)#jj9rvqA@$v#;`G{9$v{Mv$9m|LzvT_+Q; zixcz)^|K-m0h`?n>`+*tP z(Rm-LI6Zx={l@|VcRlhty0yQGutBwUtf0qF{hmTcxA7@-X$GL9dkP(0gy6dvfZhR4 z=pCj-2;I?Dqa9mbjV{dqbad6|=pqE)#en?sG@R1Q(a}wV5W1tAjgD^KY;aLylN6|~JNk<@9~gIt4gtRB5;1+eO&W^0RV7F(3Zf!k*rO* V{*6{hgLBdOu?pH|l}Kv){{rk>bF%;d literal 0 HcmV?d00001 diff --git a/textures/toolbox_jungle_front.png b/textures/toolbox_jungle_front.png new file mode 100644 index 0000000000000000000000000000000000000000..4d88605c5d354199186bb1a827b67caa135ab797 GIT binary patch literal 2397 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 literal 0 HcmV?d00001 diff --git a/textures/toolbox_pine_top.png b/textures/toolbox_pine_top.png new file mode 100644 index 0000000000000000000000000000000000000000..15a750cf616f89c5c0567834932d8865f2c7cb0f GIT binary patch literal 3119 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 JPDHLkV1hAY+noRa literal 0 HcmV?d00001 diff --git a/textures/toolbox_steel_front.png b/textures/toolbox_steel_front.png new file mode 100644 index 0000000000000000000000000000000000000000..0399b0d6b17c0e172aa91311a71e3bcebfac6ea1 GIT binary patch literal 2542 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 Ef|>ra$N&HU literal 0 HcmV?d00001 diff --git a/textures/toolbox_steel_top.png b/textures/toolbox_steel_top.png new file mode 100644 index 0000000000000000000000000000000000000000..21f3e6248ea8cb01cd61f84114e40c1bd0741cbd GIT binary patch literal 3007 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 B%g+D+ literal 0 HcmV?d00001 diff --git a/textures/toolbox_top.xcf b/textures/toolbox_top.xcf new file mode 100644 index 0000000000000000000000000000000000000000..cb6c4860764fffe944badc4be0c823b44f68d706 GIT binary patch literal 12314 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 Date: Thu, 8 Oct 2020 10:20:47 +0100 Subject: [PATCH 02/12] Removed lost HTML tag --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 494736d..9bc7c6c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,3 @@ - - # more_chests Originally a fork of 0gb.us's chests_0gb_us (https://forum.minetest.net/viewtopic.php?f=11&t=4366). Megaf's more_chests fixes several bugs, uses new textures and adds compatibility with [VanessaE's Pipeworks] (https://github.com/VanessaE/pipeworks) mod. From 426a13089c1fcde3b4812cb876522b91c1f31330 Mon Sep 17 00:00:00 2001 From: Megaf Date: Thu, 22 Oct 2020 21:47:46 +0100 Subject: [PATCH 03/12] Revert "Removed lost HTML tag" This reverts commit 1d59b74c8999d864931a2d25a264b2cb7406b4ef. --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 9bc7c6c..494736d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ + + # more_chests Originally a fork of 0gb.us's chests_0gb_us (https://forum.minetest.net/viewtopic.php?f=11&t=4366). Megaf's more_chests fixes several bugs, uses new textures and adds compatibility with [VanessaE's Pipeworks] (https://github.com/VanessaE/pipeworks) mod. From 058b3a0d4b83537a416dc0115a5c17c6c6af3024 Mon Sep 17 00:00:00 2001 From: Megaf Date: Thu, 22 Oct 2020 21:47:59 +0100 Subject: [PATCH 04/12] Revert "Mod rewrite and new models (#21)" This reverts commit 74b3c5a25dff5e4cf306e7eb93e4ed831a4d29eb. --- README.md | 102 +++++++--------------- utils/aliases.lua => aliases.lua | 0 cobble.lua | 115 +++++++++++++++++++++++++ dropbox.lua | 113 ++++++++++++++++++++++++ init.lua | 16 ++-- locale/more_chests.fr.tr | 10 +-- locale/more_chests.it.tr | 17 ---- locale/template.txt | 17 +--- models/cobble.lua | 26 ------ models/dropbox.lua | 45 ---------- models/fridge.lua | 50 ----------- models/secret.lua | 54 ------------ models/shared.lua | 72 ---------------- models/toolbox.lua | 34 -------- models/wifi.lua | 34 -------- secret.lua | 132 ++++++++++++++++++++++++++++ shared.lua | 138 ++++++++++++++++++++++++++++++ textures/fridge_front.png | Bin 1586 -> 0 bytes textures/fridge_side.png | Bin 2066 -> 0 bytes textures/toolbox_acacia_front.png | Bin 2562 -> 0 bytes textures/toolbox_acacia_top.png | Bin 3226 -> 0 bytes textures/toolbox_aspen_front.png | Bin 2171 -> 0 bytes textures/toolbox_aspen_top.png | Bin 2857 -> 0 bytes textures/toolbox_front.xcf | Bin 17577 -> 0 bytes textures/toolbox_jungle_front.png | Bin 2397 -> 0 bytes textures/toolbox_jungle_top.png | Bin 2860 -> 0 bytes textures/toolbox_pine_front.png | Bin 2478 -> 0 bytes textures/toolbox_pine_top.png | Bin 3119 -> 0 bytes textures/toolbox_steel_front.png | Bin 2542 -> 0 bytes textures/toolbox_steel_top.png | Bin 3007 -> 0 bytes textures/toolbox_top.xcf | Bin 12314 -> 0 bytes textures/toolbox_wood_front.png | Bin 2413 -> 0 bytes textures/toolbox_wood_top.png | Bin 3088 -> 0 bytes utils/actions.lua | 90 ------------------- utils/base.lua | 97 --------------------- utils/formspec.lua | 38 -------- wifi.lua | 54 ++++++++++++ 37 files changed, 595 insertions(+), 659 deletions(-) rename utils/aliases.lua => aliases.lua (100%) create mode 100644 cobble.lua create mode 100644 dropbox.lua delete mode 100644 locale/more_chests.it.tr delete mode 100644 models/cobble.lua delete mode 100644 models/dropbox.lua delete mode 100644 models/fridge.lua delete mode 100644 models/secret.lua delete mode 100644 models/shared.lua delete mode 100644 models/toolbox.lua delete mode 100644 models/wifi.lua create mode 100644 secret.lua create mode 100644 shared.lua delete mode 100644 textures/fridge_front.png delete mode 100644 textures/fridge_side.png delete mode 100644 textures/toolbox_acacia_front.png delete mode 100644 textures/toolbox_acacia_top.png delete mode 100644 textures/toolbox_aspen_front.png delete mode 100644 textures/toolbox_aspen_top.png delete mode 100644 textures/toolbox_front.xcf delete mode 100644 textures/toolbox_jungle_front.png delete mode 100644 textures/toolbox_jungle_top.png delete mode 100644 textures/toolbox_pine_front.png delete mode 100644 textures/toolbox_pine_top.png delete mode 100644 textures/toolbox_steel_front.png delete mode 100644 textures/toolbox_steel_top.png delete mode 100644 textures/toolbox_top.xcf delete mode 100644 textures/toolbox_wood_front.png delete mode 100644 textures/toolbox_wood_top.png delete mode 100644 utils/actions.lua delete mode 100644 utils/base.lua delete mode 100644 utils/formspec.lua create mode 100644 wifi.lua diff --git a/README.md b/README.md index 494736d..d5dc1f1 100644 --- a/README.md +++ b/README.md @@ -1,85 +1,47 @@ - +more_chests +=========== -# more_chests -Originally a fork of 0gb.us's chests_0gb_us (https://forum.minetest.net/viewtopic.php?f=11&t=4366). -Megaf's more_chests fixes several bugs, uses new textures and adds compatibility with [VanessaE's Pipeworks] (https://github.com/VanessaE/pipeworks) mod. -nxet's rework introduces a new backend which allows for easier extension of the available models, including two new models showcasing the feature. +More Chests +This mod is a fork of 0gb.us's chests_0gb_us https://forum.minetest.net/viewtopic.php?f=11&t=4366 -### Available models -> NOTE: descriptions of the original models come from 0gb.us initial effort +Megaf's more_chests fixes several bugs, uses new textures and adds compatibility with [VanessaE's Pipeworks] (https://github.com/VanessaE/pipeworks) mod. -#### Cobble Chest -This locked chest looks like cobblestone, and has no info text. Great for hiding things in. However, unlike real cobblestone, this chest is breakable by hand. If you suspect there is one hiding, hold the left mouse button and run your hand along the walls. When cracks appear, you've found the chest. -1 | 2 | 3 ----|---|--- -default:wood | default:cobble | default:wood -default:cobble | default:steel_ingot | default:cobble -default:wood | default:cobble | default:wood +The following text was writen by 0gb.us +``` +Cobble Chest: +{'default:wood','default:cobble','default:wood'}, +{'default:cobble','default:steel_ingot','default:cobble'}, +{'default:wood','default:cobble','default:wood'} +This locked chest looks like cobblestone, and has no info text. Great for hiding things in. However, unlike real cobblestone, this chest is breakable by hand. If you suspect there is one hiding, Hold the left mouse button, ant run your hand along the walls. When cracks appear, you've found the chest. + +Drop Box: +{'default:wood','','default:wood'}, +{'default:wood','default:steel_ingot','default:wood'}, +{'default:wood','default:wood','default:wood'} -#### Drop Box Anyone can put things in, but only the chest's placer can remove items. -1 | 2 | 3 ----|---|--- -default:wood | _empty_ | default:wood -default:wood | default:steel_ingot | default:wood -default:wood | default:wood | default:wood +Secret Chest: +{'default:wood','default:cobble','default:wood'}, +{'default:wood','default:steel_ingot','default:wood'}, +{'default:wood','default:wood','default:wood'} -#### Secret Chest -As long as you remember to click "close" before you leave the chest, no one can see what the chest contains. Only the chest's owner can click "open" and "close" on the chest's formspec, revealing and hiding the chest's contents. -1 | 2 | 3 ----|---|--- -default:wood | default:cobble | default:wood -default:wood | default:steel_ingot | default:wood -default:wood | default:wood | default:wood +As long as you remember to click “close” before you leave the chest, no one can see what the chest contains. Only the chest's owner can click “open” and “close” on the chest's formspec, revealing and hiding the chest's contents. +Shared Chest: +{'default:wood','default:leaves','default:wood'}, +{'default:wood','default:steel_ingot','default:wood'}, +{'default:wood','default:wood','default:wood'} -#### Shared Chest Exactly what it sounds like. The chest's placer can add people to the chest's shared list using the chest's formspec. Warning: anyone you add may empty the chest. When the chest is empty, it can be mined by anyone, just like a regular locked chest. -1 | 2 | 3 ----|---|--- -default:wood | default:leaves | default:wood -default:wood | default:steel_ingot | default:wood -default:wood | default:wood | default:wood +Wifi Chest + +{'default:wood','default:mese','default:wood'}, +{'default:wood','default:steel_ingot','default:wood'}, +{'default:wood','default:wood','default:wood'} -#### Wifi Chest A wacky chest that doesn't store it's items in the usual way, but instead, stores them remotely. For that reason, all wifi chests appear to have the same inventory. Due to not actually having an inventory, wifi chests can also be mined, even when they appear to have stuff in them. Lastly, as everyone gets their own wifi account, the items you see in the wifi chest are not the same items anyone else sees. This chest's properties make it nice for keeping secrets, as well as essentially almost doubling your inventory space, if you choose to carry one with you. -1 | 2 | 3 ----|---|--- -default:wood | default:mese | default:wood -default:wood | default:steel_ingot | default:wood -default:wood | default:wood | default:wood - - -#### Fridge -A new model which comes in two forms, 1- and 2-block tall, which indeed have different sizes inventories. No fancy functionality here, I just wanted to know at a glance which one is the chest I'm storing food into. - -###### Fridge Recipe -1 | 2 | 3 ----|---|--- -_empty_ | default:steel_ingot | _empty_ -default:steel_ingot | default:ice | default:steel_ingot -_empty_ | default:steel_ingot | _empty_ - -###### Big Fridge Recipe -1 | 2 | 3 ----|---|--- -default:steel_ingot | default:steel_ingot | default:steel_ingot -default:steel_ingot | default:ice | default:steel_ingot -default:steel_ingot | default:steel_ingot | default:steel_ingot - - -#### Toolbox -This model has no particular functionality to offer other than giving your tools' chest a new look. As a bonus you can also craft the chest with different types of wood, which will give you different results. For the fanciest garage workshop you ever built on Minetest. -1 | 2 | 3 ----|---|--- -default:wood | default:wood | default:wood -default:wood | default:pickaxe | default:wood -default:wood | default:wood | default:wood -> Note: crafting also accepts Aspen, Acacia, Junglewood, Pine and Steel instead of wood +``` diff --git a/utils/aliases.lua b/aliases.lua similarity index 100% rename from utils/aliases.lua rename to aliases.lua diff --git a/cobble.lua b/cobble.lua new file mode 100644 index 0000000..6bb2c4c --- /dev/null +++ b/cobble.lua @@ -0,0 +1,115 @@ +-- Load support for translation. +local S = minetest.get_translator("more_chests") + +local function has_locked_chest_privilege(meta, player) + if player:get_player_name() ~= meta:get_string("owner") then + return false + end + return true +end + +minetest.register_node("more_chests:cobble", { + description = S("Cobble Chest"), + tiles = {"default_cobble.png", "default_cobble.png", "default_cobble.png", + "default_cobble.png", "default_cobble.png", "cobblechest_front.png"}, + paramtype2 = "facedir", + groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, +-- First attempt to add a way to connect to pipeworks. + tube = { + insert_object = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:add_item("main", stack) + end, + can_insert = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:room_for_item("main", stack) + end, + input_inventory = "main", + connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} + }, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string("owner", placer:get_player_name() or "") + + end, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", + "size[8,9]".. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[current_name;main;0,0.3;8,4;]".. + "list[current_player;main;0,4.85;8,1;]" .. + "list[current_player;main;0,6.08;8,3;8]" .. + "listring[current_name;main]".. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,4.85)) + meta:set_string("owner", "") + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + end, + can_dig = function(pos,player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("main") + end, + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + if not has_locked_chest_privilege(meta, player) then + minetest.log("action", player:get_player_name().. + " tried to access a locked chest belonging to ".. + meta:get_string("owner").." at ".. + minetest.pos_to_string(pos)) + return 0 + end + return count + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if not has_locked_chest_privilege(meta, player) then + minetest.log("action", player:get_player_name().. + " tried to access a locked chest belonging to ".. + meta:get_string("owner").." at ".. + minetest.pos_to_string(pos)) + return 0 + end + return stack:get_count() + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if not has_locked_chest_privilege(meta, player) then + minetest.log("action", player:get_player_name().. + " tried to access a locked chest belonging to ".. + meta:get_string("owner").." at ".. + minetest.pos_to_string(pos)) + return 0 + end + return stack:get_count() + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name().. + " moves stuff in locked chest at "..minetest.pos_to_string(pos)) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name().. + " moves stuff to locked chest at "..minetest.pos_to_string(pos)) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name().. + " takes stuff from locked chest at "..minetest.pos_to_string(pos)) + end, +}) + +minetest.register_craft({ + output = 'more_chests:cobble', + recipe = { + {'default:wood','default:cobble','default:wood'}, + {'default:cobble','default:steel_ingot','default:cobble'}, + {'default:wood','default:cobble','default:wood'} + } +}) diff --git a/dropbox.lua b/dropbox.lua new file mode 100644 index 0000000..a8f16de --- /dev/null +++ b/dropbox.lua @@ -0,0 +1,113 @@ +-- Load support for translation. +local S = minetest.get_translator("more_chests") +local DS = minetest.get_translator("default") + +local function has_locked_chest_privilege(meta, player) + if player:get_player_name() ~= meta:get_string("owner") then + return false + end + return true +end + +minetest.register_node("more_chests:dropbox", { + description = S("Dropbox"), + tiles = {"dropbox_top.png", "dropbox_top.png", "dropbox_side.png", + "dropbox_side.png", "dropbox_side.png", "dropbox_front.png"}, + paramtype2 = "facedir", + groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, +-- Pipeworks + tube = { + insert_object = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:add_item("main", stack) + end, + can_insert = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:room_for_item("main", stack) + end, + input_inventory = "main", + connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} + }, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string("owner", placer:get_player_name() or "") + meta:set_string("infotext", S("@1 (owned by @2)", + S("Dropbox"), + meta:get_string("owner"))) + end, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", + "size[8,9]".. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[current_name;main;0,0.3;8,4;]".. + "list[current_player;main;0,4.85;8,1;]" .. + "list[current_player;main;0,6.08;8,3;8]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,4.85)) + meta:set_string("infotext", DS("Chest")) + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + end, + can_dig = function(pos,player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("main") + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if not has_locked_chest_privilege(meta, player) then + minetest.log("action", player:get_player_name().. + " tried to access a dropbox belonging to ".. + meta:get_string("owner").." at ".. + minetest.pos_to_string(pos)) + return 0 + end + return stack:get_count() + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if has_locked_chest_privilege(meta, player) then + return stack:get_count() + end + local target = meta:get_inventory():get_list(listname)[index] + local target_name = target:get_name() + local stack_count = stack:get_count() + if target_name == stack:get_name() + and target:get_count() < stack_count then + return stack_count + end + if target_name ~= "" then + return 0 + end + return stack_count + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name().. + " moves stuff in dropbox at "..minetest.pos_to_string(pos)) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name().. + " moves stuff to dropbox at "..minetest.pos_to_string(pos)) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name().. + " takes stuff from dropbox at "..minetest.pos_to_string(pos)) + end, +}) + +minetest.register_craft({ + output = 'more_chests:dropbox', + recipe = { + {'default:wood','','default:wood'}, + {'default:wood','default:steel_ingot','default:wood'}, + {'default:wood','default:wood','default:wood'} + } +}) diff --git a/init.lua b/init.lua index b1e85a0..5b161ec 100644 --- a/init.lua +++ b/init.lua @@ -1,11 +1,7 @@ -dofile(minetest.get_modpath("more_chests").."/models/cobble.lua") -dofile(minetest.get_modpath("more_chests").."/models/dropbox.lua") -dofile(minetest.get_modpath("more_chests").."/models/fridge.lua") -dofile(minetest.get_modpath("more_chests").."/models/secret.lua") -dofile(minetest.get_modpath("more_chests").."/models/shared.lua") -dofile(minetest.get_modpath("more_chests").."/models/toolbox.lua") -dofile(minetest.get_modpath("more_chests").."/models/wifi.lua") +dofile(minetest.get_modpath("more_chests").."/cobble.lua") +dofile(minetest.get_modpath("more_chests").."/dropbox.lua") +dofile(minetest.get_modpath("more_chests").."/secret.lua") +dofile(minetest.get_modpath("more_chests").."/shared.lua") +dofile(minetest.get_modpath("more_chests").."/wifi.lua") +dofile(minetest.get_modpath("more_chests").."/aliases.lua") -dofile(minetest.get_modpath("more_chests").."/utils/aliases.lua") - -print ("[MOD] more_chests loaded") diff --git a/locale/more_chests.fr.tr b/locale/more_chests.fr.tr index 002f8d9..1fe8fa1 100644 --- a/locale/more_chests.fr.tr +++ b/locale/more_chests.fr.tr @@ -1,17 +1,11 @@ # textdomain: more_chests Cobble Chest=Coffre en pierre taillée Dropbox=Boîte de dépôt -Fridge=Réfrigérateur -Big Fridge=Grand réfrigérateur Secret Chest=Coffre secret Shared Chest=Coffre partagé Wifi Chest=Coffre wifi -Wooden Toolbox=Boîte à outils en bois -Aspen Wood Toolbox=Boîte à outils en bois de tremble -Acacia Wood Toolbox=Boîte à outils en bois d’acacia -Junglewood Toolbox=Boîte à outils en bois de la jungle -Pine Wood Toolbox=Boîte à outils en bois de pin -Steel Toolbox=Boîte à outils en acier + + @1 (owned by @2)=@1 (appartient à @2) Shared with (separate names with spaces)=Partagé avec (séparez les noms avec des espaces) submit=valider diff --git a/locale/more_chests.it.tr b/locale/more_chests.it.tr deleted file mode 100644 index 740616e..0000000 --- a/locale/more_chests.it.tr +++ /dev/null @@ -1,17 +0,0 @@ -# textdomain: more_chests -Cobble Chest=Baule in ciottoli -Dropbox=Baule Donazioni -Fridge=Frigorifero -Big Fridge=Frigorifero Grande -Secret Chest=Baule Segreto -Shared Chest=Baule Condiviso -Wifi Chest=Baule WiFi -Wooden Toolbox=Scatola degli attrezzi in legno -Aspen Wood Toolbox=Scatola degli attrezzi in legno di pioppo -Acacia Wood Toolbox=Scatola degli attrezzi in legno di acacia -Junglewood Toolbox=Scatola degli attrezzi in legno di jungla -Pine Wood Toolbox=Scatola degli attrezzi in legno di pino -Steel Toolbox=Scatola degli attrezzi in acciaio -@1 (owned by @2)=@1 (di proprietà di @2) -Shared with (separate names with spaces)=Condiviso con (separa i nomi con degli spazi) -submit=invia diff --git a/locale/template.txt b/locale/template.txt index 5784d43..d95f7b1 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -1,17 +1,6 @@ # textdomain: more_chests -Cobble Chest= -Dropbox= -Fridge= -Big Fridge= Secret Chest= -Shared Chest= Wifi Chest= -Wooden Toolbox= -Aspen Wood Toolbox= -Acacia Wood Toolbox= -Junglewood Toolbox= -Pine Wood Toolbox= -Steel Toolbox= -@1 (owned by @2)= -Shared with (separate names with spaces)= -submit= +Cobble Chest= +Shared Chest= +Dropbox= diff --git a/models/cobble.lua b/models/cobble.lua deleted file mode 100644 index 2a568fa..0000000 --- a/models/cobble.lua +++ /dev/null @@ -1,26 +0,0 @@ -local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") -local S = minetest.get_translator("more_chests") - -local cobble = gen_def({ - description = S("Cobble Chest"), - type = "chest", - size = "small", - tiles = { - top = "default_cobble.png", - side = "default_cobble.png", - front = "cobblechest_front.png" - }, - pipeworks_enabled = true, - recipe = { - {"group:wood", "default:cobble", "group:wood"}, - {"default:cobble", "default:steel_ingot", "default:cobble"}, - {"group:wood", "default:cobble", "group:wood"} - }, -}) - - -minetest.register_node("more_chests:cobble", cobble) -minetest.register_craft({ - output = "more_chests:cobble", - recipe = cobble.recipe, -}) diff --git a/models/dropbox.lua b/models/dropbox.lua deleted file mode 100644 index 94da127..0000000 --- a/models/dropbox.lua +++ /dev/null @@ -1,45 +0,0 @@ -local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") -local actions = dofile(minetest.get_modpath("more_chests") .. "/utils/actions.lua") -local S = minetest.get_translator("more_chests") - -local dropbox = gen_def({ - description = S("Dropbox"), - type = "dropbox", - size = "small", - tiles = { - top = "dropbox_top.png", - side = "dropbox_side.png", - front = "dropbox_front.png" - }, - pipeworks_enabled = true, - recipe = { - {"group:wood", "", "group:wood"}, - {"group:wood", "default:steel_ingot", "group:wood"}, - {"group:wood", "group:wood", "group:wood"} - }, - allow_metadata_inventory_move = false, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if actions.has_locked_chest_privilege(meta, player) then - return stack:get_count() - end - local target = meta:get_inventory():get_list(listname)[index] - local target_name = target:get_name() - local stack_count = stack:get_count() - if target_name == stack:get_name() - and target:get_count() < stack_count then - return stack_count - end - if target_name ~= "" then - return 0 - end - return stack_count - end -}) - - -minetest.register_node("more_chests:dropbox", dropbox) -minetest.register_craft({ - output = "more_chests:dropbox", - recipe = dropbox.recipe, -}) diff --git a/models/fridge.lua b/models/fridge.lua deleted file mode 100644 index 4600d68..0000000 --- a/models/fridge.lua +++ /dev/null @@ -1,50 +0,0 @@ -local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") -local S = minetest.get_translator("more_chests") - --- TODO model open - -local fridge = gen_def({ - description = S("Fridge"), - type = "fridge", - size = "small", - tiles = { - side = "fridge_side.png", - front = "fridge_front.png", - }, - recipe = { - {"", "default:steel_ingot", ""}, - {"default:steel_ingot", "default:ice", "default:steel_ingot"}, - {"", "default:steel_ingot", ""} - }, -}) - -minetest.register_node("more_chests:fridge", fridge) -minetest.register_craft({ - output = "more_chests:fridge", - recipe = fridge.recipe, -}) - - -local big_fridge = gen_def({ - description = S("Big Fridge"), - type = "fridge", - size = "big", - node_box = { - {-0.5, -0.5, -0.5, 0.5, 1.5, 0.5}, - }, - tiles = { - side = "fridge_side.png", - front = "fridge_front.png", - }, - recipe = { - {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, - {"default:steel_ingot", "default:ice", "default:steel_ingot"}, - {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} - }, -}) - -minetest.register_node("more_chests:big_fridge", big_fridge) -minetest.register_craft({ - output = "more_chests:big_fridge", - recipe = big_fridge.recipe, -}) diff --git a/models/secret.lua b/models/secret.lua deleted file mode 100644 index 2536694..0000000 --- a/models/secret.lua +++ /dev/null @@ -1,54 +0,0 @@ -local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") -local actions = dofile(minetest.get_modpath("more_chests") .. "/utils/actions.lua") -local S = minetest.get_translator("more_chests") - -local open = "size[8,10]".. - default.gui_bg .. - default.gui_bg_img .. - default.gui_slots .. - "list[current_name;main;0,0.3;8,4;]" .. - "list[current_player;main;0,4.85;8,1;]" .. - "list[current_player;main;0,6.08;8,3;8]" .. - "listring[current_name;main]" .. - "listring[current_player;main]" .. - "button[3,9;2,1;open;close]" .. - default.get_hotbar_bg(0,4.85) - -local closed = "size[2,1]" .. - "button[0,0;2,1;open;open]" - -local secret = gen_def({ - description = S("Secret Chest"), - type = "secret chest", - size = "small", - tiles = { - top = "secret_top.png", - side = "secret_side.png", - front = "secret_front.png" - }, - formspec = open, - pipeworks_enabled = true, - recipe = { - {"group:wood", "default:cobble", "group:wood"}, - {"group:wood", "default:steel_ingot", "group:wood"}, - {"group:wood", "group:wood", "group:wood"} - }, -}) - -secret.on_receive_fields = function(pos, formname, fields, sender) - local meta = minetest.get_meta(pos) - if actions.has_locked_chest_privilege(meta, sender) then - if fields.open == "open" then - meta:set_string("formspec", open) - else - meta:set_string("formspec", closed) - end - end -end - - -minetest.register_node("more_chests:secret", secret) -minetest.register_craft({ - output = "more_chests:secret", - recipe = secret.recipe, -}) diff --git a/models/shared.lua b/models/shared.lua deleted file mode 100644 index b4272fa..0000000 --- a/models/shared.lua +++ /dev/null @@ -1,72 +0,0 @@ -local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") -local actions = dofile(minetest.get_modpath("more_chests") .. "/utils/actions.lua") -local S = minetest.get_translator("more_chests") - -local function get_formspec(string) - return "size[8,10]" .. - default.gui_bg .. - default.gui_bg_img .. - default.gui_slots .. - "list[current_name;main;0,0.3;8,4;]" .. - "list[current_player;main;0,4.85;8,1;]" .. - "list[current_player;main;0,6;8,3;8]" .. - "field[.25,9.5;8,1;shared;" .. - S("Shared with (separate names with spaces)") .. - ":;" .. string .. "]" .. - "button[6,9.2;2,1;submit;" .. - S("submit") .. "]" .. - "listring[current_name;main]" .. - "listring[current_player;main]" .. - default.get_hotbar_bg(0,4.85) -end - -local function check_privs(meta, player) - local name = player:get_player_name() - local shared = " " .. meta:get_string("shared") .. " " - if name == meta:get_string("owner") then - return true - elseif shared:find(" " .. name .. " ") then - return true - else - return false - end -end - -local shared = gen_def({ - description = S("Shared Chest"), - type = "shared chest", - size = "small", - tiles = { - top = "shared_top.png", - side = "shared_side.png", - front = "shared_front.png" - }, - formspec = get_formspec(""), - pipeworks_enabled = true, - sounds = default.node_sound_wood_defaults(), - recipe = { - {"group:wood", "default:leaves", "group:wood"}, - {"group:wood", "default:steel_ingot", "group:wood"}, - {"group:wood", "group:wood", "group:wood"} - }, - allow_metadata_inventory_move = actions.get_allow_metadata_inventory_move{"shared chest", check_privs=check_privs}, - allow_metadata_inventory_put = actions.get_allow_metadata_inventory_put{"shared chest", check_privs=check_privs}, - allow_metadata_inventory_take = actions.get_allow_metadata_inventory_take{"shared chest", check_privs=check_privs}, -}) - -shared.on_receive_fields = function(pos, formspec, fields, sender) - local meta = minetest.get_meta(pos); - if fields.shared then - if meta:get_string("owner") == sender:get_player_name() then - meta:set_string("shared", fields.shared) - meta:set_string("formspec", get_formspec(fields.shared)) - end - end -end - - -minetest.register_node("more_chests:shared", shared) -minetest.register_craft({ - output = "more_chests:shared", - recipe = shared.recipe, -}) diff --git a/models/toolbox.lua b/models/toolbox.lua deleted file mode 100644 index 3b72476..0000000 --- a/models/toolbox.lua +++ /dev/null @@ -1,34 +0,0 @@ -local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") -local S = minetest.get_translator("more_chests") - -local function register_toolbox(description, type, side_tile, recipe) - local def = gen_def({ - description = description, - type = "toolbox", - size = "big", - -- node_box = {-0.5, -0.5, -0.5, 1.5, 0.5, 0.5}, -- makes it two blocks wide - tiles = { - side = side_tile, - front = "toolbox_" .. type .. "_front.png", - top = "toolbox_" .. type .. "_top.png", - }, - recipe = recipe, - }) - minetest.register_node("more_chests:toolbox_" .. type, def) -end - -local function gen_recipe(craft_item) - return { - {craft_item, craft_item, craft_item}, - {craft_item, "group:pickaxe", craft_item}, - {craft_item, craft_item, craft_item} - } -end - -register_toolbox(S("Wooden Toolbox"), "wood", "default_wood.png", gen_recipe("default:wood")) -register_toolbox(S("Aspen Wood Toolbox"), "aspen", "default_aspen_wood.png", gen_recipe("default:aspen_wood")) -register_toolbox(S("Acacia Wood Toolbox"), "acacia", "default_acacia_wood.png", gen_recipe("default:acacia_wood")) -register_toolbox(S("Junglewood Toolbox"), "jungle", "default_junglewood.png", gen_recipe("default:junglewood")) -register_toolbox(S("Pine Wood Toolbox"), "pine", "default_pine_wood.png", gen_recipe("default:pine_wood")) - -register_toolbox(S("Steel Toolbox"), "steel", "default_steel_block.png", gen_recipe("default:steel_ingot")) diff --git a/models/wifi.lua b/models/wifi.lua deleted file mode 100644 index f40d491..0000000 --- a/models/wifi.lua +++ /dev/null @@ -1,34 +0,0 @@ -local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") -local S = minetest.get_translator("more_chests") - -local wifi = gen_def({ - description = S("Wifi Chest"), - type = "wifi chest", - size = "small", - tiles = { - top = "wifi_top.png", - side = "wifi_side.png", - front = "wifi_front.png" - }, - recipe = { - {"group:wood", "default:mese", "group:wood"}, - {"group:wood", "default:steel_ingot", "group:wood"}, - {"group:wood", "group:wood", "group:wood"} - }, - allow_metadata_inventory_move = false, - allow_metadata_inventory_put = false, - allow_metadata_inventory_take = false, -}) - -wifi.can_dig = function(pos, player) return true end - -minetest.register_node("more_chests:wifi", wifi) -minetest.register_craft({ - output = "more_chests:wifi", - recipe = wifi.recipe, -}) - -minetest.register_on_joinplayer(function(player) - local inv = player:get_inventory() - inv:set_size("more_chests:wifi", 8*4) -end) diff --git a/secret.lua b/secret.lua new file mode 100644 index 0000000..71fe742 --- /dev/null +++ b/secret.lua @@ -0,0 +1,132 @@ +-- Load support for translation. +local S = minetest.get_translator("more_chests") + +local function has_locked_chest_privilege(meta, player) + if player:get_player_name() ~= meta:get_string("owner") then + return false + end + return true +end + +local open = "size[8,10]".. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[current_name;main;0,0.3;8,4;]".. + "list[current_player;main;0,4.85;8,1;]" .. + "list[current_player;main;0,6.08;8,3;8]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. + "button[3,9;2,1;open;close]" .. + default.get_hotbar_bg(0,4.85) +local closed = "size[2,1]".. + "button[0,0;2,1;open;open]" + +minetest.register_node("more_chests:secret", { + description = S("Secret Chest"), + tiles = {"secret_top.png", "secret_top.png", "secret_side.png", + "secret_side.png", "secret_side.png", "secret_front.png"}, + paramtype2 = "facedir", + groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, +-- Pipeworks + tube = { + insert_object = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:add_item("main", stack) + end, + can_insert = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:room_for_item("main", stack) + end, + input_inventory = "main", + connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} + }, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string("owner", placer:get_player_name() or "") + meta:set_string("infotext", S("@1 (owned by @2)", + S("Secret Chest"), + meta:get_string("owner"))) + end, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", open) + meta:set_string("infotext", S("Secret Chest")) + meta:set_string("owner", "") + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + end, + can_dig = function(pos,player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("main") + end, + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + if not has_locked_chest_privilege(meta, player) then + minetest.log("action", player:get_player_name().. + " tried to access a secret chest belonging to ".. + meta:get_string("owner").." at ".. + minetest.pos_to_string(pos)) + return 0 + end + return count + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if not has_locked_chest_privilege(meta, player) then + minetest.log("action", player:get_player_name().. + " tried to access a secret chest belonging to ".. + meta:get_string("owner").." at ".. + minetest.pos_to_string(pos)) + return 0 + end + return stack:get_count() + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if not has_locked_chest_privilege(meta, player) then + minetest.log("action", player:get_player_name().. + " tried to access a secret chest belonging to ".. + meta:get_string("owner").." at ".. + minetest.pos_to_string(pos)) + return 0 + end + return stack:get_count() + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name().. + " moves stuff in secret chest at "..minetest.pos_to_string(pos)) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name().. + " moves stuff to secret chest at "..minetest.pos_to_string(pos)) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name().. + " takes stuff from secret chest at "..minetest.pos_to_string(pos)) + end, + on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + if has_locked_chest_privilege(meta, sender) then + if fields.open == "open" then + meta:set_string("formspec", open) + else + meta:set_string("formspec", closed) + end + end + end, +}) + +minetest.register_craft({ + output = 'more_chests:secret', + recipe = { + {'default:wood','default:cobble','default:wood'}, + {'default:wood','default:steel_ingot','default:wood'}, + {'default:wood','default:wood','default:wood'} + } +}) diff --git a/shared.lua b/shared.lua new file mode 100644 index 0000000..e100a93 --- /dev/null +++ b/shared.lua @@ -0,0 +1,138 @@ +-- Load support for translation. +local S = minetest.get_translator("more_chests") + +local function has_locked_chest_privilege(meta, player) + local name = player:get_player_name() + local shared = " "..meta:get_string("shared").." " + if name == meta:get_string("owner") then + return true + elseif shared:find(" "..name.." ") then + + return true + else + return false + end +end + +local function get_formspec(string) + return "size[8,10]".. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[current_name;main;0,0.3;8,4;]".. + "list[current_player;main;0,4.85;8,1;]" .. + "list[current_player;main;0,6;8,3;8]" .. + "field[.25,9.5;8,1;shared;"..S("Shared with (separate names with spaces)")..":;"..string.."]".. + "button[6,9.2;2,1;submit;"..S("submit").."]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,4.85) +end + +minetest.register_node("more_chests:shared", { + description = S("Shared Chest"), + tiles = {"shared_top.png", "shared_top.png", "shared_side.png", + "shared_side.png", "shared_side.png", "shared_front.png"}, + paramtype2 = "facedir", + groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, +-- Pipeworks + tube = { + insert_object = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:add_item("main", stack) + end, + can_insert = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:room_for_item("main", stack) + end, + input_inventory = "main", + connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} + }, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string("owner", placer:get_player_name() or "") + meta:set_string("infotext", S("@1 (owned by @2)", + S("Shared Chest"), + meta:get_string("owner"))) + end, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_formspec("")) + meta:set_string("infotext", S("Shared Chest")) + meta:set_string("owner", "") + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + end, + can_dig = function(pos,player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("main") + end, + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + if not has_locked_chest_privilege(meta, player) then + minetest.log("action", player:get_player_name().. + " tried to access a shared chest belonging to ".. + meta:get_string("owner").." at ".. + minetest.pos_to_string(pos)) + return 0 + end + return count + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if not has_locked_chest_privilege(meta, player) then + minetest.log("action", player:get_player_name().. + " tried to access a shared chest belonging to ".. + meta:get_string("owner").." at ".. + minetest.pos_to_string(pos)) + return 0 + end + return stack:get_count() + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if not has_locked_chest_privilege(meta, player) then + minetest.log("action", player:get_player_name().. + " tried to access a shared chest belonging to ".. + meta:get_string("owner").." at ".. + minetest.pos_to_string(pos)) + return 0 + end + return stack:get_count() + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name().. + " moves stuff in shared chest at "..minetest.pos_to_string(pos)) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name().. + " moves stuff to shared chest at "..minetest.pos_to_string(pos)) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name().. + " takes stuff from shared chest at "..minetest.pos_to_string(pos)) + end, + on_receive_fields = function(pos, formspec, fields, sender) + local meta = minetest.get_meta(pos); + if fields.shared then + if meta:get_string("owner") == sender:get_player_name() then + meta:set_string("shared", fields.shared); + meta:set_string("formspec", get_formspec(fields.shared)) + end + end + end, +}) + +minetest.register_craft({ + output = 'more_chests:shared', + recipe = { + {'default:wood','default:leaves','default:wood'}, + {'default:wood','default:steel_ingot','default:wood'}, + {'default:wood','default:wood','default:wood'} + } +}) diff --git a/textures/fridge_front.png b/textures/fridge_front.png deleted file mode 100644 index 3818b7af4d0942b9fdce60ceedb7eae1e6f2cc87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1586 zcmV-22F>}2P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1Y?mg6W4{Ld-&2uR}dI2g=(dxJUt78po^lj-i+ z35mf%NTN!DsPosqRsDkxYu3tGA6#@!<71+UoG=Lb`dmF})1Tu-&%ujatqF!m(98Ae z&Y_H6Nq`mLfvod z{xSu4E(A>`7$dB>HT6#TCv6$3wWThR4ht*9#Vw~1Mq{o$p#?&y4oq#ww>R~aH~NWK z0fV-~9I(NpkITei>5*H~c^2qdZIr%BgM1kV013fRC<$a4W061J1msY%VvVxaI_qt) z(IzL(IP0AAuANcIi#OhS=e-X;`V=IXV1o-jgb+iD90f<1jV^i>LyR#cI888}usT5_ zrGpPS%wZ3A_#+(gNEzvqO}5!(pF@s06)sXx{>2rqN+_|UlTM`4X-<2()1TptXR64x zD%Dh5UG+88Skq!{u=>gxZOr|iH5#ln#!T1q57r>|ewv_moY=-07-K_V+&2c0(A+rF zfsEnCT;ohfMp0M>Yh)Wag&JdE(454!(&FyH+;4eP*8GS!{=}SW)cp8&Rzo4`*`Y7UlbzlA64W(aPI+`j7C8V2DUlGHunPPg^8-;dF>UcK6V-`DUM9(npa z;_%t+s^;A7*dY0zmA=!fFBI@+Wev;e=f3kT0o4D?phu!8^BEZT0H&T_z}Ud%@8EsQ zioI92Y?PDo8rFJSA+$%=Q~Yg-+;#W9n0*QUv5mRtc4hfqEHA8mj$!GFOwlTXT;^Pg z>c>1A{#gC@a8jK~Xl6P(H!abAB=j;+KdA#ZPmwnzq`ua5w?pV%C8{5WvW|||+P6r^ zAJ_Tr7uZfOV2k>p$9TNA;b`j{A*`rV{S(;RQ?spTlIAfn%w>92b=GCzH)|8?`;z7)%Wy@nFV?cVx>Hlt6NrfLC7Pz8EK6>;8=K7rtu>)<_I*!T zmIHY@odPhQ&xhJ`-y`q}{DS3j34n9%ZNX?T2&n7&S3%cxbX`XnhW{P>sNmc8du+E` zMC4b&CtR=Bw_4x#V+Ee1wf;D`UatW##t=mj0BM^3t>AfBYmK!QYb`}la5x-B+zBu^ z{|cW3fQXPJ$s1<^pp+UFwbp2@iQ{-k==F)un?*z<%QC6!TE2xbM!K$(34pbh$Kx?t zoaZ^m)doGs?ZQC-N z&DihvIOkAG(KHQto>Ns7Q521m2#TVRBuO}*&qKD>T7n=LKGf?y_;UvcPN$O?V}?U{ k#bU7-MH zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1b>(!(YU{Ld+R1cZ1VhliQz4SM`8AaLR@`KIkO zo*05bNV_ZHsOzskyZQqkqmxnAh3J#_8Xuc%G8vty*Jrh)?Yzqmy*qE?>O3$QVzj(| z`b*|#jJtb5urglW$5p6eCyJqMSq$>n*`Ooyq8MVc#z}swBO8#@O1S;qMt3Z=bF@DGe+ zoZM&ZCPEL^_Ren)U?Aw%&kJ_Fx7ho&qRZ9;DX%1`9m?!sVgZyqmw8+PUx$8}SHcw$ zVg+LjY!+NqQ6dAhJ6UR!sna#vN);|zbD4nFmH=6H1|z&ze*81H^NLqFh*GM<5Hgn|I2j@^**Faq~pN~ewm>fxG|U;cgzAI)CE&F z@tv1?(T#o~mcgK#Fh>NKby+5gqgz`%d1lOW+A6(LgF+JnfCzg#I718ukPqw#NfC?* zM8GkEpA63pTT{RQIcFNF4sMt|$cbj`jWvPhT;t3dMri>Njy+N(f}squtaZ>&un`){ zj-6G`Iq!mtF1hU4TkpL0!H*i10|y&i@F9d4Qpk~`jV}5aVvH%~WD=uG?ByzifHN_h5-aetjx1suhvn!6)U)w0=5b>E(yCu3 z91A&2qp0Iyv}94AXl|Y&A$`W6@}Sf$kBUaMoNFVB;vCD`yVWaxWb#;}cT3#v0X0X$ zH>YZtR#5PzW#i>h^LxmTR(*_VO|DP^%WQMa-66ScQaZWb7!|h><~%L5+oqKWb-d=t zh3ywmuIL!r?q#)cboCL0DH{r##RjEJvL{nty-Pe(DA7VW4xB?iiTR%{`sGB5dQEmn zYCFNkmb84mBC_o1*ltO5#j!4%cn1)tD$c#EjuhJ(jYgj1jVd05a+mGNKABnC$xwC^ zp&$ca6!pa;0H8nmtab-4TEaooK{QDzf!)h6bDk0DhHc+cG)K-NMOhiwNQDGJ;nq|0D492=`X4#*wio zg`e)^6RRhh_MP~2T=Xw4N)HZ6#%RX-QQr1_eN--8k7GN5liSAbIA+mOZ|?XndW$>3 z;Gnpb4ehAwa7(Re^=Og&E`d^}w3GrA>g}k=HS43%Rcg=NyJfR$Bp+nGKTMS*^X!35 zF`s%b%1^Q0XN1r1b!d3sMT9u9myZ<%e6a>IjlUJ5Bc8hem;?SfHdMMv^M@Kf>DitO z@}0!49AND@MW(a`igY`2^zYABW^+hFZ;Lyjin`C!bB5h2h+CcYNSJn~i4^gtb*9Mh zTXNHH5}?R)`k50GzcCA?v&7qm3?B4*w?W}|b;E_UM|Sp`jp;}}^-{nOFj}W?rPh7n zR_~y{D4^000SaNLh0L01FWS01FWTe`H^g00007bV*G`2jm3;4;3IJZ#6Ce z00JIKL_t(I%Y~E8ZrV^3guinE6aR@Cti&xyt=e_p{|)j2-87p@q^*F2`UjiX7~7`{ z6Q@xYJ*%sGXGU{pbfjs2s_GGABK|k0(}|+UNs>PV!GigG%6Mc}C^bz}aL9B3Pp4A= zJkJ~MvUCf$ROOM@cNv)oQB?&vH!($#<9pWtR8R+U^%3R~QLVYO1m&%Q67O zG=w3H%<9EKrx`FA&d=oScKasGwrPMdoo2m2oO}ad9()}H(sV<8Y6emmh5+pMdu&Jg zynMeGXj_M_n-1W|$DB!ThMQZer%zu{Z4mhYfa$C9(Qfz+#+>NXLd-CztuJJsJ z zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1bvmgOoA{AU%t1cVU7av0C)9lYgt2(a@GIaF4^ z>r7)~0g^(5gc<+*cbfm;=VD04OH3h$VDa$AIWhe|_#Zv7LF+nTYJu(yS}%^N~wuB6ho<&b!HHT=5U)oPXEOw3k^g z?>@pAT`(Uz;|3F3+>@@t`@i5{*4??QhdATT>^}FMxgTGgcR#)O&X&{9&#o{w9D(rS zqtj3F($DuY?nxv1So!HgEjHW7--GYw>}k%itt&pjQ^6dgE>qSM1S?$0YgoV)@h^Ce z>&mziOl&}`1I>!78Or3~?Ma?G6`C|w+o(ZB?}m$LookL)U*hPpYj8iY*Ndi$fT0^s zK&1gSMz_0lp|x&a>orPPxf3KEVKTyqx66Fi`8U@+(VQB(L^j>Nf?iIe25KmBdWRGM zp?Q2N%fIU~4{>83fMp;k%gqS}7F+ieRp=wOc;U>D6YGuLTZ3Xh6Tn4STc8Xv5U_z* zD3FcLMI!hy0iOcR9eY=S0ExIxW&#`L0C1AiwJ|2rl6B&CH>d?b2nUXU1{(!nc`t~c z=o4b72#Yr&5+q8JEG2O8K|%;1DsWVZ9DS4+VvH%~SQ00nB!v`HN;#G6GK0b-ha62# zIpx(n5(mM4g91eXf_rn9p|Th^PsT30)HAw+ozUDl%w#jQ?{ zZJ-U(8=33jrFF6;Z3ug!l3P0;-Rol78hv0`uU)lxB&R8DNGL!6W>e~EU=|+1ssO{2 zv6q-B4!EfeKw97kOvKu4W2MOq=WXFMLmr-0red$2ANu6YqwOSR1Y3IXH#Uf*MX>Ew~6 zv1kM6^GMMJTSv!+*kgxqZ8ffl63V&7u5nU~h6_}TskQ0-c1IiB^Jk%5uF!56wH`xI zYFPnkz3gx-m}{@9_1pLDWOcAFS39z4pcGEk#u+Z<1Gaq0OL?DB2J{u=&_+hi1LnZ6 zrJOBGGf`nsZD5Cx>1vj(^dSWZplVgWqUgIvd@;cMdc-wgN?e@5rF0Mth^^Zh+4dAB zn6!g>P6Pt~G~6+Fa0@h-xsE=IF7tV~owlthb4styj+>9t%|~qZr|`xxT;o!uu3ajRa<6gxmC+mXCWbC-o!8M(y3idG@qgKpAmyJau3dYx#c!JGm z?K8#Mh_Q+}Q=~P620@H7)`>b21*D4_1p@X)Gi9;yXk(5U2dRYhbEysTSF#vYzze@t z;za)`Qr%)YWu&DeXaY=if<-nv6yM)>v#BYlKC3B>qo7Kl3crm&f2)U1VYlcA&QE>6NFE5bu?^6q#$eW3%;6#Vf9cKqB_X~I zFq%YsTy8?OhU6vQQ7d#)b~z@w+{YbI@9Dx^53)Iokd-$WIiuR!1HVbQcWb^Cz*%o+ zLSP+`C2`8%g%i@TE27)EV4EVo$k6BoF;&{NX(i3IYe)XWeZRN8`8Dx;L4IZ|XD;d? z7157RLS2gsI7_e$w}jd9o`%~%6}|F&p55q26hwJVkTftg*&`Tb!bs=pz?154HG`>b zT7z$Dk1$Th>1T6jji1ene@Fgb^PbWkhHHVMdC1}Hg+i=-vV%)(_tJKjN zu`)*Qa-Ngsw=XxZxx!IB0LEYKNU%t73c48%kO=HwE$dFjn`#~^+LCt47PzGNhYBBg z_j(4q@TvT8((%5Z+JBi`GftjmHN6=>J$f6C>jlJr48>*0`KhG)4Ilk(#1{k1 z+lZBPo#r|5BUT(y{D4^000SaNLh0L04^f{ z04^f|c%?sf00007bV*G`2jm3;5)&a2%#s}d00JIKL_t(o!_AjJQxicL#($UGAxOx; zIdUM3!{{hsWN0u29r6kM1X5T~rJ<&zv7xbW{1$!!rK7;YVVFU5Mnz!Y0^DGNpac?% z&FZ?n(4f1YRG)!xiJso;b1=?MT2tvdi1WsPP~N{HdMihsp80sRw1 z4DH3EfeL_;)L7Xqw1xEPK#ywcvhnRqG^d8rp$02m`tBe`QuFQialhz_>yv#30Nb`F z%X?-Z`Rmmm0OYbGb>GfU+^gAVs5LWPUqEE}L$dSgve*>VfTZ1KV-hLRx#}x7`UJbY1w@1Cs%_ zn1PVfa8GBb8Zij*QNifoUFP3!wsgCNMJ_v{RG<=g_35A~CzQ^%Qxt|(LThS^|*LrI}F`|6Y9$e9iv?;Ms8XU2!Yv@&L&jy$`(13|3@W zZaYrsvb@(z$|D#M$G zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1eyax5zj{AU%j1V9MEa(F3Xb}-AI6i{uuZJ#)I zV!GT7MNvGIsg$r=|M|DNf8i5L@-DHITyysLq?&4Ms1$!brwl&r-~EaA5$?aVyVrw= zCPGQ)Hm}>ip`AZokaXMo*LEl4j#KVH!GD>WY-X$9e&r5C@wA6~@9KT8rBBf zJLEST-S)t5?ev-^epylYnEA^Cl+Azse6pSDEUN45uB8l1Wp_9AY-QKbvBQ+KU(2`z zUq)T_RdE$eGl19xnjP10p@s-+Ye->+7Bs9~jxeyq6jv0KF^)*Pt&qeT2h1NR*%dSj zRho_pP#Hjt&>UZD347kU=NqA5<{8j41`HPP#<$D;)cC(#uYpvJx*_=TvK7`9jni0$ zA!onn1wevcoAS2rzT79?_)owR5aeyjSg-b3{N~xvQSP2rw zHCJ)9)LL7^qzywiyxq{FwH`b5)Vb#_z4Y4K0DVRpJo1oHMjdU&NfYir^AtDBth24K zK&6!yue@ZHRaaARO-YloW)&@3wY^ZgsD4E)ydn2z)WSv05KFtCe4vJAk!Ofta>9lg z5Q`}QaWMoy=xCVv5>kqWoMGl`gi~+?YJm-$84NKXm{y3a;f37?a(~3lar#HN#ov%~ z2HpPyIcLya)=-PeW=tnlhC+8|*X z`1Cb&s3vM4s6C5CTL)`IK^_%>TRKI+=?9IG1>Spi!N+W^jL|AcEQvF%=|KbtZ4X`H zei&)Mi`rgMPoP+w2b+{L?{-bTwI)gH(pC%nB+wdhHeO564{Yxk8f(Rx7wK{{=vs>E z7W9QBv^8NCn&qs$*pt0_^*ct|D1uRfvM5C?Eva@_L0JS4f@1;x+7`F&u^FwHzQSHm z0Z}e})!ajsz4KK2#kz!$SJ^zWgk{?g1ITpob$k67R*yn7QnBv1) zFS0?iH|hgYzhKRd=u)D#rX+phuQ&MY?$R}-42y&^N7l(ugE>3KhP!qQw2j=W#%t!- z65=y_xU3HEwn7dO=9n<97!mySgreb+%Y7zMX=dnMNK-(aG%oE76`1LC8)$s-k`GgX zUt^a#AXTQSflAdJ@{D>lpifT-+1e~vIzI+q;Q8gvwNxmSfTL>u)%rmcgn8&qT9{1`M zvOjGSJjfNCD&{7f9fSZlO>j4zvd)CF;%1ga^`iK?o2^Qfz z&N+r(0?Q|bX&v_0wM7h(|5ewx!ua+ zcGiky5|o9*R_?~lHAjF%8BI6h^K9ho&Ux(nnuUg5svi*hIeYWc%6iYIs> zBQdY#--DOKI^nnYV*ts!-IA+_4o@~V!mGECE>`h2hFZY_-pt0iE#)TjjU5O&sXepGc8(AHkF2n~VU z%MHjgEms$h0&R=VFiV5bDq%c*2bv+F?qfUpfoG!clFcUjV%kwjRUF?M1b zL3-O8913~^*TPwH;7GJRC+%c(o83C#EE7laRxSw7xP+oQ&&hp00v@9M??UR0FVHE8B!@t00009a7bBm001r{001r{0eGc9 zb^rhX2XskIMF->s0umn->&h820008%Nkl6zFxcM<0MHi&)MI%KarZNO zK>XBrUxQ;d;hz0`2>|q3p(zLXBQAke{*>N3b_R6rvwG%1WV-+W7_s&=>@1iwzWqRp0{~!JVg7C;4FGsOY$gEY$mE&RY8dG51_1op+5!L+ibWSBQ|gHrIfHwPOBz185QRuo(V)e6BrJ?=U2hf-+X!Zr{Ee@4-`)R z;p;%3wUT`%iC~84fXg=z0Eqen_^zM>3YvkE7@d^Zm3JeswBA7q`_5{Ff{4r zLbJa}0082%HdO}?GL_Gt^a+Y*!%8ZBLX|MO@ta$>cDgL(d7iz}nwhcMyF6WJDFf3- z>E;-qe=c?zxaa<*9-@q&6Pu(zFlh<$4imgM5EW1k_J15&$rN#d^F|5Qrs3FpB*^Wi2zz=}0x-)@5v{M+AURcSZmJV+&ybz>MA6eg?)C z!s1U3gj)qpijz%X<_w9EywIOVR$_wIh3RZwg!YZ`oU z%FQg1lm!6rg`#+NeSiRP^`9fCvil7M)64WjYU|kp_(D!FzgbcQNH<^G?gg|8);2bo_PybbsL@-lSl2a}J8>P+KTewkBb~4!zW@LL M07*qoM6N<$f*72!!{EP) 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 Hu0mjf(Z)It diff --git a/textures/toolbox_front.xcf b/textures/toolbox_front.xcf deleted file mode 100644 index 380ecab2aa2a63ecafe20ec3c1584614afe74c3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17577 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 V{*6{hgLBdOu?pH|l}Kv){{rk>bF%;d diff --git a/textures/toolbox_jungle_front.png b/textures/toolbox_jungle_front.png deleted file mode 100644 index 4d88605c5d354199186bb1a827b67caa135ab797..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2397 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 diff --git a/textures/toolbox_pine_top.png b/textures/toolbox_pine_top.png deleted file mode 100644 index 15a750cf616f89c5c0567834932d8865f2c7cb0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3119 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 JPDHLkV1hAY+noRa diff --git a/textures/toolbox_steel_front.png b/textures/toolbox_steel_front.png deleted file mode 100644 index 0399b0d6b17c0e172aa91311a71e3bcebfac6ea1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2542 zcmV*P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1bxw(BSk{bv+C1O$l3a4?UxdImN8-ol6^KDkxv z-mdt>R?97~KApHM<^6+*W6=YEn6>%Km2zryd2adTcc z40$~L{WFfOUopvP*c+WclS8$-=^$&HN3gAzpm|N z)vd?xkPwW{SkF7-h9_@v&tk>j--<7{p>KX0*{v*$U-?OhEKk&0$JrLHUqiq~37rbS!{Uxu94 zRd8jv*nn6EnisBSsE|XnCk5(MY0_BFMh#mGZn%V}bItiRmVI)?H3Xgzeq1zN^2K-K zGf-(j&12Y|z0k5-mc2$9mODYy5f&rN_;HzUgMV_Jh31shC9?U%3j1=B)7XX}CwFK8 z5SlxtyyCkq^OiUE4OkBZd4)N{!D_F2iHqr#TYll}p~p5DdsBl_-wPl_u+7*Ec_3gT zd8SAmmadpxp;7DQE`NoKuXv>^U*)O|>C-~v7F%k$l~%j!zJvZf_GEhQrPo0N zsWigi5l0$%lu;*gZTcA|&p6Y}v&?!>+o*n`Mi1ov9yQvi31VUCr59=#PDz&_DJLwL z0WlW{h$le+3GD0tLl?r(839DWNo_bcR# zK=*GTX9T*9+)v!Tpw{c^D1HGXER>j9KT+5)C0CcB&@OqRG1>ieK?T1BFPmM;l>+0> zT3$*-2%JjF{>uP6AS{4D#|slqig5Q|lfb zzPkb=(fSeL!8MB5AY}GLSaY3KETHGLHos_R@fuxv`nuL;aU$DUx|6v+np{(>FgAEi zPl4Uik4wL({ zLY>!n`9=|@;8Pr8A}%2`dwVG!Edj{Sd%DRW!~-Gwc&<2o?7V=I<$hfzm_R8`MhHJirsY2S$zo(m7UZL(T^=88}C6CZ{vf1qb0AY}V5(|{(1TV)}z^UfGs@i*2T_O5j&Esj)}d zz>(_KPVrkI@XM5ets!qyJpwX2`<=Y5X{1MF@l{<0Nrp5T2^(x`ur;+`d3zYh*w`gL zE+G^YJ8=ntlxh#(+$zM2B6%YMB3ueczelt6d`+IHAviplPaimOZ0(7O+$&JHWy9tfns;o0VaG#Hs`j!Bv zw?K$8H+%C90H)o}gkO^1mwC}sYD-RWp(*dNqtbI&`78-I zm2vhP_EZArR5AFA}-<$^Xx@4}Dno22_%ERm%9TC>`( ztGnCtslu(s=fPnU7F~n*StCw8(#^M>BKV*6(%LpOF@4uAap>0VBhZzUN%4`v3p{24YJ`L;#NfkN|xdQYlRU000Sa zNLh0L04^f{04^f|c%?sf00007bV*G`2jm3;5-1<+A7G9E00Ra|L_t(o!_8OiN*h5G zJ^P(aXiz~dSPKQ8q`rwL{ZMPg7FwxLXbGaW_)%+VAHb(+U%+2Ng@#0^8+SME?(Fu* z+?nRa{EeIW6LvDQcjnxC&pB(Ho}Lx}&~CTUJ8atq0AyJP0GNF^3jheN0suf5h5&$C ztp)(-bUFY4(=^$y<2V3-G)(~j)Ay%Y91|rETb*!z{xP0DTe_2=M~5dkJ3EsHP?LL~ z8UTRf}~A}?q`u5v;tka@|zg0gxs?R1}zHtz87oH`Mzee$rn;!!!#&K_P`f< zu7|ak%K(6#ozEytL4i~a@Pilz-ycQMh}6K$gBbw8&tD2@d8V728vuaic?^1ufal`d z$q%Gy#vs-=q!d;C+O42*H`ZNLJ^~lNFWAIgbV8ozn4FyCT>t=cbB~4|d~tD^BQP;B z0RUKEf6KZ+<;Za*PuP|Q(`#=6PbR70}+vB%C^1kToa*z+F1U-x%rwSFf}zbFo!Bo zX3AXBemI7s*D6{)Jot(L(%O`fiuhl4>BKeJ1$`zv5H($n|j)Q#+<3<_YWdx_(d&XV~N8hi&*( zpVz?Ampx4?y$q*B#dOG+2r&>!i^M8R1-V^|r8Fbs@^0%5M?fu5BO^wuR^$spK@N#j zObw9>O{pZ{pZYph`rJQM zmuLq=xl>iF9F^je%gamZ2HEFTQb{$h{D+`+F1-f+0k$zyu(?1B`2YX_07*qoM6N<$ Ef|>ra$N&HU diff --git a/textures/toolbox_steel_top.png b/textures/toolbox_steel_top.png deleted file mode 100644 index 21f3e6248ea8cb01cd61f84114e40c1bd0741cbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3007 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 B%g+D+ diff --git a/textures/toolbox_top.xcf b/textures/toolbox_top.xcf deleted file mode 100644 index cb6c4860764fffe944badc4be0c823b44f68d706..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12314 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 Date: Sat, 24 Oct 2020 20:47:43 +0200 Subject: [PATCH 05/12] change wifi tiles back (#15) --- textures/wifi_front.png | Bin 864 -> 0 bytes textures/wifi_front_animated.png | Bin 0 -> 462 bytes textures/wifi_side.png | Bin 833 -> 244 bytes textures/wifi_top.png | Bin 741 -> 239 bytes wifi.lua | 4 +++- 5 files changed, 3 insertions(+), 1 deletion(-) delete mode 100644 textures/wifi_front.png create mode 100644 textures/wifi_front_animated.png diff --git a/textures/wifi_front.png b/textures/wifi_front.png deleted file mode 100644 index eb07ab21cd2d0f2e86680947647bdc12620b7003..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 864 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47>@?{gt!8^3=B*R3_x)fMn)zE zCSC?+eg+l+26kQs4n78M0Y)I=5oF{QV&oNO;uB%w7i9(_0WoF)aTXydRv`%%VJS9Y zDGm`Hc40|&AX`+LO;mNkuOHzSHQh`rWmP<;J8;GQpxTTeOrR8~~mH1>- z_+?ZCW#kzYHHBmq*cFr+l(a--l?3F}h2<1Q1PMHQ9B71czQR3#ME#g$Y=l+`7a)FqYFMO3szRJ0|P zHN=1nRc%2vEeTb1UJWfVHBAY1ZGJ6n84WE-O>J2%9XTM<))my(m)9|r*VU8P)mPBf z6)@71*E5jUGZZw|=QlBsH#Ai?FjX=%mNHdQH8xQ*F;g`)S2s0RF}GB;u#~d3k#;cE zw6@c=vDUV;)3vkHv3D}Gx72lTGX^poZPi>Y)x0fD-JCT1tgPKVH2rKf{jJTsyxro$ zedFT%6M`c%lHCeZqYINto9nYW3rbs>A}3@QPbn{%T9L6hzi) z^mS#w&m+Yr#-#gTc_2_ovcxr_#5q4VH#M(>!MP|ku_QG`p**uBL&4qCHz2%`PaLS| zkEe@ch{WY&kFN%W-wI4We=zy{p~0w zW5WWj)zNKFzI%IodEWkm-J6-!MYv||qFt9R?_RVc#*7 diff --git a/textures/wifi_front_animated.png b/textures/wifi_front_animated.png new file mode 100644 index 0000000000000000000000000000000000000000..77bcb445e079bfeee19427bc467930578535a95e GIT binary patch literal 462 zcmV;<0WtoGP)N-6{J+j zP}kAn5!+I{qgO8Ha;B}t+gJY|KavH`j58lLsaU3>^)AYQ~gJqeab-yvd=c+u2WgP2&U*bevodkqijh6km3 z&-Djfx7r`lmN4%>V!Z07*qoM6N<$ Eg1gqr*Z=?k literal 0 HcmV?d00001 diff --git a/textures/wifi_side.png b/textures/wifi_side.png index f48a4660d9c42b4881b07ba299f16c82d55517eb..f58fae953ab70fc10aa8eec832df4074db24e485 100644 GIT binary patch delta 227 zcmX@e_JwhRWIY=L1B3kM|A|0~Ey>&61xN$IPv_nBK#H@#BeIx*f$sobP^i(<#WBR<^wQviybOvQ&PB>QSd%T+tuA4IU&_X*C0>!4 zvoJtM$w)(xUodd3DGS?%1V({s1%~iX;xTVRHyx0@=_`<%er~~5x0Q?Yw7(8A5T-G@yGywq1BTn7` literal 833 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47&iy_gt!7}1_q!Y3j-Su13NDR z2Ok5sAOp7$Bewtpj}Rk|AR~wrW&)DDKqSn>E5rmO`G81-nNNg?UzC|&l$BqYSwNIo zK#W;HoK--CSx}r=P=ZZRoJB~IRY-zWNRk~$3QMvIOR)<}u!%^siO6t>NU@2^u!~A_ zh)S}H%5VUY7!b*F14(f?PH{P2aT!htc`hK5RN$AC<&~1=mQv)FQsR|T;Feb6kx}N8 zk>i(<6_k1c&{)~nSjEIp#l%$A)I!V5Let7x!`fEY)=t;n z$;i>lz{$nT$;r^g&D6!g(ACq#)zRF=+1$<9#NFN8%h}S)&BDva!Nb$a+s!#3&?zv` zKE%f@CNv@=E;chIGA};1ATG5ktDvSLyDdMrvmm>xaQgDaTs-%00%MUe$=lt9p@UV{ z1IXbl@Q5sCVBi)8VMc~ob0mO*>?NMQuI%@Dr1-=o_sxs{0~C@hag8W(&d<$F%`0JW zE=o--Nlj5G&n(GMaQE~L2yf&Q2P%5+>Eak7aXI+}$5-A?j?&()4}9GmAA38}IM%+& z*UgwQA?!|g^sQ^r?+yvX+=!eSd1dZ|>r?06zBKvWQGppZ0_RS-HANs^aC*??c`pwp zyt^<%^oiW-#{w^(Opg&tK69XzO=5?|0TcEa&mKHVPS_|UEG8zh>FE}c$wB7AsVNB? zMTEl)lAmug3^p_|7EMb@5ET;(D_E1fd5Y*Y!ztStIVDz}%rM#9$tkVb#pT_^;^R|N z^4j$0T+t&TZyTZ_woKvm^(j76aY(ggEAy5Hre%58+^QI@ax}e^R?Yk6pj-6wU(uy+ nOlMNr_B;}E;^FbhU|{f?V0`n7+@g4(*BLxr{an^LB{Ts5D5lR? diff --git a/textures/wifi_top.png b/textures/wifi_top.png index 2e107d7b1e9dd0a175b1b031b1a39490e182e8bb..35c01d0f9d8deb6111caffde111a447368384271 100644 GIT binary patch delta 222 zcmaFL`krxuWIY=L1B3kM|A|0~Ey>&61xN$IPv_nBK#H@#BeIx*f$sg9_(5}p^Q{(D)i`QT*j!kTyIFKcZ+RhTMSX>lUwxb^(kC)1^LH+&3n|H<^M(EAe` SH$y(qAq<|belF{r5}E)c;Zz_1 delta 728 zcmaFQ_>^^mWIZzj1A~Sxe=q|Bqf3BKh^x4Qnz*8xgrd5HlDed_hLnn?lqwKuNdu9Z zmW;Z#oQAHFzKN=liHeDtnu(dZnT49UmAbj5y1BK6g_WkIwWg(wrj@m(m5mkpD25& z7d=O3Jx3Q^Cs#cu7kwvZeGutt0Ajf5JGmPGNoQAmXEy_9R|97^BWFhgXLmzq4+9r> z0~ZfN7Y_qhcS8{JFm&}a0+Md-hHf6lZmx#z9)|9oM(!R)_3oa=?p`MDo@VauMjl?q z9-gKiZYCaHCZ0g#ZRY82>gi?f>2BraZ4=;a7vy6flEVW7!l$Y5#Svk=9w7n zof_kl789AC5t1Drl9N!<(rnn&21s-{+Cy6Sw&E-G32KOtQo^qQp5rH#aq}gu%HeHL)Z$MWH;iBtya7(>EZz zkxv|GGLxr^V~E6M(R0t8nhhjcA3AtwMuBXfgsnK%Slz$t`rrTN zaR)xnYi<+W>%nCe_?sipbZN_n1K0QN{bjqU{)=^Xo-Kb;%e_3wil2SOZ<)^6dwEpd zD$o*Gw&gWjW4XF=%-3A*RhhPYi%!fx$Z+rL0_o7Zo#0&P$U!9tD@Rtm0!q09M zk69+Q6Sr#fJ&&Wglyw+-4~^=cLEJCs#}s-jOxp;r@4W zOa5){-l#y!MWXt%4tVV2{CiXr@-d#6m s!{7G69Gth4;&3fPu!~>FVdQ&MBb@04-Vd#sB~S diff --git a/wifi.lua b/wifi.lua index 8345ef7..4f795a2 100644 --- a/wifi.lua +++ b/wifi.lua @@ -4,7 +4,9 @@ local S = minetest.get_translator("more_chests") minetest.register_node("more_chests:wifi", { description = S("Wifi Chest"), tiles = {"wifi_top.png", "wifi_top.png", "wifi_side.png", - "wifi_side.png", "wifi_side.png", "wifi_front.png"}, + "wifi_side.png", "wifi_side.png", + {name="wifi_front_animated.png", animation={type="vertical_frames", + aspect_w=16, aspect_h=16, length=2.0}}}, paramtype2 = "facedir", groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,}, legacy_facedir_simple = true, From cac8cddc6629e511ec04210a84fb9369d987da5b Mon Sep 17 00:00:00 2001 From: DS Date: Sun, 25 Oct 2020 12:24:03 +0100 Subject: [PATCH 06/12] make the wifi chest pipeworkable (#16) * Make the wifi chest pipeworkable * fix mod crashing without pipeworks --- mod.conf | 1 + wifi.lua | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/mod.conf b/mod.conf index 0d4e2e2..e125a6b 100644 --- a/mod.conf +++ b/mod.conf @@ -1,3 +1,4 @@ name = more_chests description = Adds several chests that behave differently, and can be used to donate items, share items, hide chests, make secret chests, and more. depends = default +optional_depends = pipeworks diff --git a/wifi.lua b/wifi.lua index 4f795a2..84534a9 100644 --- a/wifi.lua +++ b/wifi.lua @@ -1,6 +1,8 @@ -- Load support for translation. local S = minetest.get_translator("more_chests") +local pipeworks_enabled = minetest.global_exists("pipeworks") + minetest.register_node("more_chests:wifi", { description = S("Wifi Chest"), tiles = {"wifi_top.png", "wifi_top.png", "wifi_side.png", @@ -8,7 +10,46 @@ minetest.register_node("more_chests:wifi", { {name="wifi_front_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}}, paramtype2 = "facedir", - groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,}, + groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, + -- Pipeworks + tube = pipeworks_enabled and { + insert_object = function(pos, node, stack, direction, owner) + if not owner then + return stack + end + local player = minetest.get_player_by_name(owner) + if not player then + return stack + end + local inv = player:get_inventory() + return inv:add_item("more_chests:wifi", stack) + end, + can_insert = function(pos, node, stack, direction, owner) + if not owner then + return false + end + local player = minetest.get_player_by_name(owner) + if not player then + return false + end + local inv = player:get_inventory() + return inv:room_for_item("more_chests:wifi", stack) + end, + input_inventory = "more_chests:wifi", + return_input_invref = function(pos, node, direction, player_name) + if not player_name then + return false + end + local player = minetest.get_player_by_name(player_name) + if not player then + return false + end + return player:get_inventory() + end, + connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} + } or nil, + after_place_node = pipeworks_enabled and pipeworks.after_place or nil, + after_dig_node = pipeworks_enabled and pipeworks.after_dig or nil, legacy_facedir_simple = true, sounds = default.node_sound_wood_defaults(), on_construct = function(pos) From 886108a1af1b553867cc23a946e40d13b8891a9a Mon Sep 17 00:00:00 2001 From: nxet Date: Thu, 8 Oct 2020 11:17:51 +0200 Subject: [PATCH 07/12] Mod rewrite and new models (#21) * Aliases moved to utils folder * Method to generate two different formspec layouts, big and small * Log Actions moved to separate module * Added method to generate a chest definition * Rewritten models * Add Fridge model * Add Toolbox models * "Mod loaded" message; Updated localization template * Add Italian localization * Fridge now has both normal and big (2 blocks) models * Fixed mixed indentation * Rewritten README; improved IT and FR (thanks to @louisroyer) localizations. --- README.md | 99 ++++++++++++++------- cobble.lua | 115 ------------------------- dropbox.lua | 113 ------------------------ init.lua | 16 ++-- locale/more_chests.fr.tr | 10 ++- locale/more_chests.it.tr | 17 ++++ locale/template.txt | 17 +++- models/cobble.lua | 26 ++++++ models/dropbox.lua | 45 ++++++++++ models/fridge.lua | 50 +++++++++++ models/secret.lua | 54 ++++++++++++ models/shared.lua | 72 ++++++++++++++++ models/toolbox.lua | 34 ++++++++ models/wifi.lua | 34 ++++++++ secret.lua | 132 ---------------------------- shared.lua | 138 ------------------------------ textures/fridge_front.png | Bin 0 -> 1586 bytes textures/fridge_side.png | Bin 0 -> 2066 bytes textures/toolbox_acacia_front.png | Bin 0 -> 2562 bytes textures/toolbox_acacia_top.png | Bin 0 -> 3226 bytes textures/toolbox_aspen_front.png | Bin 0 -> 2171 bytes textures/toolbox_aspen_top.png | Bin 0 -> 2857 bytes textures/toolbox_front.xcf | Bin 0 -> 17577 bytes textures/toolbox_jungle_front.png | Bin 0 -> 2397 bytes textures/toolbox_jungle_top.png | Bin 0 -> 2860 bytes textures/toolbox_pine_front.png | Bin 0 -> 2478 bytes textures/toolbox_pine_top.png | Bin 0 -> 3119 bytes textures/toolbox_steel_front.png | Bin 0 -> 2542 bytes textures/toolbox_steel_top.png | Bin 0 -> 3007 bytes textures/toolbox_top.xcf | Bin 0 -> 12314 bytes textures/toolbox_wood_front.png | Bin 0 -> 2413 bytes textures/toolbox_wood_top.png | Bin 0 -> 3088 bytes utils/actions.lua | 90 +++++++++++++++++++ aliases.lua => utils/aliases.lua | 0 utils/base.lua | 97 +++++++++++++++++++++ utils/formspec.lua | 38 ++++++++ 36 files changed, 655 insertions(+), 542 deletions(-) delete mode 100644 cobble.lua delete mode 100644 dropbox.lua create mode 100644 locale/more_chests.it.tr create mode 100644 models/cobble.lua create mode 100644 models/dropbox.lua create mode 100644 models/fridge.lua create mode 100644 models/secret.lua create mode 100644 models/shared.lua create mode 100644 models/toolbox.lua create mode 100644 models/wifi.lua delete mode 100644 secret.lua delete mode 100644 shared.lua create mode 100644 textures/fridge_front.png create mode 100644 textures/fridge_side.png create mode 100644 textures/toolbox_acacia_front.png create mode 100644 textures/toolbox_acacia_top.png create mode 100644 textures/toolbox_aspen_front.png create mode 100644 textures/toolbox_aspen_top.png create mode 100644 textures/toolbox_front.xcf create mode 100644 textures/toolbox_jungle_front.png create mode 100644 textures/toolbox_jungle_top.png create mode 100644 textures/toolbox_pine_front.png create mode 100644 textures/toolbox_pine_top.png create mode 100644 textures/toolbox_steel_front.png create mode 100644 textures/toolbox_steel_top.png create mode 100644 textures/toolbox_top.xcf create mode 100644 textures/toolbox_wood_front.png create mode 100644 textures/toolbox_wood_top.png create mode 100644 utils/actions.lua rename aliases.lua => utils/aliases.lua (100%) create mode 100644 utils/base.lua create mode 100644 utils/formspec.lua diff --git a/README.md b/README.md index d5dc1f1..9bc7c6c 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,80 @@ -more_chests -=========== +# more_chests +Originally a fork of 0gb.us's chests_0gb_us (https://forum.minetest.net/viewtopic.php?f=11&t=4366). +Megaf's more_chests fixes several bugs, uses new textures and adds compatibility with [VanessaE's Pipeworks] (https://github.com/VanessaE/pipeworks) mod. +nxet's rework introduces a new backend which allows for easier extension of the available models, including two new models showcasing the feature. -More Chests -This mod is a fork of 0gb.us's chests_0gb_us https://forum.minetest.net/viewtopic.php?f=11&t=4366 +### Available models +> NOTE: descriptions of the original models come from 0gb.us initial effort -Megaf's more_chests fixes several bugs, uses new textures and adds compatibility with [VanessaE's Pipeworks] (https://github.com/VanessaE/pipeworks) mod. +#### Cobble Chest +This locked chest looks like cobblestone, and has no info text. Great for hiding things in. However, unlike real cobblestone, this chest is breakable by hand. If you suspect there is one hiding, hold the left mouse button and run your hand along the walls. When cracks appear, you've found the chest. +1 | 2 | 3 +---|---|--- +default:wood | default:cobble | default:wood +default:cobble | default:steel_ingot | default:cobble +default:wood | default:cobble | default:wood -The following text was writen by 0gb.us -``` -Cobble Chest: -{'default:wood','default:cobble','default:wood'}, -{'default:cobble','default:steel_ingot','default:cobble'}, -{'default:wood','default:cobble','default:wood'} - -This locked chest looks like cobblestone, and has no info text. Great for hiding things in. However, unlike real cobblestone, this chest is breakable by hand. If you suspect there is one hiding, Hold the left mouse button, ant run your hand along the walls. When cracks appear, you've found the chest. - -Drop Box: -{'default:wood','','default:wood'}, -{'default:wood','default:steel_ingot','default:wood'}, -{'default:wood','default:wood','default:wood'} +#### Drop Box Anyone can put things in, but only the chest's placer can remove items. +1 | 2 | 3 +---|---|--- +default:wood | _empty_ | default:wood +default:wood | default:steel_ingot | default:wood +default:wood | default:wood | default:wood -Secret Chest: -{'default:wood','default:cobble','default:wood'}, -{'default:wood','default:steel_ingot','default:wood'}, -{'default:wood','default:wood','default:wood'} -As long as you remember to click “close” before you leave the chest, no one can see what the chest contains. Only the chest's owner can click “open” and “close” on the chest's formspec, revealing and hiding the chest's contents. +#### Secret Chest +As long as you remember to click "close" before you leave the chest, no one can see what the chest contains. Only the chest's owner can click "open" and "close" on the chest's formspec, revealing and hiding the chest's contents. +1 | 2 | 3 +---|---|--- +default:wood | default:cobble | default:wood +default:wood | default:steel_ingot | default:wood +default:wood | default:wood | default:wood -Shared Chest: -{'default:wood','default:leaves','default:wood'}, -{'default:wood','default:steel_ingot','default:wood'}, -{'default:wood','default:wood','default:wood'} +#### Shared Chest Exactly what it sounds like. The chest's placer can add people to the chest's shared list using the chest's formspec. Warning: anyone you add may empty the chest. When the chest is empty, it can be mined by anyone, just like a regular locked chest. +1 | 2 | 3 +---|---|--- +default:wood | default:leaves | default:wood +default:wood | default:steel_ingot | default:wood +default:wood | default:wood | default:wood -Wifi Chest - -{'default:wood','default:mese','default:wood'}, -{'default:wood','default:steel_ingot','default:wood'}, -{'default:wood','default:wood','default:wood'} +#### Wifi Chest A wacky chest that doesn't store it's items in the usual way, but instead, stores them remotely. For that reason, all wifi chests appear to have the same inventory. Due to not actually having an inventory, wifi chests can also be mined, even when they appear to have stuff in them. Lastly, as everyone gets their own wifi account, the items you see in the wifi chest are not the same items anyone else sees. This chest's properties make it nice for keeping secrets, as well as essentially almost doubling your inventory space, if you choose to carry one with you. -``` +1 | 2 | 3 +---|---|--- +default:wood | default:mese | default:wood +default:wood | default:steel_ingot | default:wood +default:wood | default:wood | default:wood + + +#### Fridge +A new model which comes in two forms, 1- and 2-block tall, which indeed have different sizes inventories. No fancy functionality here, I just wanted to know at a glance which one is the chest I'm storing food into. + +###### Fridge Recipe +1 | 2 | 3 +---|---|--- +_empty_ | default:steel_ingot | _empty_ +default:steel_ingot | default:ice | default:steel_ingot +_empty_ | default:steel_ingot | _empty_ + +###### Big Fridge Recipe +1 | 2 | 3 +---|---|--- +default:steel_ingot | default:steel_ingot | default:steel_ingot +default:steel_ingot | default:ice | default:steel_ingot +default:steel_ingot | default:steel_ingot | default:steel_ingot + + +#### Toolbox +This model has no particular functionality to offer other than giving your tools' chest a new look. As a bonus you can also craft the chest with different types of wood, which will give you different results. For the fanciest garage workshop you ever built on Minetest. +1 | 2 | 3 +---|---|--- +default:wood | default:wood | default:wood +default:wood | default:pickaxe | default:wood +default:wood | default:wood | default:wood +> Note: crafting also accepts Aspen, Acacia, Junglewood, Pine and Steel instead of wood diff --git a/cobble.lua b/cobble.lua deleted file mode 100644 index 6bb2c4c..0000000 --- a/cobble.lua +++ /dev/null @@ -1,115 +0,0 @@ --- Load support for translation. -local S = minetest.get_translator("more_chests") - -local function has_locked_chest_privilege(meta, player) - if player:get_player_name() ~= meta:get_string("owner") then - return false - end - return true -end - -minetest.register_node("more_chests:cobble", { - description = S("Cobble Chest"), - tiles = {"default_cobble.png", "default_cobble.png", "default_cobble.png", - "default_cobble.png", "default_cobble.png", "cobblechest_front.png"}, - paramtype2 = "facedir", - groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, --- First attempt to add a way to connect to pipeworks. - tube = { - insert_object = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:add_item("main", stack) - end, - can_insert = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:room_for_item("main", stack) - end, - input_inventory = "main", - connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} - }, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - after_place_node = function(pos, placer) - local meta = minetest.get_meta(pos) - meta:set_string("owner", placer:get_player_name() or "") - - end, - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec", - "size[8,9]".. - default.gui_bg .. - default.gui_bg_img .. - default.gui_slots .. - "list[current_name;main;0,0.3;8,4;]".. - "list[current_player;main;0,4.85;8,1;]" .. - "list[current_player;main;0,6.08;8,3;8]" .. - "listring[current_name;main]".. - "listring[current_player;main]" .. - default.get_hotbar_bg(0,4.85)) - meta:set_string("owner", "") - local inv = meta:get_inventory() - inv:set_size("main", 8*4) - end, - can_dig = function(pos,player) - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory() - return inv:is_empty("main") - end, - allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a locked chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return count - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a locked chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return stack:get_count() - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a locked chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return stack:get_count() - end, - on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in locked chest at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to locked chest at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from locked chest at "..minetest.pos_to_string(pos)) - end, -}) - -minetest.register_craft({ - output = 'more_chests:cobble', - recipe = { - {'default:wood','default:cobble','default:wood'}, - {'default:cobble','default:steel_ingot','default:cobble'}, - {'default:wood','default:cobble','default:wood'} - } -}) diff --git a/dropbox.lua b/dropbox.lua deleted file mode 100644 index a8f16de..0000000 --- a/dropbox.lua +++ /dev/null @@ -1,113 +0,0 @@ --- Load support for translation. -local S = minetest.get_translator("more_chests") -local DS = minetest.get_translator("default") - -local function has_locked_chest_privilege(meta, player) - if player:get_player_name() ~= meta:get_string("owner") then - return false - end - return true -end - -minetest.register_node("more_chests:dropbox", { - description = S("Dropbox"), - tiles = {"dropbox_top.png", "dropbox_top.png", "dropbox_side.png", - "dropbox_side.png", "dropbox_side.png", "dropbox_front.png"}, - paramtype2 = "facedir", - groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, --- Pipeworks - tube = { - insert_object = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:add_item("main", stack) - end, - can_insert = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:room_for_item("main", stack) - end, - input_inventory = "main", - connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} - }, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - after_place_node = function(pos, placer) - local meta = minetest.get_meta(pos) - meta:set_string("owner", placer:get_player_name() or "") - meta:set_string("infotext", S("@1 (owned by @2)", - S("Dropbox"), - meta:get_string("owner"))) - end, - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec", - "size[8,9]".. - default.gui_bg .. - default.gui_bg_img .. - default.gui_slots .. - "list[current_name;main;0,0.3;8,4;]".. - "list[current_player;main;0,4.85;8,1;]" .. - "list[current_player;main;0,6.08;8,3;8]" .. - "listring[current_name;main]" .. - "listring[current_player;main]" .. - default.get_hotbar_bg(0,4.85)) - meta:set_string("infotext", DS("Chest")) - local inv = meta:get_inventory() - inv:set_size("main", 8*4) - end, - can_dig = function(pos,player) - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory() - return inv:is_empty("main") - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a dropbox belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return stack:get_count() - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if has_locked_chest_privilege(meta, player) then - return stack:get_count() - end - local target = meta:get_inventory():get_list(listname)[index] - local target_name = target:get_name() - local stack_count = stack:get_count() - if target_name == stack:get_name() - and target:get_count() < stack_count then - return stack_count - end - if target_name ~= "" then - return 0 - end - return stack_count - end, - on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in dropbox at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to dropbox at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from dropbox at "..minetest.pos_to_string(pos)) - end, -}) - -minetest.register_craft({ - output = 'more_chests:dropbox', - recipe = { - {'default:wood','','default:wood'}, - {'default:wood','default:steel_ingot','default:wood'}, - {'default:wood','default:wood','default:wood'} - } -}) diff --git a/init.lua b/init.lua index 5b161ec..b1e85a0 100644 --- a/init.lua +++ b/init.lua @@ -1,7 +1,11 @@ -dofile(minetest.get_modpath("more_chests").."/cobble.lua") -dofile(minetest.get_modpath("more_chests").."/dropbox.lua") -dofile(minetest.get_modpath("more_chests").."/secret.lua") -dofile(minetest.get_modpath("more_chests").."/shared.lua") -dofile(minetest.get_modpath("more_chests").."/wifi.lua") -dofile(minetest.get_modpath("more_chests").."/aliases.lua") +dofile(minetest.get_modpath("more_chests").."/models/cobble.lua") +dofile(minetest.get_modpath("more_chests").."/models/dropbox.lua") +dofile(minetest.get_modpath("more_chests").."/models/fridge.lua") +dofile(minetest.get_modpath("more_chests").."/models/secret.lua") +dofile(minetest.get_modpath("more_chests").."/models/shared.lua") +dofile(minetest.get_modpath("more_chests").."/models/toolbox.lua") +dofile(minetest.get_modpath("more_chests").."/models/wifi.lua") +dofile(minetest.get_modpath("more_chests").."/utils/aliases.lua") + +print ("[MOD] more_chests loaded") diff --git a/locale/more_chests.fr.tr b/locale/more_chests.fr.tr index 1fe8fa1..002f8d9 100644 --- a/locale/more_chests.fr.tr +++ b/locale/more_chests.fr.tr @@ -1,11 +1,17 @@ # textdomain: more_chests Cobble Chest=Coffre en pierre taillée Dropbox=Boîte de dépôt +Fridge=Réfrigérateur +Big Fridge=Grand réfrigérateur Secret Chest=Coffre secret Shared Chest=Coffre partagé Wifi Chest=Coffre wifi - - +Wooden Toolbox=Boîte à outils en bois +Aspen Wood Toolbox=Boîte à outils en bois de tremble +Acacia Wood Toolbox=Boîte à outils en bois d’acacia +Junglewood Toolbox=Boîte à outils en bois de la jungle +Pine Wood Toolbox=Boîte à outils en bois de pin +Steel Toolbox=Boîte à outils en acier @1 (owned by @2)=@1 (appartient à @2) Shared with (separate names with spaces)=Partagé avec (séparez les noms avec des espaces) submit=valider diff --git a/locale/more_chests.it.tr b/locale/more_chests.it.tr new file mode 100644 index 0000000..740616e --- /dev/null +++ b/locale/more_chests.it.tr @@ -0,0 +1,17 @@ +# textdomain: more_chests +Cobble Chest=Baule in ciottoli +Dropbox=Baule Donazioni +Fridge=Frigorifero +Big Fridge=Frigorifero Grande +Secret Chest=Baule Segreto +Shared Chest=Baule Condiviso +Wifi Chest=Baule WiFi +Wooden Toolbox=Scatola degli attrezzi in legno +Aspen Wood Toolbox=Scatola degli attrezzi in legno di pioppo +Acacia Wood Toolbox=Scatola degli attrezzi in legno di acacia +Junglewood Toolbox=Scatola degli attrezzi in legno di jungla +Pine Wood Toolbox=Scatola degli attrezzi in legno di pino +Steel Toolbox=Scatola degli attrezzi in acciaio +@1 (owned by @2)=@1 (di proprietà di @2) +Shared with (separate names with spaces)=Condiviso con (separa i nomi con degli spazi) +submit=invia diff --git a/locale/template.txt b/locale/template.txt index d95f7b1..5784d43 100644 --- a/locale/template.txt +++ b/locale/template.txt @@ -1,6 +1,17 @@ # textdomain: more_chests -Secret Chest= -Wifi Chest= Cobble Chest= -Shared Chest= Dropbox= +Fridge= +Big Fridge= +Secret Chest= +Shared Chest= +Wifi Chest= +Wooden Toolbox= +Aspen Wood Toolbox= +Acacia Wood Toolbox= +Junglewood Toolbox= +Pine Wood Toolbox= +Steel Toolbox= +@1 (owned by @2)= +Shared with (separate names with spaces)= +submit= diff --git a/models/cobble.lua b/models/cobble.lua new file mode 100644 index 0000000..2a568fa --- /dev/null +++ b/models/cobble.lua @@ -0,0 +1,26 @@ +local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") +local S = minetest.get_translator("more_chests") + +local cobble = gen_def({ + description = S("Cobble Chest"), + type = "chest", + size = "small", + tiles = { + top = "default_cobble.png", + side = "default_cobble.png", + front = "cobblechest_front.png" + }, + pipeworks_enabled = true, + recipe = { + {"group:wood", "default:cobble", "group:wood"}, + {"default:cobble", "default:steel_ingot", "default:cobble"}, + {"group:wood", "default:cobble", "group:wood"} + }, +}) + + +minetest.register_node("more_chests:cobble", cobble) +minetest.register_craft({ + output = "more_chests:cobble", + recipe = cobble.recipe, +}) diff --git a/models/dropbox.lua b/models/dropbox.lua new file mode 100644 index 0000000..94da127 --- /dev/null +++ b/models/dropbox.lua @@ -0,0 +1,45 @@ +local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") +local actions = dofile(minetest.get_modpath("more_chests") .. "/utils/actions.lua") +local S = minetest.get_translator("more_chests") + +local dropbox = gen_def({ + description = S("Dropbox"), + type = "dropbox", + size = "small", + tiles = { + top = "dropbox_top.png", + side = "dropbox_side.png", + front = "dropbox_front.png" + }, + pipeworks_enabled = true, + recipe = { + {"group:wood", "", "group:wood"}, + {"group:wood", "default:steel_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"} + }, + allow_metadata_inventory_move = false, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if actions.has_locked_chest_privilege(meta, player) then + return stack:get_count() + end + local target = meta:get_inventory():get_list(listname)[index] + local target_name = target:get_name() + local stack_count = stack:get_count() + if target_name == stack:get_name() + and target:get_count() < stack_count then + return stack_count + end + if target_name ~= "" then + return 0 + end + return stack_count + end +}) + + +minetest.register_node("more_chests:dropbox", dropbox) +minetest.register_craft({ + output = "more_chests:dropbox", + recipe = dropbox.recipe, +}) diff --git a/models/fridge.lua b/models/fridge.lua new file mode 100644 index 0000000..4600d68 --- /dev/null +++ b/models/fridge.lua @@ -0,0 +1,50 @@ +local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") +local S = minetest.get_translator("more_chests") + +-- TODO model open + +local fridge = gen_def({ + description = S("Fridge"), + type = "fridge", + size = "small", + tiles = { + side = "fridge_side.png", + front = "fridge_front.png", + }, + recipe = { + {"", "default:steel_ingot", ""}, + {"default:steel_ingot", "default:ice", "default:steel_ingot"}, + {"", "default:steel_ingot", ""} + }, +}) + +minetest.register_node("more_chests:fridge", fridge) +minetest.register_craft({ + output = "more_chests:fridge", + recipe = fridge.recipe, +}) + + +local big_fridge = gen_def({ + description = S("Big Fridge"), + type = "fridge", + size = "big", + node_box = { + {-0.5, -0.5, -0.5, 0.5, 1.5, 0.5}, + }, + tiles = { + side = "fridge_side.png", + front = "fridge_front.png", + }, + recipe = { + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "default:ice", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} + }, +}) + +minetest.register_node("more_chests:big_fridge", big_fridge) +minetest.register_craft({ + output = "more_chests:big_fridge", + recipe = big_fridge.recipe, +}) diff --git a/models/secret.lua b/models/secret.lua new file mode 100644 index 0000000..2536694 --- /dev/null +++ b/models/secret.lua @@ -0,0 +1,54 @@ +local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") +local actions = dofile(minetest.get_modpath("more_chests") .. "/utils/actions.lua") +local S = minetest.get_translator("more_chests") + +local open = "size[8,10]".. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[current_name;main;0,0.3;8,4;]" .. + "list[current_player;main;0,4.85;8,1;]" .. + "list[current_player;main;0,6.08;8,3;8]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. + "button[3,9;2,1;open;close]" .. + default.get_hotbar_bg(0,4.85) + +local closed = "size[2,1]" .. + "button[0,0;2,1;open;open]" + +local secret = gen_def({ + description = S("Secret Chest"), + type = "secret chest", + size = "small", + tiles = { + top = "secret_top.png", + side = "secret_side.png", + front = "secret_front.png" + }, + formspec = open, + pipeworks_enabled = true, + recipe = { + {"group:wood", "default:cobble", "group:wood"}, + {"group:wood", "default:steel_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"} + }, +}) + +secret.on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + if actions.has_locked_chest_privilege(meta, sender) then + if fields.open == "open" then + meta:set_string("formspec", open) + else + meta:set_string("formspec", closed) + end + end +end + + +minetest.register_node("more_chests:secret", secret) +minetest.register_craft({ + output = "more_chests:secret", + recipe = secret.recipe, +}) diff --git a/models/shared.lua b/models/shared.lua new file mode 100644 index 0000000..b4272fa --- /dev/null +++ b/models/shared.lua @@ -0,0 +1,72 @@ +local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") +local actions = dofile(minetest.get_modpath("more_chests") .. "/utils/actions.lua") +local S = minetest.get_translator("more_chests") + +local function get_formspec(string) + return "size[8,10]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[current_name;main;0,0.3;8,4;]" .. + "list[current_player;main;0,4.85;8,1;]" .. + "list[current_player;main;0,6;8,3;8]" .. + "field[.25,9.5;8,1;shared;" .. + S("Shared with (separate names with spaces)") .. + ":;" .. string .. "]" .. + "button[6,9.2;2,1;submit;" .. + S("submit") .. "]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,4.85) +end + +local function check_privs(meta, player) + local name = player:get_player_name() + local shared = " " .. meta:get_string("shared") .. " " + if name == meta:get_string("owner") then + return true + elseif shared:find(" " .. name .. " ") then + return true + else + return false + end +end + +local shared = gen_def({ + description = S("Shared Chest"), + type = "shared chest", + size = "small", + tiles = { + top = "shared_top.png", + side = "shared_side.png", + front = "shared_front.png" + }, + formspec = get_formspec(""), + pipeworks_enabled = true, + sounds = default.node_sound_wood_defaults(), + recipe = { + {"group:wood", "default:leaves", "group:wood"}, + {"group:wood", "default:steel_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"} + }, + allow_metadata_inventory_move = actions.get_allow_metadata_inventory_move{"shared chest", check_privs=check_privs}, + allow_metadata_inventory_put = actions.get_allow_metadata_inventory_put{"shared chest", check_privs=check_privs}, + allow_metadata_inventory_take = actions.get_allow_metadata_inventory_take{"shared chest", check_privs=check_privs}, +}) + +shared.on_receive_fields = function(pos, formspec, fields, sender) + local meta = minetest.get_meta(pos); + if fields.shared then + if meta:get_string("owner") == sender:get_player_name() then + meta:set_string("shared", fields.shared) + meta:set_string("formspec", get_formspec(fields.shared)) + end + end +end + + +minetest.register_node("more_chests:shared", shared) +minetest.register_craft({ + output = "more_chests:shared", + recipe = shared.recipe, +}) diff --git a/models/toolbox.lua b/models/toolbox.lua new file mode 100644 index 0000000..3b72476 --- /dev/null +++ b/models/toolbox.lua @@ -0,0 +1,34 @@ +local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") +local S = minetest.get_translator("more_chests") + +local function register_toolbox(description, type, side_tile, recipe) + local def = gen_def({ + description = description, + type = "toolbox", + size = "big", + -- node_box = {-0.5, -0.5, -0.5, 1.5, 0.5, 0.5}, -- makes it two blocks wide + tiles = { + side = side_tile, + front = "toolbox_" .. type .. "_front.png", + top = "toolbox_" .. type .. "_top.png", + }, + recipe = recipe, + }) + minetest.register_node("more_chests:toolbox_" .. type, def) +end + +local function gen_recipe(craft_item) + return { + {craft_item, craft_item, craft_item}, + {craft_item, "group:pickaxe", craft_item}, + {craft_item, craft_item, craft_item} + } +end + +register_toolbox(S("Wooden Toolbox"), "wood", "default_wood.png", gen_recipe("default:wood")) +register_toolbox(S("Aspen Wood Toolbox"), "aspen", "default_aspen_wood.png", gen_recipe("default:aspen_wood")) +register_toolbox(S("Acacia Wood Toolbox"), "acacia", "default_acacia_wood.png", gen_recipe("default:acacia_wood")) +register_toolbox(S("Junglewood Toolbox"), "jungle", "default_junglewood.png", gen_recipe("default:junglewood")) +register_toolbox(S("Pine Wood Toolbox"), "pine", "default_pine_wood.png", gen_recipe("default:pine_wood")) + +register_toolbox(S("Steel Toolbox"), "steel", "default_steel_block.png", gen_recipe("default:steel_ingot")) diff --git a/models/wifi.lua b/models/wifi.lua new file mode 100644 index 0000000..f40d491 --- /dev/null +++ b/models/wifi.lua @@ -0,0 +1,34 @@ +local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") +local S = minetest.get_translator("more_chests") + +local wifi = gen_def({ + description = S("Wifi Chest"), + type = "wifi chest", + size = "small", + tiles = { + top = "wifi_top.png", + side = "wifi_side.png", + front = "wifi_front.png" + }, + recipe = { + {"group:wood", "default:mese", "group:wood"}, + {"group:wood", "default:steel_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"} + }, + allow_metadata_inventory_move = false, + allow_metadata_inventory_put = false, + allow_metadata_inventory_take = false, +}) + +wifi.can_dig = function(pos, player) return true end + +minetest.register_node("more_chests:wifi", wifi) +minetest.register_craft({ + output = "more_chests:wifi", + recipe = wifi.recipe, +}) + +minetest.register_on_joinplayer(function(player) + local inv = player:get_inventory() + inv:set_size("more_chests:wifi", 8*4) +end) diff --git a/secret.lua b/secret.lua deleted file mode 100644 index 71fe742..0000000 --- a/secret.lua +++ /dev/null @@ -1,132 +0,0 @@ --- Load support for translation. -local S = minetest.get_translator("more_chests") - -local function has_locked_chest_privilege(meta, player) - if player:get_player_name() ~= meta:get_string("owner") then - return false - end - return true -end - -local open = "size[8,10]".. - default.gui_bg .. - default.gui_bg_img .. - default.gui_slots .. - "list[current_name;main;0,0.3;8,4;]".. - "list[current_player;main;0,4.85;8,1;]" .. - "list[current_player;main;0,6.08;8,3;8]" .. - "listring[current_name;main]" .. - "listring[current_player;main]" .. - "button[3,9;2,1;open;close]" .. - default.get_hotbar_bg(0,4.85) -local closed = "size[2,1]".. - "button[0,0;2,1;open;open]" - -minetest.register_node("more_chests:secret", { - description = S("Secret Chest"), - tiles = {"secret_top.png", "secret_top.png", "secret_side.png", - "secret_side.png", "secret_side.png", "secret_front.png"}, - paramtype2 = "facedir", - groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, --- Pipeworks - tube = { - insert_object = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:add_item("main", stack) - end, - can_insert = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:room_for_item("main", stack) - end, - input_inventory = "main", - connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} - }, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - after_place_node = function(pos, placer) - local meta = minetest.get_meta(pos) - meta:set_string("owner", placer:get_player_name() or "") - meta:set_string("infotext", S("@1 (owned by @2)", - S("Secret Chest"), - meta:get_string("owner"))) - end, - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec", open) - meta:set_string("infotext", S("Secret Chest")) - meta:set_string("owner", "") - local inv = meta:get_inventory() - inv:set_size("main", 8*4) - end, - can_dig = function(pos,player) - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory() - return inv:is_empty("main") - end, - allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a secret chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return count - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a secret chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return stack:get_count() - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a secret chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return stack:get_count() - end, - on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in secret chest at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to secret chest at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from secret chest at "..minetest.pos_to_string(pos)) - end, - on_receive_fields = function(pos, formname, fields, sender) - local meta = minetest.get_meta(pos) - if has_locked_chest_privilege(meta, sender) then - if fields.open == "open" then - meta:set_string("formspec", open) - else - meta:set_string("formspec", closed) - end - end - end, -}) - -minetest.register_craft({ - output = 'more_chests:secret', - recipe = { - {'default:wood','default:cobble','default:wood'}, - {'default:wood','default:steel_ingot','default:wood'}, - {'default:wood','default:wood','default:wood'} - } -}) diff --git a/shared.lua b/shared.lua deleted file mode 100644 index e100a93..0000000 --- a/shared.lua +++ /dev/null @@ -1,138 +0,0 @@ --- Load support for translation. -local S = minetest.get_translator("more_chests") - -local function has_locked_chest_privilege(meta, player) - local name = player:get_player_name() - local shared = " "..meta:get_string("shared").." " - if name == meta:get_string("owner") then - return true - elseif shared:find(" "..name.." ") then - - return true - else - return false - end -end - -local function get_formspec(string) - return "size[8,10]".. - default.gui_bg .. - default.gui_bg_img .. - default.gui_slots .. - "list[current_name;main;0,0.3;8,4;]".. - "list[current_player;main;0,4.85;8,1;]" .. - "list[current_player;main;0,6;8,3;8]" .. - "field[.25,9.5;8,1;shared;"..S("Shared with (separate names with spaces)")..":;"..string.."]".. - "button[6,9.2;2,1;submit;"..S("submit").."]" .. - "listring[current_name;main]" .. - "listring[current_player;main]" .. - default.get_hotbar_bg(0,4.85) -end - -minetest.register_node("more_chests:shared", { - description = S("Shared Chest"), - tiles = {"shared_top.png", "shared_top.png", "shared_side.png", - "shared_side.png", "shared_side.png", "shared_front.png"}, - paramtype2 = "facedir", - groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, --- Pipeworks - tube = { - insert_object = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:add_item("main", stack) - end, - can_insert = function(pos, node, stack, direction) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:room_for_item("main", stack) - end, - input_inventory = "main", - connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} - }, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - after_place_node = function(pos, placer) - local meta = minetest.get_meta(pos) - meta:set_string("owner", placer:get_player_name() or "") - meta:set_string("infotext", S("@1 (owned by @2)", - S("Shared Chest"), - meta:get_string("owner"))) - end, - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec", get_formspec("")) - meta:set_string("infotext", S("Shared Chest")) - meta:set_string("owner", "") - local inv = meta:get_inventory() - inv:set_size("main", 8*4) - end, - can_dig = function(pos,player) - local meta = minetest.get_meta(pos); - local inv = meta:get_inventory() - return inv:is_empty("main") - end, - allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a shared chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return count - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a shared chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return stack:get_count() - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then - minetest.log("action", player:get_player_name().. - " tried to access a shared chest belonging to ".. - meta:get_string("owner").." at ".. - minetest.pos_to_string(pos)) - return 0 - end - return stack:get_count() - end, - on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in shared chest at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to shared chest at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from shared chest at "..minetest.pos_to_string(pos)) - end, - on_receive_fields = function(pos, formspec, fields, sender) - local meta = minetest.get_meta(pos); - if fields.shared then - if meta:get_string("owner") == sender:get_player_name() then - meta:set_string("shared", fields.shared); - meta:set_string("formspec", get_formspec(fields.shared)) - end - end - end, -}) - -minetest.register_craft({ - output = 'more_chests:shared', - recipe = { - {'default:wood','default:leaves','default:wood'}, - {'default:wood','default:steel_ingot','default:wood'}, - {'default:wood','default:wood','default:wood'} - } -}) diff --git a/textures/fridge_front.png b/textures/fridge_front.png new file mode 100644 index 0000000000000000000000000000000000000000..3818b7af4d0942b9fdce60ceedb7eae1e6f2cc87 GIT binary patch literal 1586 zcmV-22F>}2P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1Y?mg6W4{Ld-&2uR}dI2g=(dxJUt78po^lj-i+ z35mf%NTN!DsPosqRsDkxYu3tGA6#@!<71+UoG=Lb`dmF})1Tu-&%ujatqF!m(98Ae z&Y_H6Nq`mLfvod z{xSu4E(A>`7$dB>HT6#TCv6$3wWThR4ht*9#Vw~1Mq{o$p#?&y4oq#ww>R~aH~NWK z0fV-~9I(NpkITei>5*H~c^2qdZIr%BgM1kV013fRC<$a4W061J1msY%VvVxaI_qt) z(IzL(IP0AAuANcIi#OhS=e-X;`V=IXV1o-jgb+iD90f<1jV^i>LyR#cI888}usT5_ zrGpPS%wZ3A_#+(gNEzvqO}5!(pF@s06)sXx{>2rqN+_|UlTM`4X-<2()1TptXR64x zD%Dh5UG+88Skq!{u=>gxZOr|iH5#ln#!T1q57r>|ewv_moY=-07-K_V+&2c0(A+rF zfsEnCT;ohfMp0M>Yh)Wag&JdE(454!(&FyH+;4eP*8GS!{=}SW)cp8&Rzo4`*`Y7UlbzlA64W(aPI+`j7C8V2DUlGHunPPg^8-;dF>UcK6V-`DUM9(npa z;_%t+s^;A7*dY0zmA=!fFBI@+Wev;e=f3kT0o4D?phu!8^BEZT0H&T_z}Ud%@8EsQ zioI92Y?PDo8rFJSA+$%=Q~Yg-+;#W9n0*QUv5mRtc4hfqEHA8mj$!GFOwlTXT;^Pg z>c>1A{#gC@a8jK~Xl6P(H!abAB=j;+KdA#ZPmwnzq`ua5w?pV%C8{5WvW|||+P6r^ zAJ_Tr7uZfOV2k>p$9TNA;b`j{A*`rV{S(;RQ?spTlIAfn%w>92b=GCzH)|8?`;z7)%Wy@nFV?cVx>Hlt6NrfLC7Pz8EK6>;8=K7rtu>)<_I*!T zmIHY@odPhQ&xhJ`-y`q}{DS3j34n9%ZNX?T2&n7&S3%cxbX`XnhW{P>sNmc8du+E` zMC4b&CtR=Bw_4x#V+Ee1wf;D`UatW##t=mj0BM^3t>AfBYmK!QYb`}la5x-B+zBu^ z{|cW3fQXPJ$s1<^pp+UFwbp2@iQ{-k==F)un?*z<%QC6!TE2xbM!K$(34pbh$Kx?t zoaZ^m)doGs?ZQC-N z&DihvIOkAG(KHQto>Ns7Q521m2#TVRBuO}*&qKD>T7n=LKGf?y_;UvcPN$O?V}?U{ k#bU7-MH zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1b>(!(YU{Ld+R1cZ1VhliQz4SM`8AaLR@`KIkO zo*05bNV_ZHsOzskyZQqkqmxnAh3J#_8Xuc%G8vty*Jrh)?Yzqmy*qE?>O3$QVzj(| z`b*|#jJtb5urglW$5p6eCyJqMSq$>n*`Ooyq8MVc#z}swBO8#@O1S;qMt3Z=bF@DGe+ zoZM&ZCPEL^_Ren)U?Aw%&kJ_Fx7ho&qRZ9;DX%1`9m?!sVgZyqmw8+PUx$8}SHcw$ zVg+LjY!+NqQ6dAhJ6UR!sna#vN);|zbD4nFmH=6H1|z&ze*81H^NLqFh*GM<5Hgn|I2j@^**Faq~pN~ewm>fxG|U;cgzAI)CE&F z@tv1?(T#o~mcgK#Fh>NKby+5gqgz`%d1lOW+A6(LgF+JnfCzg#I718ukPqw#NfC?* zM8GkEpA63pTT{RQIcFNF4sMt|$cbj`jWvPhT;t3dMri>Njy+N(f}squtaZ>&un`){ zj-6G`Iq!mtF1hU4TkpL0!H*i10|y&i@F9d4Qpk~`jV}5aVvH%~WD=uG?ByzifHN_h5-aetjx1suhvn!6)U)w0=5b>E(yCu3 z91A&2qp0Iyv}94AXl|Y&A$`W6@}Sf$kBUaMoNFVB;vCD`yVWaxWb#;}cT3#v0X0X$ zH>YZtR#5PzW#i>h^LxmTR(*_VO|DP^%WQMa-66ScQaZWb7!|h><~%L5+oqKWb-d=t zh3ywmuIL!r?q#)cboCL0DH{r##RjEJvL{nty-Pe(DA7VW4xB?iiTR%{`sGB5dQEmn zYCFNkmb84mBC_o1*ltO5#j!4%cn1)tD$c#EjuhJ(jYgj1jVd05a+mGNKABnC$xwC^ zp&$ca6!pa;0H8nmtab-4TEaooK{QDzf!)h6bDk0DhHc+cG)K-NMOhiwNQDGJ;nq|0D492=`X4#*wio zg`e)^6RRhh_MP~2T=Xw4N)HZ6#%RX-QQr1_eN--8k7GN5liSAbIA+mOZ|?XndW$>3 z;Gnpb4ehAwa7(Re^=Og&E`d^}w3GrA>g}k=HS43%Rcg=NyJfR$Bp+nGKTMS*^X!35 zF`s%b%1^Q0XN1r1b!d3sMT9u9myZ<%e6a>IjlUJ5Bc8hem;?SfHdMMv^M@Kf>DitO z@}0!49AND@MW(a`igY`2^zYABW^+hFZ;Lyjin`C!bB5h2h+CcYNSJn~i4^gtb*9Mh zTXNHH5}?R)`k50GzcCA?v&7qm3?B4*w?W}|b;E_UM|Sp`jp;}}^-{nOFj}W?rPh7n zR_~y{D4^000SaNLh0L01FWS01FWTe`H^g00007bV*G`2jm3;4;3IJZ#6Ce z00JIKL_t(I%Y~E8ZrV^3guinE6aR@Cti&xyt=e_p{|)j2-87p@q^*F2`UjiX7~7`{ z6Q@xYJ*%sGXGU{pbfjs2s_GGABK|k0(}|+UNs>PV!GigG%6Mc}C^bz}aL9B3Pp4A= zJkJ~MvUCf$ROOM@cNv)oQB?&vH!($#<9pWtR8R+U^%3R~QLVYO1m&%Q67O zG=w3H%<9EKrx`FA&d=oScKasGwrPMdoo2m2oO}ad9()}H(sV<8Y6emmh5+pMdu&Jg zynMeGXj_M_n-1W|$DB!ThMQZer%zu{Z4mhYfa$C9(Qfz+#+>NXLd-CztuJJsJ z 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 M07*qoM6N<$f*72!!{EP) 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 Hu0mjf(Z)It literal 0 HcmV?d00001 diff --git a/textures/toolbox_front.xcf b/textures/toolbox_front.xcf new file mode 100644 index 0000000000000000000000000000000000000000..380ecab2aa2a63ecafe20ec3c1584614afe74c3e GIT binary patch literal 17577 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 V{*6{hgLBdOu?pH|l}Kv){{rk>bF%;d literal 0 HcmV?d00001 diff --git a/textures/toolbox_jungle_front.png b/textures/toolbox_jungle_front.png new file mode 100644 index 0000000000000000000000000000000000000000..4d88605c5d354199186bb1a827b67caa135ab797 GIT binary patch literal 2397 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 literal 0 HcmV?d00001 diff --git a/textures/toolbox_pine_top.png b/textures/toolbox_pine_top.png new file mode 100644 index 0000000000000000000000000000000000000000..15a750cf616f89c5c0567834932d8865f2c7cb0f GIT binary patch literal 3119 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 JPDHLkV1hAY+noRa literal 0 HcmV?d00001 diff --git a/textures/toolbox_steel_front.png b/textures/toolbox_steel_front.png new file mode 100644 index 0000000000000000000000000000000000000000..0399b0d6b17c0e172aa91311a71e3bcebfac6ea1 GIT binary patch literal 2542 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 Ef|>ra$N&HU literal 0 HcmV?d00001 diff --git a/textures/toolbox_steel_top.png b/textures/toolbox_steel_top.png new file mode 100644 index 0000000000000000000000000000000000000000..21f3e6248ea8cb01cd61f84114e40c1bd0741cbd GIT binary patch literal 3007 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 B%g+D+ literal 0 HcmV?d00001 diff --git a/textures/toolbox_top.xcf b/textures/toolbox_top.xcf new file mode 100644 index 0000000000000000000000000000000000000000..cb6c4860764fffe944badc4be0c823b44f68d706 GIT binary patch literal 12314 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 Date: Thu, 25 Feb 2021 16:48:58 +0100 Subject: [PATCH 08/12] Fix wifi chest front texture --- models/wifi.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/models/wifi.lua b/models/wifi.lua index f40d491..19bdd0f 100644 --- a/models/wifi.lua +++ b/models/wifi.lua @@ -8,7 +8,8 @@ local wifi = gen_def({ tiles = { top = "wifi_top.png", side = "wifi_side.png", - front = "wifi_front.png" + front = {name="wifi_front_animated.png", animation={type="vertical_frames", + aspect_w=16, aspect_h=16, length=2.0}} }, recipe = { {"group:wood", "default:mese", "group:wood"}, From f1cfa9d7f356bd299a9b7d8d20ee4e2b4fe21d51 Mon Sep 17 00:00:00 2001 From: Louis <55180044+louisroyer@users.noreply.github.com> Date: Thu, 25 Feb 2021 16:53:34 +0100 Subject: [PATCH 09/12] Add .luacheckrc --- .luacheckrc | 25 +++++++++++++++++++++++++ utils/formspec.lua | 1 + 2 files changed, 26 insertions(+) create mode 100644 .luacheckrc diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..5ee1cab --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,25 @@ +std = "lua51+minetest" +unused_args = false +allow_defined_top = true +max_line_length = 999 + +stds.minetest = { + read_globals = { + "minetest", + "VoxelManip", + "VoxelArea", + "PseudoRandom", + "ItemStack", + "default", + table = { + fields = { + "copy", + }, + }, + } +} + +read_globals = { + "pipeworks", +} + diff --git a/utils/formspec.lua b/utils/formspec.lua index 8e089ab..073c49c 100644 --- a/utils/formspec.lua +++ b/utils/formspec.lua @@ -1,4 +1,5 @@ function generate(size) + local cfg if size == "small" then cfg = { window_width = 8, From 9526aec1cdeea5a912d7f5337c8b6e2bb47bb264 Mon Sep 17 00:00:00 2001 From: Louis <55180044+louisroyer@users.noreply.github.com> Date: Thu, 25 Feb 2021 17:10:22 +0100 Subject: [PATCH 10/12] Recipes not part of def Fixes #22 --- models/cobble.lua | 13 ++++++------- models/dropbox.lua | 11 +++++------ models/fridge.lua | 25 ++++++++++++------------- models/secret.lua | 11 +++++------ models/shared.lua | 11 +++++------ models/toolbox.lua | 37 ++++++++++++++++++------------------- models/wifi.lua | 11 +++++------ utils/base.lua | 1 - 8 files changed, 56 insertions(+), 64 deletions(-) diff --git a/models/cobble.lua b/models/cobble.lua index 2a568fa..8c27183 100644 --- a/models/cobble.lua +++ b/models/cobble.lua @@ -10,17 +10,16 @@ local cobble = gen_def({ side = "default_cobble.png", front = "cobblechest_front.png" }, - pipeworks_enabled = true, - recipe = { - {"group:wood", "default:cobble", "group:wood"}, - {"default:cobble", "default:steel_ingot", "default:cobble"}, - {"group:wood", "default:cobble", "group:wood"} - }, + pipeworks_enabled = true }) minetest.register_node("more_chests:cobble", cobble) minetest.register_craft({ output = "more_chests:cobble", - recipe = cobble.recipe, + recipe = { + {"group:wood", "default:cobble", "group:wood"}, + {"default:cobble", "default:steel_ingot", "default:cobble"}, + {"group:wood", "default:cobble", "group:wood"} + } }) diff --git a/models/dropbox.lua b/models/dropbox.lua index 94da127..65a1f0d 100644 --- a/models/dropbox.lua +++ b/models/dropbox.lua @@ -12,11 +12,6 @@ local dropbox = gen_def({ front = "dropbox_front.png" }, pipeworks_enabled = true, - recipe = { - {"group:wood", "", "group:wood"}, - {"group:wood", "default:steel_ingot", "group:wood"}, - {"group:wood", "group:wood", "group:wood"} - }, allow_metadata_inventory_move = false, allow_metadata_inventory_put = function(pos, listname, index, stack, player) local meta = minetest.get_meta(pos) @@ -41,5 +36,9 @@ local dropbox = gen_def({ minetest.register_node("more_chests:dropbox", dropbox) minetest.register_craft({ output = "more_chests:dropbox", - recipe = dropbox.recipe, + recipe = { + {"group:wood", "", "group:wood"}, + {"group:wood", "default:steel_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"} + } }) diff --git a/models/fridge.lua b/models/fridge.lua index 4600d68..0848e59 100644 --- a/models/fridge.lua +++ b/models/fridge.lua @@ -3,6 +3,7 @@ local S = minetest.get_translator("more_chests") -- TODO model open +-- normal fridge local fridge = gen_def({ description = S("Fridge"), type = "fridge", @@ -11,20 +12,19 @@ local fridge = gen_def({ side = "fridge_side.png", front = "fridge_front.png", }, - recipe = { - {"", "default:steel_ingot", ""}, - {"default:steel_ingot", "default:ice", "default:steel_ingot"}, - {"", "default:steel_ingot", ""} - }, }) minetest.register_node("more_chests:fridge", fridge) minetest.register_craft({ output = "more_chests:fridge", - recipe = fridge.recipe, + recipe = { + {"", "default:steel_ingot", ""}, + {"default:steel_ingot", "default:ice", "default:steel_ingot"}, + {"", "default:steel_ingot", ""} + } }) - +-- big fridge local big_fridge = gen_def({ description = S("Big Fridge"), type = "fridge", @@ -36,15 +36,14 @@ local big_fridge = gen_def({ side = "fridge_side.png", front = "fridge_front.png", }, - recipe = { - {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, - {"default:steel_ingot", "default:ice", "default:steel_ingot"}, - {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} - }, }) minetest.register_node("more_chests:big_fridge", big_fridge) minetest.register_craft({ output = "more_chests:big_fridge", - recipe = big_fridge.recipe, + recipe = { + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "default:ice", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} + } }) diff --git a/models/secret.lua b/models/secret.lua index 2536694..5a32eda 100644 --- a/models/secret.lua +++ b/models/secret.lua @@ -28,11 +28,6 @@ local secret = gen_def({ }, formspec = open, pipeworks_enabled = true, - recipe = { - {"group:wood", "default:cobble", "group:wood"}, - {"group:wood", "default:steel_ingot", "group:wood"}, - {"group:wood", "group:wood", "group:wood"} - }, }) secret.on_receive_fields = function(pos, formname, fields, sender) @@ -50,5 +45,9 @@ end minetest.register_node("more_chests:secret", secret) minetest.register_craft({ output = "more_chests:secret", - recipe = secret.recipe, + recipe = { + {"group:wood", "default:cobble", "group:wood"}, + {"group:wood", "default:steel_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"} + } }) diff --git a/models/shared.lua b/models/shared.lua index b4272fa..03825bf 100644 --- a/models/shared.lua +++ b/models/shared.lua @@ -44,11 +44,6 @@ local shared = gen_def({ formspec = get_formspec(""), pipeworks_enabled = true, sounds = default.node_sound_wood_defaults(), - recipe = { - {"group:wood", "default:leaves", "group:wood"}, - {"group:wood", "default:steel_ingot", "group:wood"}, - {"group:wood", "group:wood", "group:wood"} - }, allow_metadata_inventory_move = actions.get_allow_metadata_inventory_move{"shared chest", check_privs=check_privs}, allow_metadata_inventory_put = actions.get_allow_metadata_inventory_put{"shared chest", check_privs=check_privs}, allow_metadata_inventory_take = actions.get_allow_metadata_inventory_take{"shared chest", check_privs=check_privs}, @@ -68,5 +63,9 @@ end minetest.register_node("more_chests:shared", shared) minetest.register_craft({ output = "more_chests:shared", - recipe = shared.recipe, + recipe = { + {"group:wood", "default:leaves", "group:wood"}, + {"group:wood", "default:steel_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"} + } }) diff --git a/models/toolbox.lua b/models/toolbox.lua index 3b72476..3a0e6e6 100644 --- a/models/toolbox.lua +++ b/models/toolbox.lua @@ -1,7 +1,7 @@ local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") local S = minetest.get_translator("more_chests") -local function register_toolbox(description, type, side_tile, recipe) +local function register_toolbox(description, material, side_tile, craft_item) local def = gen_def({ description = description, type = "toolbox", @@ -9,26 +9,25 @@ local function register_toolbox(description, type, side_tile, recipe) -- node_box = {-0.5, -0.5, -0.5, 1.5, 0.5, 0.5}, -- makes it two blocks wide tiles = { side = side_tile, - front = "toolbox_" .. type .. "_front.png", - top = "toolbox_" .. type .. "_top.png", + front = "toolbox_" .. material .. "_front.png", + top = "toolbox_" .. material .. "_top.png", }, - recipe = recipe, }) - minetest.register_node("more_chests:toolbox_" .. type, def) + minetest.register_node("more_chests:toolbox_" .. material, def) + minetest.register_craft({ + output = "morechests:toolbox_" .. material, + recipe = { + {craft_item, craft_item, craft_item}, + {craft_item, "group:pickaxe", craft_item}, + {craft_item, craft_item, craft_item} + } + }) end -local function gen_recipe(craft_item) - return { - {craft_item, craft_item, craft_item}, - {craft_item, "group:pickaxe", craft_item}, - {craft_item, craft_item, craft_item} - } -end -register_toolbox(S("Wooden Toolbox"), "wood", "default_wood.png", gen_recipe("default:wood")) -register_toolbox(S("Aspen Wood Toolbox"), "aspen", "default_aspen_wood.png", gen_recipe("default:aspen_wood")) -register_toolbox(S("Acacia Wood Toolbox"), "acacia", "default_acacia_wood.png", gen_recipe("default:acacia_wood")) -register_toolbox(S("Junglewood Toolbox"), "jungle", "default_junglewood.png", gen_recipe("default:junglewood")) -register_toolbox(S("Pine Wood Toolbox"), "pine", "default_pine_wood.png", gen_recipe("default:pine_wood")) - -register_toolbox(S("Steel Toolbox"), "steel", "default_steel_block.png", gen_recipe("default:steel_ingot")) +register_toolbox(S("Wooden Toolbox"), "wood", "default_wood.png", "default:wood") +register_toolbox(S("Aspen Wood Toolbox"), "aspen", "default_aspen_wood.png", "default:aspen_wood") +register_toolbox(S("Acacia Wood Toolbox"), "acacia", "default_acacia_wood.png", "default:acacia_wood") +register_toolbox(S("Junglewood Toolbox"), "jungle", "default_junglewood.png", "default:junglewood") +register_toolbox(S("Pine Wood Toolbox"), "pine", "default_pine_wood.png", "default:pine_wood") +register_toolbox(S("Steel Toolbox"), "steel", "default_steel_block.png", "default:steel_ingot") diff --git a/models/wifi.lua b/models/wifi.lua index 19bdd0f..bfcef10 100644 --- a/models/wifi.lua +++ b/models/wifi.lua @@ -11,11 +11,6 @@ local wifi = gen_def({ front = {name="wifi_front_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}} }, - recipe = { - {"group:wood", "default:mese", "group:wood"}, - {"group:wood", "default:steel_ingot", "group:wood"}, - {"group:wood", "group:wood", "group:wood"} - }, allow_metadata_inventory_move = false, allow_metadata_inventory_put = false, allow_metadata_inventory_take = false, @@ -26,7 +21,11 @@ wifi.can_dig = function(pos, player) return true end minetest.register_node("more_chests:wifi", wifi) minetest.register_craft({ output = "more_chests:wifi", - recipe = wifi.recipe, + recipe = { + {"group:wood", "default:mese", "group:wood"}, + {"group:wood", "default:steel_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"} + }, }) minetest.register_on_joinplayer(function(player) diff --git a/utils/base.lua b/utils/base.lua index 2405fee..6d7947c 100644 --- a/utils/base.lua +++ b/utils/base.lua @@ -34,7 +34,6 @@ function generate_chest_def(def) oddly_breakable_by_hand=2 }, sounds = def.sounds or default.node_sound_wood_defaults(), - recipe = def.recipe, -- TODO this is buggy, reason why all models except from toolbox have their own extra call to minetest.register_craft - TODO possibily other similar bugs? after_place_node = function(pos, placer) local meta = minetest.get_meta(pos) meta:set_string("owner", placer:get_player_name() or "") From 109e6b1fdc79f3152fc78397cb25eb2e04c8e97d Mon Sep 17 00:00:00 2001 From: Louis <55180044+louisroyer@users.noreply.github.com> Date: Thu, 25 Feb 2021 18:03:57 +0100 Subject: [PATCH 11/12] Right inventory for wifi chests Fix #23 --- models/toolbox.lua | 2 +- models/wifi.lua | 45 +++++++++++++++++++-- utils/base.lua | 10 +++-- utils/formspec.lua | 13 +++++-- wifi.lua | 97 ---------------------------------------------- 5 files changed, 59 insertions(+), 108 deletions(-) delete mode 100644 wifi.lua diff --git a/models/toolbox.lua b/models/toolbox.lua index 3a0e6e6..0e287eb 100644 --- a/models/toolbox.lua +++ b/models/toolbox.lua @@ -15,7 +15,7 @@ local function register_toolbox(description, material, side_tile, craft_item) }) minetest.register_node("more_chests:toolbox_" .. material, def) minetest.register_craft({ - output = "morechests:toolbox_" .. material, + output = "more_chests:toolbox_" .. material, recipe = { {craft_item, craft_item, craft_item}, {craft_item, "group:pickaxe", craft_item}, diff --git a/models/wifi.lua b/models/wifi.lua index bfcef10..669fbf1 100644 --- a/models/wifi.lua +++ b/models/wifi.lua @@ -1,5 +1,6 @@ local gen_def = dofile(minetest.get_modpath("more_chests") .. "/utils/base.lua") local S = minetest.get_translator("more_chests") +local pipeworks_enabled = minetest.global_exists("pipeworks") local wifi = gen_def({ description = S("Wifi Chest"), @@ -11,13 +12,51 @@ local wifi = gen_def({ front = {name="wifi_front_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}} }, - allow_metadata_inventory_move = false, - allow_metadata_inventory_put = false, - allow_metadata_inventory_take = false, + inventory_name = "more_chests:wifi", + pipeworks_enabled = pipeworks_enabled, -- this adds groups }) +-- wifi chests can always be removed because content is detached wifi.can_dig = function(pos, player) return true end +-- pipeworks support (we need to override what is created by gen_def because too generic) +wifi.tube = pipeworks_enabled and { + insert_object = function(pos, node, stack, direction, owner) + if not owner then + return stack + end + local player = minetest.get_player_by_name(owner) + if not player then + return stack + end + local inv = player:get_inventory() + return inv:add_item("more_chests:wifi", stack) + end, + can_insert = function(pos, node, stack, direction, owner) + if not owner then + return false + end + local player = minetest.get_player_by_name(owner) + if not player then + return false + end + local inv = player:get_inventory() + return inv:room_for_item("more_chests:wifi", stack) + end, + input_inventory = "more_chests:wifi", + return_input_invref = function(pos, node, direction, player_name) + if not player_name then + return false + end + local player = minetest.get_player_by_name(player_name) + if not player then + return false + end + return player:get_inventory() + end, + connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} +} or nil + minetest.register_node("more_chests:wifi", wifi) minetest.register_craft({ output = "more_chests:wifi", diff --git a/utils/base.lua b/utils/base.lua index 6d7947c..d6858aa 100644 --- a/utils/base.lua +++ b/utils/base.lua @@ -41,13 +41,15 @@ function generate_chest_def(def) end, on_construct = function(pos) local meta = minetest.get_meta(pos) - local formspec_str = def.formspec or generate_formspec_string(def.size) + local formspec_str = def.formspec or generate_formspec_string(def.size, def.inventory_name or nil) meta:set_string("formspec", formspec_str) meta:set_string("infotext", def.description) meta:set_string("owner", "") - local inv = meta:get_inventory() - local chest_size = def.size == "big" and 14*5 or 8*4 - inv:set_size("main", chest_size) + if def.inventory_name == nil or def.inventory_name == "main" then + local inv = meta:get_inventory() + local chest_size = def.size == "big" and 14*5 or 8*4 + inv:set_size("main", chest_size) + end end, can_dig = function(pos,player) local meta = minetest.get_meta(pos) diff --git a/utils/formspec.lua b/utils/formspec.lua index 073c49c..1452e61 100644 --- a/utils/formspec.lua +++ b/utils/formspec.lua @@ -1,5 +1,12 @@ -function generate(size) +function generate(size, inventory_name) local cfg + + -- chest inventory name + local inv_name = inventory_name + if inv_name == nil then + inv_name = "main" + end + if size == "small" then cfg = { window_width = 8, @@ -23,7 +30,7 @@ function generate(size) default.gui_bg .. default.gui_bg_img .. default.gui_slots .. - "list[current_name;main;0,0.3;" .. + "list["..((inv_name == "main") and "current_name" or "current_player")..";"..inv_name..";0,0.3;" .. cfg.chest_width .. "," .. cfg.chest_height .. ";]" .. "list[current_player;main;" .. player_inv_x_orig .. "," .. player_inv_y_orig .. @@ -31,7 +38,7 @@ function generate(size) "list[current_player;main;" .. player_inv_x_orig .. "," .. (player_inv_y_orig + 1.15) .. ";8,3;8]" .. - "listring[current_name;main]" .. + "listring["..(inv_name == "main" and "current_name" or "current_player")..";"..inv_name.."]" .. "listring[current_player;main]" .. default.get_hotbar_bg(player_inv_x_orig, player_inv_y_orig) end diff --git a/wifi.lua b/wifi.lua deleted file mode 100644 index 84534a9..0000000 --- a/wifi.lua +++ /dev/null @@ -1,97 +0,0 @@ --- Load support for translation. -local S = minetest.get_translator("more_chests") - -local pipeworks_enabled = minetest.global_exists("pipeworks") - -minetest.register_node("more_chests:wifi", { - description = S("Wifi Chest"), - tiles = {"wifi_top.png", "wifi_top.png", "wifi_side.png", - "wifi_side.png", "wifi_side.png", - {name="wifi_front_animated.png", animation={type="vertical_frames", - aspect_w=16, aspect_h=16, length=2.0}}}, - paramtype2 = "facedir", - groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, - -- Pipeworks - tube = pipeworks_enabled and { - insert_object = function(pos, node, stack, direction, owner) - if not owner then - return stack - end - local player = minetest.get_player_by_name(owner) - if not player then - return stack - end - local inv = player:get_inventory() - return inv:add_item("more_chests:wifi", stack) - end, - can_insert = function(pos, node, stack, direction, owner) - if not owner then - return false - end - local player = minetest.get_player_by_name(owner) - if not player then - return false - end - local inv = player:get_inventory() - return inv:room_for_item("more_chests:wifi", stack) - end, - input_inventory = "more_chests:wifi", - return_input_invref = function(pos, node, direction, player_name) - if not player_name then - return false - end - local player = minetest.get_player_by_name(player_name) - if not player then - return false - end - return player:get_inventory() - end, - connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} - } or nil, - after_place_node = pipeworks_enabled and pipeworks.after_place or nil, - after_dig_node = pipeworks_enabled and pipeworks.after_dig or nil, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec", - "size[8,9]".. - default.gui_bg .. - default.gui_bg_img .. - default.gui_slots .. - "list[current_player;more_chests:wifi;0,0.3;8,4;]".. - "list[current_player;main;0,4.85;8,1;]" .. - "list[current_player;main;0,6.08;8,3;8]" .. - "listring[current_player;more_chests:wifi]" .. - "listring[current_player;main]" .. - default.get_hotbar_bg(0,4.85)) - - meta:set_string("infotext", S("Wifi Chest")) - end, - on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in wifi chest at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to wifi chest at "..minetest.pos_to_string(pos)) - end, - on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from wifi chest at "..minetest.pos_to_string(pos)) - end, -}) - -minetest.register_craft({ - output = 'more_chests:wifi', - recipe = { - {'default:wood','default:mese','default:wood'}, - {'default:wood','default:steel_ingot','default:wood'}, - {'default:wood','default:wood','default:wood'} - } -}) - -minetest.register_on_joinplayer(function(player) - local inv = player:get_inventory() - inv:set_size("more_chests:wifi", 8*4) -end) From 61db871d3f30fbf5257b95d1ad4e89e2b19636eb Mon Sep 17 00:00:00 2001 From: Louis <55180044+louisroyer@users.noreply.github.com> Date: Sat, 6 Mar 2021 17:58:27 +0100 Subject: [PATCH 12/12] Insertion with vacuum pipes Insertion is now done into the wifi-chest of the player who placed the wifi chest when the item to be inserted has no owner yet (otherwise, it is inserted into the wifi-chest of the player who own the item). --- models/wifi.lua | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/models/wifi.lua b/models/wifi.lua index 669fbf1..506bac9 100644 --- a/models/wifi.lua +++ b/models/wifi.lua @@ -22,10 +22,18 @@ wifi.can_dig = function(pos, player) return true end -- pipeworks support (we need to override what is created by gen_def because too generic) wifi.tube = pipeworks_enabled and { insert_object = function(pos, node, stack, direction, owner) + local wifi_chest_owner if not owner then - return stack + local wifi_chest = minetest.get_meta(pos) + if not wifi_chest then + return stack + end + wifi_chest_owner = wifi_chest:get_string("owner") + if not wifi_chest_owner then + return stack + end end - local player = minetest.get_player_by_name(owner) + local player = minetest.get_player_by_name(owner or wifi_chest_owner) if not player then return stack end @@ -33,10 +41,18 @@ wifi.tube = pipeworks_enabled and { return inv:add_item("more_chests:wifi", stack) end, can_insert = function(pos, node, stack, direction, owner) + local wifi_chest_owner if not owner then - return false + local wifi_chest = minetest.get_meta(pos) + if not wifi_chest then + return stack + end + wifi_chest_owner = wifi_chest:get_string("owner") + if not wifi_chest_owner then + return false + end end - local player = minetest.get_player_by_name(owner) + local player = minetest.get_player_by_name(owner or wifi_chest_owner) if not player then return false end