diff --git a/games/devtest/mods/testtools/README.md b/games/devtest/mods/testtools/README.md index a1eb95ed7..72f0a2db0 100644 --- a/games/devtest/mods/testtools/README.md +++ b/games/devtest/mods/testtools/README.md @@ -40,6 +40,14 @@ Usage: * Punch: Open node metadata editor +## Item Meta Editor +Edit and view metadata of items. + +Usage: + +* Place/Punch: Opens item metadata editor of the item in the next + inventory slot from the wielded item + ## Entity Rotator Changes the entity rotation (with `set_rotation`). diff --git a/games/devtest/mods/testtools/init.lua b/games/devtest/mods/testtools/init.lua index 1041acdeb..abc1ed79b 100644 --- a/games/devtest/mods/testtools/init.lua +++ b/games/devtest/mods/testtools/init.lua @@ -693,30 +693,40 @@ local function use_loadstring(param, player) return true, errOrResult end --- Node Meta Editor +-- Item Meta Editor + Node Meta Editor local node_meta_posses = {} -local node_meta_latest_keylist = {} +local meta_latest_keylist = {} -local function show_node_meta_formspec(user, pos, key, value, keylist) +local function show_meta_formspec(user, metatype, pos_or_item, key, value, keylist) local textlist if keylist then textlist = "textlist[0,0.5;2.5,6.5;keylist;"..keylist.."]" else textlist = "" end - minetest.show_formspec(user:get_player_name(), - "testtools:node_meta_editor", - "size[15,9]".. + + local form = "size[15,9]".. "label[0,0;"..F(S("Current keys:")).."]".. textlist.. "field[3,0.5;12,1;key;"..F(S("Key"))..";"..F(key).."]".. "textarea[3,1.5;12,6;value;"..F(S("Value (use empty value to delete key)"))..";"..F(value).."]".. - "button[0,8;3,1;get;"..F(S("Get value")).."]".. - "button[4,8;3,1;set;"..F(S("Set value")).."]".. - "label[0,7.2;"..F(S("pos = @1", minetest.pos_to_string(pos))).."]") + "button[4,8;3,1;set;"..F(S("Set value")).."]" + + local extra_label + local formname + if metatype == "node" then + formname = "testtools:node_meta_editor" + extra_label = S("pos = @1", minetest.pos_to_string(pos_or_item)) + else + formname = "testtools:item_meta_editor" + extra_label = S("item = @1", pos_or_item:get_name()) + end + form = form .. "label[0,7.2;"..F(extra_label).."]" + + minetest.show_formspec(user:get_player_name(), formname, form) end -local function get_node_meta_keylist(meta, playername, escaped) +local function get_meta_keylist(meta, playername, escaped) local keys = {} local ekeys = {} local mtable = meta:to_table() @@ -729,7 +739,7 @@ local function get_node_meta_keylist(meta, playername, escaped) end end if playername then - node_meta_latest_keylist[playername] = keys + meta_latest_keylist[playername] = keys end return table.concat(ekeys, ",") end @@ -750,11 +760,47 @@ minetest.register_tool("testtools:node_meta_editor", { node_meta_posses[user:get_player_name()] = pos local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - show_node_meta_formspec(user, pos, "", "", get_node_meta_keylist(meta, user:get_player_name(), true)) + show_meta_formspec(user, "node", pos, "", "", get_meta_keylist(meta, user:get_player_name(), true)) return itemstack end, }) +local function get_item_next_to_wielded_item(player) + local inv = player:get_inventory() + local wield = player:get_wield_index() + local itemstack = inv:get_stack("main", wield+1) + return itemstack +end +local function set_item_next_to_wielded_item(player, itemstack) + local inv = player:get_inventory() + local wield = player:get_wield_index() + inv:set_stack("main", wield+1, itemstack) +end + +local function use_item_meta_editor(itemstack, user, pointed_thing) + if not user:is_player() then + return itemstack + end + local item_to_edit = get_item_next_to_wielded_item(user) + if item_to_edit:is_empty() then + minetest.chat_send_player(user:get_player_name(), S("Place an item next to the Item Meta Editor in your inventory first!")) + return itemstack + end + local meta = item_to_edit:get_meta() + show_meta_formspec(user, "item", item_to_edit, "", "", get_meta_keylist(meta, user:get_player_name(), true)) + return itemstack +end + +minetest.register_tool("testtools:item_meta_editor", { + description = S("Item Meta Editor") .. "\n" .. + S("Punch/Place: Edit item metadata of item in the next inventory slot"), + inventory_image = "testtools_item_meta_editor.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = use_item_meta_editor, + on_secondary_use = use_item_meta_editor, + on_place = use_item_meta_editor, +}) + minetest.register_on_player_receive_fields(function(player, formname, fields) if not (player and player:is_player()) then return @@ -832,17 +878,30 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) player:set_wielded_item(witem) end end - elseif formname == "testtools:node_meta_editor" then + elseif formname == "testtools:node_meta_editor" or formname == "testtools:item_meta_editor" then local name = player:get_player_name() - local pos = node_meta_posses[name] + local metatype + local pos_or_item + if formname == "testtools:node_meta_editor" then + metatype = "node" + pos_or_item = node_meta_posses[name] + else + metatype = "item" + pos_or_item = get_item_next_to_wielded_item(player) + end if fields.keylist then local evnt = minetest.explode_textlist_event(fields.keylist) if evnt.type == "DCL" or evnt.type == "CHG" then - local keylist_table = node_meta_latest_keylist[name] - if not pos then + local keylist_table = meta_latest_keylist[name] + if metatype == "node" and not pos_or_item then return end - local meta = minetest.get_meta(pos) + local meta + if metatype == "node" then + meta = minetest.get_meta(pos_or_item) + else + meta = pos_or_item:get_meta() + end if not keylist_table then return end @@ -856,31 +915,37 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) keylist_escaped[k] = F(v) end local keylist = table.concat(keylist_escaped, ",") - show_node_meta_formspec(player, pos, key, value, keylist) + show_meta_formspec(player, metatype, pos_or_item, key, value, keylist) return end elseif fields.key and fields.key ~= "" and fields.value then - if not pos then + if metatype == "node" and not pos_or_item then return end - local meta = minetest.get_meta(pos) - if fields.get then - local value = meta:get_string(fields.key) - show_node_meta_formspec(player, pos, fields.key, value, - get_node_meta_keylist(meta, name, true)) - return - elseif fields.set then + local meta + if metatype == "node" then + meta = minetest.get_meta(pos_or_item) + elseif metatype == "item" then + if pos_or_item:is_empty() then + return + end + meta = pos_or_item:get_meta() + end + if fields.set then meta:set_string(fields.key, fields.value) - show_node_meta_formspec(player, pos, fields.key, fields.value, - get_node_meta_keylist(meta, name, true)) - return + if metatype == "item" then + set_item_next_to_wielded_item(player, pos_or_item) + end + show_meta_formspec(player, metatype, pos_or_item, fields.key, fields.value, + get_meta_keylist(meta, name, true)) end + return end end end) minetest.register_on_leaveplayer(function(player) local name = player:get_player_name() - node_meta_latest_keylist[name] = nil + meta_latest_keylist[name] = nil node_meta_posses[name] = nil end) diff --git a/games/devtest/mods/testtools/textures/testtools_item_meta_editor.png b/games/devtest/mods/testtools/textures/testtools_item_meta_editor.png new file mode 100644 index 000000000..5cebb0a9d Binary files /dev/null and b/games/devtest/mods/testtools/textures/testtools_item_meta_editor.png differ