commit fa84f7c226960a24b95e51b385991b776402940e Author: Wuzzy Date: Sat Nov 5 21:12:14 2022 +0100 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..e2cd60e --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +## Get Item + +This Minetest mod allows you to get easy access to all items of the game, +including items that players might not supposed to get (e.g. items +that are normally hidden from a Creative Mode inventory). + +Players need to have the 'give' privilege to use this mod. + +It works in all games. + +## Usage + +To use anything, you need to have the 'give' privilege. + +If you have it, you can access items in 3 ways: + +* Bag of Everything [`getitem:bag`]: + * An item. Use the 'punch' key to open the dialog +* Chest of Everything [`getitem:chest`]: + * A block. Place it anywhere, then press + the 'place' key while pointing on it +* Chat command `/getitem`: Type it into the chat + +In the item window, you can drag out items at will into your +inventory. Put items into the trash slot to destroy them. + +## Credits + +Created by Wuzzy. +Licensed under the MIT License. diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..90a39e9 --- /dev/null +++ b/init.lua @@ -0,0 +1,261 @@ +local F = minetest.formspec_escape +local S = minetest.get_translator("getitem") + +local detached_inventories = {} +local current_pages = {} + +local SLOTS_W = 10 +local SLOTS_H = 5 +local SLOTS = SLOTS_W * SLOTS_H + +local function allow_check(player, msg_disallowed) + if player and player:is_player() then + local name = player:get_player_name() + if minetest.check_player_privs(name, "give") then + return -1 + else + minetest.chat_send_player(name, msg_disallowed) + minetest.close_formspec(name, "getitem:getitem") + return 0 + end + else + return -1 + end +end + +-- Create detached inventories +local function add_detached_inventories(player) + local name = player:get_player_name() + local inv_items = minetest.create_detached_inventory("getitem_items_"..name, { + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + return 0 + end, + allow_put = function(inv, listname, index, stack, player) + return 0 + end, + allow_take = function(inv, listname, index, stack, player) + return allow_check(player, S("You can't take items ('give' privilege required).")) + end, + }, name) + local inv_trash = minetest.create_detached_inventory("getitem_trash_"..name, { + allow_take = function(inv, listname, index, stack, player) + return 0 + end, + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + return 0 + end, + allow_put = function(inv, listname, index, stack, player) + local ret = allow_check(player, S("You can't trash items ('give' privilege required).")) + if ret == -1 then + return stack:get_count() + else + return 0 + end + end, + on_put = function(inv, listname, index, stack, player) + inv:set_list(listname, {}) + end, + }, name) + inv_trash:set_size("main", 1) + detached_inventories[name] = { items = inv_items, trash = inv_trash } +end + +local max_page = 1 + +local function get_formspec(page, name) + local start = 0 + (page-1)*SLOTS + if not name then + return "" + end + local player = minetest.get_player_by_name(name) + local playerinvsize = player:get_inventory():get_size("main") + local hotbarsize = player:hud_get_hotbar_itemcount() + local pinv_w, pinv_h, pinv_x + pinv_w = hotbarsize + pinv_h = math.ceil(playerinvsize / pinv_w) + pinv_w = math.min(pinv_w, 10) + pinv_h = math.min(pinv_w, 4) + pinv_x = 0 + if pinv_w < 9 then + pinv_x = 1 + end + + local pagestr = "" + if max_page > 1 then + pagestr = "button[0,5;1,1;getitem_prev;"..F(S("<")).."]".. + "button[1,5;1,1;getitem_next;"..F(S(">")).."]".. + "label[2,5;"..F(S("Page: @1/@2", page, max_page)).."]" + end + + return "size[10,10]".. + "list[detached:getitem_items_"..name..";main;0,0;"..SLOTS_W..","..SLOTS_H..";"..start.."]".. + "list[current_player;main;"..pinv_x..",6;"..pinv_w..","..pinv_h..";]" .. + "label[8,5;"..F(S("Trash:")).."]" .. + "list[detached:getitem_trash_"..name..";main;9,5;1,1]" .. + pagestr .. + "listring[detached:getitem_items_"..name..";main]".. + "listring[current_player;main]".. + "listring[detached:getitem_trash_"..name..";main]" +end + +local show_formspec = function(name) + if not minetest.check_player_privs(name, "give") then + minetest.chat_send_player(name, S("You need to have the 'give' privilege to use this.")) + minetest.close_formspec(name, "getitem:getitem") + return false + end + local page = current_pages[name] + local form = get_formspec(page, name) + minetest.show_formspec(name, "getitem:getitem", form) + return true +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname == "getitem:getitem" then + local name = player:get_player_name() + if not minetest.check_player_privs(name, "give") then + minetest.chat_send_player(name, S("You need to have the 'give' privilege to use this.")) + minetest.close_formspec(name, "getitem:getitem") + return + end + local page = current_pages[name] + local old_page = page + if fields.getitem_next then + page = page + 1 + elseif fields.getitem_prev then + page = page - 1 + else + return + end + if page < 1 then + page = 1 + end + if page > max_page then + page = max_page + end + if page ~= old_page then + current_pages[name] = page + show_formspec(name) + end + end +end) + +minetest.register_chatcommand("giveitem", { + description = S("Show a dialog to receive all items"), + param = "", + privs = { give = true }, + func = function(name, param) + return show_formspec(name) + end, +}) + +minetest.register_tool("getitem:bag", { + description = S("Bag of Everything"), + _tt_help = S("Grants access to all items"), + inventory_image = "getitem_bag.png", + wield_image = "getitem_bag.png", + groups = { disable_repair = 1, not_in_creative_inventory = 1 }, + on_use = function(itemstack, user) + if user and user:is_player() then + local name = user:get_player_name() + show_formspec(name) + end + end, +}) + +minetest.register_node("getitem:chest", { + description = S("Chest of Everything"), + _tt_help = S("Grants access to all items"), + tiles = { + "getitem_chest_top.png", + "getitem_chest_bottom.png", + "getitem_chest_side.png", + "getitem_chest_side.png", + "getitem_chest_side.png", + "getitem_chest_front.png", + }, + paramtype2 = "facedir", + groups = { dig_immediate=2, not_in_creative_inventory = 1}, + is_ground_content = false, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", S("Chest of Everything")) + end, + on_rightclick = function(pos, node, clicker) + if clicker and clicker:is_player() then + local name = clicker:get_player_name() + show_formspec(name) + end + end, +}) + +local getitem_table + +minetest.register_on_mods_loaded(function() + local items = {} + for itemstring,_ in pairs(minetest.registered_items) do + if itemstring ~= "" and itemstring ~= "unknown" and itemstring ~= "ignore" then + table.insert(items, itemstring) + end + end + --[[ Sort items in this order: + * Nodes + * Tools + * Craftitems + * items from this mod (come last) ]] + local function compare(item1, item2) + local def1 = minetest.registered_items[item1] + local def2 = minetest.registered_items[item2] + local tool1 = def1.type == "tool" + local tool2 = def2.type == "tool" + local craftitem1 = def1.type == "craft" + local craftitem2 = def2.type == "craft" + local node1 = def1.type == "node" + local node2 = def2.type == "node" + local nici1 = minetest.get_item_group(item1, "not_in_creative_inventory") == 1 or not def1.description + local nici2 = minetest.get_item_group(item2, "not_in_creative_inventory") == 1 or not def2.description + local getitem1 = string.sub(item1, 1, 8) == "getitem:" + local getitem2 = string.sub(item2, 1, 8) == "getitem:" + if getitem1 and not getitem2 then + return false + elseif not getitem1 and getitem2 then + return true + elseif node1 and not node2 then + return true + elseif not node1 and node2 then + return false + elseif tool1 and not tool2 then + return true + elseif not tool1 and tool2 then + return false + elseif craftitem1 and not craftitem2 then + return true + elseif not craftitem1 and craftitem2 then + return false + else + return item1 < item2 + end + end + table.sort(items, compare) + + max_page = math.ceil(#items / SLOTS) + + getitem_table = items +end) + +minetest.register_on_joinplayer(function(player) + add_detached_inventories(player) + local name = player:get_player_name() + local inv = detached_inventories[name].items + inv:set_size("main", #getitem_table) + inv:set_list("main", {}) + for i=1, #getitem_table do + inv:add_item("main", getitem_table[i]) + end + current_pages[name] = 1 +end) + +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + current_pages[name] = nil +end) diff --git a/locale/getitem.de.tr b/locale/getitem.de.tr new file mode 100644 index 0000000..b4f5351 --- /dev/null +++ b/locale/getitem.de.tr @@ -0,0 +1,12 @@ +# textdomain: getitem +You can't take items ('give' privilege required).=Sie können keine Gegenstände entnehmen („give“-Privileg benötigt). +You can't trash items ('give' privilege required).=Sie können keine Gegenstände entsorgen („give“-Privileg benötigt). +Trash:=Müll: +<=< +>=> +Page: @1/@2=Seite: @1/@2 +You need to have the 'give' privilege to use this.=Sie benötigen das „give“-Privileg, um dies benutzen zu können. +Show a dialog to receive all items=Zeigt einen Dialog, aus dem man alle Gegenstände entnehmen kann. +Bag of Everything=Tasche mit Allem +Grants access to all items=Gewährt Zugriff zu allen Gegenständen +Chest of Everything=Truhe mit Allem diff --git a/locale/template.txt b/locale/template.txt new file mode 100644 index 0000000..98d0b9c --- /dev/null +++ b/locale/template.txt @@ -0,0 +1,12 @@ +# textdomain: getitem +You can't take items ('give' privilege required).= +You can't trash items ('give' privilege required).= +Trash:= +<= +>= +Page: @1/@2= +You need to have the 'give' privilege to use this.= +Show a dialog to receive all items= +Bag of Everything= +Grants access to all items= +Chest of Everything= diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..29b79c2 --- /dev/null +++ b/mod.conf @@ -0,0 +1,3 @@ +name = getitem +description = Allows you to get all items +optional_depends = tt diff --git a/textures/getitem_bag.png b/textures/getitem_bag.png new file mode 100644 index 0000000..7c18907 Binary files /dev/null and b/textures/getitem_bag.png differ diff --git a/textures/getitem_chest_bottom.png b/textures/getitem_chest_bottom.png new file mode 100644 index 0000000..fdfe538 Binary files /dev/null and b/textures/getitem_chest_bottom.png differ diff --git a/textures/getitem_chest_front.png b/textures/getitem_chest_front.png new file mode 100644 index 0000000..0f11fc9 Binary files /dev/null and b/textures/getitem_chest_front.png differ diff --git a/textures/getitem_chest_side.png b/textures/getitem_chest_side.png new file mode 100644 index 0000000..6204a64 Binary files /dev/null and b/textures/getitem_chest_side.png differ diff --git a/textures/getitem_chest_top.png b/textures/getitem_chest_top.png new file mode 100644 index 0000000..1dc033b Binary files /dev/null and b/textures/getitem_chest_top.png differ