Mods in den Spieleordner reingeschoben. So richtig tief.

This commit is contained in:
N-Nachtigal 2025-05-08 22:41:25 +02:00
parent b4b6c08f4f
commit f7bc25a670
1674 changed files with 56056 additions and 530 deletions

View file

@ -0,0 +1,17 @@
name: luacheck
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: apt
run: sudo apt-get install -y luarocks
- name: luacheck install
run: luarocks install --local luacheck
- name: luacheck run
run: $HOME/.luarocks/bin/luacheck ./

3
mods/drawers/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
## Eclipse project files & directories
.project
.settings

29
mods/drawers/.luacheckrc Normal file
View file

@ -0,0 +1,29 @@
unused = false
max_line_length = 240
globals = {
"drawers"
}
read_globals = {
-- Stdlib
string = {fields = {"split"}},
table = {fields = {"copy", "getn"}},
-- Minetest
"vector", "ItemStack",
"dump", "VoxelArea",
-- deps
"minetest",
"core",
"default",
"mcl_core",
"mcl_sounds",
"pipeworks",
"screwdriver",
"digilines",
"mesecon",
"techage"
}

117
mods/drawers/LICENSE.txt Normal file
View file

@ -0,0 +1,117 @@
Minetest Mod Storage Drawers
============================
License of source code:
-----------------------
Copyright (C) 2017-2020 Linus Jahn <lnj@kaidan.im>
Copyright (C) 2016 Mango Tango <mtango688@gmail.com>
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
License of translations:
------------------------
CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
No Copyright
Minetest Mod Storage Drawers Translators
The person who associated a work with this deed has dedicated the work to the public
domain by waiving all of his or her rights to the work worldwide under copyright law,
including all related and neighboring rights, to the extent allowed by law.
You can copy, modify, distribute and perform the work, even for commercial purposes, all
without asking permission. See Other Information below.
Other Information
In no way are the patent or trademark rights of any person affected by CC0, nor are the
rights that other persons may have in the work or in how the work is used, such as
publicity or privacy rights.
Unless expressly stated otherwise, the person who associated a work with this deed makes
no warranties about the work, and disclaims liability for all uses of the work, to the
fullest extent permitted by applicable law.
When using or citing the work, you should not imply endorsement by the author or the
affirmer.
For more details:
https://creativecommons.org/publicdomain/zero/1.0/
License of media:
-----------------
Copyright (C) 2012 ultradust (https://www.freesound.org/people/ultradust/) (CC BY 3.0):
sounds/drawers_interact.1.ogg (edited by tacotexmex)
sounds/drawers_interact.2.ogg (edited by tacotexmex)
Copyright (C) 2014 Justin Aquadro (MIT):
textures/drawers_acacia_wood_mcl_front_1.png
textures/drawers_acacia_wood_mcl_front_2.png
textures/drawers_acacia_wood_mcl_front_4.png
textures/drawers_acacia_wood_mcl.png
textures/drawers_aspen_wood_front_1.png
textures/drawers_aspen_wood_front_2.png
textures/drawers_aspen_wood_front_4.png
textures/drawers_aspen_wood.png
textures/drawers_birch_wood_front_1.png
textures/drawers_birch_wood_front_2.png
textures/drawers_birch_wood_front_4.png
textures/drawers_birch_wood.png
textures/drawers_controller_front.png
textures/drawers_controller_side.png
textures/drawers_controller_top.png
textures/drawers_dark_oak_wood_front_1.png
textures/drawers_dark_oak_wood_front_2.png
textures/drawers_dark_oak_wood_front_4.png
textures/drawers_dark_oak_wood.png
textures/drawers_junglewood_mcl_front_1.png
textures/drawers_junglewood_mcl_front_2.png
textures/drawers_junglewood_mcl_front_4.png
textures/drawers_junglewood_mcl.png
textures/drawers_oak_wood_front_1.png
textures/drawers_oak_wood_front_2.png
textures/drawers_oak_wood_front_4.png
textures/drawers_oak_wood.png
textures/drawers_pine_wood_front_1.png
textures/drawers_pine_wood_front_2.png
textures/drawers_pine_wood_front_4.png
textures/drawers_pine_wood.png
textures/drawers_spruce_wood_front_1.png
textures/drawers_spruce_wood_front_2.png
textures/drawers_spruce_wood_front_4.png
textures/drawers_spruce_wood.png
textures/drawers_trim.png
textures/drawers_upgrade_diamond.png
textures/drawers_upgrade_emerald.png
textures/drawers_upgrade_gold.png
textures/drawers_upgrade_iron.png
textures/drawers_upgrade_mithril.png (colors adapted by Linus Jahn <lnj@kaidan.im>, 2020)
textures/drawers_upgrade_obsidian.png
textures/drawers_upgrade_steel.png
textures/drawers_upgrade_slot_bg.png (extracted from gui/drawers_1.png by LNJ <git@lnj.li>)
textures/drawers_upgrade_template.png
textures/drawers_wood_front_1.png
textures/drawers_wood_front_2.png
textures/drawers_wood_front_4.png
textures/drawers_wood.png
Everything not listed in here:
Copyright (C) 2017-2020 Linus Jahn <lnj@kaidan.im> (MIT)

58
mods/drawers/README.md Normal file
View file

@ -0,0 +1,58 @@
# Minetest Mod Storage Drawers
[![ContentDB](https://content.minetest.net/packages/LNJ/drawers/shields/downloads/)](https://content.minetest.net/packages/LNJ/drawers/)
![](https://github.com/minetest-mods/drawers/workflows/luacheck/badge.svg)
Version 0.6.5, License: MIT
## Description
This mod adds simple item storages showing the item's inventory image in the
front. By left- or right-clicking the image you can take or add stacks. If you
also hold the shift-key only a single item will be removed/added.
There's also a 'Drawer Controller' which can insert items automatically into a
network of drawers. Just place the drawers next to each other, so they are
connected and the drawer controller will sort the items automatically. If you
want to connect drawers, but you don't want to place another drawer, just use
the 'Drawer Trim'.
Do you have too many cobblestones for one drawer? No problem, just add some
drawer upgrades to your drawer! They are available in different sizes and are
crafted by steel, gold, obsidian, diamonds or mithril.
## Notes
This mod requires Minetest 0.4.14 or later. The `default` mod from MTG or the
MineClone 2 mods are only optional dependencies for crafting recipes.
## To-Do
- [x] Add usable 1x1 drawer
- [x] Add a drawer controller for auto-sorting items into a drawer-network
- [ ] Add half-sized drawers
- [x] Add 2x2 and 1x2 drawers
- [ ] Add compacting drawers for auto-crafting blocks/ingots/fragments
- [ ] Add a key (or something similar) for locking the item (so the item is
also displayed at count 0)
- [ ] Add duct tape to transport drawers
- [x] Support pipeworks
- [ ] Support hoppers (needs hoppers mod change)
- [x] Make drawers upgradable
- [x] Add drawers in all wood types
- [x] Make them digilines compatible
## Bug reports and suggestions
You can report bugs and suggest ideas on [GitHub](http://github.com/lnj2/drawers/issues/new),
alternatively you can also [email](mailto:git@lnj.li) me.
## Credits
#### Thanks to:
* Justin Aquadro ([@jaquadro](http://github.com/jaquadro)), developer of the
original Minecraft Mod (also licensed under MIT :smiley:) — Textures and Ideas
* Mango Tango <<mtango688@gmail.com>> ([@mtango688](http://github.com/mtango688)),
creator of the Minetest Mod ["Caches"](https://github.com/mtango688/caches/)
— I reused some code by you. :)
## Links
* [Minetest Forums](https://forum.minetest.net/viewtopic.php?f=9&t=17134)
* [Minetest Wiki](http://wiki.minetest.net/Mods/Storage_Drawers)
* [Weblate](https://hosted.weblate.org/projects/minetest/mod-storage-drawers/)
* [GitHub](http://github.com/minetest-mods/drawers/)

384
mods/drawers/init.lua Normal file
View file

@ -0,0 +1,384 @@
--[[
Minetest Mod Storage Drawers - A Mod adding storage drawers
Copyright (C) 2017-2020 Linus Jahn <lnj@kaidan.im>
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]
local MP = core.get_modpath(core.get_current_modname())
local S = minetest.get_translator('drawers')
local NS = minetest.get_translator('drawers')
drawers = {}
drawers.drawer_visuals = {}
drawers.WOOD_ITEMSTRING = "group:wood"
if core.get_modpath("default") and default then
drawers.WOOD_SOUNDS = default.node_sound_wood_defaults()
drawers.CHEST_ITEMSTRING = "default:chest"
elseif core.get_modpath("mcl_core") and mcl_core then -- MineClone 2
drawers.CHEST_ITEMSTRING = "mcl_chests:chest"
if core.get_modpath("mcl_sounds") and mcl_sounds then
drawers.WOOD_SOUNDS = mcl_sounds.node_sound_wood_defaults()
end
else
drawers.CHEST_ITEMSTRING = "chest"
end
drawers.enable_1x1 = not core.settings:get_bool("drawers_disable_1x1")
drawers.enable_1x2 = not core.settings:get_bool("drawers_disable_1x2")
drawers.enable_2x2 = not core.settings:get_bool("drawers_disable_2x2")
drawers.CONTROLLER_RANGE = 14
--
-- GUI
--
drawers.gui_bg = "bgcolor[#080808BB;true]"
drawers.gui_slots = "listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]"
if (core.get_modpath("mcl_core")) and mcl_core then -- MCL2
drawers.gui_bg_img = "background[5,5;1,1;crafting_creative_bg.png;true]"
else
drawers.gui_bg_img = "background[5,5;1,1;gui_formbg.png;true]"
end
--
-- Load API
--
dofile(MP .. "/lua/helpers.lua")
dofile(MP .. "/lua/visual.lua")
dofile(MP .. "/lua/api.lua")
dofile(MP .. "/lua/controller.lua")
--
-- Register drawers
--
if core.get_modpath("default") and default then
drawers.register_drawer("drawers:wood", {
description = S("Wooden"),
tiles1 = drawers.node_tiles_front_other("drawers_wood_front_1.png",
"drawers_wood.png"),
tiles2 = drawers.node_tiles_front_other("drawers_wood_front_2.png",
"drawers_wood.png"),
tiles4 = drawers.node_tiles_front_other("drawers_wood_front_4.png",
"drawers_wood.png"),
groups = {choppy = 3, oddly_breakable_by_hand = 2},
sounds = drawers.WOOD_SOUNDS,
drawer_stack_max_factor = 32, -- 4 * 8 normal chest size
material = drawers.WOOD_ITEMSTRING
})
drawers.register_drawer("drawers:acacia_wood", {
description = S("Acacia Wood"),
tiles1 = drawers.node_tiles_front_other("drawers_acacia_wood_front_1.png",
"drawers_acacia_wood.png"),
tiles2 = drawers.node_tiles_front_other("drawers_acacia_wood_front_2.png",
"drawers_acacia_wood.png"),
tiles4 = drawers.node_tiles_front_other("drawers_acacia_wood_front_4.png",
"drawers_acacia_wood.png"),
groups = {choppy = 3, oddly_breakable_by_hand = 2},
sounds = drawers.WOOD_SOUNDS,
drawer_stack_max_factor = 32, -- 4 * 8 normal mcl chest size
material = "default:acacia_wood"
})
drawers.register_drawer("drawers:aspen_wood", {
description = S("Aspen Wood"),
tiles1 = drawers.node_tiles_front_other("drawers_aspen_wood_front_1.png",
"drawers_aspen_wood.png"),
tiles2 = drawers.node_tiles_front_other("drawers_aspen_wood_front_2.png",
"drawers_aspen_wood.png"),
tiles4 = drawers.node_tiles_front_other("drawers_aspen_wood_front_4.png",
"drawers_aspen_wood.png"),
groups = {choppy = 3, oddly_breakable_by_hand = 2},
sounds = drawers.WOOD_SOUNDS,
drawer_stack_max_factor = 32, -- 4 * 8 normal chest size
material = "default:aspen_wood"
})
drawers.register_drawer("drawers:junglewood", {
description = S("Junglewood"),
tiles1 = drawers.node_tiles_front_other("drawers_junglewood_front_1.png",
"drawers_junglewood.png"),
tiles2 = drawers.node_tiles_front_other("drawers_junglewood_front_2.png",
"drawers_junglewood.png"),
tiles4 = drawers.node_tiles_front_other("drawers_junglewood_front_4.png",
"drawers_junglewood.png"),
groups = {choppy = 3, oddly_breakable_by_hand = 2},
sounds = drawers.WOOD_SOUNDS,
drawer_stack_max_factor = 32, -- 4 * 8 normal mcl chest size
material = "default:junglewood"
})
drawers.register_drawer("drawers:pine_wood", {
description = S("Pine Wood"),
tiles1 = drawers.node_tiles_front_other("drawers_pine_wood_front_1.png",
"drawers_pine_wood.png"),
tiles2 = drawers.node_tiles_front_other("drawers_pine_wood_front_2.png",
"drawers_pine_wood.png"),
tiles4 = drawers.node_tiles_front_other("drawers_pine_wood_front_4.png",
"drawers_pine_wood.png"),
groups = {choppy = 3, oddly_breakable_by_hand = 2},
sounds = drawers.WOOD_SOUNDS,
drawer_stack_max_factor = 32, -- 4 * 8 normal chest size
material = "default:pine_wood"
})
elseif core.get_modpath("mcl_core") and mcl_core then
drawers.register_drawer("drawers:oakwood", {
description = S("Oak Wood"),
tiles1 = drawers.node_tiles_front_other("drawers_oak_wood_front_1.png",
"drawers_oak_wood.png"),
tiles2 = drawers.node_tiles_front_other("drawers_oak_wood_front_2.png",
"drawers_oak_wood.png"),
tiles4 = drawers.node_tiles_front_other("drawers_oak_wood_front_4.png",
"drawers_oak_wood.png"),
groups = {handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1},
sounds = drawers.WOOD_SOUNDS,
drawer_stack_max_factor = 36, -- 4 * 9 normal mcl chest size
material = drawers.WOOD_ITEMSTRING,
_mcl_blast_resistance = 15,
_mcl_hardness = 2,
})
drawers.register_drawer("drawers:acaciawood", {
description = S("Acacia Wood"),
tiles1 = drawers.node_tiles_front_other("drawers_acacia_wood_mcl_front_1.png",
"drawers_acacia_wood_mcl.png"),
tiles2 = drawers.node_tiles_front_other("drawers_acacia_wood_mcl_front_2.png",
"drawers_acacia_wood_mcl.png"),
tiles4 = drawers.node_tiles_front_other("drawers_acacia_wood_mcl_front_4.png",
"drawers_acacia_wood_mcl.png"),
groups = {handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1},
sounds = drawers.WOOD_SOUNDS,
drawer_stack_max_factor = 36, -- 4 * 9 normal mcl chest size
material = "mcl_core:acaciawood",
_mcl_blast_resistance = 15,
_mcl_hardness = 2,
})
drawers.register_drawer("drawers:birchwood", {
description = S("Birch Wood"),
tiles1 = drawers.node_tiles_front_other("drawers_birch_wood_front_1.png",
"drawers_birch_wood.png"),
tiles2 = drawers.node_tiles_front_other("drawers_birch_wood_front_2.png",
"drawers_birch_wood.png"),
tiles4 = drawers.node_tiles_front_other("drawers_birch_wood_front_4.png",
"drawers_birch_wood.png"),
groups = {handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1},
sounds = drawers.WOOD_SOUNDS,
drawer_stack_max_factor = 36, -- 4 * 9 normal mcl chest size
material = "mcl_core:birchwood",
_mcl_blast_resistance = 15,
_mcl_hardness = 2,
})
drawers.register_drawer("drawers:darkwood", {
description = S("Dark Oak Wood"),
tiles1 = drawers.node_tiles_front_other("drawers_dark_oak_wood_front_1.png",
"drawers_dark_oak_wood.png"),
tiles2 = drawers.node_tiles_front_other("drawers_dark_oak_wood_front_2.png",
"drawers_dark_oak_wood.png"),
tiles4 = drawers.node_tiles_front_other("drawers_dark_oak_wood_front_4.png",
"drawers_dark_oak_wood.png"),
groups = {handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1},
sounds = drawers.WOOD_SOUNDS,
drawer_stack_max_factor = 36, -- 4 * 9 normal mcl chest size
material = "mcl_core:darkwood",
_mcl_blast_resistance = 15,
_mcl_hardness = 2,
})
drawers.register_drawer("drawers:junglewood", {
description = S("Junglewood"),
tiles1 = drawers.node_tiles_front_other("drawers_junglewood_mcl_front_1.png",
"drawers_junglewood_mcl.png"),
tiles2 = drawers.node_tiles_front_other("drawers_junglewood_mcl_front_2.png",
"drawers_junglewood_mcl.png"),
tiles4 = drawers.node_tiles_front_other("drawers_junglewood_mcl_front_4.png",
"drawers_junglewood_mcl.png"),
groups = {handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1},
sounds = drawers.WOOD_SOUNDS,
drawer_stack_max_factor = 36, -- 4 * 9 normal mcl chest size
material = "mcl_core:junglewood",
_mcl_blast_resistance = 15,
_mcl_hardness = 2,
})
drawers.register_drawer("drawers:sprucewood", {
description = S("Spruce Wood"),
tiles1 = drawers.node_tiles_front_other("drawers_spruce_wood_front_1.png",
"drawers_spruce_wood.png"),
tiles2 = drawers.node_tiles_front_other("drawers_spruce_wood_front_2.png",
"drawers_spruce_wood.png"),
tiles4 = drawers.node_tiles_front_other("drawers_spruce_wood_front_4.png",
"drawers_spruce_wood.png"),
groups = {handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1},
sounds = drawers.WOOD_SOUNDS,
drawer_stack_max_factor = 36, -- 4 * 9 normal mcl chest size
material = "mcl_core:sprucewood",
_mcl_blast_resistance = 15,
_mcl_hardness = 2,
})
-- backwards compatibility
core.register_alias("drawers:wood1", "drawers:oakwood1")
core.register_alias("drawers:wood2", "drawers:oakwood2")
core.register_alias("drawers:wood4", "drawers:oakwood4")
else
drawers.register_drawer("drawers:wood", {
description = S("Wooden"),
tiles1 = drawers.node_tiles_front_other("drawers_wood_front_1.png",
"drawers_wood.png"),
tiles2 = drawers.node_tiles_front_other("drawers_wood_front_2.png",
"drawers_wood.png"),
tiles4 = drawers.node_tiles_front_other("drawers_wood_front_4.png",
"drawers_wood.png"),
groups = {choppy = 3, oddly_breakable_by_hand = 2},
sounds = drawers.WOOD_SOUNDS,
drawer_stack_max_factor = 32, -- 4 * 8 normal chest size
material = drawers.WOOD_ITEMSTRING
})
end
--
-- Register drawer upgrades
--
if core.get_modpath("default") and default then
drawers.register_drawer_upgrade("drawers:upgrade_steel", {
description = S("Steel Drawer Upgrade (x2)"),
inventory_image = "drawers_upgrade_steel.png",
groups = {drawer_upgrade = 100},
recipe_item = "default:steel_ingot"
})
drawers.register_drawer_upgrade("drawers:upgrade_gold", {
description = S("Gold Drawer Upgrade (x3)"),
inventory_image = "drawers_upgrade_gold.png",
groups = {drawer_upgrade = 200},
recipe_item = "default:gold_ingot"
})
drawers.register_drawer_upgrade("drawers:upgrade_obsidian", {
description = S("Obsidian Drawer Upgrade (x4)"),
inventory_image = "drawers_upgrade_obsidian.png",
groups = {drawer_upgrade = 300},
recipe_item = "default:obsidian"
})
drawers.register_drawer_upgrade("drawers:upgrade_diamond", {
description = S("Diamond Drawer Upgrade (x8)"),
inventory_image = "drawers_upgrade_diamond.png",
groups = {drawer_upgrade = 700},
recipe_item = "default:diamond"
})
elseif core.get_modpath("mcl_core") and mcl_core then
drawers.register_drawer_upgrade("drawers:upgrade_iron", {
description = S("Iron Drawer Upgrade (x2)"),
inventory_image = "drawers_upgrade_iron.png",
groups = {drawer_upgrade = 100},
recipe_item = "mcl_core:iron_ingot"
})
drawers.register_drawer_upgrade("drawers:upgrade_gold", {
description = S("Gold Drawer Upgrade (x3)"),
inventory_image = "drawers_upgrade_gold.png",
groups = {drawer_upgrade = 200},
recipe_item = "mcl_core:gold_ingot"
})
drawers.register_drawer_upgrade("drawers:upgrade_obsidian", {
description = S("Obsidian Drawer Upgrade (x4)"),
inventory_image = "drawers_upgrade_obsidian.png",
groups = {drawer_upgrade = 300},
recipe_item = "mcl_core:obsidian"
})
drawers.register_drawer_upgrade("drawers:upgrade_diamond", {
description = S("Diamond Drawer Upgrade (x8)"),
inventory_image = "drawers_upgrade_diamond.png",
groups = {drawer_upgrade = 700},
recipe_item = "mcl_core:diamond"
})
drawers.register_drawer_upgrade("drawers:upgrade_emerald", {
description = S("Emerald Drawer Upgrade (x13)"),
inventory_image = "drawers_upgrade_emerald.png",
groups = {drawer_upgrade = 1200},
recipe_item = "mcl_core:emerald"
})
end
if core.get_modpath("moreores") then
drawers.register_drawer_upgrade("drawers:upgrade_mithril", {
description = S("Mithril Drawer Upgrade (x13)"),
inventory_image = "drawers_upgrade_mithril.png",
groups = {drawer_upgrade = 1200},
recipe_item = "moreores:mithril_ingot"
})
end
--
-- Register drawer trim
--
if core.get_modpath("mcl_core") and mcl_core then
core.register_node("drawers:trim", {
description = S("Wooden Trim"),
tiles = {"drawers_trim.png"},
groups = {drawer_connector = 1, handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1},
_mcl_blast_resistance = 15,
_mcl_hardness = 2,
})
else
core.register_node("drawers:trim", {
description = S("Wooden Trim"),
tiles = {"drawers_trim.png"},
groups = {drawer_connector = 1, choppy = 3, oddly_breakable_by_hand = 2},
})
end
core.register_craft({
output = "drawers:trim 6",
recipe = {
{"group:stick", "group:wood", "group:stick"},
{"group:wood", "group:wood", "group:wood"},
{"group:stick", "group:wood", "group:stick"}
}
})
--
-- Register drawer upgrade template
--
core.register_craftitem("drawers:upgrade_template", {
description = S("Drawer Upgrade Template"),
inventory_image = "drawers_upgrade_template.png"
})
core.register_craft({
output = "drawers:upgrade_template 4",
recipe = {
{"group:stick", "group:stick", "group:stick"},
{"group:stick", "group:drawer", "group:stick"},
{"group:stick", "group:stick", "group:stick"}
}
})

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=@1 шуфляда
@1 Drawers (1x2)=@1 шуфляды (1x2)
@1 Drawers (2x2)=@1 шуфляды (2x2)
Empty=Пустая
Drawer Controller=Кантролер шуфляды
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% поўны)
@1 @2 (@3% full)=@1 @2 (@3% поўны)
Acacia Wood=Драўніна акацыі
Aspen Wood=Асінавая драўніна
Junglewood=Джунглевая драўніна
Pine Wood=Хваёвая драўніна
Oak Wood=Дубовая драўніна
Birch Wood=Бярозавая драўніна
Dark Oak Wood=Цёмная дубовая драўніна
Spruce Wood=Ялінавая драўніна
Steel Drawer Upgrade (x2)=Мадэрнізацыя сталёвай шуфляды (x2)
Gold Drawer Upgrade (x3)=Мадэрнізацыя залатой шуфляды (x3)
Obsidian Drawer Upgrade (x4)=Мадэрнізацыя абсідыянавай шуфляды (x5)
Diamond Drawer Upgrade (x8)=Мадэрнізацыя дыяментавай шуфляды (x8)
Iron Drawer Upgrade (x2)=Мадэрнізацыя жалезнай шуфляды (x2)
Emerald Drawer Upgrade (x13)=Мадэрнізацыя смарагдавай шуфляды (x13)
Mithril Drawer Upgrade (x13)=Мадэрнізацыя смарагдавай шуфляды (x13)
Wooden Trim=Драўлянае аздабленне
Drawer Upgrade Template=Шаблон мадэрнізацыі шуфляды
Wooden=Драўляны

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=@১ ড্রয়ার
@1 Drawers (1x2)=@১ ড্রয়ার (১x২)
@1 Drawers (2x2)=@১ ড্রয়ার (২x২)
Empty=খালি
Drawer Controller=ড্রয়ার কন্ট্রোলার
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% পূর্ণ)
@1 @2 (@3% full)=@1 @2 (@3% পূর্ণ)
Acacia Wood=বাবলা কাঠ
Aspen Wood=ভূর্জ কাঠ
Junglewood=জংলিকাঠ
Pine Wood=পাইন কাঠ
Oak Wood=
Birch Wood=ভূর্জ কাঠ
Dark Oak Wood=
Spruce Wood=
Steel Drawer Upgrade (x2)=
Gold Drawer Upgrade (x3)=
Obsidian Drawer Upgrade (x4)=
Diamond Drawer Upgrade (x8)=
Iron Drawer Upgrade (x2)=
Emerald Drawer Upgrade (x13)=
Mithril Drawer Upgrade (x13)=
Wooden Trim=
Drawer Upgrade Template=
Wooden=কাঠের

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=Šuplík @1
@1 Drawers (1x2)=Šuplíky @1 (1x2)
@1 Drawers (2x2)=Šuplíky @1 (2x2)
Empty=Prázdný
Drawer Controller=
Digiline Channel=
Save=
@1 (@2% full)=@1 (z @2 % plný)
@1 @2 (@3% full)=@1 @2 (z @3 % plný)
Acacia Wood=ze dřeva akácie
Aspen Wood=ze dřeva osiky
Junglewood=ze dřeva džunglovníku
Pine Wood=ze borovicového dřeva
Oak Wood=ze dubového dřeva
Birch Wood=z bukového dřeva
Dark Oak Wood=z tmavého dubového dřeva
Spruce Wood=ze smrkového dřeva
Steel Drawer Upgrade (x2)=Ocelové vylepšení šuplíku (x2)
Gold Drawer Upgrade (x3)=Zlaté vylepšení šuplíku (x3)
Obsidian Drawer Upgrade (x4)=Obsidiánové vylepšení šuplíku (x5)
Diamond Drawer Upgrade (x8)=Diamantové vylepšení šuplíku (x8)
Iron Drawer Upgrade (x2)=Železné vylepšení šuplíku (x2)
Emerald Drawer Upgrade (x13)=Emeraldové vylepšení šuplíku (x13)
Mithril Drawer Upgrade (x13)=Emeraldové vylepšení šuplíku (x13)
Wooden Trim=Dřevěný Ořez
Drawer Upgrade Template=Šablona vylepšení šuplíku
Wooden=Dřevěný

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=@1schubfach
@1 Drawers (1x2)=@1schubfächer (1×2)
@1 Drawers (2x2)=@1schubfächer (2×2)
Empty=Leer
Drawer Controller=Schubfach Steuerung
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% voll)
@1 @2 (@3% full)=@1 @2 (@3% voll)
Acacia Wood=Akazienholz
Aspen Wood=Espenholz
Junglewood=Tropenholz
Pine Wood=Kiefernholz
Oak Wood=Eichenholz
Birch Wood=Birkenholz
Dark Oak Wood=Dunkeleichenholz
Spruce Wood=Fichtenholz
Steel Drawer Upgrade (x2)=Stahl-Schubfachverbesserung (×2)
Gold Drawer Upgrade (x3)=Gold-Schubfachverbesserung (×3)
Obsidian Drawer Upgrade (x4)=Obsidian-Schubfachverbesserung (×5)
Diamond Drawer Upgrade (x8)=Diamant-Schubfachverbesserung (×8)
Iron Drawer Upgrade (x2)=Eisen-Schubfachverbesserung (×2)
Emerald Drawer Upgrade (x13)=Smaragd-Schubfachverbesserung (×13)
Mithril Drawer Upgrade (x13)=Smaragd-Schubfachverbesserung (×13)
Wooden Trim=Holzverkleidung
Drawer Upgrade Template=Schubfachverbesserungsvorlage
Wooden=Holz

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=@1 συρτάρι
@1 Drawers (1x2)=@1 συρτάρια (1x2)
@1 Drawers (2x2)=@1 συρτάρια (2x2)
Empty=Κενό
Drawer Controller=Ελεγκτής συρταριού
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% Πλήρης)
@1 @2 (@3% full)=
Acacia Wood=Ξύλο ακακίας
Aspen Wood=
Junglewood=
Pine Wood=Ξύλο πεύκου
Oak Wood=Ξύλο βελανιδιάς
Birch Wood=Ξύλο σημύδας
Dark Oak Wood=Σκούρο ξύλο βελανιδιάς
Spruce Wood=Ξύλο ερυθρελάτης
Steel Drawer Upgrade (x2)=Χαλύβδινη αναβάθμιση συρταριού (x2)
Gold Drawer Upgrade (x3)=Χρυσού αναβάθμιση συρταριού (x3)
Obsidian Drawer Upgrade (x4)=
Diamond Drawer Upgrade (x8)=Διαμαντένια Αναβάθμιση συρταριού (x8)
Iron Drawer Upgrade (x2)=Σιδερένια αναβάθμιση συρταριού (x2)
Emerald Drawer Upgrade (x13)=Σμαραγδένια αναβάθμιση συρταριού (x13)
Mithril Drawer Upgrade (x13)=
Wooden Trim=
Drawer Upgrade Template=
Wooden=Ξύλινο

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=@1 tirkesto
@1 Drawers (1x2)=@1 tirkestoj (1×2)
@1 Drawers (2x2)=@1 tirkestoj (2×2)
Empty=Malplena
Drawer Controller=Regilo de tirkesto
Digiline Channel=
Save=
@1 (@2% full)=@1 (plena je @2%)
@1 @2 (@3% full)=@1 @2 (plena je @3%)
Acacia Wood=Akacia ligno
Aspen Wood=Tremola ligno
Junglewood=Ĝangala ligno
Pine Wood=Abia ligno
Oak Wood=Kverka ligno
Birch Wood=Betula ligno
Dark Oak Wood=Malhela kverka ligno
Spruce Wood=Picea ligno
Steel Drawer Upgrade (x2)=Ŝtala plibonigo de tirkesto (×2)
Gold Drawer Upgrade (x3)=Ora plibonigo de tirkesto (×3)
Obsidian Drawer Upgrade (x4)=Obsidiana plibonigo de tirkesto (×5)
Diamond Drawer Upgrade (x8)=Diamanta plibonigo de tirkesto (×8)
Iron Drawer Upgrade (x2)=Fera plibonigo de tirkesto (×2)
Emerald Drawer Upgrade (x13)=Smeralda plibonigo de tirkesto (×13)
Mithril Drawer Upgrade (x13)=Smeralda plibonigo de tirkesto (×13)
Wooden Trim=
Drawer Upgrade Template=Ŝablono por plibonigo de tirkesto
Wooden=Ligna

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=
@1 Drawers (1x2)=Mejora para Gavetas de Hierro (x2)
@1 Drawers (2x2)=Mejora para Gavetas de Hierro (x2)
Empty=Vacío
Drawer Controller=Controlador de Gavetas
Digiline Channel=
Save=
@1 (@2% full)=
@1 @2 (@3% full)=
Acacia Wood=Madera de acacia
Aspen Wood=Madera de álamo
Junglewood=Madera tropical
Pine Wood=Madera de pino
Oak Wood=Madera de roble
Birch Wood=Madera de abedul
Dark Oak Wood=Madera de roble oscuro
Spruce Wood=Madera de pícea
Steel Drawer Upgrade (x2)=Mejora para Gavetas de Acero (x2)
Gold Drawer Upgrade (x3)=Mejora para Gavetas de Oro (x3)
Obsidian Drawer Upgrade (x4)=Mejora para Gavetas de Obsidiana (x5)
Diamond Drawer Upgrade (x8)=Mejora para Gavetas de Diamante (x8)
Iron Drawer Upgrade (x2)=Mejora para Gavetas de Hierro (x2)
Emerald Drawer Upgrade (x13)=Mejora para Gavetas de Esmeralda (x13)
Mithril Drawer Upgrade (x13)=Mejora para Gavetas de Esmeralda (x13)
Wooden Trim=Recorte De Madera
Drawer Upgrade Template=Plantilla de mejoras para gavetas
Wooden=De Madera

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=@1 salv
@1 Drawers (1x2)=@1 salved (1x2)
@1 Drawers (2x2)=@1 salved (2x2)
Empty=Tühi
Drawer Controller=Salve juhtpult
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% täis)
@1 @2 (@3% full)=@1 @2 (@3% täis)
Acacia Wood=Akaatsia puidust
Aspen Wood=Haavast
Junglewood=Tihniku puidust
Pine Wood=Männist
Oak Wood=Tammest
Birch Wood=Kasest
Dark Oak Wood=Tõmmu-tammest
Spruce Wood=Kuusest
Steel Drawer Upgrade (x2)=Teras salve täiustus (x2)
Gold Drawer Upgrade (x3)=Kuld salve täiustus (x3)
Obsidian Drawer Upgrade (x4)=Vulkaanklaas salve täiustus (x5)
Diamond Drawer Upgrade (x8)=Teemant salve täiustus (x8)
Iron Drawer Upgrade (x2)=Raud salve täiustus (x2)
Emerald Drawer Upgrade (x13)=Smaragd salve täiustus (x13)
Mithril Drawer Upgrade (x13)=Smaragd salve täiustus (x13)
Wooden Trim=Puitliist
Drawer Upgrade Template=Salve täiustamise kava
Wooden=Puidust

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=Tiroir @1
@1 Drawers (1x2)=Tiroirs (1x2) @1
@1 Drawers (2x2)=Tiroirs (2x2) @1
Empty=Vide
Drawer Controller=Contrôleur de Tiroirs
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% plein)
@1 @2 (@3% full)=@1 @2 (@3% plein)
Acacia Wood=Bois d'acacia
Aspen Wood=Bois de tremble
Junglewood=Bois de jungle
Pine Wood=Bois de pin
Oak Wood=Bois de chêne
Birch Wood=Bois de bouleau
Dark Oak Wood=Bois de chêne foncé
Spruce Wood=Bois d'épicéa
Steel Drawer Upgrade (x2)=Amélioration tiroir en acier (x2)
Gold Drawer Upgrade (x3)=Amélioration tiroir en or (x3)
Obsidian Drawer Upgrade (x4)=Amélioration tiroir en obsidienne (x5)
Diamond Drawer Upgrade (x8)=Amélioration tiroir en diamant (x8)
Iron Drawer Upgrade (x2)=Amélioration tiroir en fer (x2)
Emerald Drawer Upgrade (x13)=Amélioration tiroir en émeraude (x13)
Mithril Drawer Upgrade (x13)=Amélioration tiroir en émeraude (x13)
Wooden Trim=Habillage en bois
Drawer Upgrade Template=Amélioration modèle de tiroir
Wooden=En bois

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=מגירה @1
@1 Drawers (1x2)=@1 מגירות (1x2)
@1 Drawers (2x2)=@1 מגירות (2x2)
Empty=ריקה
Drawer Controller=
Digiline Channel=
Save=
@1 (@2% full)=@1 (תפוסה של @1%)
@1 @2 (@3% full)=@1 @2 (תפוסה של @3%)
Acacia Wood=עץ שיטה
Aspen Wood=עץ אספן
Junglewood=עץ ג׳ונגל
Pine Wood=עץ אורן
Oak Wood=עץ אלון
Birch Wood=עץ לבנה
Dark Oak Wood=עץ אלון כהה
Spruce Wood=עץ אשוח
Steel Drawer Upgrade (x2)=
Gold Drawer Upgrade (x3)=
Obsidian Drawer Upgrade (x4)=
Diamond Drawer Upgrade (x8)=
Iron Drawer Upgrade (x2)=
Emerald Drawer Upgrade (x13)=
Mithril Drawer Upgrade (x13)=
Wooden Trim=
Drawer Upgrade Template=
Wooden=מעץ

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=Laci @1
@1 Drawers (1x2)=Laci @1 (1x2)
@1 Drawers (2x2)=Laci @1 (2x2)
Empty=Kosong
Drawer Controller=Pengendali Laci
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% penuh)
@1 @2 (@3% full)=@1 @2 (@3% penuh)
Acacia Wood=Kayu Akasia
Aspen Wood=Kayu Aspen
Junglewood=Kayu Rimba
Pine Wood=Kayu Pinus
Oak Wood=Kayu Ek
Birch Wood=Kayu Birch
Dark Oak Wood=Kayu Ek Gelap
Spruce Wood=Kayu Cemara
Steel Drawer Upgrade (x2)=Tingkatkan menjadi Laci Baja (x2)
Gold Drawer Upgrade (x3)=Tingkatkan menjadi Laci Emas (x3)
Obsidian Drawer Upgrade (x4)=Tingkatkan menjadi Laci Obsidian (x5)
Diamond Drawer Upgrade (x8)=Tingkatkan menjadi Laci Berlian (x8)
Iron Drawer Upgrade (x2)=Tingkatkan menjadi Laci Besi (x2)
Emerald Drawer Upgrade (x13)=Tingkatkan menjadi Laci Zamrud (x13)
Mithril Drawer Upgrade (x13)=Tingkatkan menjadi Laci Zamrud (x13)
Wooden Trim=Ukiran Kayu
Drawer Upgrade Template=Templat Peningkatan Laci
Wooden=Kayu

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=@1 Cassetto
@1 Drawers (1x2)=@1 Cassetti (1x2)
@1 Drawers (2x2)=@1 Cassetti (2x2)
Empty=Vuoto
Drawer Controller=
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% pieno)
@1 @2 (@3% full)=@1 @2 (@3% pieno)
Acacia Wood=Legno di acacia
Aspen Wood=Legno di pioppo
Junglewood=Legno della giungla
Pine Wood=Legno di pino
Oak Wood=Legno di quercia
Birch Wood=Legno di betulla
Dark Oak Wood=Legno di quercia scura
Spruce Wood=Legno di abete rosso
Steel Drawer Upgrade (x2)=Miglioramento d'acciaio della cassettiera (x2)
Gold Drawer Upgrade (x3)=Miglioramento d'oro della cassettiera (x3)
Obsidian Drawer Upgrade (x4)=Miglioramento d'ossidiana della cassettiera (x5)
Diamond Drawer Upgrade (x8)=Miglioramento di diamante della cassettiera (x8)
Iron Drawer Upgrade (x2)=Miglioramento di ferro della cassettiera (x3)
Emerald Drawer Upgrade (x13)=Miglioramento di smeraldo della cassettiera (x13)
Mithril Drawer Upgrade (x13)=Miglioramento di smeraldo della cassettiera (x13)
Wooden Trim=di legno
Drawer Upgrade Template=Modello di miglioramento della cassettiera
Wooden=Di legno

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=Laci @1
@1 Drawers (1x2)=Laci @1 (1x2)
@1 Drawers (2x2)=Laci @1 (2x2)
Empty=Kosong
Drawer Controller=Pengawal Laci
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% penuh)
@1 @2 (@3% full)=@1 @2 (@3% penuh)
Acacia Wood=Papan Kayu Akasia
Aspen Wood=Papan Kayu Aspen
Junglewood=Papan Kayu Hutan
Pine Wood=Papan Kayu Pain
Oak Wood=Papan Kayu Oak
Birch Wood=Papan Kayu Birch
Dark Oak Wood=Papan Kayu Oak Gelap
Spruce Wood=Papan Kayu Fir
Steel Drawer Upgrade (x2)=Naik Taraf Laci - Keluli (x2)
Gold Drawer Upgrade (x3)=Naik Taraf Laci - Emas (x3)
Obsidian Drawer Upgrade (x4)=Naik Taraf Laci - Obsidia (x5)
Diamond Drawer Upgrade (x8)=Naik Taraf Laci - Intan (x8)
Iron Drawer Upgrade (x2)=Naik Taraf Laci - Besi (x2)
Emerald Drawer Upgrade (x13)=Naik Taraf Laci - Zamrud (x13)
Mithril Drawer Upgrade (x13)=Naik Taraf Laci - Zamrud (x13)
Wooden Trim=Hiasan Kayu
Drawer Upgrade Template=Templat Naik Taraf Laci
Wooden=Kayu

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=لاچي @1
@1 Drawers (1x2)=لاچي @1 جنيس 1x2
@1 Drawers (2x2)=لاچي @1 جنيس 2x2
Empty=کوسوڠ
Drawer Controller=ڤڠاول لاچي
Digiline Channel=
Save=
@1 (@2% full)=@1⹁ @2% ڤنوه
@1 @2 (@3% full)=@2 @1⹁ @3% ڤنوه
Acacia Wood=ڤاڤن کايو اکاسيا
Aspen Wood=ڤاڤن کايو اسڤين
Junglewood=ڤاڤن کايو هوتن
Pine Wood=ڤاڤن کايو ڤاين
Oak Wood=ڤاڤن کايو اوک
Birch Wood=ڤاڤن کايو برچ
Dark Oak Wood=ڤاڤن کايو اوک ݢلڤ
Spruce Wood=ڤاڤن کايو فير
Steel Drawer Upgrade (x2)=ناٴيق طرف لاچي - کلولي⹁ x2
Gold Drawer Upgrade (x3)=ناٴيق طرف لاچي - امس⹁ x3
Obsidian Drawer Upgrade (x4)=ناٴيق طرف لاچي - اوبسيدي⹁ x5
Diamond Drawer Upgrade (x8)=ناٴيق طرف لاچي - اينتن⹁ x8
Iron Drawer Upgrade (x2)=ناٴيق طرف لاچي - بسي⹁ x2
Emerald Drawer Upgrade (x13)=ناٴيق طرف لاچي - زمرود⹁ x13
Mithril Drawer Upgrade (x13)=ناٴيق طرف لاچي - زمرود⹁ x13
Wooden Trim=هياسن کايو
Drawer Upgrade Template=تمڤلت ناٴيق طرف لاچي
Wooden=کايو

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=@1 Skuff
@1 Drawers (1x2)=@1 Skuffer (1x2)
@1 Drawers (2x2)=@1 Skuffer (2x2)
Empty=Tom
Drawer Controller=Skuffekontrollør
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% full)
@1 @2 (@3% full)=@1 @2 (@3% full)
Acacia Wood=Akasie
Aspen Wood=Osp
Junglewood=Regnskogtømmer
Pine Wood=Furu
Oak Wood=Eik
Birch Wood=Bjørk
Dark Oak Wood=Mørk eik
Spruce Wood=Gran
Steel Drawer Upgrade (x2)=Stålskuffoppgradering (x2)
Gold Drawer Upgrade (x3)=Gullskuffoppgradering (x3)
Obsidian Drawer Upgrade (x4)=Obsidianskuffoppgradering (x5)
Diamond Drawer Upgrade (x8)=Diamantskuffoppgradering (x8)
Iron Drawer Upgrade (x2)=Jernskuffoppgradering (x2)
Emerald Drawer Upgrade (x13)=Smaragdskuffoppgradering (x13)
Mithril Drawer Upgrade (x13)=Smaragdskuffoppgradering (x13)
Wooden Trim=Kledning i tre
Drawer Upgrade Template=Mal for oppgradering av skuffer
Wooden=Tre

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=@1 Lade
@1 Drawers (1x2)=@1 Lades (1x2)
@1 Drawers (2x2)=@1 Lades (2x2)
Empty=Leeg
Drawer Controller=
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% vol)
@1 @2 (@3% full)=@1 @2 (@3% vol)
Acacia Wood=Acacia Hout
Aspen Wood=Espenhout
Junglewood=Junglehout
Pine Wood=Dennenhout
Oak Wood=Eikenhout
Birch Wood=Berken hout
Dark Oak Wood=Donker Eikenhout
Spruce Wood=Sparrenhout
Steel Drawer Upgrade (x2)=Stalen Lade Upgrade (x2)
Gold Drawer Upgrade (x3)=Gouden Lade Upgrade (x3)
Obsidian Drawer Upgrade (x4)=Obsidianen Lade Upgrade (x5)
Diamond Drawer Upgrade (x8)=Diamanten Lade Upgrade (x8)
Iron Drawer Upgrade (x2)=Ijzeren Lade Upgrade (x2)
Emerald Drawer Upgrade (x13)=Smaragden Lade upgrade (x13)
Mithril Drawer Upgrade (x13)=Smaragden Lade upgrade (x13)
Wooden Trim=Houten bekleding
Drawer Upgrade Template=Lade Upgrade Template
Wooden=Houten

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=@1 Szuflada
@1 Drawers (1x2)=@1 Szuflady (1x2)
@1 Drawers (2x2)=@1 Szuflady (2x2)
Empty=Pusta
Drawer Controller=Kontroler szuflady
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% napełnione)
@1 @2 (@3% full)=@1 @2 (@3% napełnione)
Acacia Wood=Drewno akacjowe
Aspen Wood=Drewno osikowe
Junglewood=Drewno jungli
Pine Wood=Drewno sosnowe
Oak Wood=Drewno dębowe
Birch Wood=Drewno brzozowe
Dark Oak Wood=Drewno ciemne dębowe
Spruce Wood=Drwno świerkowe
Steel Drawer Upgrade (x2)=Ulepszenie stalowej szuflady(x2)
Gold Drawer Upgrade (x3)=Ulepszenie złotej szuflady (x3)
Obsidian Drawer Upgrade (x4)=Ulepszenie obsydianowej szuflady (x5)
Diamond Drawer Upgrade (x8)=Ulepszenie diamentowej szuflady (x8)
Iron Drawer Upgrade (x2)=Żelazna aktualizacja szuflady (x2)
Emerald Drawer Upgrade (x13)=Ulepszenie szmaragdowej szuflady (x13)
Mithril Drawer Upgrade (x13)=Ulepszenie szmaragdowej szuflady (x13)
Wooden Trim=Drewniane wykończenia
Drawer Upgrade Template=Szablon ulepszenia szuflady
Wooden=Drewniany

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=Armário @1
@1 Drawers (1x2)=Armários @1 (1x2)
@1 Drawers (2x2)=Armários @1 (2x2)
Empty=Vazio
Drawer Controller=Controlador de Armários
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% cheio)
@1 @2 (@3% full)=@1 @2 (@3% cheio)
Acacia Wood=Lenha de Acácia
Aspen Wood=Lenha de Álamo
Junglewood=Lenha da selva
Pine Wood=Lenha de Pinheiro
Oak Wood=Lenha de Carvalho
Birch Wood=Lenha de Bétula
Dark Oak Wood=Lenha de Carvalho Escuro
Spruce Wood=Lenha de Abeto
Steel Drawer Upgrade (x2)=Melhoria de Armário de Aço (x2)
Gold Drawer Upgrade (x3)=Melhoria de Armário de Ouro (x3)
Obsidian Drawer Upgrade (x4)=Melhoria de Armário de Obsidiana (x5)
Diamond Drawer Upgrade (x8)=Melhoria de Armário de Diamante (x8)
Iron Drawer Upgrade (x2)=Melhoria de Armário de Ferro (x2)
Emerald Drawer Upgrade (x13)=Melhoria de Armário de Esmeralda (x13)
Mithril Drawer Upgrade (x13)=Melhoria de Armário de Esmeralda (x13)
Wooden Trim=Guarnição de Madeira
Drawer Upgrade Template=Modelo de Melhoria de Armário
Wooden=Madeira

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=Armário @1
@1 Drawers (1x2)=Armários @1 (1x2)
@1 Drawers (2x2)=Armários @1 (2x2)
Empty=Vazio
Drawer Controller=Controlador de Armários
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% cheio)
@1 @2 (@3% full)=@1 @2 (@3% cheio)
Acacia Wood=Lenha de Acácia
Aspen Wood=Lenha de Álamo
Junglewood=Lenha da selva
Pine Wood=Lenha de Pinheiro
Oak Wood=Lenha de Carvalho
Birch Wood=Lenha de Bétula
Dark Oak Wood=Lenha de Carvalho Escuro
Spruce Wood=Lenha de Abeto
Steel Drawer Upgrade (x2)=Melhoria de Armário de Aço (x2)
Gold Drawer Upgrade (x3)=Melhoria de Armário de Ouro (x3)
Obsidian Drawer Upgrade (x4)=Melhoria de Armário de Obsidiana (x5)
Diamond Drawer Upgrade (x8)=Melhoria de Armário de Diamante (x8)
Iron Drawer Upgrade (x2)=Melhoria de Armário de Ferro (x2)
Emerald Drawer Upgrade (x13)=Melhoria de Armário de Esmeralda (x13)
Mithril Drawer Upgrade (x13)=Melhoria de Armário de Esmeralda (x13)
Wooden Trim=Guarnição de Madeira
Drawer Upgrade Template=Modelo de Melhoria de Armário
Wooden=Madeira

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=@1 Ящик
@1 Drawers (1x2)=@1 Ящики (1x2)
@1 Drawers (2x2)=@1 Ящики (2x2)
Empty=Пусто
Drawer Controller=Контролер ящика
Digiline Channel=
Save=
@1 (@2% full)=@1 (@2% полон)
@1 @2 (@3% full)=@1 @2 (@3% полон)
Acacia Wood=Акация
Aspen Wood=Осина
Junglewood=Тропическое дерево
Pine Wood=Сосна
Oak Wood=Дуб
Birch Wood=Берёза
Dark Oak Wood=Тёмный дуб
Spruce Wood=Ель
Steel Drawer Upgrade (x2)=Стальной ящик Улучшение (x2)
Gold Drawer Upgrade (x3)=Золотой ящик Улучшение (x3)
Obsidian Drawer Upgrade (x4)=Обсидиановый ящик Улучшение (x5)
Diamond Drawer Upgrade (x8)=Алмазный ящик Улучшение (x8)
Iron Drawer Upgrade (x2)=Железный ящик Улучшение (x2)
Emerald Drawer Upgrade (x13)=Изумрудный ящик Улучшение (x13)
Mithril Drawer Upgrade (x13)=Изумрудный ящик Улучшение (x13)
Wooden Trim=Деревянная отделка
Drawer Upgrade Template=Шаблон улучшения ящика
Wooden=Деревянный

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=@1låda
@1 Drawers (1x2)=@1lådor (1x2)
@1 Drawers (2x2)=@1lådor (2x2)
Empty=Tom
Drawer Controller=Lådkontroll
Digiline Channel=Digilinekanal
Save=Spara
@1 (@2% full)=@1 (@2% fullt)
@1 @2 (@3% full)=@1 @2 (@3% fullt)
Acacia Wood=Acaciaträ
Aspen Wood=Aspträ
Junglewood=Djungelträ
Pine Wood=Tallträ
Oak Wood=Ekträ
Birch Wood=Björkträ
Dark Oak Wood=Mörk ekträ
Spruce Wood=Granträ
Steel Drawer Upgrade (x2)=Stållådeuppgradering (x2)
Gold Drawer Upgrade (x3)=Guldlådeuppgradering (x3)
Obsidian Drawer Upgrade (x4)=Obsidianlådeuppgradering (x4)
Diamond Drawer Upgrade (x8)=Diamantlådeuppgradering (x8)
Iron Drawer Upgrade (x2)=Järnlådeuppgradering (x2)
Emerald Drawer Upgrade (x13)=Smaragdlådeuppgradering (x13)
Mithril Drawer Upgrade (x13)=Mithrillådeuppgradering (x13)
Wooden Trim=Trätrim
Drawer Upgrade Template=Lådeuppgraderingsmall
Wooden=Trä

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=@1 Çekmece
@1 Drawers (1x2)=@1 Çekmece (1x2)
@1 Drawers (2x2)=@1 Çekmece (2x2)
Empty=Boş
Drawer Controller=Çekmece Denetleyicisi
Digiline Channel=
Save=
@1 (@2% full)=@1 (%@2 dolu)
@1 @2 (@3% full)=@1 @2 (%@3 dolu)
Acacia Wood=Akasya Ahşap
Aspen Wood=Kavak Ahşap
Junglewood=Cangıl Ahşap
Pine Wood=Çam Ahşap
Oak Wood=Meşe Ahşap
Birch Wood=Huş Ahşap
Dark Oak Wood=Koyu Meşe Ahşap
Spruce Wood=Ladin Ahşap
Steel Drawer Upgrade (x2)=Çelik Çekmece Yükseltme (x2)
Gold Drawer Upgrade (x3)=Altın Çekmece Yükseltme (x3)
Obsidian Drawer Upgrade (x4)=Obsidyen Çekmece Yükseltme (x5)
Diamond Drawer Upgrade (x8)=Elmas Çekmece Yükseltme (x8)
Iron Drawer Upgrade (x2)=Demir Çekmece Yükseltme (x2)
Emerald Drawer Upgrade (x13)=Zümrüt Çekmece Yükseltme (x13)
Mithril Drawer Upgrade (x13)=Zümrüt Çekmece Yükseltme (x13)
Wooden Trim=Ahşap Döşeme
Drawer Upgrade Template=Çekmece Yükseltme Şablonu
Wooden=Ahşap

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=
@1 Drawers (1x2)=
@1 Drawers (2x2)=
Empty=空的
Drawer Controller=
Digiline Channel=
Save=
@1 (@2% full)=
@1 @2 (@3% full)=
Acacia Wood=金合欢木
Aspen Wood=
Junglewood=丛林木
Pine Wood=
Oak Wood=橡木
Birch Wood=白桦木
Dark Oak Wood=深色橡木
Spruce Wood=云杉木
Steel Drawer Upgrade (x2)=
Gold Drawer Upgrade (x3)=
Obsidian Drawer Upgrade (x4)=
Diamond Drawer Upgrade (x8)=
Iron Drawer Upgrade (x2)=
Emerald Drawer Upgrade (x13)=
Mithril Drawer Upgrade (x13)=
Wooden Trim=
Drawer Upgrade Template=
Wooden=木制

View file

@ -0,0 +1,28 @@
# textdomain: drawers
@1 Drawer=
@1 Drawers (1x2)=
@1 Drawers (2x2)=
Empty=
Drawer Controller=
Digiline Channel=
Save=
@1 (@2% full)=
@1 @2 (@3% full)=
Acacia Wood=
Aspen Wood=
Junglewood=
Pine Wood=
Oak Wood=
Birch Wood=
Dark Oak Wood=
Spruce Wood=
Steel Drawer Upgrade (x2)=
Gold Drawer Upgrade (x3)=
Obsidian Drawer Upgrade (x4)=
Diamond Drawer Upgrade (x8)=
Iron Drawer Upgrade (x2)=
Emerald Drawer Upgrade (x13)=
Mithril Drawer Upgrade (x13)=
Wooden Trim=
Drawer Upgrade Template=
Wooden=

427
mods/drawers/lua/api.lua Normal file
View file

@ -0,0 +1,427 @@
--[[
Minetest Mod Storage Drawers - A Mod adding storage drawers
Copyright (C) 2017-2020 Linus Jahn <lnj@kaidan.im>
Copyright (C) 2016 Mango Tango <mtango688@gmail.com>
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]
local S = minetest.get_translator('drawers')
drawers.node_box_simple = {
{-0.5, -0.5, -0.4375, 0.5, 0.5, 0.5},
{-0.5, -0.5, -0.5, -0.4375, 0.5, -0.4375},
{0.4375, -0.5, -0.5, 0.5, 0.5, -0.4375},
{-0.4375, 0.4375, -0.5, 0.4375, 0.5, -0.4375},
{-0.4375, -0.5, -0.5, 0.4375, -0.4375, -0.4375},
}
drawers.drawer_formspec = "size[9,7]" ..
"list[context;upgrades;2,0.5;5,1;]" ..
"list[current_player;main;0,3;9,4;]" ..
"listring[context;upgrades]" ..
"listring[current_player;main]" ..
drawers.gui_bg ..
drawers.gui_bg_img ..
drawers.gui_slots ..
drawers.get_upgrade_slots_bg(2, 0.5)
-- construct drawer
function drawers.drawer_on_construct(pos)
local node = core.get_node(pos)
local ndef = core.registered_nodes[node.name]
local drawerType = ndef.groups.drawer
local base_stack_max = core.nodedef_default.stack_max or 99
local stack_max_factor = ndef.drawer_stack_max_factor or 24 -- 3x8
stack_max_factor = math.floor(stack_max_factor / drawerType) -- drawerType => number of drawers in node
-- meta
local meta = core.get_meta(pos)
local i = 1
while i <= drawerType do
local vid = i
-- 1x1 drawers don't have numbers in the meta fields
if drawerType == 1 then vid = "" end
meta:set_string("name"..vid, "")
meta:set_int("count"..vid, 0)
meta:set_int("max_count"..vid, base_stack_max * stack_max_factor)
meta:set_int("base_stack_max"..vid, base_stack_max)
meta:set_string("entity_infotext"..vid, drawers.gen_info_text(S("Empty"), 0,
stack_max_factor, base_stack_max))
meta:set_int("stack_max_factor"..vid, stack_max_factor)
i = i + 1
end
-- spawn all visuals
drawers.spawn_visuals(pos)
-- create drawer upgrade inventory
meta:get_inventory():set_size("upgrades", 5)
-- set the formspec
meta:set_string("formspec", drawers.drawer_formspec)
end
-- destruct drawer
function drawers.drawer_on_destruct(pos)
drawers.remove_visuals(pos)
-- clean up visual cache
if drawers.drawer_visuals[core.hash_node_position(pos)] then
drawers.drawer_visuals[core.hash_node_position(pos)] = nil
end
end
-- drop all items
function drawers.drawer_on_dig(pos, node, player)
local drawerType = 1
if core.registered_nodes[node.name] then
drawerType = core.registered_nodes[node.name].groups.drawer
end
if core.is_protected(pos,player:get_player_name()) then
core.record_protection_violation(pos,player:get_player_name())
return 0
end
local meta = core.get_meta(pos)
local k = 1
while k <= drawerType do
-- don't add a number in meta fields for 1x1 drawers
local vid = tostring(k)
if drawerType == 1 then vid = "" end
local count = meta:get_int("count"..vid)
local name = meta:get_string("name"..vid)
-- drop the items
local stack_max = ItemStack(name):get_stack_max()
local j = math.floor(count / stack_max) + 1
local i = 1
while i <= j do
local rndpos = drawers.randomize_pos(pos)
if i ~= j then
core.add_item(rndpos, name .. " " .. stack_max)
else
core.add_item(rndpos, name .. " " .. count % stack_max)
end
i = i + 1
end
k = k + 1
end
-- drop all drawer upgrades
local upgrades = meta:get_inventory():get_list("upgrades")
if upgrades then
for _,itemStack in pairs(upgrades) do
if itemStack:get_count() > 0 then
local rndpos = drawers.randomize_pos(pos)
core.add_item(rndpos, itemStack:get_name())
end
end
end
-- remove node
core.node_dig(pos, node, player)
end
function drawers.drawer_allow_metadata_inventory_put(pos, listname, index, stack, player)
if core.is_protected(pos,player:get_player_name()) then
core.record_protection_violation(pos,player:get_player_name())
return 0
end
if listname ~= "upgrades" then
return 0
end
if stack:get_count() > 1 then
return 0
end
if core.get_item_group(stack:get_name(), "drawer_upgrade") < 1 then
return 0
end
return 1
end
function drawers.add_drawer_upgrade(pos, listname, index, stack, player)
-- only do anything if adding to upgrades
if listname ~= "upgrades" then return end
drawers.update_drawer_upgrades(pos)
end
function drawers.remove_drawer_upgrade(pos, listname, index, stack, player)
-- only do anything if adding to upgrades
if listname ~= "upgrades" then return end
drawers.update_drawer_upgrades(pos)
end
--[[
Inserts an incoming stack into a specific slot of a drawer.
]]
function drawers.drawer_insert_object(pos, stack, visualid)
local visual = drawers.get_visual(pos, visualid)
if not visual then
return stack
end
return visual:try_insert_stack(stack, true)
end
--[[
Inserts an incoming stack into a drawer and uses all slots.
]]
function drawers.drawer_insert_object_from_tube(pos, node, stack, direction)
local drawer_visuals = drawers.drawer_visuals[core.hash_node_position(pos)]
if not drawer_visuals then
return stack
end
-- first try to insert in the correct slot (if there are already items)
local leftover = stack
for _, visual in pairs(drawer_visuals) do
if visual.itemName == stack:get_name() then
leftover = visual:try_insert_stack(leftover, true)
end
end
-- if there's still something left, also use other slots
if leftover:get_count() > 0 then
for _, visual in pairs(drawer_visuals) do
leftover = visual:try_insert_stack(leftover, true)
end
end
return leftover
end
--[[
Returns how much (count) of a stack can be inserted to a drawer slot.
]]
function drawers.drawer_can_insert_stack(pos, stack, visualid)
local visual = drawers.get_visual(pos, visualid)
if not visual then
return 0
end
return visual:can_insert_stack(stack)
end
--[[
Returns whether a stack can be (partially) inserted to any slot of a drawer.
]]
function drawers.drawer_can_insert_stack_from_tube(pos, node, stack, direction)
local drawer_visuals = drawers.drawer_visuals[core.hash_node_position(pos)]
if not drawer_visuals then
return false
end
for _, visual in pairs(drawer_visuals) do
if visual:can_insert_stack(stack) > 0 then
return true
end
end
return false
end
function drawers.drawer_take_item(pos, itemstack)
local drawer_visuals = drawers.drawer_visuals[core.hash_node_position(pos)]
if not drawer_visuals then
return ItemStack("")
end
-- check for max count
if itemstack:get_count() > itemstack:get_stack_max() then
itemstack:set_count(itemstack:get_stack_max())
end
for _, visual in pairs(drawer_visuals) do
if visual.itemName == itemstack:get_name() then
return visual:take_items(itemstack:get_count())
end
end
return ItemStack()
end
--[[
Returns the content of a drawer slot.
]]
function drawers.drawer_get_content(pos, visualid)
local drawer_meta = core.get_meta(pos)
return {
name = drawer_meta:get_string("name" .. visualid),
count = drawer_meta:get_int("count" .. visualid),
maxCount = drawer_meta:get_int("max_count" .. visualid)
}
end
function drawers.register_drawer(name, def)
def.description = def.description or S("Wooden")
def.drawtype = "nodebox"
def.node_box = {type = "fixed", fixed = drawers.node_box_simple}
def.collision_box = {type = "regular"}
def.selection_box = {type = "fixed", fixed = drawers.node_box_simple}
def.paramtype = "light"
def.paramtype2 = "facedir"
def.legacy_facedir_simple = true
def.groups = def.groups or {}
def.drawer_stack_max_factor = def.drawer_stack_max_factor or 24
-- events
def.on_construct = drawers.drawer_on_construct
def.on_destruct = drawers.drawer_on_destruct
def.on_dig = drawers.drawer_on_dig
def.allow_metadata_inventory_put = drawers.drawer_allow_metadata_inventory_put
def.allow_metadata_inventory_take = drawers.drawer_allow_metadata_inventory_put
def.on_metadata_inventory_put = drawers.add_drawer_upgrade
def.on_metadata_inventory_take = drawers.remove_drawer_upgrade
if minetest.get_modpath("screwdriver") and screwdriver then
def.on_rotate = def.on_rotate or screwdriver.disallow
end
if minetest.get_modpath("pipeworks") and pipeworks then
def.groups.tubedevice = 1
def.groups.tubedevice_receiver = 1
def.tube = def.tube or {}
def.tube.insert_object = def.tube.insert_object or
drawers.drawer_insert_object_from_tube
def.tube.can_insert = def.tube.can_insert or
drawers.drawer_can_insert_stack_from_tube
def.tube.connect_sides = {left = 1, right = 1, back = 1, top = 1,
bottom = 1}
def.after_place_node = pipeworks.after_place
def.after_dig_node = pipeworks.after_dig
end
local has_mesecons_mvps = minetest.get_modpath("mesecons_mvps")
if drawers.enable_1x1 then
-- normal drawer 1x1 = 1
local def1 = table.copy(def)
def1.description = S("@1 Drawer", def.description)
def1.tiles = def.tiles or def.tiles1
def1.tiles1 = nil
def1.tiles2 = nil
def1.tiles4 = nil
def1.groups.drawer = 1
core.register_node(name .. "1", def1)
core.register_alias(name, name .. "1") -- 1x1 drawer is the default one
if has_mesecons_mvps then
-- don't let drawers be moved by pistons, visual glitches and
-- possible duplication bugs occur otherwise
mesecon.register_mvps_stopper(name .. "1")
end
end
if drawers.enable_1x2 then
-- 1x2 = 2
local def2 = table.copy(def)
def2.description = S("@1 Drawers (1x2)", def.description)
def2.tiles = def.tiles2
def2.tiles1 = nil
def2.tiles2 = nil
def2.tiles4 = nil
def2.groups.drawer = 2
core.register_node(name .. "2", def2)
if has_mesecons_mvps then
mesecon.register_mvps_stopper(name .. "2")
end
end
if drawers.enable_2x2 then
-- 2x2 = 4
local def4 = table.copy(def)
def4.description = S("@1 Drawers (2x2)", def.description)
def4.tiles = def.tiles4
def4.tiles1 = nil
def4.tiles2 = nil
def4.tiles4 = nil
def4.groups.drawer = 4
core.register_node(name .. "4", def4)
if has_mesecons_mvps then
mesecon.register_mvps_stopper(name .. "4")
end
end
if (not def.no_craft) and def.material then
if drawers.enable_1x1 then
core.register_craft({
output = name .. "1",
recipe = {
{def.material, def.material, def.material},
{ "", drawers.CHEST_ITEMSTRING, "" },
{def.material, def.material, def.material}
}
})
end
if drawers.enable_1x2 then
core.register_craft({
output = name .. "2 2",
recipe = {
{def.material, drawers.CHEST_ITEMSTRING, def.material},
{def.material, def.material, def.material},
{def.material, drawers.CHEST_ITEMSTRING, def.material}
}
})
end
if drawers.enable_2x2 then
core.register_craft({
output = name .. "4 4",
recipe = {
{drawers.CHEST_ITEMSTRING, def.material, drawers.CHEST_ITEMSTRING},
{ def.material, def.material, def.material },
{drawers.CHEST_ITEMSTRING, def.material, drawers.CHEST_ITEMSTRING}
}
})
end
end
end
function drawers.register_drawer_upgrade(name, def)
def.groups = def.groups or {}
def.groups.drawer_upgrade = def.groups.drawer_upgrade or 100
def.inventory_image = def.inventory_image or "drawers_upgrade_template.png"
def.stack_max = 1
local recipe_item = def.recipe_item or "air"
def.recipe_item = nil
core.register_craftitem(name, def)
if not def.no_craft then
core.register_craft({
output = name,
recipe = {
{recipe_item, "group:stick", recipe_item},
{"group:stick", "drawers:upgrade_template", "group:stick"},
{recipe_item, "group:stick", recipe_item}
}
})
end
end

View file

@ -0,0 +1,545 @@
--[[
Minetest Mod Storage Drawers - A Mod adding storage drawers
Copyright (C) 2017-2020 Linus Jahn <lnj@kaidan.im>
Copyright (C) 2018 isaiah658
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]--
--[[ The gist of how the drawers mod stores data is that there are entities
and the drawer node itself. The entities are needed to allow having multiple
drawers in one node. The entities and node each store metadata about the item
counts and such. It is necessary to change both at once otherwise in some cases
the entity values are used and in other cases the node metadata is used.
The gist of how the controller works is this. The drawer controller scans the
adjacent tiles and puts the item names and other info such as coordinates and
the visualid of the entity in a table. That table is saved in the controllers
metadata. The table is used to help prevent needing to scan all the drawers to
deposit an item in certain situations. The table is only updated on an as needed
basis, not by a specific time/interval. Controllers that have no items will not
continue scanning drawers. ]]--
local S = minetest.get_translator('drawers')
local default_loaded = core.get_modpath("default") and default
local mcl_loaded = core.get_modpath("mcl_core") and mcl_core
local pipeworks_loaded = core.get_modpath("pipeworks") and pipeworks
local digilines_loaded = core.get_modpath("digilines") and digilines
local techage_loaded = core.get_modpath("techage") and techage
local function controller_formspec(pos)
local formspec =
"size[8,8.5]"..
drawers.gui_bg..
drawers.gui_bg_img..
drawers.gui_slots..
"label[0,0;" .. S("Drawer Controller") .. "]" ..
"list[current_name;src;3.5,1.75;1,1;]"..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
"listring[current_player;main]"..
"listring[current_name;src]"..
"listring[current_player;main]"
if digilines_loaded and pipeworks_loaded then
formspec = formspec .. "field[1,3.5;4,1;digilineChannel;" .. S("Digiline Channel") .. ";${digilineChannel}]"
formspec = formspec .. "button_exit[5,3.2;2,1;saveChannel;" .. S("Save") .. "]"
end
return formspec
end
local function is_valid_drawer_index_slot(net_index, item_name)
return net_index and
net_index[item_name] and
net_index[item_name].drawer_pos and
net_index[item_name].drawer_pos.x and
net_index[item_name].drawer_pos.y and
net_index[item_name].drawer_pos.z and
net_index[item_name].visualid
end
local function controller_index_slot(pos, visualid)
return {
drawer_pos = pos,
visualid = visualid
}
end
local function compare_pos(pos1, pos2)
return pos1.x == pos2.x and pos1.y == pos2.y and pos1.z == pos2.z
end
local function contains_pos(list, p)
for _,v in ipairs(list) do
if compare_pos(v, p) then
return true
end
end
return false
end
-- iterator for iterating from 1 -> to
local function range(to)
local i = 0
return function()
if i == to then
return nil
end
i = i + 1
return i, i
end
end
local function pos_in_range(pos1, pos2)
local diff = {
pos1.x - pos2.x,
pos1.y - pos2.y,
pos1.z - pos2.z
}
for _,v in ipairs(diff) do
if v < 0 then
v = v * -1
end
if v > drawers.CONTROLLER_RANGE then
return false
end
end
return true
end
local function add_drawer_to_inventory(controllerInventory, pos)
-- the number of slots is saved as drawer group
local slots = core.get_item_group(core.get_node(pos).name, "drawer")
if not slots then
return
end
local meta = core.get_meta(pos)
if not meta then
return
end
local i = 1
while i <= slots do
-- nothing is appended in case the drawer has only one slot
local slot_id = ""
if slots ~= 1 then
slot_id = tostring(i)
end
local item_id = meta:get_string("name" .. slot_id)
local drawer_meta_entity_infotext = meta:get_string("entity_infotext" .. slot_id)
if item_id == "" and not controllerInventory["empty"] then
controllerInventory["empty"] = controller_index_slot(pos, slot_id)
elseif item_id ~= "" then
-- If we already indexed this item previously, check which drawer
-- has the most space and have that one be the one indexed
if controllerInventory[item_id] then
local content = drawers.drawer_get_content(controllerInventory[item_id].drawer_pos, controllerInventory[item_id].visualid)
local new_content = drawers.drawer_get_content(pos, slot_id)
-- If the already indexed drawer has less space, we override the
-- table index for that item with the new drawer
if (new_content.maxCount - new_content.count) > (content.maxCount - content.count) then
controllerInventory[item_id] = controller_index_slot(pos, slot_id)
end
else
controllerInventory[item_id] = controller_index_slot(pos, slot_id)
end
end
i = i + 1
end
end
local function find_connected_drawers(controller_pos, pos, foundPositions)
foundPositions = foundPositions or {}
pos = pos or controller_pos
local newPositions = core.find_nodes_in_area(
{x = pos.x - 1, y = pos.y - 1, z = pos.z - 1},
{x = pos.x + 1, y = pos.y + 1, z = pos.z + 1},
{"group:drawer", "group:drawer_connector"}
)
for _,p in ipairs(newPositions) do
-- check that this node hasn't been scanned yet
if not compare_pos(pos, p) and not contains_pos(foundPositions, p)
and pos_in_range(controller_pos, pos) then
-- add new position
table.insert(foundPositions, p)
-- search for other drawers from the new pos
find_connected_drawers(controller_pos, p, foundPositions)
end
end
return foundPositions
end
local function index_drawers(pos)
--[[
The pos parameter is the controllers position
We store the item name as a string key and the value is a table with position x,
position y, position z, and visualid. Those are all strings as well with the
values assigned to them that way we don't need to worry about the ordering of
the table. The count and max count are not stored as those values have a high
potential of being outdated quickly. It's better to grab the values from the
drawer when needed so you know you are working with accurate numbers.
]]
local controllerInventory = {}
for _,drawerPos in ipairs(find_connected_drawers(pos)) do
add_drawer_to_inventory(controllerInventory, drawerPos)
end
return controllerInventory
end
--[[
Returns a table of all stored itemstrings in the drawer network with their
drawer position and visualid.
It uses the cached data, if possible, but if the itemstring is not contained
the network is reindexed.
]]
local function controller_get_drawer_index(pos, itemstring)
local meta = core.get_meta(pos)
-- If the index has not been created, the item isn't in the index, the
-- item in the drawer is no longer the same item in the index, or the item
-- is in the index but it's full, run the index_drawers function.
local drawer_net_index = core.deserialize(meta:get_string("drawers_table_index"))
-- If the index has not been created
-- If the item isn't in the index (or the index is corrupted)
if not is_valid_drawer_index_slot(drawer_net_index, itemstring) then
drawer_net_index = index_drawers(pos)
meta:set_string("drawers_table_index", core.serialize(drawer_net_index))
-- There is a valid entry in the index: check that the entry is still up-to-date
else
local content = drawers.drawer_get_content(
drawer_net_index[itemstring].drawer_pos,
drawer_net_index[itemstring].visualid)
if content.name ~= itemstring or content.count >= content.maxCount then
drawer_net_index = index_drawers(pos)
meta:set_string("drawers_table_index", core.serialize(drawer_net_index))
end
end
return drawer_net_index
end
local function controller_insert_to_drawers(pos, stack)
-- Inizialize metadata
local meta = core.get_meta(pos)
local inv = meta:get_inventory()
local drawer_net_index = controller_get_drawer_index(pos, stack:get_name())
-- We check if there is a drawer with the item and it isn't full. We will
-- put the items we can into it.
if drawer_net_index[stack:get_name()] then
local drawer_pos = drawer_net_index[stack:get_name()]["drawer_pos"]
local visualid = drawer_net_index[stack:get_name()]["visualid"]
local content = drawers.drawer_get_content(drawer_pos, visualid)
-- If the the item in the drawer is the same as the one we are trying to
-- store, the drawer is not full, and the drawer entity is loaded, we
-- will put the items in the drawer
if content.name == stack:get_name() and
content.count < content.maxCount and
drawers.drawer_visuals[core.hash_node_position(drawer_pos)] then
return drawers.drawer_insert_object(drawer_pos, stack, visualid)
end
elseif drawer_net_index["empty"] then
local drawer_pos = drawer_net_index["empty"]["drawer_pos"]
local visualid = drawer_net_index["empty"]["visualid"]
local content = drawers.drawer_get_content(drawer_pos, visualid)
-- If the drawer is still empty and the drawer entity is loaded, we will
-- put the items in the drawer
if content.name == "" and drawers.drawer_visuals[core.hash_node_position(drawer_pos)] then
local leftover = drawers.drawer_insert_object(drawer_pos, stack, visualid)
-- Add the item to the drawers table index and set the empty one to nil
drawer_net_index["empty"] = nil
drawer_net_index[stack:get_name()] = controller_index_slot(drawer_pos, visualid)
-- Set the controller metadata
meta:set_string("drawers_table_index", core.serialize(drawer_net_index))
return leftover
end
end
return stack
end
local function controller_can_dig(pos, player)
local meta = core.get_meta(pos);
local inv = meta:get_inventory()
return inv:is_empty("src")
end
local function controller_on_construct(pos)
local meta = core.get_meta(pos)
meta:set_string("drawers_table_index", "")
meta:set_string("formspec", controller_formspec(pos))
meta:get_inventory():set_size("src", 1)
end
local function controller_on_blast(pos)
local drops = {}
default.get_inventory_drops(pos, "src", drops)
drops[#drops+1] = "drawers:controller"
core.remove_node(pos)
return drops
end
local function controller_allow_metadata_inventory_put(pos, listname, index, stack, player)
if (player and core.is_protected(pos, player:get_player_name())) or listname ~= "src" then
return 0
end
local drawer_net_index = controller_get_drawer_index(pos, stack:get_name())
if drawer_net_index[stack:get_name()] then
local drawer = drawer_net_index[stack:get_name()]
if drawers.drawer_get_content(drawer.drawer_pos, drawer.visualid).name == stack:get_name() then
return drawers.drawer_can_insert_stack(drawer.drawer_pos, stack, drawer["visualid"])
end
end
if drawer_net_index["empty"] then
local drawer = drawer_net_index["empty"]
if drawers.drawer_get_content(drawer.drawer_pos, drawer.visualid).name == "" then
return drawers.drawer_can_insert_stack(drawer.drawer_pos, stack, drawer.visualid)
end
end
return 0
end
local function controller_allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
local meta = core.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
return controller_allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
end
local function controller_allow_metadata_inventory_take(pos, listname, index, stack, player)
if core.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end
local function controller_on_metadata_inventory_put(pos, listname, index, stack, player)
if listname ~= "src" then
return
end
local inv = core.get_meta(pos):get_inventory()
local complete_stack = inv:get_stack("src", 1)
local leftover = controller_insert_to_drawers(pos, complete_stack)
inv:set_stack("src", 1, leftover)
end
local function controller_on_digiline_receive(pos, _, channel, msg)
local meta = core.get_meta(pos)
if channel ~= meta:get_string("digilineChannel") then
return
end
local item = ItemStack(msg)
local drawers_index = controller_get_drawer_index(pos, item:get_name())
if not drawers_index[item:get_name()] then
-- we can't do anything: the requested item doesn't exist
return
end
local taken_stack = drawers.drawer_take_item(
drawers_index[item:get_name()]["drawer_pos"], item)
local dir = core.facedir_to_dir(core.get_node(pos).param2)
-- prevent crash if taken_stack ended up with a nil value
if taken_stack then
pipeworks.tube_inject_item(pos, pos, dir, taken_stack:to_string())
end
end
local function controller_on_receive_fields(pos, formname, fields, sender)
if core.is_protected(pos, sender:get_player_name()) then
return
end
local meta = core.get_meta(pos)
if fields.saveChannel then
meta:set_string("digilineChannel", fields.digilineChannel)
end
end
-- Registers the drawer controller
local function register_controller()
-- Set the controller definition using a table to allow for pipeworks and
-- potentially other mod support
local def = {}
def.description = S("Drawer Controller")
def.drawtype = "nodebox"
def.node_box = { type = "fixed", fixed = drawers.node_box_simple }
def.collision_box = { type = "regular" }
def.selection_box = { type = "regular" }
def.paramtype = "light"
def.paramtype2 = "facedir"
def.legacy_facedir_simple = true
-- add pipe connectors, if pipeworks is enabled
if pipeworks_loaded then
def.tiles = {
"drawers_controller_top.png^pipeworks_tube_connection_metallic.png",
"drawers_controller_top.png^pipeworks_tube_connection_metallic.png",
"drawers_controller_side.png^pipeworks_tube_connection_metallic.png",
"drawers_controller_side.png^pipeworks_tube_connection_metallic.png",
"drawers_controller_top.png^pipeworks_tube_connection_metallic.png",
"drawers_controller_front.png"
}
else
def.tiles = {
"drawers_controller_top.png",
"drawers_controller_top.png",
"drawers_controller_side.png",
"drawers_controller_side.png",
"drawers_controller_top.png",
"drawers_controller_front.png"
}
end
-- MCL2 requires a few different groups and parameters that MTG does not
if mcl_loaded then
def.groups = {
pickaxey = 1, stone = 1, building_block = 1, material_stone = 1
}
def._mcl_blast_resistance = 30
def._mcl_hardness = 1.5
else
def.groups = {
cracky = 3, level = 2
}
end
def.can_dig = controller_can_dig
def.on_construct = controller_on_construct
def.on_blast = controller_on_blast
def.on_receive_fields = controller_on_receive_fields
def.on_metadata_inventory_put = controller_on_metadata_inventory_put
def.allow_metadata_inventory_put = controller_allow_metadata_inventory_put
def.allow_metadata_inventory_move = controller_allow_metadata_inventory_move
def.allow_metadata_inventory_take = controller_allow_metadata_inventory_take
if pipeworks_loaded then
def.groups.tubedevice = 1
def.groups.tubedevice_receiver = 1
def.tube = {}
def.tube.insert_object = function(pos, node, stack, tubedir)
return controller_insert_to_drawers(pos, stack)
end
def.tube.can_insert = function(pos, node, stack, tubedir)
return controller_allow_metadata_inventory_put(pos, "src", nil, stack, nil) > 0
end
def.tube.connect_sides = {
left = 1, right = 1, back = 1, top = 1, bottom = 1
}
def.after_place_node = pipeworks.after_place
def.after_dig_node = pipeworks.after_dig
end
if digilines_loaded and pipeworks_loaded then
def.digiline = {
receptor = {},
effector = {
action = controller_on_digiline_receive
},
}
end
core.register_node("drawers:controller", def)
if techage_loaded then
techage.register_node({"drawers:controller"}, {
on_push_item = function(pos, in_dir, stack)
return controller_insert_to_drawers(pos, stack)
end
})
end
end
-- register drawer controller
register_controller()
if default_loaded then
core.register_craft({
output = 'drawers:controller',
recipe = {
{'default:steel_ingot', 'default:diamond', 'default:steel_ingot'},
{'default:tin_ingot', 'group:drawer', 'default:copper_ingot'},
{'default:steel_ingot', 'default:diamond', 'default:steel_ingot'},
}
})
elseif mcl_loaded then
core.register_craft({
output = 'drawers:controller',
recipe = {
{'mcl_core:iron_ingot', 'mcl_core:diamond', 'mcl_core:iron_ingot'},
{'mcl_core:gold_ingot', 'group:drawer', 'mcl_core:gold_ingot'},
{'mcl_core:iron_ingot', 'mcl_core:diamond', 'mcl_core:iron_ingot'},
}
})
else
-- Because the rest of the drawers mod doesn't have a hard depend on
-- default, I changed the recipe to have an alternative
core.register_craft({
output = 'drawers:controller',
recipe = {
{'group:stone', 'group:stone', 'group:stone'},
{'group:stone', 'group:drawer', 'group:stone'},
{'group:stone', 'group:stone', 'group:stone'},
}
})
end

View file

@ -0,0 +1,286 @@
--[[
Minetest Mod Storage Drawers - A Mod adding storage drawers
Copyright (C) 2017-2019 Linus Jahn <lnj@kaidan.im>
Copyright (C) 2016 Mango Tango <mtango688@gmail.com>
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]
local S = minetest.get_translator('drawers')
-- GUI
function drawers.get_upgrade_slots_bg(x,y)
local out = ""
for i = 0, 4, 1 do
out = out .."image["..x+i..","..y..";1,1;drawers_upgrade_slot_bg.png]"
end
return out
end
function drawers.gen_info_text(basename, count, factor, stack_max)
local maxCount = stack_max * factor
local percent = count / maxCount * 100
-- round the number (float -> int)
percent = math.floor(percent + 0.5)
if count == 0 then
return S("@1 (@2% full)", basename, tostring(percent))
else
return S("@1 @2 (@3% full)", tostring(count), basename, tostring(percent))
end
end
-- Get an image string from a tile definition
local function tile_to_image(tile, fallback_image)
if not tile then
return fallback_image
end
local tile_type = type(tile)
if tile_type == "string" then
return tile
end
assert(tile_type == "table", "Tile definition is not a string or table")
local image = tile.name or tile.image
assert(image, "Tile definition has no image file specified")
if tile.color then
local colorstr = core.colorspec_to_colorstring(tile.color)
if colorstr then
return image .. "^[multiply:" .. colorstr
end
end
return image
end
function drawers.get_inv_image(name)
local texture = "blank.png"
local def = core.registered_items[name]
if not def then return end
if def.inventory_image and #def.inventory_image > 0 then
texture = def.inventory_image
else
if not def.tiles then return texture end
local tiles = table.copy(def.tiles)
local top = tile_to_image(tiles[1])
local left = tile_to_image(tiles[3], top)
local right = tile_to_image(tiles[5], left)
texture = core.inventorycube(top, left, right)
end
return texture
end
function drawers.spawn_visuals(pos)
local node = core.get_node(pos)
local ndef = core.registered_nodes[node.name]
local drawerType = ndef.groups.drawer
-- data for the new visual
drawers.last_drawer_pos = pos
drawers.last_drawer_type = drawerType
if drawerType == 1 then -- 1x1 drawer
drawers.last_visual_id = ""
drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name"))
local bdir = core.facedir_to_dir(node.param2)
local fdir = vector.new(-bdir.x, 0, -bdir.z)
local pos2 = vector.add(pos, vector.multiply(fdir, 0.45))
local obj = core.add_entity(pos2, "drawers:visual")
if not obj then return end
if bdir.x < 0 then obj:set_yaw(0.5 * math.pi) end
if bdir.z < 0 then obj:set_yaw(math.pi) end
if bdir.x > 0 then obj:set_yaw(1.5 * math.pi) end
drawers.last_texture = nil
elseif drawerType == 2 then
local bdir = core.facedir_to_dir(node.param2)
local fdir1
local fdir2
if node.param2 == 2 or node.param2 == 0 then
fdir1 = vector.new(-bdir.x, 0.5, -bdir.z)
fdir2 = vector.new(-bdir.x, -0.5, -bdir.z)
else
fdir1 = vector.new(-bdir.x, 0.5, -bdir.z)
fdir2 = vector.new(-bdir.x, -0.5, -bdir.z)
end
local objs = {}
drawers.last_visual_id = 1
drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name1"))
local pos1 = vector.add(pos, vector.multiply(fdir1, 0.45))
objs[1] = core.add_entity(pos1, "drawers:visual")
drawers.last_visual_id = 2
drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name2"))
local pos2 = vector.add(pos, vector.multiply(fdir2, 0.45))
objs[2] = core.add_entity(pos2, "drawers:visual")
for i,obj in pairs(objs) do
if bdir.x < 0 then obj:set_yaw(0.5 * math.pi) end
if bdir.z < 0 then obj:set_yaw(math.pi) end
if bdir.x > 0 then obj:set_yaw(1.5 * math.pi) end
end
else -- 2x2 drawer
local bdir = core.facedir_to_dir(node.param2)
local fdir1
local fdir2
local fdir3
local fdir4
if node.param2 == 2 then
fdir1 = vector.new(-bdir.x + 0.5, 0.5, -bdir.z)
fdir2 = vector.new(-bdir.x - 0.5, 0.5, -bdir.z)
fdir3 = vector.new(-bdir.x + 0.5, -0.5, -bdir.z)
fdir4 = vector.new(-bdir.x - 0.5, -0.5, -bdir.z)
elseif node.param2 == 0 then
fdir1 = vector.new(-bdir.x - 0.5, 0.5, -bdir.z)
fdir2 = vector.new(-bdir.x + 0.5, 0.5, -bdir.z)
fdir3 = vector.new(-bdir.x - 0.5, -0.5, -bdir.z)
fdir4 = vector.new(-bdir.x + 0.5, -0.5, -bdir.z)
elseif node.param2 == 1 then
fdir1 = vector.new(-bdir.x, 0.5, -bdir.z + 0.5)
fdir2 = vector.new(-bdir.x, 0.5, -bdir.z - 0.5)
fdir3 = vector.new(-bdir.x, -0.5, -bdir.z + 0.5)
fdir4 = vector.new(-bdir.x, -0.5, -bdir.z - 0.5)
else
fdir1 = vector.new(-bdir.x, 0.5, -bdir.z - 0.5)
fdir2 = vector.new(-bdir.x, 0.5, -bdir.z + 0.5)
fdir3 = vector.new(-bdir.x, -0.5, -bdir.z - 0.5)
fdir4 = vector.new(-bdir.x, -0.5, -bdir.z + 0.5)
end
local objs = {}
drawers.last_visual_id = 1
drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name1"))
local pos1 = vector.add(pos, vector.multiply(fdir1, 0.45))
objs[1] = core.add_entity(pos1, "drawers:visual")
drawers.last_visual_id = 2
drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name2"))
local pos2 = vector.add(pos, vector.multiply(fdir2, 0.45))
objs[2] = core.add_entity(pos2, "drawers:visual")
drawers.last_visual_id = 3
drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name3"))
local pos3 = vector.add(pos, vector.multiply(fdir3, 0.45))
objs[3] = core.add_entity(pos3, "drawers:visual")
drawers.last_visual_id = 4
drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name4"))
local pos4 = vector.add(pos, vector.multiply(fdir4, 0.45))
objs[4] = core.add_entity(pos4, "drawers:visual")
for i,obj in pairs(objs) do
if bdir.x < 0 then obj:set_yaw(0.5 * math.pi) end
if bdir.z < 0 then obj:set_yaw(math.pi) end
if bdir.x > 0 then obj:set_yaw(1.5 * math.pi) end
end
end
end
function drawers.remove_visuals(pos)
local objs = core.get_objects_inside_radius(pos, 0.56)
if not objs then return end
for _, obj in pairs(objs) do
if obj and obj:get_luaentity() and
obj:get_luaentity().name == "drawers:visual" then
obj:remove()
end
end
end
--[[
Returns the visual object for the visualid of the drawer at pos.
visualid can be: "", "1", "2", ... or 1, 2, ...
]]
function drawers.get_visual(pos, visualid)
local drawer_visuals = drawers.drawer_visuals[core.hash_node_position(pos)]
if not drawer_visuals then
return nil
end
-- not a real index (starts with 1)
local index = tonumber(visualid)
if visualid == "" then
index = 1
end
return drawer_visuals[index]
end
function drawers.update_drawer_upgrades(pos)
local node = core.get_node(pos)
local ndef = core.registered_nodes[node.name]
local drawerType = ndef.groups.drawer
-- default number of slots/stacks
local stackMaxFactor = ndef.drawer_stack_max_factor
-- storage percent with all upgrades
local storagePercent = 100
-- get info of all upgrades
local inventory = core.get_meta(pos):get_inventory():get_list("upgrades")
for _,itemStack in pairs(inventory) do
local iname = itemStack:get_name()
local idef = core.registered_items[iname]
local addPercent = idef.groups.drawer_upgrade or 0
storagePercent = storagePercent + addPercent
end
-- i.e.: 150% / 100 => 1.50
stackMaxFactor = math.floor(stackMaxFactor * (storagePercent / 100))
-- calculate stack_max factor for a single drawer
stackMaxFactor = stackMaxFactor / drawerType
-- set the new stack max factor in all visuals
local drawer_visuals = drawers.drawer_visuals[core.hash_node_position(pos)]
if not drawer_visuals then return end
for _,visual in pairs(drawer_visuals) do
visual:setStackMaxFactor(stackMaxFactor)
end
end
function drawers.randomize_pos(pos)
local rndpos = table.copy(pos)
local x = math.random(-50, 50) * 0.01
local z = math.random(-50, 50) * 0.01
rndpos.x = rndpos.x + x
rndpos.y = rndpos.y + 0.25
rndpos.z = rndpos.z + z
return rndpos
end
function drawers.node_tiles_front_other(front, other)
return {other, other, other, other, other, front}
end

463
mods/drawers/lua/visual.lua Normal file
View file

@ -0,0 +1,463 @@
--[[
Minetest Mod Storage Drawers - A Mod adding storage drawers
Copyright (C) 2017-2019 Linus Jahn <lnj@kaidan.im>
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]
local S = minetest.get_translator('drawers')
core.register_entity("drawers:visual", {
initial_properties = {
hp_max = 1,
physical = false,
collide_with_objects = false,
collisionbox = {-0.4374, -0.4374, 0, 0.4374, 0.4374, 0}, -- for param2 0, 2
visual = "upright_sprite", -- "wielditem" for items without inv img?
visual_size = {x = 0.6, y = 0.6},
textures = {"blank.png"},
spritediv = {x = 1, y = 1},
initial_sprite_basepos = {x = 0, y = 0},
is_visible = true,
},
get_staticdata = function(self)
return core.serialize({
drawer_posx = self.drawer_pos.x,
drawer_posy = self.drawer_pos.y,
drawer_posz = self.drawer_pos.z,
texture = self.texture,
drawerType = self.drawerType,
visualId = self.visualId
})
end,
on_activate = function(self, staticdata, dtime_s)
-- Restore data
local data = core.deserialize(staticdata)
if data then
self.drawer_pos = {
x = data.drawer_posx,
y = data.drawer_posy,
z = data.drawer_posz,
}
self.texture = data.texture
self.drawerType = data.drawerType or 1
self.visualId = data.visualId or ""
-- backwards compatibility
if self.texture == "drawers_empty.png" then
self.texture = "blank.png"
end
else
self.drawer_pos = drawers.last_drawer_pos
self.texture = drawers.last_texture or "blank.png"
self.visualId = drawers.last_visual_id
self.drawerType = drawers.last_drawer_type
end
local node = minetest.get_node(self.object:get_pos())
if core.get_item_group(node.name, "drawer") == 0 then
self.object:remove()
return
end
-- add self to public drawer visuals
-- this is needed because there is no other way to get this class
-- only the underlying LuaEntitySAO
-- PLEASE contact me, if this is wrong
local vId = self.visualId
if vId == "" then vId = 1 end
local posstr = core.hash_node_position(self.drawer_pos)
if not drawers.drawer_visuals[posstr] then
drawers.drawer_visuals[posstr] = {[vId] = self}
else
drawers.drawer_visuals[posstr][vId] = self
end
-- get meta
self.meta = core.get_meta(self.drawer_pos)
-- collisionbox
node = core.get_node(self.drawer_pos)
local colbox
if self.drawerType ~= 2 then
if node.param2 == 1 or node.param2 == 3 then
colbox = {0, -0.4374, -0.4374, 0, 0.4374, 0.4374}
else
colbox = {-0.4374, -0.4374, 0, 0.4374, 0.4374, 0} -- for param2 = 0 or 2
end
-- only half the size if it's a small drawer
if self.drawerType > 1 then
for i,j in pairs(colbox) do
colbox[i] = j * 0.5
end
end
else
if node.param2 == 1 or node.param2 == 3 then
colbox = {0, -0.2187, -0.4374, 0, 0.2187, 0.4374}
else
colbox = {-0.4374, -0.2187, 0, 0.4374, 0.2187, 0} -- for param2 = 0 or 2
end
end
-- visual size
local visual_size = {x = 0.6, y = 0.6}
if self.drawerType >= 2 then
visual_size = {x = 0.3, y = 0.3}
end
-- drawer values
local vid = self.visualId
self.count = self.meta:get_int("count"..vid)
self.itemName = self.meta:get_string("name"..vid)
self.maxCount = self.meta:get_int("max_count"..vid)
self.itemStackMax = self.meta:get_int("base_stack_max"..vid)
self.stackMaxFactor = self.meta:get_int("stack_max_factor"..vid)
-- infotext
local infotext = self.meta:get_string("entity_infotext"..vid) .. "\n\n\n\n\n"
self.object:set_properties({
collisionbox = colbox,
infotext = infotext,
textures = {self.texture},
visual_size = visual_size
})
-- make entity undestroyable
self.object:set_armor_groups({immortal = 1})
end,
on_rightclick = function(self, clicker)
if core.is_protected(self.drawer_pos, clicker:get_player_name()) then
core.record_protection_violation(self.drawer_pos, clicker:get_player_name())
return
end
-- used to check if we need to play a sound in the end
local inventoryChanged = false
-- When the player uses the drawer with their bare hand all
-- stacks from the inventory will be added to the drawer.
if self.itemName ~= "" and
clicker:get_wielded_item():get_name() == "" and
not clicker:get_player_control().sneak then
-- try to insert all items from inventory
local i = 0
local inv = clicker:get_inventory()
while i <= inv:get_size("main") do
-- set current stack to leftover of insertion
local leftover = self.try_insert_stack(
self,
inv:get_stack("main", i),
true
)
-- check if something was added
if leftover:get_count() < inv:get_stack("main", i):get_count() then
inventoryChanged = true
end
-- set new stack
inv:set_stack("main", i, leftover)
i = i + 1
end
else
-- try to insert wielded item only
local leftover = self.try_insert_stack(
self,
clicker:get_wielded_item(),
not clicker:get_player_control().sneak
)
-- check if something was added
if clicker:get_wielded_item():get_count() > leftover:get_count() then
inventoryChanged = true
end
-- set the leftover as new wielded item for the player
clicker:set_wielded_item(leftover)
end
if inventoryChanged then
self:play_interact_sound()
end
end,
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
local node = minetest.get_node(self.object:get_pos())
if core.get_item_group(node.name, "drawer") == 0 then
self.object:remove()
return
end
local add_stack = not puncher:get_player_control().sneak
if core.is_protected(self.drawer_pos, puncher:get_player_name()) then
core.record_protection_violation(self.drawer_pos, puncher:get_player_name())
return
end
local inv = puncher:get_inventory()
if inv == nil then
return
end
local spaceChecker = ItemStack(self.itemName)
if add_stack then
spaceChecker:set_count(spaceChecker:get_stack_max())
end
if not inv:room_for_item("main", spaceChecker) then
return
end
local stack
if add_stack then
stack = self:take_stack()
else
stack = self:take_items(1)
end
if stack ~= nil then
-- add removed stack to player's inventory
inv:add_item("main", stack)
-- play the interact sound
self:play_interact_sound()
end
end,
take_items = function(self, removeCount)
local meta = core.get_meta(self.drawer_pos)
if self.count <= 0 then
return
end
if removeCount > self.count then
removeCount = self.count
end
local stack = ItemStack(self.itemName)
stack:set_count(removeCount)
-- update the drawer count
self.count = self.count - removeCount
self:updateInfotext()
self:updateTexture()
self:saveMetaData()
-- return the stack that was removed from the drawer
return stack
end,
take_stack = function(self)
return self:take_items(ItemStack(self.itemName):get_stack_max())
end,
can_insert_stack = function(self, stack)
if stack:get_name() == "" or stack:get_count() <= 0 then
return 0
end
-- don't allow unstackable stacks
if self.itemName == "" and stack:get_stack_max() ~= 1 then
return stack:get_count()
end
if self.itemName ~= stack:get_name() then
return 0
end
if (self.count + stack:get_count()) <= self.maxCount then
return stack:get_count()
end
return self.maxCount - self.count
end,
try_insert_stack = function(self, itemstack, insert_all)
local stackCount = itemstack:get_count()
local stackName = itemstack:get_name()
local insertCount = self:can_insert_stack(itemstack)
if insertCount == 0 then
return itemstack
end
-- only add one, if player holding sneak key
if not insert_all then
insertCount = 1
end
-- in case the drawer was empty, initialize count, itemName, maxCount
if self.itemName == "" then
self.count = 0
self.itemName = itemstack:get_name()
self.maxCount = itemstack:get_stack_max() * self.stackMaxFactor
self.itemStackMax = itemstack:get_stack_max()
end
-- update everything
self.count = self.count + insertCount
self:updateInfotext()
self:updateTexture()
self:saveMetaData()
-- return leftover
itemstack:take_item(insertCount)
if itemstack:get_count() == 0 then
return ItemStack("")
end
return itemstack
end,
updateInfotext = function(self)
local itemDescription = ""
if core.registered_items[self.itemName] then
itemDescription = core.registered_items[self.itemName].description
end
if self.count <= 0 then
self.itemName = ""
self.meta:set_string("name"..self.visualId, self.itemName)
self.texture = "blank.png"
itemDescription = S("Empty")
end
local infotext = drawers.gen_info_text(itemDescription,
self.count, self.stackMaxFactor, self.itemStackMax)
self.meta:set_string("entity_infotext"..self.visualId, infotext)
self.object:set_properties({
infotext = infotext .. "\n\n\n\n\n"
})
end,
updateTexture = function(self)
-- texture
self.texture = drawers.get_inv_image(self.itemName)
self.object:set_properties({
textures = {self.texture}
})
end,
dropStack = function(self, itemStack)
-- print warning if dropping higher stack counts than allowed
if itemStack:get_count() > itemStack:get_stack_max() then
core.log("warning", "[drawers] Dropping item stack with higher count than allowed")
end
-- find a position containing air
local dropPos = core.find_node_near(self.drawer_pos, 1, {"air"}, false)
-- if no pos found then drop on the top of the drawer
if not dropPos then
dropPos = self.object:get_pos()
dropPos.y = dropPos.y + 1
end
-- drop the item stack
core.item_drop(itemStack, nil, dropPos)
end,
dropItemOverload = function(self)
-- drop stacks until there are no more items than allowed
while self.count > self.maxCount do
-- remove the overflow
local removeCount = self.count - self.maxCount
-- if this is too much for a single stack, only take the
-- stack limit
if removeCount > self.itemStackMax then
removeCount = self.itemStackMax
end
-- remove this count from the drawer
self.count = self.count - removeCount
-- create a new item stack having the size of the remove
-- count
local stack = ItemStack(self.itemName)
stack:set_count(removeCount)
print(stack:to_string())
-- drop the stack
self:dropStack(stack)
end
end,
setStackMaxFactor = function(self, stackMaxFactor)
self.stackMaxFactor = stackMaxFactor
self.maxCount = self.stackMaxFactor * self.itemStackMax
-- will drop possible overflowing items
self:dropItemOverload()
self:updateInfotext()
self:saveMetaData()
end,
play_interact_sound = function(self)
core.sound_play("drawers_interact", {
pos = self.object:get_pos(),
max_hear_distance = 6,
gain = 2.0
})
end,
saveMetaData = function(self, meta)
self.meta:set_int("count"..self.visualId, self.count)
self.meta:set_string("name"..self.visualId, self.itemName)
self.meta:set_int("max_count"..self.visualId, self.maxCount)
self.meta:set_int("base_stack_max"..self.visualId, self.itemStackMax)
self.meta:set_int("stack_max_factor"..self.visualId, self.stackMaxFactor)
end
})
core.register_lbm({
name = "drawers:restore_visual",
nodenames = {"group:drawer"},
run_at_every_load = true,
action = function(pos, node)
local meta = core.get_meta(pos)
-- create drawer upgrade inventory
meta:get_inventory():set_size("upgrades", 5)
-- set the formspec
meta:set_string("formspec", drawers.drawer_formspec)
-- count the drawer visuals
local drawerType = core.registered_nodes[node.name].groups.drawer
local foundVisuals = 0
local objs = core.get_objects_inside_radius(pos, 0.56)
if objs then
for _, obj in pairs(objs) do
if obj and obj:get_luaentity() and
obj:get_luaentity().name == "drawers:visual" then
foundVisuals = foundVisuals + 1
end
end
end
-- if all drawer visuals were found, return
if foundVisuals == drawerType then
return
end
-- not enough visuals found, remove existing and create new ones
drawers.remove_visuals(pos)
drawers.spawn_visuals(pos)
end
})

7
mods/drawers/mod.conf Normal file
View file

@ -0,0 +1,7 @@
name = drawers
description = Storage Drawers - A Mod adding simple storages for items and blocks, showing the item's inventory image in the front.
optional_depends = default, mcl_core, screwdriver, pipeworks, moreores, digilines, mesecons_mvps, techage
min_minetest_version = 5.0
release = 16765
author = LNJ
title = Storage Drawers

BIN
mods/drawers/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

View file

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 664 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 657 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B