202 lines
7.3 KiB
Groff
202 lines
7.3 KiB
Groff
local modname = minetest.get_current_modname()
|
|
local ci = {}
|
|
ci.blocks = {} -- Die komplette Master-Liste aller Items
|
|
ci.pages = {} -- Speichert Seite UND Anzahl pro Spieler
|
|
ci.searches = {} -- Speichert den aktuellen Suchbegriff pro Spieler
|
|
|
|
local columns = 15
|
|
local rows = 7
|
|
local nodes_per_page = columns * rows
|
|
|
|
minetest.register_privilege("ci", {
|
|
description = "Allows the player to use the ci command",
|
|
give_to_singleplayer = false
|
|
})
|
|
|
|
local function has_permission(player_name)
|
|
return minetest.check_player_privs(player_name, {ci=true})
|
|
end
|
|
|
|
-- Items laden
|
|
minetest.register_on_mods_loaded(function()
|
|
minetest.after(0, function()
|
|
local list_items = minetest.settings:get_bool("ci_list_items") ~= false
|
|
local list_tools = minetest.settings:get_bool("ci_list_tools") ~= false
|
|
|
|
ci.blocks = {}
|
|
for name, def in pairs(minetest.registered_items) do
|
|
if def and name ~= "" and not name:find("alias:") then
|
|
local is_node = (def.type == "node")
|
|
local is_tool = (list_tools and def.type == "tool")
|
|
local is_item = (list_items and (def.type == "craftitem" or def.type == "none" or not def.type))
|
|
|
|
if is_node or is_tool or is_item then
|
|
table.insert(ci.blocks, name)
|
|
end
|
|
end
|
|
end
|
|
table.sort(ci.blocks)
|
|
print("[ci] " .. #ci.blocks .. " Einträge geladen.")
|
|
end)
|
|
end)
|
|
|
|
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)
|
|
|
|
-- Struktur für Spieler-Status sicherstellen
|
|
if not ci.pages[player_name] then
|
|
ci.pages[player_name] = {page = 1, quantity = 1}
|
|
end
|
|
|
|
local current_page = ci.pages[player_name].page
|
|
local current_qty = ci.pages[player_name].quantity
|
|
local total_pages = math.ceil(#filtered_blocks / nodes_per_page)
|
|
|
|
if current_page > total_pages then
|
|
current_page = math.max(1, total_pages)
|
|
ci.pages[player_name].page = current_page
|
|
end
|
|
|
|
local current_search = ci.searches[player_name] or ""
|
|
|
|
local formspec = "size[17.5,12.8]" ..
|
|
"label[0.5,0.2;Wähle ein Item für dein Inventar:]"
|
|
|
|
local start_index = (current_page - 1) * nodes_per_page + 1
|
|
local end_index = math.min(current_page * nodes_per_page, #filtered_blocks)
|
|
|
|
for i = start_index, end_index do
|
|
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
|
|
|
|
-- Button mit technischem Namen im Tooltip
|
|
formspec = formspec ..
|
|
string.format("item_image_button[%f,%f;1,1;%s;add_%s;]",
|
|
x, y, minetest.formspec_escape(block), minetest.formspec_escape(block)) ..
|
|
string.format("tooltip[add_%s;%s\n[%s]]",
|
|
minetest.formspec_escape(block),
|
|
minetest.formspec_escape(minetest.registered_items[block].description or ""),
|
|
minetest.formspec_escape(block))
|
|
end
|
|
|
|
-- Steuerelemente (Anzahl-Feld nutzt jetzt current_qty)
|
|
formspec = formspec ..
|
|
"field[0.5,9.2;5.5,1;search;Suche:;" .. minetest.formspec_escape(current_search) .. "]" ..
|
|
"button[6.1,8.85;2,1;do_search;Suchen]" ..
|
|
"button[8.2,8.85;1,1;reset_search;X]" ..
|
|
"field[13.0,9.2;4,1;quantity;Anzahl:;" .. current_qty .. "]"
|
|
|
|
formspec = formspec ..
|
|
"label[8,10.4;Seite " .. current_page .. " von " .. total_pages .. "]"
|
|
if current_page > 1 then
|
|
formspec = formspec .. "button[6.8,10.4;1.2,1;prev;<<]"
|
|
end
|
|
if current_page < total_pages then
|
|
formspec = formspec .. "button[9.5,10.4;1.2,1;next;>>]"
|
|
end
|
|
|
|
formspec = formspec .. "button_exit[7.75,11.5;2,1;exit;Schließen]"
|
|
|
|
return formspec
|
|
end
|
|
|
|
minetest.register_chatcommand("ci", {
|
|
description = "Kreativ-Inventar öffnen",
|
|
privs = {ci=true},
|
|
func = function(name)
|
|
if not has_permission(name) then return false, "Keine Rechte." end
|
|
ci.pages[name] = {page = 1, quantity = 1}
|
|
ci.searches[name] = nil
|
|
local player = minetest.get_player_by_name(name)
|
|
if player then minetest.show_formspec(name, modname .. ":form", ci.get_formspec(player)) end
|
|
return true
|
|
end,
|
|
})
|
|
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if formname ~= modname .. ":form" then return end
|
|
local player_name = player:get_player_name()
|
|
if not has_permission(player_name) then return end
|
|
|
|
-- Aktuelle Anzahl immer zwischenspeichern, wenn ein Feld gesendet wird
|
|
if fields.quantity then
|
|
ci.pages[player_name].quantity = tonumber(fields.quantity) or 1
|
|
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].page = 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].page = 1
|
|
minetest.show_formspec(player_name, modname .. ":form", ci.get_formspec(player))
|
|
return
|
|
end
|
|
|
|
if fields.next then
|
|
ci.pages[player_name].page = ci.pages[player_name].page + 1
|
|
minetest.show_formspec(player_name, modname .. ":form", ci.get_formspec(player))
|
|
return
|
|
elseif fields.prev then
|
|
ci.pages[player_name].page = math.max(1, ci.pages[player_name].page - 1)
|
|
minetest.show_formspec(player_name, modname .. ":form", ci.get_formspec(player))
|
|
return
|
|
end
|
|
|
|
for field, _ in pairs(fields) do
|
|
if field:sub(1, 4) == "add_" then
|
|
local itemname = field:sub(5)
|
|
local qty = ci.pages[player_name].quantity
|
|
local inv = player:get_inventory()
|
|
if inv then
|
|
inv:add_item("main", itemname .. " " .. qty)
|
|
minetest.chat_send_player(player_name, "Hinzugefügt: " .. qty .. "x " .. itemname)
|
|
end
|
|
-- Formspec bleibt offen, Anzahl bleibt erhalten
|
|
minetest.show_formspec(player_name, modname .. ":form", ci.get_formspec(player))
|
|
return
|
|
end
|
|
end
|
|
end)
|
|
|
|
-- i3 Integration
|
|
minetest.after(0, function()
|
|
if minetest.global_exists("i3_extrabuttons") then
|
|
i3_extrabuttons.new_tab("cinventory", {
|
|
description = "Kreativ-Inventar",
|
|
priv = "ci",
|
|
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)
|