From 886108a1af1b553867cc23a946e40d13b8891a9a Mon Sep 17 00:00:00 2001 From: nxet Date: Thu, 8 Oct 2020 11:17:51 +0200 Subject: [PATCH] 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 zcmV+~4AAq5P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O1e?k~1j|{Ld-&2!Ife*egEQph39YW?)f63 ziBQsc%Gti9RJ%WbFcrf@#r z4*AVSw>|J%J3W_)-*yzfR{r)v#5e!?d$FDBtg7prPEv-Yvb%?R9A($gvBQ+KhhEJM*O(kpBn$4>p79CQ8xr%pSHrjqOk_s zFy!oxUH~NMwJC4=?#sRK#=ihdK#;eYD-I~WpD8+rFK*Gsnb41Ya{jnRDDzGL6Jc$} zW&!~Lp968o!Iv0I2(V)XK7yS`O0ffhz#M0A3T%inz^T#J#+VXz-^lSaLs|d?Q>FrF z8VSHkiNT+eDmWxeoE$S}E?l{>WXdUX&begMC@EA@;gU-!wX`CYYN}jwEw$EGrNu^& zFmAaO*J^7`1d9r$7K|435b3c~Pn~=2rPtoN4A5t!!6T0{>S#k|oHXJ7Gtc5?oo&hr z3shQZ@ye^Ly4n&2*OW9VYu2Jwo5~Zli|TjO!W(kGqZTe|hFIGD$`@*AF6A*rFganv z42Z=PfOs(kK-3X4 zJnw3&WA_pZkhk()rqk0`DSM^_-`N!lWq&9gDw(F$d8|C*u7VP0^=j^W8a|ctbabJ% z4+}l#d<^;2G0U_ag*4j3AdrE5GU!2CyEexd<;*nFZ)bD6!b%ZPd~zRS6_rt1n9WeiP{?#%(CT5OVh|VG z8=8}9pIUKT1~sX7?64+T3)X8%Tb$B3Ex6It6rJ#aKEnMTu+W#GwaxROIl&a0kgHZ1 zxpP*y-`y)5A|7Y1W^7jr{xeJw)`1J+ED ziyxySz)34ndmnSmvU;8}SJHl$LQwaW4*dt>Z&yZ9%5=LFhy)Jn8Qyv}R1)I!4>H5( zX4zfz+Q1E{*Ex?f`@o$lzq$r2lY4$eaEQRL2?*YWBtwM(VeH@@GsGV?%q}*24o_>1 zYLgcjo0owAqYh#md$tCd!R%o{T&VRX6H?S2>u6{gYXJ?~bSl+!E9K0sm03D&6EelH zM__R35|XU?L3(_8me``K)Hw5GY|*r6ZqQZu}%;uC63vdf)N8Q-$BXE_fixI zmQ#U6S~cbh{2h=RXRU*#)vb)#?nvFjf`<$xv030{T7YWTIT5L*gCBLc7edK0mqA4! z(BMbI<~m2=HNJ>ek?>yug8pDt-SipDk_cTRD~_^CYkQU#Y(N4y=zSQ-3r7WnZI6Zu z39TV#tZRL{<{r$wY{ckwR}*2Y75FZQ@wKftiiPQp4gv>+zW29u25K7(ntM8`Q0Voi z?z%I?ICZ>D+A@YeiS{ecUNjgJAvmR@bc?BkPhq8;9hrJPc6`^@k)iDCL2pFvWr$@+2h&q#El$c-o&9!S~+ zx;5deJ8V0wMI`l;iQmiopppa#_6{Vm-if|?A?h4`u8a@L#W!koq5g=H{?n4~^B($S zWGFC>m5`&}*DM2CLRBrlf4;<_+Hl6Q33u2sm>VM*f&zPu7JVL5LBDsuYCY$GgBev} z%m?_bT6!FBu2X+It^?<4U_Fj;5)7^i{U3D_ z65N#^DT$pZ&m>z8SIvcE)95TP98&=4iL`p#1}0LFQxkH9uzlEUiJaMd9-~WJ2iXjKDGBlxBn;LWLCw_*g=Q@3a2p zmkPNiuhs#1G`e^}?uqmEL<1gyL~EPUl9sjITeo}1-3>{DO=AK8T4u|=6)E7Ny{&Gc z>wch=<^-9n@b%dr^zRRVfBP`1>nLOkt)2nMn*<^J5%!zc2PXF?j$_UXRWizg z^-;QZm!RSuUv>6BmXqRaW*q9mBCv`jK&tj_0NKMgofn(Hya9*x_pr!DkXBn}^Ej;7 z=j|hu{^I;kUq7Ee&Yb=4hmOxibFWr=FYyK2-2VVu#%prT5A_xR000JJOGiWij{uMW zeHl_IO#lD@32;bRa{vG?BLDy{BLR4&KXw2B00(qQO+^Rf1p*QuHa@CY)&Kwl0ZBwb zR9M5!S50UWK@|RWvuP+z&~313u!^nH;w5-7Ac$h6r+V;IX{(1KJyZlwTA>t`BKD{k zdnm<&RA~>=gGHqxD1uNBN-s8|Dc07Q#QvFt*peR)v$NURokZN*Ot1008O4N=f@=?C?;2|Cl41NHSlgUr~{%W@2qQ4ghfPYtU3wN)dTCBE}8R<|+WB z%wE#|f1>SpZAmClH;9C9JTE*e)N-eK7{K?U2meVY0LLCSie<^NugX)yqH+2P5%%_> z#cEq(puKNQxc2nJJTQ12?I-H_S+Ei#c`nD}0QMIZl#G7fk_U!*0*Hj(L6&5^StjQ- zdzTOi@zG@vX!b7Y%%HYT0svMgTZ<~yGc?PcHwrJx1OBE{+=WdL1$;+NZsC9#{b}O< z)q-1epbn5YSes|EXZJAS#%hS0w@#We+B$DsxHHAP7u(C@1zQmiG2fO5h;nz6Ztxr= z!MOMd08pvc>UYHGK%35hA`69rHU9Z;9^kQFS&C2|K#aZjy-iv<5dO$GD;W=$EhNw} z0sxqOa(QR#fk4NIu8goADERUPxgGtD4ClM5)Us+s0EkXMBAgQJvT)0`A>a#k=|8g~ z+$?aZ#OW?N5xNHesPG7?-V~{va=AQ%(4jLoxXKuXrxG#yvcNc~@W}Kq<02yp0MKx@ z7Yna$5(TK`sYI+SVbtPEPqk$&y&gkDOCJ|GGvc<_gyE^X%zI>dxHu0)zr43ixIfs9 zWR&p4%;PRgpAfiMNI@#sb_9$>WD*M{A-C&#!@nbc0MDGSGqeBz002ov 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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