updated search, itemlist and much more...

This commit is contained in:
Rainer 2026-02-12 13:39:26 +01:00
parent bc5850150b
commit 3b9d57e883
7 changed files with 1320 additions and 157 deletions

View file

@ -1,11 +1,12 @@
local modname = minetest.get_current_modname()
local ci = {}
ci.blocks = {} -- complete list of node names
ci.pages = {} -- current page per player
ci.selected_item = {} -- store selected item per player
ci.blocks = {} -- Die komplette Master-Liste aller Items
ci.pages = {} -- Speichert die aktuelle Seite pro Spieler
ci.searches = {} -- Speichert den aktuellen Suchbegriff pro Spieler
local columns = 15
local rows = 7
local nodes_per_page = columns * rows -- 105 nodes per page
local nodes_per_page = columns * rows
minetest.register_privilege("ci", {
description = "Allows the player to use the ci command",
@ -16,43 +17,71 @@ local function has_permission(player_name)
return minetest.check_player_privs(player_name, {ci=true})
end
-- Build the list of nodes after all mods are loaded.
minetest.register_on_mods_loaded(function()
local list_items = minetest.settings:get_bool("ci_list_items")
local list_tools = minetest.settings:get_bool("ci_list_tools")
for name, def in pairs(minetest.registered_items) do
if def.type == "node" or (list_items and def.type == "craftitem") or (list_tools and def.type == "tool") then
table.insert(ci.blocks, name)
if def.type ~= "alias" and (def.type == "node" or
(list_items and def.type == "craftitem") or
(list_tools and def.type == "tool")) then
table.insert(ci.blocks, name)
end
end
table.sort(ci.blocks)
print("[ci] Loaded " .. #ci.blocks .. " items.")
end)
function ci.get_total_pages()
return math.ceil(#ci.blocks / nodes_per_page)
minetest.register_on_leaveplayer(function(player)
local player_name = player:get_player_name()
ci.pages[player_name] = nil
ci.searches[player_name] = nil
end)
function ci.get_filtered_blocks(player_name)
local search_term = ci.searches[player_name]
if not search_term or search_term == "" then
return ci.blocks
end
local filtered = {}
local term_lower = search_term:lower()
for _, item_name in ipairs(ci.blocks) do
if item_name:lower():find(term_lower, 1, true) then
table.insert(filtered, item_name)
end
end
return filtered
end
function ci.get_formspec(player)
local player_name = player:get_player_name()
local filtered_blocks = ci.get_filtered_blocks(player_name)
local current_page = ci.pages[player_name] or 1
local total_pages = ci.get_total_pages()
local total_pages = math.ceil(#filtered_blocks / nodes_per_page)
local formspec = "size[17.5,10.5]" ..
"label[0.5,0.2;Select a block to add to your inventory:]" ..
"field[4,9.1;2,1;quantity;Amount:;1]" ..
"label[8.5,9;Page " .. current_page .. " of " .. total_pages .. "]"
if current_page > total_pages then
current_page = math.max(1, total_pages)
ci.pages[player_name] = current_page
end
local current_search = ci.searches[player_name] or ""
local formspec = "size[17.5,12.8]" ..
"label[0.5,0.2;Select an item to add to your inventory:]"
local start_index = (current_page - 1) * nodes_per_page + 1
local end_index = math.min(current_page * nodes_per_page, #ci.blocks)
local end_index = math.min(current_page * nodes_per_page, #filtered_blocks)
-- Place the block buttons in a grid.
for i = start_index, end_index do
local block = ci.blocks[i]
local rel = i - start_index -- relative index on this page
local block = filtered_blocks[i]
local rel = i - start_index
local col = rel % columns
local row = math.floor(rel / columns)
local x = 0.5 + col * 1.1
local y = 1 + row * 1.1
-- RÜCKGÄNGIG GEMACHT: Die gesamte Tooltip-Logik wurde entfernt.
-- Der item_image_button wird jetzt wieder in seiner einfachsten Form ohne Label erstellt.
formspec = formspec ..
string.format("item_image_button[%f,%f;1,1;%s;add_%s;]",
x, y,
@ -60,32 +89,42 @@ function ci.get_formspec(player)
minetest.formspec_escape(block))
end
-- Steuerelemente
formspec = formspec ..
"field[0.5,9.2;5.5,1;search;Search:;" .. minetest.formspec_escape(current_search) .. "]" ..
"button[6.1,8.85;2,1;do_search;Search]" ..
"button[8.2,8.85;1,1;reset_search;X]" ..
"field[13.0,9.2;4,1;quantity;Amount:;1]"
formspec = formspec ..
"label[8,10.4;Page " .. current_page .. " of " .. total_pages .. "]"
if current_page > 1 then
formspec = formspec .. "button[6.25,9;2,0.5;prev;Previous]"
formspec = formspec .. "button[6.8,10.4;1.2,1;prev;<<]"
end
if current_page < total_pages then
formspec = formspec .. "button[10.25,9;2,0.5;next;Next]"
formspec = formspec .. "button[9.5,10.4;1.2,1;next;>>]"
end
formspec = formspec .. "button_exit[8.25,9.75;2,0.5;exit;Close]"
formspec = formspec .. "button_exit[7.75,11.5;2,1;exit;Close]"
return formspec
end
minetest.register_chatcommand("ci", {
description = "Open block list GUI with pages",
description = "Open creative inventory GUI",
privs = {ci=true},
func = function(name, param)
if not has_permission(name) then
return false, "You do not have permission to use this command."
end
ci.pages[name] = 1
ci.searches[name] = nil
local player = minetest.get_player_by_name(name)
if not player then
return false, "Player not found."
end
local formspec = ci.get_formspec(player)
minetest.show_formspec(name, modname .. ":form", formspec)
return true, "Opening block list..."
minetest.show_formspec(name, modname .. ":form", ci.get_formspec(player))
return true, "Opening creative inventory..."
end,
})
@ -94,40 +133,71 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
return
end
local player_name = player:get_player_name()
if not has_permission(player_name) then
if not has_permission(player_name) then
minetest.chat_send_player(player_name, "You do not have permission to use this.")
return
end
if fields.do_search or (fields.key_enter_field and fields.key_enter_field == "search") then
ci.searches[player_name] = fields.search
ci.pages[player_name] = 1
minetest.show_formspec(player_name, modname .. ":form", ci.get_formspec(player))
return
elseif fields.reset_search then
ci.searches[player_name] = nil
ci.pages[player_name] = 1
minetest.show_formspec(player_name, modname .. ":form", ci.get_formspec(player))
return
end
if fields.next then
local total_pages = ci.get_total_pages()
local filtered_blocks = ci.get_filtered_blocks(player_name)
local total_pages = math.ceil(#filtered_blocks / nodes_per_page)
local current_page = ci.pages[player_name] or 1
if current_page < total_pages then
ci.pages[player_name] = current_page + 1
end
minetest.show_formspec(player_name, modname .. ":form", ci.get_formspec(player))
return true
return
elseif fields.prev then
local current_page = ci.pages[player_name] or 1
if current_page > 1 then
ci.pages[player_name] = current_page - 1
end
minetest.show_formspec(player_name, modname .. ":form", ci.get_formspec(player))
return true
return
end
local quantity = tonumber(fields.quantity)
if not quantity or quantity < 1 then
minetest.chat_send_player(player_name, "Invalid quantity, giving 1 instead.")
quantity = 1
end
-- If a block button was pressed, add that block in specified quantity.
local quantity = tonumber(fields.quantity) or 1
if quantity < 1 then quantity = 1 end
for field, _ in pairs(fields) do
if field:sub(1, 4) == "add_" then
local blockname = field:sub(5)
local itemname = field:sub(5)
local inv = player:get_inventory()
if inv then
inv:add_item("main", blockname .. " " .. quantity)
minetest.chat_send_player(player_name, "Added " .. quantity .. " of: " .. blockname)
inv:add_item("main", itemname .. " " .. quantity)
minetest.chat_send_player(player_name, "Added " .. quantity .. " of: " .. itemname)
end
return true
minetest.show_formspec(player_name, modname .. ":form", ci.get_formspec(player))
return
end
end
end)
minetest.after(0, function()
if minetest.global_exists("i3_extrabuttons") then
i3_extrabuttons.new_tab("cinventory", {
description = "Kreativ-Inventar",
priv = "ci", -- optional: nur Spieler mit ci-Priv sehen den Tab
formspec = function(player, data, fs) end,
fields = function(player, data, fields)
i3.set_tab(player, "inventory")
minetest.show_formspec(player:get_player_name(), modname .. ":form", ci.get_formspec(player))
end,
})
end
end)