217 lines
6.8 KiB
Lua
217 lines
6.8 KiB
Lua
-- =================================================================
|
|
-- Luanti POIs Mod v16 (Finale Version mit GUI-Anpassungen)
|
|
-- =================================================================
|
|
|
|
-- 1. Setup und Konfiguration
|
|
-------------------------------------------------------------------
|
|
poi = {
|
|
points = {},
|
|
categories = {},
|
|
player_gui_state = {}
|
|
}
|
|
|
|
poi.modname = minetest.get_current_modname()
|
|
local storage = minetest.get_mod_storage()
|
|
|
|
-- Die Kategorien als feste, saubere Liste
|
|
poi.categories = {
|
|
"General", "Village", "Building", "Market", "Landscape",
|
|
"Cave", "Recreation", "Bank", "Post", "Station", "Street", "Nether-Portal"
|
|
}
|
|
local category_list_for_gui = table.concat(poi.categories, ",")
|
|
|
|
|
|
-- 2. Kernfunktionen: Speichern, Laden und eine neue Hilfsfunktion
|
|
-------------------------------------------------------------------
|
|
function poi.save()
|
|
storage:set_string("data", minetest.write_json(poi.points))
|
|
end
|
|
|
|
function poi.load()
|
|
local json_data = storage:get_string("data")
|
|
if json_data and json_data ~= "" then
|
|
poi.points = minetest.parse_json(json_data) or {}
|
|
else
|
|
poi.points = {}
|
|
end
|
|
print("[MOD] " .. poi.modname .. ": " .. table.getn(poi.points) .. " POIs geladen.")
|
|
end
|
|
|
|
-- NEUE Hilfsfunktion: Findet die ID zu einem gegebenen Namen
|
|
local function get_category_id_by_name(name_to_find)
|
|
for id, name in ipairs(poi.categories) do
|
|
if name == name_to_find then
|
|
return id
|
|
end
|
|
end
|
|
return 1 -- Fallback auf "General"
|
|
end
|
|
|
|
|
|
-- 3. GUI-Funktion (Mit deinen Anpassungen)
|
|
-------------------------------------------------------------------
|
|
function poi.show_gui(player_name)
|
|
local player = minetest.get_player_by_name(player_name)
|
|
if not player then return end
|
|
|
|
if not poi.player_gui_state[player_name] then
|
|
poi.player_gui_state[player_name] = { selected_poi_name = "" }
|
|
end
|
|
local state = poi.player_gui_state[player_name]
|
|
|
|
local sorted_poi_names = {}
|
|
for name in pairs(poi.points) do table.insert(sorted_poi_names, name) end
|
|
table.sort(sorted_poi_names)
|
|
|
|
local selected_idx = 0
|
|
local current_category_id = 1
|
|
if state.selected_poi_name ~= "" and poi.points[state.selected_poi_name] then
|
|
for i, name in ipairs(sorted_poi_names) do
|
|
if name == state.selected_poi_name then
|
|
selected_idx = i
|
|
current_category_id = poi.points[state.selected_poi_name].category_id
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
local formspec = "size[8.5,8]" ..
|
|
"label[0.2,0.2;POI Management]" ..
|
|
"textlist[0.2,0.6;4,6;poi_list;" .. table.concat(sorted_poi_names, ",") .. ";" .. selected_idx .. "]" ..
|
|
"field[4.8,1.1;3.7,1;poi_name;POI Name;" .. state.selected_poi_name .."]" ..
|
|
"label[4.5,1.6;Category:]" ..
|
|
"dropdown[4.5,2;3.8,1;category_dropdown;" .. category_list_for_gui .. ";" .. current_category_id .."]" ..
|
|
"button[4.5,3.5;1.8,1;create_new;Neu anlegen]" ..
|
|
"button[6.5,3.5;1.8,1;update;Update/Rename]" ..
|
|
"button[4.5,5;1.8,1;move;Verschieben]" ..
|
|
"button[6.5,5;1.8,1;delete;Löschen]" ..
|
|
"button_exit[0.2,7;8.1,1;exit;Schließen]"
|
|
|
|
minetest.show_formspec(player_name, poi.modname .. ":main", formspec)
|
|
end
|
|
|
|
|
|
-- 4. GUI-Callback (Handler)
|
|
-------------------------------------------------------------------
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if formname ~= poi.modname .. ":main" then return end
|
|
|
|
local player_name = player:get_player_name()
|
|
local state = poi.player_gui_state[player_name]
|
|
if not state then return end
|
|
|
|
local poi_list_event = minetest.explode_textlist_event(fields.poi_list)
|
|
if poi_list_event.type == "CHG" then
|
|
local sorted_list = {}
|
|
for name in pairs(poi.points) do table.insert(sorted_list, name) end
|
|
table.sort(sorted_list)
|
|
state.selected_poi_name = sorted_list[poi_list_event.index] or ""
|
|
poi.show_gui(player_name)
|
|
return
|
|
end
|
|
|
|
if fields.create_new then
|
|
local name = fields.poi_name
|
|
if name and name ~= "" then
|
|
if poi.points[name] then
|
|
minetest.chat_send_player(player_name, "FEHLER: Ein POI mit diesem Namen existiert bereits.")
|
|
else
|
|
local cat_name = fields.category_dropdown
|
|
local cat_id = get_category_id_by_name(cat_name)
|
|
poi.points[name] = {
|
|
pos = player:getpos(),
|
|
owner = player_name,
|
|
category_id = cat_id,
|
|
category_name = cat_name
|
|
}
|
|
poi.save()
|
|
minetest.chat_send_player(player_name, "POI '" .. name .. "' erstellt (Kategorie: " .. cat_name .. ").")
|
|
state.selected_poi_name = name
|
|
end
|
|
else
|
|
minetest.chat_send_player(player_name, "FEHLER: Name für neuen POI darf nicht leer sein.")
|
|
end
|
|
poi.show_gui(player_name)
|
|
return
|
|
end
|
|
|
|
if fields.update then
|
|
local selected_name = state.selected_poi_name
|
|
local new_name = fields.poi_name
|
|
|
|
if selected_name and selected_name ~= "" and poi.points[selected_name] then
|
|
local cat_name = fields.category_dropdown
|
|
local cat_id = get_category_id_by_name(cat_name)
|
|
local data = poi.points[selected_name]
|
|
data.category_id = cat_id
|
|
data.category_name = cat_name
|
|
|
|
if new_name and new_name ~= "" and new_name ~= selected_name then
|
|
if poi.points[new_name] then
|
|
minetest.chat_send_player(player_name, "FEHLER: Der neue Name '"..new_name.."' existiert bereits.")
|
|
else
|
|
poi.points[new_name] = data
|
|
poi.points[selected_name] = nil
|
|
minetest.chat_send_player(player_name, "POI umbenannt und aktualisiert.")
|
|
state.selected_poi_name = new_name
|
|
end
|
|
else
|
|
poi.points[selected_name] = data
|
|
minetest.chat_send_player(player_name, "POI '" .. selected_name .. "' aktualisiert.")
|
|
end
|
|
poi.save()
|
|
else
|
|
minetest.chat_send_player(player_name, "FEHLER: Keinen POI zum Aktualisieren ausgewählt.")
|
|
end
|
|
poi.show_gui(player_name)
|
|
return
|
|
end
|
|
|
|
if fields.move then
|
|
local name = state.selected_poi_name
|
|
if name and poi.points[name] then
|
|
poi.points[name].pos = player:getpos()
|
|
poi.save()
|
|
minetest.chat_send_player(player_name, "POI '"..name.."' an neue Position verschoben.")
|
|
else
|
|
minetest.chat_send_player(player_name, "FEHLER: Keinen POI zum Verschieben ausgewählt.")
|
|
end
|
|
poi.show_gui(player_name)
|
|
return
|
|
end
|
|
|
|
if fields.delete then
|
|
local name = state.selected_poi_name
|
|
if name and poi.points[name] then
|
|
poi.points[name] = nil
|
|
poi.save()
|
|
minetest.chat_send_player(player_name, "POI '"..name.."' gelöscht.")
|
|
state.selected_poi_name = ""
|
|
else
|
|
minetest.chat_send_player(player_name, "FEHLER: Keinen POI zum Löschen ausgewählt.")
|
|
end
|
|
poi.show_gui(player_name)
|
|
return
|
|
end
|
|
end)
|
|
|
|
|
|
-- 5. Befehle und Privilegien
|
|
-------------------------------------------------------------------
|
|
minetest.register_privilege("poi", {
|
|
description = "Allows managing POIs for the web map."
|
|
})
|
|
|
|
minetest.register_chatcommand("poi_gui", {
|
|
params = "",
|
|
description = "Shows the POI management GUI.",
|
|
privs = {poi = true},
|
|
func = function(name)
|
|
poi.show_gui(name)
|
|
end,
|
|
})
|
|
|
|
|
|
-- 6. Mod starten
|
|
-------------------------------------------------------------------
|
|
poi.load()
|